]> rtime.felk.cvut.cz Git - jailhouse.git/commitdiff
x86: Add AMD-V definitions and data structures
authorValentine Sinitsyn <valentine.sinitsyn@gmail.com>
Sun, 3 Aug 2014 17:41:07 +0000 (23:41 +0600)
committerJan Kiszka <jan.kiszka@siemens.com>
Sat, 1 Nov 2014 19:10:08 +0000 (20:10 +0100)
AMD-V data structures (VMCB, exit codes, flags etc) were adapted
from the Xvisor code. See http://xhypervisor.org for details.

Signed-off-by: Valentine Sinitsyn <valentine.sinitsyn@gmail.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
hypervisor/arch/x86/include/asm/percpu.h
hypervisor/arch/x86/include/asm/svm.h

index 3566566bbc6216e8ffba9e50cfe0302e89f68ea8..e35191a8789a41df459a54e970f81b0ab3611f95 100644 (file)
@@ -32,6 +32,7 @@
 
 #include <asm/cell.h>
 #include <asm/spinlock.h>
+#include <asm/svm.h>
 #include <asm/vmx.h>
 
 /**
@@ -140,7 +141,9 @@ struct per_cpu {
                                __attribute__((aligned(PAGE_SIZE)));
                };
                struct {
-                       /* TODO: Add VMCB block here */
+                       /** VMCB block, required by SVM. */
+                       struct vmcb vmcb
+                               __attribute__((aligned(PAGE_SIZE)));
                        /** SVM Host save area; opaque to us. */
                        u8 host_state[PAGE_SIZE]
                                __attribute__((aligned(PAGE_SIZE)));
index e764bc12330b23b05a49320ac51aab8a26540dfd..b3915ad727cc8ad6b22984ba9b83d2515d4c0188 100644 (file)
@@ -1,11 +1,16 @@
 /*
  * Jailhouse, a Linux-based partitioning hypervisor
  *
+ * Copyright (c) 2005-2007, Advanced Micro Devices, Inc
+ * Copyright (c) 2004, Intel Corporation.
  * Copyright (c) Valentine Sinitsyn, 2014
  *
  * Authors:
  *  Valentine Sinitsyn <valentine.sinitsyn@gmail.com>
  *
+ * Definitions in this file were adapted from Xvisor source code.
+ * See http://xhypervisor.org for details.
+ *
  * This work is licensed under the terms of the GNU GPL, version 2.  See
  * the COPYING file in the top-level directory.
  */
 #ifndef _JAILHOUSE_ASM_SVM_H
 #define _JAILHOUSE_ASM_SVM_H
 
