diff options
Diffstat (limited to 'testcases/kernel/kvm/include/kvm_x86.h')
-rw-r--r-- | testcases/kernel/kvm/include/kvm_x86.h | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/testcases/kernel/kvm/include/kvm_x86.h b/testcases/kernel/kvm/include/kvm_x86.h index 4f3671135..bc36c0e0f 100644 --- a/testcases/kernel/kvm/include/kvm_x86.h +++ b/testcases/kernel/kvm/include/kvm_x86.h @@ -10,6 +10,9 @@ #include "kvm_test.h" +#define PAGESIZE 0x1000 +#define KVM_GDT_SIZE 32 + /* Interrupts */ #define X86_INTR_COUNT 256 @@ -38,19 +41,48 @@ #define INTR_SECURITY_ERROR 30 +/* Segment descriptor flags */ +#define SEGTYPE_LDT 0x02 +#define SEGTYPE_TSS 0x09 +#define SEGTYPE_TSS_BUSY 0x0b +#define SEGTYPE_CALL_GATE 0x0c +#define SEGTYPE_INTR_GATE 0x0e +#define SEGTYPE_TRAP_GATE 0x0f +#define SEGTYPE_RODATA 0x10 +#define SEGTYPE_RWDATA 0x12 +#define SEGTYPE_STACK 0x16 +#define SEGTYPE_CODE 0x1a +#define SEGTYPE_MASK 0x1f + +#define SEGFLAG_NSYSTEM 0x10 +#define SEGFLAG_PRESENT 0x80 +#define SEGFLAG_CODE64 0x200 +#define SEGFLAG_32BIT 0x400 +#define SEGFLAG_PAGE_LIMIT 0x800 + + /* CPUID constants */ #define CPUID_GET_INPUT_RANGE 0x80000000 #define CPUID_GET_EXT_FEATURES 0x80000001 +#define CPUID_GET_SVM_FEATURES 0x8000000a /* Model-specific CPU register constants */ #define MSR_EFER 0xc0000080 +#define MSR_VM_CR 0xc0010114 +#define MSR_VM_HSAVE_PA 0xc0010117 #define EFER_SCE (1 << 0) /* SYSCALL/SYSRET instructions enabled */ #define EFER_LME (1 << 8) /* CPU is running in 64bit mode */ #define EFER_LMA (1 << 10) /* CPU uses 64bit memory paging (read-only) */ #define EFER_NXE (1 << 11) /* Execute disable bit active */ +#define EFER_SVME (1 << 12) /* AMD SVM instructions enabled */ +#define VM_CR_DPD (1 << 0) +#define VM_CR_R_INIT (1 << 1) +#define VM_CR_DIS_A20M (1 << 2) +#define VM_CR_LOCK (1 << 3) +#define VM_CR_SVMDIS (1 << 4) /* Control register constants */ #define CR4_VME (1 << 0) @@ -91,6 +123,25 @@ struct intr_descriptor { #endif /* defined(__x86_64__) */ } __attribute__((__packed__)); +struct segment_descriptor { + unsigned int limit_lo : 16; + unsigned int baseaddr_lo : 24; + unsigned int flags_lo : 8; + unsigned int limit_hi : 4; + unsigned int flags_hi : 4; + unsigned int baseaddr_hi : 8; +} __attribute__((__packed__)); + +struct segment_descriptor64 { + unsigned int limit_lo : 16; + unsigned int baseaddr_lo : 24; + unsigned int flags_lo : 8; + unsigned int limit_hi : 4; + unsigned int flags_hi : 4; + uint64_t baseaddr_hi : 40; + uint32_t reserved; +} __attribute__((__packed__)); + struct page_table_entry_pae { unsigned int present: 1; unsigned int writable: 1; @@ -116,15 +167,36 @@ struct kvm_cregs { unsigned long cr0, cr2, cr3, cr4; }; +struct kvm_sregs { + uint16_t cs, ds, es, fs, gs, ss; +}; + +struct kvm_regs64 { + uint64_t rax, rbx, rcx, rdx, rdi, rsi, rbp, rsp; + uint64_t r8, r9, r10, r11, r12, r13, r14, r15; +}; + extern struct page_table_entry_pae kvm_pagetable[]; extern struct intr_descriptor kvm_idt[X86_INTR_COUNT]; +extern struct segment_descriptor kvm_gdt[KVM_GDT_SIZE]; /* Page table helper functions */ uintptr_t kvm_get_page_address_pae(const struct page_table_entry_pae *entry); +/* Segment descriptor table functions */ +void kvm_set_segment_descriptor(struct segment_descriptor *dst, + uint64_t baseaddr, uint32_t limit, unsigned int flags); +void kvm_parse_segment_descriptor(struct segment_descriptor *src, + uint64_t *baseaddr, uint32_t *limit, unsigned int *flags); +int kvm_find_free_descriptor(const struct segment_descriptor *table, + size_t size); +unsigned int kvm_create_stack_descriptor(struct segment_descriptor *table, + size_t tabsize, void *stack_base); + /* Functions for querying CPU info and status */ void kvm_get_cpuid(unsigned int eax, unsigned int ecx, struct kvm_cpuid *buf); void kvm_read_cregs(struct kvm_cregs *buf); +void kvm_read_sregs(struct kvm_sregs *buf); uint64_t kvm_rdmsr(unsigned int msr); void kvm_wrmsr(unsigned int msr, uint64_t value); |