aboutsummaryrefslogtreecommitdiff
path: root/testcases/kernel/kvm/include/kvm_x86.h
diff options
context:
space:
mode:
Diffstat (limited to 'testcases/kernel/kvm/include/kvm_x86.h')
-rw-r--r--testcases/kernel/kvm/include/kvm_x86.h72
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);