cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

x86_descr.c (4204B)


      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.1 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