qemu/target/i386/hvf/x86_descr.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2016 Veertu Inc,
   3 * Copyright (C) 2017 Google Inc,
   4 *
   5 * This program is free software; you can redistribute it and/or
   6 * modify it under the terms of the GNU Lesser General Public
   7 * License as published by the Free Software Foundation; either
   8 * version 2 of the License, or (at your option) any later version.
   9 *
  10 * This program is distributed in the hope that it will be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13 * Lesser General Public License for more details.
  14 *
  15 * You should have received a copy of the GNU Lesser General Public
  16 * License along with this program; if not, see <http://www.gnu.org/licenses/>.
  17 */
  18
  19#include "qemu/osdep.h"
  20
  21#include "qemu-common.h"
  22#include "vmx.h"
  23#include "x86_descr.h"
  24
  25#define VMX_SEGMENT_FIELD(seg)                        \
  26    [R_##seg] = {                                     \
  27        .selector = VMCS_GUEST_##seg##_SELECTOR,      \
  28        .base = VMCS_GUEST_##seg##_BASE,              \
  29        .limit = VMCS_GUEST_##seg##_LIMIT,            \
  30        .ar_bytes = VMCS_GUEST_##seg##_ACCESS_RIGHTS, \
  31}
  32
  33static const struct vmx_segment_field {
  34    int selector;
  35    int base;
  36    int limit;
  37    int ar_bytes;
  38} vmx_segment_fields[] = {
  39    VMX_SEGMENT_FIELD(ES),
  40    VMX_SEGMENT_FIELD(CS),
  41    VMX_SEGMENT_FIELD(SS),
  42    VMX_SEGMENT_FIELD(DS),
  43    VMX_SEGMENT_FIELD(FS),
  44    VMX_SEGMENT_FIELD(GS),
  45    VMX_SEGMENT_FIELD(LDTR),
  46    VMX_SEGMENT_FIELD(TR),
  47};
  48
  49uint32_t vmx_read_segment_limit(CPUState *cpu, X86Seg seg)
  50{
  51    return (uint32_t)rvmcs(cpu->hvf_fd, vmx_segment_fields[seg].limit);
  52}
  53
  54uint32_t vmx_read_segment_ar(CPUState *cpu, X86Seg seg)
  55{
  56    return (uint32_t)rvmcs(cpu->hvf_fd, vmx_segment_fields[seg].ar_bytes);
  57}
  58
  59uint64_t vmx_read_segment_base(CPUState *cpu, X86Seg seg)
  60{
  61    return rvmcs(cpu->hvf_fd, vmx_segment_fields[seg].base);
  62}
  63
  64x68_segment_selector vmx_read_segment_selector(CPUState *cpu, X86Seg seg)
  65{
  66    x68_segment_selector sel;
  67    sel.sel = rvmcs(cpu->hvf_fd, vmx_segment_fields[seg].selector);
  68    return sel;
  69}
  70
  71void vmx_write_segment_selector(struct CPUState *cpu, x68_segment_selector selector, X86Seg seg)
  72{
  73    wvmcs(cpu->hvf_fd, vmx_segment_fields[seg].selector, selector.sel);
  74}
  75
  76void vmx_read_segment_descriptor(struct CPUState *cpu, struct vmx_segment *desc, X86Seg seg)
  77{
  78    desc->sel = rvmcs(cpu->hvf_fd, vmx_segment_fields[seg].selector);
  79    desc->base = rvmcs(cpu->hvf_fd, vmx_segment_fields[seg].base);
  80    desc->limit = rvmcs(cpu->hvf_fd, vmx_segment_fields[seg].limit);
  81    desc->ar = rvmcs(cpu->hvf_fd, vmx_segment_fields[seg].ar_bytes);
  82}
  83
  84void vmx_write_segment_descriptor(CPUState *cpu, struct vmx_segment *desc, X86Seg seg)
  85{
  86    const struct vmx_segment_field *sf = &vmx_segment_fields[seg];
  87
  88    wvmcs(cpu->hvf_fd, sf->base, desc->base);
  89    wvmcs(cpu->hvf_fd, sf->limit, desc->limit);
  90    wvmcs(cpu->hvf_fd, sf->selector, desc->sel);
  91    wvmcs(cpu->hvf_fd, sf->ar_bytes, desc->ar);
  92}
  93
  94void x86_segment_descriptor_to_vmx(struct CPUState *cpu, x68_segment_selector selector, struct x86_segment_descriptor *desc, struct vmx_segment *vmx_desc)
  95{
  96    vmx_desc->sel = selector.sel;
  97    vmx_desc->base = x86_segment_base(desc);
  98    vmx_desc->limit = x86_segment_limit(desc);
  99
 100    vmx_desc->ar = (selector.sel ? 0 : 1) << 16 |
 101                    desc->g << 15 |
 102                    desc->db << 14 |
 103                    desc->l << 13 |
 104                    desc->avl << 12 |
 105                    desc->p << 7 |
 106                    desc->dpl << 5 |
 107                    desc->s << 4 |
 108                    desc->type;
 109}
 110
 111void vmx_segment_to_x86_descriptor(struct CPUState *cpu, struct vmx_segment *vmx_desc, struct x86_segment_descriptor *desc)
 112{
 113    x86_set_segment_limit(desc, vmx_desc->limit);
 114    x86_set_segment_base(desc, vmx_desc->base);
 115    
 116    desc->type = vmx_desc->ar & 15;
 117    desc->s = (vmx_desc->ar >> 4) & 1;
 118    desc->dpl = (vmx_desc->ar >> 5) & 3;
 119    desc->p = (vmx_desc->ar >> 7) & 1;
 120    desc->avl = (vmx_desc->ar >> 12) & 1;
 121    desc->l = (vmx_desc->ar >> 13) & 1;
 122    desc->db = (vmx_desc->ar >> 14) & 1;
 123    desc->g = (vmx_desc->ar >> 15) & 1;
 124}
 125
 126