-/* Nothing here yet */
+#include <jailhouse/types.h>
+
+#define EFER_SVME              (1UL << 12)
+#define VM_CR_SVMDIS           (1UL << 4)
+
+#define MSR_VM_CR              0xc0010114
+#define MSR_VM_HSAVE_PA                0xc0010117
+
+#define SVM_MSRPM_0000         0
+#define SVM_MSRPM_C000         1
+#define SVM_MSRPM_C001         2
+#define SVM_MSRPM_RESV         3
+
+#define NPT_PAGE_DIR_LEVELS    4
+
+struct svm_segment {
+       u16 selector;
+       u16 access_rights;
+       u32 limit;
+       u64 base;
+} __attribute__((packed));
+
+/* general 1 intercepts */
+enum generic_interrupt_1_bits {
+       GENERAL1_INTERCEPT_INTR          = 1 << 0,
+       GENERAL1_INTERCEPT_NMI           = 1 << 1,
+       GENERAL1_INTERCEPT_SMI           = 1 << 2,
+       GENERAL1_INTERCEPT_INIT          = 1 << 3,
+       GENERAL1_INTERCEPT_VINTR         = 1 << 4,
+       GENERAL1_INTERCEPT_CR0_SEL_WRITE = 1 << 5,
+       GENERAL1_INTERCEPT_IDTR_READ     = 1 << 6,
+       GENERAL1_INTERCEPT_GDTR_READ     = 1 << 7,
+       GENERAL1_INTERCEPT_LDTR_READ     = 1 << 8,
+       GENERAL1_INTERCEPT_TR_READ       = 1 << 9,
+       GENERAL1_INTERCEPT_IDTR_WRITE    = 1 << 10,
+       GENERAL1_INTERCEPT_GDTR_WRITE    = 1 << 11,
+       GENERAL1_INTERCEPT_LDTR_WRITE    = 1 << 12,
+       GENERAL1_INTERCEPT_TR_WRITE      = 1 << 13,
+       GENERAL1_INTERCEPT_RDTSC         = 1 << 14,
+       GENERAL1_INTERCEPT_RDPMC         = 1 << 15,
+       GENERAL1_INTERCEPT_PUSHF         = 1 << 16,
+       GENERAL1_INTERCEPT_POPF          = 1 << 17,
+       GENERAL1_INTERCEPT_CPUID         = 1 << 18,
+       GENERAL1_INTERCEPT_RSM           = 1 << 19,
+       GENERAL1_INTERCEPT_IRET          = 1 << 20,
+       GENERAL1_INTERCEPT_SWINT         = 1 << 21,
+       GENERAL1_INTERCEPT_INVD          = 1 << 22,
+       GENERAL1_INTERCEPT_PAUSE         = 1 << 23,
+       GENERAL1_INTERCEPT_HLT           = 1 << 24,
+       GENERAL1_INTERCEPT_INVLPG        = 1 << 25,
+       GENERAL1_INTERCEPT_INVLPGA       = 1 << 26,
+       GENERAL1_INTERCEPT_IOIO_PROT     = 1 << 27,
+       GENERAL1_INTERCEPT_MSR_PROT      = 1 << 28,
+       GENERAL1_INTERCEPT_TASK_SWITCH   = 1 << 29,
+       GENERAL1_INTERCEPT_FERR_FREEZE   = 1 << 30,
+       GENERAL1_INTERCEPT_SHUTDOWN_EVT  = 1 << 31
+};
+
+/* general 2 intercepts */
+enum generic_interrupts_2_bits {
+       GENERAL2_INTERCEPT_VMRUN   = 1 << 0,
+       GENERAL2_INTERCEPT_VMMCALL = 1 << 1,
+       GENERAL2_INTERCEPT_VMLOAD  = 1 << 2,
+       GENERAL2_INTERCEPT_VMSAVE  = 1 << 3,
+       GENERAL2_INTERCEPT_STGI    = 1 << 4,
+       GENERAL2_INTERCEPT_CLGI    = 1 << 5,
+       GENERAL2_INTERCEPT_SKINIT  = 1 << 6,
+       GENERAL2_INTERCEPT_RDTSCP  = 1 << 7,
+       GENERAL2_INTERCEPT_ICEBP   = 1 << 8,
+       GENERAL2_INTERCEPT_WBINVD  = 1 << 9,
+       GENERAL2_INTERCEPT_MONITOR = 1 << 10,
+       GENERAL2_INTERCEPT_MWAIT   = 1 << 11,
+       GENERAL2_INTERCEPT_MWAIT_CONDITIONAL = 1 << 12
+};
+
+enum vm_exit_code {
+       /* control register read exitcodes */
+       VMEXIT_CR0_READ    =   0,
+       VMEXIT_CR1_READ    =   1,
+       VMEXIT_CR2_READ    =   2,
+       VMEXIT_CR3_READ    =   3,
+       VMEXIT_CR4_READ    =   4,
+       VMEXIT_CR5_READ    =   5,
+       VMEXIT_CR6_READ    =   6,
+       VMEXIT_CR7_READ    =   7,
+       VMEXIT_CR8_READ    =   8,
+       VMEXIT_CR9_READ    =   9,
+       VMEXIT_CR10_READ   =  10,
+       VMEXIT_CR11_READ   =  11,
+       VMEXIT_CR12_READ   =  12,
+       VMEXIT_CR13_READ   =  13,
+       VMEXIT_CR14_READ   =  14,
+       VMEXIT_CR15_READ   =  15,
+
+       /* control register write exitcodes */
+       VMEXIT_CR0_WRITE   =  16,
+       VMEXIT_CR1_WRITE   =  17,
+       VMEXIT_CR2_WRITE   =  18,
+       VMEXIT_CR3_WRITE   =  19,
+       VMEXIT_CR4_WRITE   =  20,
+       VMEXIT_CR5_WRITE   =  21,
+       VMEXIT_CR6_WRITE   =  22,
+       VMEXIT_CR7_WRITE   =  23,
+       VMEXIT_CR8_WRITE   =  24,
+       VMEXIT_CR9_WRITE   =  25,
+       VMEXIT_CR10_WRITE  =  26,
+       VMEXIT_CR11_WRITE  =  27,
+       VMEXIT_CR12_WRITE  =  28,
+       VMEXIT_CR13_WRITE  =  29,
+       VMEXIT_CR14_WRITE  =  30,
+       VMEXIT_CR15_WRITE  =  31,
+
+       /* debug register read exitcodes */
+       VMEXIT_DR0_READ    =  32,
+       VMEXIT_DR1_READ    =  33,
+       VMEXIT_DR2_READ    =  34,
+       VMEXIT_DR3_READ    =  35,
+       VMEXIT_DR4_READ    =  36,
+       VMEXIT_DR5_READ    =  37,
+       VMEXIT_DR6_READ    =  38,
+       VMEXIT_DR7_READ    =  39,
+       VMEXIT_DR8_READ    =  40,
+       VMEXIT_DR9_READ    =  41,
+       VMEXIT_DR10_READ   =  42,
+       VMEXIT_DR11_READ   =  43,
+       VMEXIT_DR12_READ   =  44,
+       VMEXIT_DR13_READ   =  45,
+       VMEXIT_DR14_READ   =  46,
+       VMEXIT_DR15_READ   =  47,
+
+       /* debug register write exitcodes */
+       VMEXIT_DR0_WRITE   =  48,
+       VMEXIT_DR1_WRITE   =  49,
+       VMEXIT_DR2_WRITE   =  50,
+       VMEXIT_DR3_WRITE   =  51,
+       VMEXIT_DR4_WRITE   =  52,
+       VMEXIT_DR5_WRITE   =  53,
+       VMEXIT_DR6_WRITE   =  54,
+       VMEXIT_DR7_WRITE   =  55,
+       VMEXIT_DR8_WRITE   =  56,
+       VMEXIT_DR9_WRITE   =  57,
+       VMEXIT_DR10_WRITE  =  58,
+       VMEXIT_DR11_WRITE  =  59,
+       VMEXIT_DR12_WRITE  =  60,
+       VMEXIT_DR13_WRITE  =  61,
+       VMEXIT_DR14_WRITE  =  62,
+       VMEXIT_DR15_WRITE  =  63,
+
+       /* processor exception exitcodes (VMEXIT_EXCP[0-31]) */
+       VMEXIT_EXCEPTION_DE      =      64, /* divide-by-zero-error */
+       VMEXIT_EXCEPTION_DB      =      65, /* debug */
+       VMEXIT_EXCEPTION_NMI     =      66, /* non-maskable-interrupt */
+       VMEXIT_EXCEPTION_BP      =      67, /* breakpoint */
+       VMEXIT_EXCEPTION_OF      =      68, /* overflow */
+       VMEXIT_EXCEPTION_BR      =      69, /* bound-range */
+       VMEXIT_EXCEPTION_UD      =      70, /* invalid-opcode*/
+       VMEXIT_EXCEPTION_NM      =      71, /* device-not-available */
+       VMEXIT_EXCEPTION_DF      =      72, /* double-fault */
+       VMEXIT_EXCEPTION_09      =      73, /* unsupported (reserved) */
+       VMEXIT_EXCEPTION_TS      =      74, /* invalid-tss */
+       VMEXIT_EXCEPTION_NP      =      75, /* segment-not-present */
+       VMEXIT_EXCEPTION_SS      =      76, /* stack */
+       VMEXIT_EXCEPTION_GP      =      77, /* general-protection */
+       VMEXIT_EXCEPTION_PF      =      78, /* page-fault */
+       VMEXIT_EXCEPTION_15      =      79, /* reserved */
+       VMEXIT_EXCEPTION_MF      =      80, /* x87 floating-point exception-pending */
+       VMEXIT_EXCEPTION_AC      =      81, /* alignment-check */
+       VMEXIT_EXCEPTION_MC      =      82, /* machine-check */
+       VMEXIT_EXCEPTION_XF      =      83, /* simd floating-point */
+
+       /* exceptions 20-31 (exitcodes 84-95) are reserved */
+
+       /* ...and the rest of the #VMEXITs */
+       VMEXIT_INTR                     =  96,
+       VMEXIT_NMI                      =  97,
+       VMEXIT_SMI                      =  98,
+       VMEXIT_INIT                     =  99,
+       VMEXIT_VINTR                    = 100,
+       VMEXIT_CR0_SEL_WRITE            = 101,
+       VMEXIT_IDTR_READ                = 102,
+       VMEXIT_GDTR_READ                = 103,
+       VMEXIT_LDTR_READ                = 104,
+       VMEXIT_TR_READ                  = 105,
+       VMEXIT_IDTR_WRITE               = 106,
+       VMEXIT_GDTR_WRITE               = 107,
+       VMEXIT_LDTR_WRITE               = 108,
+       VMEXIT_TR_WRITE                 = 109,
+       VMEXIT_RDTSC                    = 110,
+       VMEXIT_RDPMC                    = 111,
+       VMEXIT_PUSHF                    = 112,
+       VMEXIT_POPF                     = 113,
+       VMEXIT_CPUID                    = 114,
+       VMEXIT_RSM                      = 115,
+       VMEXIT_IRET                     = 116,
+       VMEXIT_SWINT                    = 117,
+       VMEXIT_INVD                     = 118,
+       VMEXIT_PAUSE                    = 119,
+       VMEXIT_HLT                      = 120,
+       VMEXIT_INVLPG                   = 121,
+       VMEXIT_INVLPGA                  = 122,
+       VMEXIT_IOIO                     = 123,
+       VMEXIT_MSR                      = 124,
+       VMEXIT_TASK_SWITCH              = 125,
+       VMEXIT_FERR_FREEZE              = 126,
+       VMEXIT_SHUTDOWN                 = 127,
+       VMEXIT_VMRUN                    = 128,
+       VMEXIT_VMMCALL                  = 129,
+       VMEXIT_VMLOAD                   = 130,
+       VMEXIT_VMSAVE                   = 131,
+       VMEXIT_STGI                     = 132,
+       VMEXIT_CLGI                     = 133,
+       VMEXIT_SKINIT                   = 134,
+       VMEXIT_RDTSCP                   = 135,
+       VMEXIT_ICEBP                    = 136,
+       VMEXIT_WBINVD                   = 137,
+       VMEXIT_MONITOR                  = 138,
+       VMEXIT_MWAIT                    = 139,
+       VMEXIT_MWAIT_CONDITIONAL        = 140,
+       VMEXIT_XSETBV                   = 141,
+       VMEXIT_NPF                      = 1024, /* nested paging fault */
+       VMEXIT_INVALID                  =  -1
+};
+
+typedef u64 vintr_t;
+typedef u64 eventinj_t;
+typedef u64 lbrctrl_t;
+
+struct vmcb {
+       u32 cr_intercepts;              /* offset 0x00 */
+       u32 dr_intercepts;              /* offset 0x04 */
+       u32 exception_intercepts;       /* offset 0x08 */
+       u32 general1_intercepts;        /* offset 0x0C */
+       u32 general2_intercepts;        /* offset 0x10 */
+       u32 res01;                      /* offset 0x14 */
+       u64 res02;                      /* offset 0x18 */
+       u64 res03;                      /* offset 0x20 */
+       u64 res04;                      /* offset 0x28 */
+       u64 res05;                      /* offset 0x30 */
+       u32 res06;                      /* offset 0x38 */
+       u16 res06a;                     /* offset 0x3C */
+       u16 pause_filter_count;         /* offset 0x3E */
+       u64 iopm_base_pa;               /* offset 0x40 */
+       u64 msrpm_base_pa;              /* offset 0x48 */
+       u64 tsc_offset;                 /* offset 0x50 */
+       u32 guest_asid;                 /* offset 0x58 */
+       u8 tlb_control;                 /* offset 0x5C */
+       u8 res07[3];
+       vintr_t vintr;                  /* offset 0x60 */
+       u64 interrupt_shadow;           /* offset 0x68 */
+       u64 exitcode;                   /* offset 0x70 */
+       u64 exitinfo1;                  /* offset 0x78 */
+       u64 exitinfo2;                  /* offset 0x80 */
+       eventinj_t      exitintinfo;    /* offset 0x88 */
+       u64 np_enable;                  /* offset 0x90 */
+       u64 res08[2];
+       eventinj_t      eventinj;       /* offset 0xA8 */
+       u64 n_cr3;                      /* offset 0xB0 */
+       lbrctrl_t lbr_control;          /* offset 0xB8 */
+       u64 res09;                      /* offset 0xC0 */
+       u64 nextrip;                    /* offset 0xC8 */
+       u8 bytes_fetched;               /* offset 0xD0 */
+       u8 guest_bytes[15];
+       u64 res10a[100];                /* offset 0xE0 pad to save area */
+
+       struct svm_segment es;          /* offset 1024 */
+       struct svm_segment cs;
+       struct svm_segment ss;
+       struct svm_segment ds;
+       struct svm_segment fs;
+       struct svm_segment gs;
+       struct svm_segment gdtr;
+       struct svm_segment ldtr;
+       struct svm_segment idtr;
+       struct svm_segment tr;
+
+       u64 res10[5];
+       u8 res11[3];
+       u8 cpl;
+       u32 res12;
+       u64 efer;                       /* offset 1024 + 0xD0 */
+       u64 res13[14];
+       u64 cr4;                        /* loffset 1024 + 0x148 */
+       u64 cr3;
+       u64 cr0;
+       u64 dr7;
+       u64 dr6;
+       u64 rflags;
+       u64 rip;
+       u64 res14[11];
+       u64 rsp;
+       u64 res15[3];
+       u64 rax;
+       u64 star;
+       u64 lstar;
+       u64 cstar;
+       u64 sfmask;
+       u64 kerngsbase;
+       u64 sysenter_cs;
+       u64 sysenter_esp;
+       u64 sysenter_eip;
+       u64 cr2;
+       u64 pdpe0;
+       u64 pdpe1;
+       u64 pdpe2;
+       u64 pdpe3;
+       u64 g_pat;
+       u64 debugctlmsr;
+       u64 lastbranchfromip;
+       u64 lastbranchtoip;
+       u64 lastintfromip;
+       u64 lastinttoip;
+       u64 res16[301];
+} __attribute__((packed));
 
 void svm_vmexit(void);