From ca616694a1ae0bb9a15b08a2dc4613f46871435d Mon Sep 17 00:00:00 2001 From: Siqueira Date: Mon, 11 Sep 2017 09:34:54 -0300 Subject: [PATCH 1/2] Applied simple fix suggested by checkpatch * Removed error messages pointed by checkpatch script * There is a lot of WARNINGS related with LINUX_VERSION_CODE. I did not change it since it is a subject of future improvements * ept.c still have some warnings, however I left it for latter update * There is some warning that I left for later inspection --- kern/compat.h | 34 +++++----- kern/core.c | 27 +++++--- kern/dune.h | 12 +++- kern/ept.c | 58 +++++++++------- kern/preempttrap.c | 13 ++-- kern/vmx.c | 166 +++++++++++++++++++++++---------------------- kern/vmx.h | 10 +-- 7 files changed, 175 insertions(+), 145 deletions(-) diff --git a/kern/compat.h b/kern/compat.h index f642fb9..4e2b69c 100644 --- a/kern/compat.h +++ b/kern/compat.h @@ -3,25 +3,25 @@ #include -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0) +#if KERNEL_VERSION(3, 1, 0) <= LINUX_VERSION_CODE #include #else #include #endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0) +#if KERNEL_VERSION(4, 1, 0) <= LINUX_VERSION_CODE #include -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0) +#elif KERNEL_VERSION(3, 4, 0) <= LINUX_VERSION_CODE #include #endif #if !defined(VMX_EPT_AD_BIT) -#define VMX_EPT_AD_BIT (1ull << 21) -#define VMX_EPT_AD_ENABLE_BIT (1ull << 6) +#define VMX_EPT_AD_BIT (1ull << 21) +#define VMX_EPT_AD_ENABLE_BIT (1ull << 6) #endif #ifndef VMX_EPT_EXTENT_INDIVIDUAL_BIT -#define VMX_EPT_EXTENT_INDIVIDUAL_BIT (1ull << 24) +#define VMX_EPT_EXTENT_INDIVIDUAL_BIT (1ull << 24) #endif #ifndef X86_CR4_PCIDE @@ -40,17 +40,17 @@ #define AR_TYPE_BUSY_64_TSS VMX_AR_TYPE_BUSY_64_TSS #endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,3,0) +#if KERNEL_VERSION(4, 3, 0) <= LINUX_VERSION_CODE static inline struct page *alloc_pages_exact_node(int nid, gfp_t gfp_mask, - unsigned int order){ + unsigned int order) { return alloc_pages_node(nid, gfp_mask, order); } #endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0) & defined(_DO_FORK) +#if KERNEL_VERSION(4, 1, 0) <= LINUX_VERSION_CODE & defined(_DO_FORK) typedef long (*do_fork_hack) (unsigned long, unsigned long, unsigned long, - int __user *, int __user *, unsigned long); + int __user *, int __user *, unsigned long); static do_fork_hack __dune_do_fork = (do_fork_hack) _DO_FORK; static inline long dune_do_fork(unsigned long clone_flags, unsigned long stack_start, @@ -72,9 +72,9 @@ dune_do_fork(unsigned long clone_flags, unsigned long stack_start, return ret; } -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) & defined(DO_FORK) +#elif KERNEL_VERSION(3, 5, 0) <= LINUX_VERSION_CODE & defined(DO_FORK) typedef long (*do_fork_hack) (unsigned long, unsigned long, unsigned long, - int __user *, int __user *); + int __user *, int __user *); static do_fork_hack __dune_do_fork = (do_fork_hack) DO_FORK; static inline long dune_do_fork(unsigned long clone_flags, unsigned long stack_start, @@ -98,12 +98,12 @@ dune_do_fork(unsigned long clone_flags, unsigned long stack_start, } #elif defined(DO_FORK) typedef long (*do_fork_hack) (unsigned long, unsigned long, - struct pt_regs *, unsigned long, - int __user *, int __user *); + struct pt_regs *, unsigned long, + int __user *, int __user *); static do_fork_hack dune_do_fork = (do_fork_hack) DO_FORK; #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0) +#if KERNEL_VERSION(3, 19, 0) > LINUX_VERSION_CODE static inline unsigned long __read_cr4(void) { return read_cr4(); @@ -118,7 +118,7 @@ static inline void cr4_clear_bits(unsigned long mask) } #endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0) +#if KERNEL_VERSION(4, 1, 0) <= LINUX_VERSION_CODE static inline void compat_fpu_restore(void) { if (!current->thread.fpu.fpregs_active) @@ -132,7 +132,7 @@ static inline void compat_fpu_restore(void) } #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,18,0) +#if KERNEL_VERSION(3, 18, 0) > LINUX_VERSION_CODE #define _PAGE_CACHE_MODE_WB _PAGE_CACHE_WB #define _PAGE_CACHE_MODE_WC _PAGE_CACHE_WC static inline long pgprot2cachemode(pgprot_t pgprot) diff --git a/kern/core.c b/kern/core.c index 8e1e6d3..1c826d0 100644 --- a/kern/core.c +++ b/kern/core.c @@ -43,21 +43,22 @@ static int dune_is_in_guest(void) static int dune_is_user_mode(void) { - return 0; + return 0; } static unsigned long dune_get_guest_ip(void) { unsigned long long ip = 0; + if (__this_cpu_read(local_vcpu)) ip = vmcs_readl(GUEST_RIP); return ip; } static struct perf_guest_info_callbacks dune_guest_cbs = { - .is_in_guest = dune_is_in_guest, - .is_user_mode = dune_is_user_mode, - .get_guest_ip = dune_get_guest_ip, + .is_in_guest = dune_is_in_guest, + .is_user_mode = dune_is_user_mode, + .get_guest_ip = dune_get_guest_ip, }; static int dune_enter(struct dune_config *conf, int64_t *ret) @@ -95,13 +96,15 @@ static long dune_dev_ioctl(struct file *filp, case DUNE_GET_SYSCALL: rdmsrl(MSR_LSTAR, r); - printk(KERN_INFO "R %lx\n", (unsigned long) r); + pr_info("R %lx\n", (unsigned long) r); break; case DUNE_GET_LAYOUT: layout.phys_limit = (1UL << boot_cpu_data.x86_phys_bits); - layout.base_map = LG_ALIGN(current->mm->mmap_base) - GPA_MAP_SIZE; - layout.base_stack = LG_ALIGN(current->mm->start_stack) - GPA_STACK_SIZE; + layout.base_map = LG_ALIGN(current->mm->mmap_base) - + GPA_MAP_SIZE; + layout.base_stack = LG_ALIGN(current->mm->start_stack) - + GPA_STACK_SIZE; r = copy_to_user((void __user *)arg, &layout, sizeof(struct dune_layout)); if (r) { @@ -151,18 +154,20 @@ static struct miscdevice dune_dev = { static int __init dune_init(void) { int r; + perf_register_guest_info_callbacks(&dune_guest_cbs); - printk(KERN_ERR "Dune module loaded\n"); + pr_err("Dune module loaded\n"); - if ((r = vmx_init())) { - printk(KERN_ERR "dune: failed to initialize vmx\n"); + r = vmx_init(); + if (r) { + pr_err("dune: failed to initialize vmx\n"); return r; } r = misc_register(&dune_dev); if (r) { - printk(KERN_ERR "dune: misc device register failed\n"); + pr_err("dune: misc device register failed\n"); vmx_exit(); } diff --git a/kern/dune.h b/kern/dune.h index efcd1f0..89612f4 100644 --- a/kern/dune.h +++ b/kern/dune.h @@ -24,6 +24,7 @@ // XXX: Must match libdune/dune.h #define DUNE_SIGNAL_INTR_BASE 200 +//TODO: Add __packed and remove __attribute__ at the end struct dune_config { __s64 ret; __u64 rax; @@ -49,12 +50,14 @@ struct dune_config { __u64 vcpu; } __attribute__((packed)); +//TODO: Add __packed and remove __attribute__ at the end struct dune_layout { __u64 phys_limit; __u64 base_map; __u64 base_stack; } __attribute__((packed)); +//TODO: Add __packed and remove __attribute__ at the end struct dune_trap_regs { __u64 rax; __u64 rbx; @@ -76,8 +79,9 @@ struct dune_trap_regs { __u64 rflags; } __attribute__((packed)); -typedef void (* dune_trap_notify_func)(struct dune_trap_regs *, void *); +typedef void (*dune_trap_notify_func)(struct dune_trap_regs*, void*); +//TODO: Add __packed and remove __attribute__ at the end struct dune_trap_config { __u64 trigger_rip; dune_trap_notify_func notify_func; @@ -87,8 +91,10 @@ struct dune_trap_config { __u8 delay; } __attribute__((packed)); -#define GPA_STACK_SIZE ((unsigned long) 1 << 30) /* 1 gigabyte */ -#define GPA_MAP_SIZE (((unsigned long) 1 << 36) - GPA_STACK_SIZE) /* 63 gigabytes */ +/* 1 gigabyte */ +#define GPA_STACK_SIZE ((unsigned long) 1 << 30) +/* 63 gigabytes */ +#define GPA_MAP_SIZE (((unsigned long) 1 << 36) - GPA_STACK_SIZE) #define LG_ALIGN(addr) ((addr + (1 << 30) - 1) & ~((1 << 30) - 1)) #endif /* __ASSEMBLY__ */ diff --git a/kern/ept.c b/kern/ept.c index 83c4e53..cafb95c 100644 --- a/kern/ept.c +++ b/kern/ept.c @@ -8,7 +8,7 @@ * process page table. Mappings are created lazily as they are needed. * We keep the EPT synchronized with the process page table through * mmu_notifier callbacks. - * + * * Some of the low-level EPT functions are based on KVM. * Original Authors: * Avi Kivity @@ -62,6 +62,7 @@ static inline bool cpu_has_vmx_ept_4levels(void) #define VMX_EPT_FAULT_WRITE 0x02 #define VMX_EPT_FAULT_INS 0x04 +// TODO: Remove typedef later typedef unsigned long epte_t; #define __EPTE_READ 0x01 @@ -124,7 +125,7 @@ static unsigned long hva_to_gpa(struct vmx_vcpu *vcpu, uintptr_t gpa; BUG_ON(!mm); - + mmap_start = LG_ALIGN(mm->mmap_base) - GPA_MAP_SIZE; stack_start = LG_ALIGN(mm->start_stack) - GPA_STACK_SIZE; @@ -135,7 +136,8 @@ static unsigned long hva_to_gpa(struct vmx_vcpu *vcpu, } else if (hva >= mmap_start) { if (hva - mmap_start >= GPA_MAP_SIZE) return ADDR_INVAL; - gpa = hva - mmap_start + phys_end - GPA_STACK_SIZE - GPA_MAP_SIZE; + gpa = hva - mmap_start + phys_end - GPA_STACK_SIZE + - GPA_MAP_SIZE; } else { if (hva >= phys_end - GPA_STACK_SIZE - GPA_MAP_SIZE) return ADDR_INVAL; @@ -155,10 +157,10 @@ static unsigned long gpa_to_hva(struct vmx_vcpu *vcpu, return gpa; else if (gpa < phys_end - GPA_STACK_SIZE) return gpa - (phys_end - GPA_STACK_SIZE - GPA_MAP_SIZE) + - LG_ALIGN(mm->mmap_base) - GPA_MAP_SIZE; + LG_ALIGN(mm->mmap_base) - GPA_MAP_SIZE; else if (gpa < phys_end) return gpa - (phys_end - GPA_STACK_SIZE) + - LG_ALIGN(mm->start_stack) - GPA_STACK_SIZE; + LG_ALIGN(mm->start_stack) - GPA_STACK_SIZE; else return ADDR_INVAL; } @@ -212,8 +214,8 @@ ept_lookup(struct vmx_vcpu *vcpu, struct mm_struct *mm, void *gpa = (void *) hva_to_gpa(vcpu, mm, (unsigned long) hva); if (gpa == (void *) ADDR_INVAL) { - printk(KERN_ERR "ept: hva %p is out of range\n", hva); - printk(KERN_ERR "ept: mem_base %lx, stack_start %lx\n", + pr_err("ept: hva %p is out of range\n", hva); + pr_err("ept: mem_base %lx, stack_start %lx\n", mm->mmap_base, mm->start_stack); return -EINVAL; } @@ -254,11 +256,13 @@ static void vmx_free_ept(unsigned long ept_root) for (i = 0; i < PTRS_PER_PGD; i++) { epte_t *pud = (epte_t *) epte_page_vaddr(pgd[i]); + if (!epte_present(pgd[i])) continue; for (j = 0; j < PTRS_PER_PUD; j++) { epte_t *pmd = (epte_t *) epte_page_vaddr(pud[j]); + if (!epte_present(pud[j])) continue; if (epte_flags(pud[j]) & __EPTE_SZ) { @@ -267,7 +271,9 @@ static void vmx_free_ept(unsigned long ept_root) } for (k = 0; k < PTRS_PER_PMD; k++) { - epte_t *pte = (epte_t *) epte_page_vaddr(pmd[k]); + epte_t *pte = (epte_t *) + epte_page_vaddr(pmd[k]); + if (!epte_present(pmd[k])) continue; if (epte_flags(pmd[k]) & __EPTE_SZ) { @@ -336,6 +342,7 @@ static int ept_clear_l2_epte(epte_t *epte) for (i = 0; i < PTRS_PER_PMD; i++) { epte_t *pte = (epte_t *) epte_page_vaddr(pmd[i]); + if (!epte_present(pmd[i])) continue; if (epte_flags(pmd[i]) & __EPTE_SZ) { @@ -402,7 +409,7 @@ static int ept_set_pfnmap_epte(struct vmx_vcpu *vcpu, int make_write, ret = ept_lookup_gpa(vcpu, (void *) gpa, 0, 1, &epte); if (ret) { spin_unlock(&vcpu->ept_lock); - printk(KERN_ERR "ept: failed to lookup EPT entry\n"); + pr_err("ept: failed to lookup EPT entry\n"); return ret; } @@ -432,14 +439,15 @@ static int ept_set_epte(struct vmx_vcpu *vcpu, int make_write, int ret; epte_t *epte, flags; struct page *page; - unsigned huge_shift; + unsigned int huge_shift; int level; ret = get_user_pages_fast(hva, 1, make_write, &page); if (ret != 1) { ret = ept_set_pfnmap_epte(vcpu, make_write, gpa, hva); + if (ret) - printk(KERN_ERR "ept: failed to get user page %lx\n", hva); + pr_err("ept: failed to get user page %lx\n", hva); return ret; } @@ -447,6 +455,7 @@ static int ept_set_epte(struct vmx_vcpu *vcpu, int make_write, huge_shift = compound_order(compound_head(page)) + PAGE_SHIFT; level = 0; + if (huge_shift == 30) level = 2; else if (huge_shift == 21) @@ -457,7 +466,7 @@ static int ept_set_epte(struct vmx_vcpu *vcpu, int make_write, if (ret) { spin_unlock(&vcpu->ept_lock); put_page(page); - printk(KERN_ERR "ept: failed to lookup EPT entry\n"); + pr_err("ept: failed to lookup EPT entry\n"); return ret; } @@ -483,7 +492,9 @@ static int ept_set_epte(struct vmx_vcpu *vcpu, int make_write, if (level) { struct page *tmp = page; + page = compound_head(page); + get_page(page); put_page(tmp); @@ -503,9 +514,9 @@ int vmx_do_ept_fault(struct vmx_vcpu *vcpu, unsigned long gpa, int ret; unsigned long hva = gpa_to_hva(vcpu, current->mm, gpa); int make_write = (fault_flags & VMX_EPT_FAULT_WRITE) ? 1 : 0; - + if (unlikely(hva == ADDR_INVAL)) { - printk(KERN_ERR "ept: gpa 0x%lx is out of range\n", gpa); + pr_err("ept: gpa 0x%lx is out of range\n", gpa); return -EINVAL; } @@ -522,7 +533,7 @@ int vmx_do_ept_fault(struct vmx_vcpu *vcpu, unsigned long gpa, * @vcpu: the vcpu * @mm: the process's mm_struct * @addr: the address of the page - * + * * Returns 1 if the page was removed, 0 otherwise */ static int ept_invalidate_page(struct vmx_vcpu *vcpu, @@ -534,7 +545,7 @@ static int ept_invalidate_page(struct vmx_vcpu *vcpu, void *gpa = (void *) hva_to_gpa(vcpu, mm, (unsigned long) addr); if (gpa == (void *) ADDR_INVAL) { - printk(KERN_ERR "ept: hva %lx is out of range\n", addr); + pr_err("ept: hva %lx is out of range\n", addr); return 0; } @@ -559,7 +570,7 @@ static int ept_invalidate_page(struct vmx_vcpu *vcpu, * @vcpu: the vcpu * @mm: the process's mm_struct * @addr: the address of the page - * + * * Returns 1 if the page is mapped, 0 otherwise */ static int ept_check_page_mapped(struct vmx_vcpu *vcpu, @@ -571,7 +582,7 @@ static int ept_check_page_mapped(struct vmx_vcpu *vcpu, void *gpa = (void *) hva_to_gpa(vcpu, mm, (unsigned long) addr); if (gpa == (void *) ADDR_INVAL) { - printk(KERN_ERR "ept: hva %lx is out of range\n", addr); + pr_err("ept: hva %lx is out of range\n", addr); return 0; } @@ -588,7 +599,7 @@ static int ept_check_page_mapped(struct vmx_vcpu *vcpu, * @mm: the process's mm_struct * @addr: the address of the page * @flush: if true, clear the A bit - * + * * Returns 1 if the page was accessed, 0 otherwise */ static int ept_check_page_accessed(struct vmx_vcpu *vcpu, @@ -601,7 +612,7 @@ static int ept_check_page_accessed(struct vmx_vcpu *vcpu, void *gpa = (void *) hva_to_gpa(vcpu, mm, (unsigned long) addr); if (gpa == (void *) ADDR_INVAL) { - printk(KERN_ERR "ept: hva %lx is out of range\n", addr); + pr_err("ept: hva %lx is out of range\n", addr); return 0; } @@ -682,7 +693,8 @@ static void ept_mmu_notifier_change_pte(struct mmu_notifier *mn, { struct vmx_vcpu *vcpu = mmu_notifier_to_vmx(mn); - pr_debug("ept: change_pte addr %lx flags %lx\n", address, pte_flags(pte)); + pr_debug("ept: change_pte addr %lx flags %lx\n", address, + pte_flags(pte)); /* * NOTE: Recent linux kernels (seen on 3.7 at least) hold a lock @@ -693,7 +705,7 @@ static void ept_mmu_notifier_change_pte(struct mmu_notifier *mn, ept_invalidate_page(vcpu, mm, address); } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0) +#if KERNEL_VERSION(3, 17, 0) <= LINUX_VERSION_CODE static int ept_mmu_notifier_clear_flush_young(struct mmu_notifier *mn, struct mm_struct *mm, unsigned long start, @@ -768,7 +780,7 @@ int vmx_init_ept(struct vmx_vcpu *vcpu) memset(page, 0, PAGE_SIZE); vcpu->ept_root = __pa(page); - + return 0; } diff --git a/kern/preempttrap.c b/kern/preempttrap.c index 3212c02..2cd1732 100644 --- a/kern/preempttrap.c +++ b/kern/preempttrap.c @@ -13,7 +13,8 @@ static struct { static void notifier_sched_in(struct preempt_notifier *notifier, int cpu) { - if (!trap_state.triggered && KSTK_EIP(current) == trap_conf.trigger_rip) { + if (!trap_state.triggered && + KSTK_EIP(current) == trap_conf.trigger_rip) { trap_state.triggered = 1; trap_state.count = trap_conf.delay; } @@ -46,7 +47,8 @@ static void notifier_sched_in(struct preempt_notifier *notifier, int cpu) /* Debuggers use the single step flags to get notification when * a breakpointed instruction is executed, so that they can * restore the int3 opcode. Unset the flags so that they don't - * get the notification in our notify_func. */ + * get the notification in our notify_func. + */ regs->flags &= ~X86_EFLAGS_TF; clear_thread_flag(TIF_SINGLESTEP); @@ -56,13 +58,16 @@ static void notifier_sched_in(struct preempt_notifier *notifier, int cpu) regs->ip = (__u64) trap_conf.notify_func; regs->di = (__u64) trap_conf.regs; regs->si = (__u64) trap_conf.priv; - /* Go past the red zone mandated by the System V x86-64 ABI. */ + /* Go past the red zone mandated by the System V + * x86-64 ABI. + */ regs->sp -= 128; } } } -static void notifier_sched_out(struct preempt_notifier *notifier, struct task_struct *next) +static void notifier_sched_out(struct preempt_notifier *notifier, + struct task_struct *next) { } diff --git a/kern/vmx.c b/kern/vmx.c index 04c639a..0c7764e 100644 --- a/kern/vmx.c +++ b/kern/vmx.c @@ -71,7 +71,7 @@ static unsigned long *msr_bitmap; #define NUM_SYSCALLS 312 -#if LINUX_VERSION_CODE <= KERNEL_VERSION(3,11,0) +#if KERNEL_VERSION(3, 11, 0) >= LINUX_VERSION_CODE typedef void (*sys_call_ptr_t)(void); #else #include @@ -201,13 +201,13 @@ static inline void __vmxoff(void) static inline void __invvpid(int ext, u16 vpid, gva_t gva) { - struct { + struct { u64 vpid : 16; u64 rsvd : 48; u64 gva; - } operand = { vpid, 0, gva }; + } operand = { vpid, 0, gva }; - asm volatile (ASM_VMX_INVVPID + asm volatile (ASM_VMX_INVVPID /* CF==1 or ZF==1 --> rc = -1 */ "; ja 1f ; ud2 ; 1:" : : "a"(&operand), "c"(ext) : "cc", "memory"); @@ -245,8 +245,7 @@ static void vmcs_clear(struct vmcs *vmcs) : "=qm"(error) : "a"(&phys_addr), "m"(phys_addr) : "cc", "memory"); if (error) - printk(KERN_ERR "kvm: vmclear fail: %p/%llx\n", - vmcs, phys_addr); + pr_err("kvm: vmclear fail: %p/%llx\n", vmcs, phys_addr); } static void vmcs_load(struct vmcs *vmcs) @@ -258,8 +257,7 @@ static void vmcs_load(struct vmcs *vmcs) : "=qm"(error) : "a"(&phys_addr), "m"(phys_addr) : "cc", "memory"); if (error) - printk(KERN_ERR "vmx: vmptrld %p/%llx failed\n", - vmcs, phys_addr); + pr_err("vmx: vmptrld %p/%llx failed\n", vmcs, phys_addr); } static __always_inline u16 vmcs_read16(unsigned long field) @@ -283,7 +281,7 @@ static __always_inline u64 vmcs_read64(unsigned long field) static noinline void vmwrite_error(unsigned long field, unsigned long value) { - printk(KERN_ERR "vmwrite error: reg %lx value %lx (err %d)\n", + pr_err("vmwrite error: reg %lx value %lx (err %d)\n", field, value, vmcs_read32(VM_INSTRUCTION_ERROR)); dump_stack(); } @@ -384,7 +382,7 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf) #endif if (_cpu_based_exec_control & CPU_BASED_ACTIVATE_SECONDARY_CONTROLS) { min2 = 0; - opt2 = SECONDARY_EXEC_WBINVD_EXITING | + opt2 = SECONDARY_EXEC_WBINVD_EXITING | SECONDARY_EXEC_ENABLE_VPID | SECONDARY_EXEC_ENABLE_EPT | SECONDARY_EXEC_RDTSCP | @@ -401,7 +399,8 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf) #endif if (_cpu_based_2nd_exec_control & SECONDARY_EXEC_ENABLE_EPT) { /* CR3 accesses and invlpg don't need to cause VM Exits when EPT - enabled */ + * enabled + */ _cpu_based_exec_control &= ~(CPU_BASED_CR3_LOAD_EXITING | CPU_BASED_CR3_STORE_EXITING | CPU_BASED_INVLPG_EXITING); @@ -449,7 +448,7 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf) vmcs_conf->pin_based_exec_ctrl = _pin_based_exec_control; vmcs_conf->cpu_based_exec_ctrl = _cpu_based_exec_control; vmcs_conf->cpu_based_2nd_exec_ctrl = _cpu_based_2nd_exec_control; - vmcs_conf->vmexit_ctrl = _vmexit_control; + vmcs_conf->vmexit_ctrl = _vmexit_control; vmcs_conf->vmentry_ctrl = _vmentry_control; vmx_capability.has_load_efer = @@ -537,8 +536,8 @@ static void vmx_setup_constant_host_state(void) vmcs_write64(HOST_IA32_PAT, low32 | ((u64) high32 << 32)); } - vmcs_write16(HOST_FS_SELECTOR, 0); /* 22.2.4 */ - vmcs_write16(HOST_GS_SELECTOR, 0); /* 22.2.4 */ + vmcs_write16(HOST_FS_SELECTOR, 0); /* 22.2.4 */ + vmcs_write16(HOST_GS_SELECTOR, 0); /* 22.2.4 */ #ifdef CONFIG_X86_64 rdmsrl(MSR_FS_BASE, tmpl); @@ -554,6 +553,7 @@ static void vmx_setup_constant_host_state(void) static inline u16 vmx_read_ldt(void) { u16 ldt; + asm("sldt %0" : "=g"(ldt)); return ldt; } @@ -570,7 +570,7 @@ static unsigned long segment_base(u16 selector) table_base = gdt->address; - if (selector & 4) { /* from ldt */ + if (selector & 4) { /* from ldt */ u16 ldt_selector = vmx_read_ldt(); if (!(ldt_selector & ~3)) @@ -581,8 +581,8 @@ static unsigned long segment_base(u16 selector) d = (struct desc_struct *)(table_base + (selector & ~7)); v = get_desc_base(d); #ifdef CONFIG_X86_64 - if (d->s == 0 && (d->type == 2 || d->type == 9 || d->type == 11)) - v |= ((unsigned long)((struct ldttss_desc64 *)d)->base3) << 32; + if (d->s == 0 && (d->type == 2 || d->type == 9 || d->type == 11)) + v |= ((unsigned long)((struct ldttss_desc64 *)d)->base3) << 32; #endif return v; } @@ -590,6 +590,7 @@ static unsigned long segment_base(u16 selector) static inline unsigned long vmx_read_tr_base(void) { u16 tr; + asm("str %0" : "=g"(tr)); return segment_base(tr); } @@ -709,6 +710,7 @@ void vmx_ept_sync_vcpu(struct vmx_vcpu *vcpu) void vmx_ept_sync_individual_addr(struct vmx_vcpu *vcpu, gpa_t gpa) { struct sync_addr_args args; + args.vcpu = vcpu; args.gpa = gpa; @@ -734,40 +736,39 @@ static void vmx_dump_cpu(struct vmx_vcpu *vcpu) flags = vmcs_readl(GUEST_RFLAGS); vmx_put_cpu(vcpu); - printk(KERN_INFO "vmx: --- Begin VCPU Dump ---\n"); - printk(KERN_INFO "vmx: CPU %d VPID %d\n", vcpu->cpu, vcpu->vpid); - printk(KERN_INFO "vmx: RIP 0x%016llx RFLAGS 0x%08lx\n", + pr_info("vmx: --- Begin VCPU Dump ---\n"); + pr_info("vmx: CPU %d VPID %d\n", vcpu->cpu, vcpu->vpid); + pr_info("vmx: RIP 0x%016llx RFLAGS 0x%08lx\n", vcpu->regs[VCPU_REGS_RIP], flags); - printk(KERN_INFO "vmx: RAX 0x%016llx RCX 0x%016llx\n", + pr_info("vmx: RAX 0x%016llx RCX 0x%016llx\n", vcpu->regs[VCPU_REGS_RAX], vcpu->regs[VCPU_REGS_RCX]); - printk(KERN_INFO "vmx: RDX 0x%016llx RBX 0x%016llx\n", + pr_info("vmx: RDX 0x%016llx RBX 0x%016llx\n", vcpu->regs[VCPU_REGS_RDX], vcpu->regs[VCPU_REGS_RBX]); - printk(KERN_INFO "vmx: RSP 0x%016llx RBP 0x%016llx\n", + pr_info("vmx: RSP 0x%016llx RBP 0x%016llx\n", vcpu->regs[VCPU_REGS_RSP], vcpu->regs[VCPU_REGS_RBP]); - printk(KERN_INFO "vmx: RSI 0x%016llx RDI 0x%016llx\n", + pr_info("vmx: RSI 0x%016llx RDI 0x%016llx\n", vcpu->regs[VCPU_REGS_RSI], vcpu->regs[VCPU_REGS_RDI]); - printk(KERN_INFO "vmx: R8 0x%016llx R9 0x%016llx\n", + pr_info("vmx: R8 0x%016llx R9 0x%016llx\n", vcpu->regs[VCPU_REGS_R8], vcpu->regs[VCPU_REGS_R9]); - printk(KERN_INFO "vmx: R10 0x%016llx R11 0x%016llx\n", + pr_info("vmx: R10 0x%016llx R11 0x%016llx\n", vcpu->regs[VCPU_REGS_R10], vcpu->regs[VCPU_REGS_R11]); - printk(KERN_INFO "vmx: R12 0x%016llx R13 0x%016llx\n", + pr_info("vmx: R12 0x%016llx R13 0x%016llx\n", vcpu->regs[VCPU_REGS_R12], vcpu->regs[VCPU_REGS_R13]); - printk(KERN_INFO "vmx: R14 0x%016llx R15 0x%016llx\n", + pr_info("vmx: R14 0x%016llx R15 0x%016llx\n", vcpu->regs[VCPU_REGS_R14], vcpu->regs[VCPU_REGS_R15]); - printk(KERN_INFO "vmx: FS.base 0x%016lx GS.base 0x%016lx\n", + pr_info("vmx: FS.base 0x%016lx GS.base 0x%016lx\n", vmcs_readl(GUEST_FS_BASE), vmcs_readl(GUEST_GS_BASE)); - printk(KERN_INFO "vmx: Dumping Stack Contents...\n"); + pr_info("vmx: Dumping Stack Contents...\n"); sp = (unsigned long *) vcpu->regs[VCPU_REGS_RSP]; for (i = 0; i < STACK_DEPTH; i++) if (get_user(val, &sp[i])) - printk(KERN_INFO "vmx: RSP%+-3ld ?\n", - i * sizeof(long)); + pr_info("vmx: RSP%+-3ld ?\n", i * sizeof(long)); else - printk(KERN_INFO "vmx: RSP%+-3ld 0x%016lx\n", + pr_info("vmx: RSP%+-3ld 0x%016lx\n", i * sizeof(long), val); - printk(KERN_INFO "vmx: --- End VCPU Dump ---\n"); + pr_info("vmx: --- End VCPU Dump ---\n"); } static u64 construct_eptp(unsigned long root_hpa) @@ -785,7 +786,8 @@ static u64 construct_eptp(unsigned long root_hpa) } /** - * vmx_setup_initial_guest_state - configures the initial state of guest registers + * vmx_setup_initial_guest_state - configures the initial state of guest + * registers */ static void vmx_setup_initial_guest_state(struct dune_config *conf) { @@ -950,13 +952,14 @@ static void vmx_setup_vmcs(struct vmx_vcpu *vcpu) vmcs_write32(PAGE_FAULT_ERROR_CODE_MASK, 0); vmcs_write32(PAGE_FAULT_ERROR_CODE_MATCH, 0); - vmcs_write32(CR3_TARGET_COUNT, 0); /* 22.2.1 */ + vmcs_write32(CR3_TARGET_COUNT, 0); /* 22.2.1 */ setup_msr(vcpu); #if 0 if (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_PAT) { u32 msr_low, msr_high; u64 host_pat; + rdmsr(MSR_IA32_CR_PAT, msr_low, msr_high); host_pat = msr_low | ((u64) msr_high << 32); /* Write the default value follow host pat */ @@ -1059,7 +1062,8 @@ static void vmx_setup_registers(struct vmx_vcpu *vcpu, struct dune_config *conf) /** * vmx_copy_registers_to_conf - copy registers to dune_config */ -static void vmx_copy_registers_to_conf(struct vmx_vcpu *vcpu, struct dune_config *conf) +static void vmx_copy_registers_to_conf(struct vmx_vcpu *vcpu, + struct dune_config *conf) { conf->rax = vcpu->regs[VCPU_REGS_RAX]; conf->rbx = vcpu->regs[VCPU_REGS_RBX]; @@ -1086,7 +1090,7 @@ static void vmx_copy_registers_to_conf(struct vmx_vcpu *vcpu, struct dune_config * * Returns: A new VCPU structure */ -static struct vmx_vcpu * vmx_create_vcpu(struct dune_config *conf) +static struct vmx_vcpu *vmx_create_vcpu(struct dune_config *conf) { struct vmx_vcpu *vcpu; @@ -1133,7 +1137,7 @@ static struct vmx_vcpu * vmx_create_vcpu(struct dune_config *conf) if (cpu_has_vmx_ept_ad_bits()) { vcpu->ept_ad_enabled = true; - printk(KERN_INFO "vmx: enabled EPT A/D bits"); + pr_info("vmx: enabled EPT A/D bits"); } if (vmx_create_ept(vcpu)) goto fail_ept; @@ -1171,8 +1175,7 @@ void vmx_cleanup(void) struct vmx_vcpu *vcpu, *tmp; list_for_each_entry_safe(vcpu, tmp, &vcpus, list) { - printk(KERN_ERR "vmx: destroying VCPU (VPID %d)\n", - vcpu->vpid); + pr_err("vmx: destroying VCPU (VPID %d)\n", vcpu->vpid); list_del(&vcpu->list); vmx_destroy_vcpu(vcpu); } @@ -1246,7 +1249,7 @@ static void make_pt_regs(struct vmx_vcpu *vcpu, struct pt_regs *regs, * in a child process since it is not running in Dune. * Our solution is to adopt a special Dune convention * where the desired %RIP address is provided in %RCX. - */ + */ if (!(__addr_ok(regs->ip))) regs->ip = regs->cx; @@ -1254,7 +1257,7 @@ static void make_pt_regs(struct vmx_vcpu *vcpu, struct pt_regs *regs, regs->ss = __USER_DS; } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,1,0) +#if KERNEL_VERSION(4, 1, 0) <= LINUX_VERSION_CODE static long dune_sys_clone(unsigned long clone_flags, unsigned long newsp, void __user *parent_tid, void __user *child_tid, unsigned long tls) @@ -1293,7 +1296,7 @@ static long dune_sys_fork(void) { struct vmx_vcpu *vcpu; struct pt_regs regs; - + asm("movq %%r11, %0" : "=r"(vcpu)); make_pt_regs(vcpu, ®s, __NR_fork); @@ -1305,7 +1308,7 @@ static long dune_sys_vfork(void) { struct vmx_vcpu *vcpu; struct pt_regs regs; - + asm("movq %%r11, %0" : "=r"(vcpu)); make_pt_regs(vcpu, ®s, __NR_vfork); @@ -1318,7 +1321,7 @@ static void vmx_init_syscall(void) { memcpy(dune_syscall_tbl, (void *) SYSCALL_TBL, sizeof(sys_call_ptr_t) * NUM_SYSCALLS); - + dune_syscall_tbl[__NR_exit] = (void *) &dune_exit; dune_syscall_tbl[__NR_exit_group] = (void *) &dune_exit_group; dune_syscall_tbl[__NR_clone] = (void *) &dune_sys_clone; @@ -1340,8 +1343,7 @@ static void vmx_init_syscall(void) */ static int __noclone vmx_run_vcpu(struct vmx_vcpu *vcpu) { - asm( - /* Store host registers */ + asm(/* Store host registers */ "push %%"R"dx; push %%"R"bp;" "push %%"R"cx \n\t" /* placeholder for guest rcx */ "push %%"R"cx \n\t" @@ -1367,8 +1369,8 @@ static int __noclone vmx_run_vcpu(struct vmx_vcpu *vcpu) "mov %c[rdi](%0), %%"R"di \n\t" "mov %c[rbp](%0), %%"R"bp \n\t" #ifdef CONFIG_X86_64 - "mov %c[r8](%0), %%r8 \n\t" - "mov %c[r9](%0), %%r9 \n\t" + "mov %c[r8](%0), %%r8 \n\t" + "mov %c[r9](%0), %%r9 \n\t" "mov %c[r10](%0), %%r10 \n\t" "mov %c[r11](%0), %%r11 \n\t" "mov %c[r12](%0), %%r12 \n\t" @@ -1449,7 +1451,7 @@ static int __noclone vmx_run_vcpu(struct vmx_vcpu *vcpu) vcpu->launched = 1; if (unlikely(vcpu->fail)) { - printk(KERN_ERR "vmx: failure detected (err %x)\n", + pr_err("vmx: failure detected (err %x)\n", vmcs_read32(VM_INSTRUCTION_ERROR)); return VMX_EXIT_REASONS_FAILED_VMENTRY; } @@ -1480,22 +1482,21 @@ static int vmx_handle_ept_violation(struct vmx_vcpu *vcpu) gva = vmcs_readl(GUEST_LINEAR_ADDRESS); gpa = vmcs_read64(GUEST_PHYSICAL_ADDRESS); vmx_put_cpu(vcpu); - + if (exit_qual & (1 << 6)) { - printk(KERN_ERR "EPT: GPA 0x%lx exceeds GAW!\n", gpa); + pr_err("EPT: GPA 0x%lx exceeds GAW!\n", gpa); return -EINVAL; } - + if (!(exit_qual & (1 << 7))) { - printk(KERN_ERR "EPT: linear address is not valid, GPA: 0x%lx!\n", gpa); + pr_err("EPT: linear address is not valid, GPA: 0x%lx!\n", gpa); return -EINVAL; } ret = vmx_do_ept_fault(vcpu, gpa, gva, exit_qual); if (ret) { - printk(KERN_ERR "vmx: page fault failure " - "GPA: 0x%lx, GVA: 0x%lx\n", + pr_err("vmx: page fault failure GPA: 0x%lx, GVA: 0x%lx\n", gpa, gva); vcpu->ret_code = DUNE_RET_EPT_VIOLATION; vmx_dump_cpu(vcpu); @@ -1512,10 +1513,10 @@ static void vmx_handle_syscall(struct vmx_vcpu *vcpu) vcpu->regs[VCPU_REGS_RAX] = -EINVAL; return; } - + if (unlikely(vcpu->regs[VCPU_REGS_RAX] == __NR_sigaltstack || vcpu->regs[VCPU_REGS_RAX] == __NR_iopl)) { - printk(KERN_INFO "vmx: got unsupported syscall\n"); + pr_info("vmx: got unsupported syscall\n"); vcpu->regs[VCPU_REGS_RAX] = -EINVAL; return; } @@ -1527,8 +1528,8 @@ static void vmx_handle_syscall(struct vmx_vcpu *vcpu) "mov %c[rdi](%0), %%"R"di \n\t" "mov %c[rsi](%0), %%"R"si \n\t" "mov %c[rdx](%0), %%"R"dx \n\t" - "mov %c[r8](%0), %%r8 \n\t" - "mov %c[r9](%0), %%r9 \n\t" + "mov %c[r8](%0), %%r8 \n\t" + "mov %c[r9](%0), %%r9 \n\t" "mov %c[syscall](%0), %%r10 \n\t" "mov %0, %%r11 \n\t" "push %0 \n\t" @@ -1552,7 +1553,8 @@ static void vmx_handle_syscall(struct vmx_vcpu *vcpu) ); /* We apply the restart semantics as if no signal handler will be - * executed. */ + * executed. + */ switch (vcpu->regs[VCPU_REGS_RAX]) { case -ERESTARTNOHAND: case -ERESTARTSYS: @@ -1595,7 +1597,7 @@ static int vmx_handle_nmi_exception(struct vmx_vcpu *vcpu) if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == INTR_TYPE_NMI_INTR) return 0; - printk(KERN_ERR "vmx: got interrupt, intr_info %x\n", intr_info); + pr_err("vmx: got interrupt, intr_info %x\n", intr_info); vcpu->ret_code = DUNE_RET_INTERRUPT; vcpu->conf->status = intr_info & INTR_INFO_VECTOR_MASK; return -EIO; @@ -1609,12 +1611,12 @@ int vmx_launch(struct dune_config *conf, int64_t *ret_code) { int ret, done = 0; u32 exit_intr_info; + struct vmx_vcpu *vcpu = vmx_create_vcpu(conf); if (!vcpu) return -ENOMEM; - printk(KERN_ERR "vmx: created VCPU (VPID %d)\n", - vcpu->vpid); + pr_err("vmx: created VCPU (VPID %d)\n", vcpu->vpid); while (1) { vmx_get_cpu(vcpu); @@ -1651,9 +1653,10 @@ int vmx_launch(struct dune_config *conf, int64_t *ret_code) ret = vmx_run_vcpu(vcpu); - /* We need to handle NMIs before interrupts are enabled */ + // We need to handle NMIs before interrupts are enabled exit_intr_info = vmcs_read32(VM_EXIT_INTR_INFO); - if ((exit_intr_info & INTR_INFO_INTR_TYPE_MASK) == INTR_TYPE_NMI_INTR && + if ((exit_intr_info & + INTR_INFO_INTR_TYPE_MASK) == INTR_TYPE_NMI_INTR && (exit_intr_info & INTR_INFO_VALID_MASK)) { asm("int $2"); } @@ -1677,7 +1680,7 @@ int vmx_launch(struct dune_config *conf, int64_t *ret_code) if (vmx_handle_nmi_exception(vcpu)) done = 1; } else if (ret != EXIT_REASON_EXTERNAL_INTERRUPT) { - printk(KERN_INFO "unhandled exit: reason %d, exit qualification %x\n", + pr_info("unhandled exit: reason %d, exit qualification %x\n", ret, vmcs_read32(EXIT_QUALIFICATION)); vcpu->ret_code = DUNE_RET_UNHANDLED_VMEXIT; vmx_dump_cpu(vcpu); @@ -1688,8 +1691,7 @@ int vmx_launch(struct dune_config *conf, int64_t *ret_code) break; } - printk(KERN_ERR "vmx: stopping VCPU (VPID %d)\n", - vcpu->vpid); + pr_err("vmx: stopping VCPU (VPID %d)\n", vcpu->vpid); *ret_code = vcpu->ret_code; @@ -1741,19 +1743,19 @@ static __init void vmx_enable(void *unused) int ret; struct vmcs *vmxon_buf = __this_cpu_read(vmxarea); - if ((ret = __vmx_enable(vmxon_buf))) + ret = __vmx_enable(vmxon_buf); + if (ret) goto failed; this_cpu_write(vmx_enabled, 1); native_store_gdt(this_cpu_ptr(&host_gdt)); - printk(KERN_INFO "vmx: VMX enabled on CPU %d\n", - raw_smp_processor_id()); + pr_info("vmx: VMX enabled on CPU %d\n", raw_smp_processor_id()); return; failed: atomic_inc(&vmx_enable_failed); - printk(KERN_ERR "vmx: failed to enable VMX, err = %d\n", ret); + pr_err("vmx: failed to enable VMX, err = %d\n", ret); } /** @@ -1789,9 +1791,9 @@ static void vmx_free_vmxon_areas(void) __init int vmx_init(void) { int r, cpu; - + if (!cpu_has_vmx()) { - printk(KERN_ERR "vmx: CPU does not support VT-x\n"); + pr_err("vmx: CPU does not support VT-x\n"); return -EIO; } @@ -1801,24 +1803,24 @@ __init int vmx_init(void) return -EIO; if (!cpu_has_vmx_vpid()) { - printk(KERN_ERR "vmx: CPU is missing required feature 'VPID'\n"); + pr_err("vmx: CPU is missing required feature 'VPID'\n"); return -EIO; } if (!cpu_has_vmx_ept()) { - printk(KERN_ERR "vmx: CPU is missing required feature 'EPT'\n"); + pr_err("vmx: CPU is missing required feature 'EPT'\n"); return -EIO; } if (!vmx_capability.has_load_efer) { - printk(KERN_ERR "vmx: ability to load EFER register is required\n"); + pr_err("vmx: ability to load EFER register is required\n"); return -EIO; } msr_bitmap = (unsigned long *)__get_free_page(GFP_KERNEL); - if (!msr_bitmap) { + if (!msr_bitmap) return -ENOMEM; - } + /* FIXME: do we need APIC virtualization (flexpriority?) */ memset(msr_bitmap, 0xff, PAGE_SIZE); @@ -1843,7 +1845,7 @@ __init int vmx_init(void) atomic_set(&vmx_enable_failed, 0); if (on_each_cpu(vmx_enable, NULL, 1)) { - printk(KERN_ERR "vmx: timeout waiting for VMX mode enable.\n"); + pr_err("vmx: timeout waiting for VMX mode enable.\n"); r = -EIO; goto failed1; /* sadly we can't totally recover */ } diff --git a/kern/vmx.h b/kern/vmx.h index ab37871..be5fb4a 100644 --- a/kern/vmx.h +++ b/kern/vmx.h @@ -70,7 +70,7 @@ struct vmx_vcpu { int ret_code; struct msr_autoload { - unsigned nr; + unsigned int nr; struct vmx_msr_entry guest[NR_AUTOLOAD_MSRS]; struct vmx_msr_entry host[NR_AUTOLOAD_MSRS]; } msr_autoload; @@ -100,9 +100,9 @@ extern void vmx_ept_sync_individual_addr(struct vmx_vcpu *vcpu, gpa_t gpa); static __always_inline unsigned long vmcs_readl(unsigned long field) { - unsigned long value; + unsigned long value; - asm volatile (ASM_VMX_VMREAD_RDX_RAX - : "=a"(value) : "d"(field) : "cc"); - return value; + asm volatile (ASM_VMX_VMREAD_RDX_RAX + : "=a"(value) : "d"(field) : "cc"); + return value; } From 9f59099f5c4563e6c094eb8b3909d0092bc626e0 Mon Sep 17 00:00:00 2001 From: rodrigosiqueira Date: Mon, 23 Oct 2017 16:29:09 -0200 Subject: [PATCH 2/2] Applied checkpatch with strict flag to kern files * kern/compat.h * kern/core.c * kern/dune.h * kern/preempttrap.c * kern/vmx.c * kern/vmx.h --- kern/compat.h | 15 +++++---- kern/core.c | 6 ++-- kern/dune.h | 16 ++++------ kern/preempttrap.c | 10 +++--- kern/vmx.c | 77 +++++++++++++++++++++++----------------------- kern/vmx.h | 23 +++++++------- 6 files changed, 71 insertions(+), 76 deletions(-) diff --git a/kern/compat.h b/kern/compat.h index 4e2b69c..ac68133 100644 --- a/kern/compat.h +++ b/kern/compat.h @@ -16,12 +16,12 @@ #endif #if !defined(VMX_EPT_AD_BIT) -#define VMX_EPT_AD_BIT (1ull << 21) -#define VMX_EPT_AD_ENABLE_BIT (1ull << 6) +#define VMX_EPT_AD_BIT BIT_ULL(21) +#define VMX_EPT_AD_ENABLE_BIT BIT_ULL(6) #endif #ifndef VMX_EPT_EXTENT_INDIVIDUAL_BIT -#define VMX_EPT_EXTENT_INDIVIDUAL_BIT (1ull << 24) +#define VMX_EPT_EXTENT_INDIVIDUAL_BIT BIT_ULL(24) #endif #ifndef X86_CR4_PCIDE @@ -47,7 +47,6 @@ static inline struct page *alloc_pages_exact_node(int nid, gfp_t gfp_mask, } #endif - #if KERNEL_VERSION(4, 1, 0) <= LINUX_VERSION_CODE & defined(_DO_FORK) typedef long (*do_fork_hack) (unsigned long, unsigned long, unsigned long, int __user *, int __user *, unsigned long); @@ -70,12 +69,11 @@ dune_do_fork(unsigned long clone_flags, unsigned long stack_start, memcpy(me, &tmp, sizeof(struct pt_regs)); return ret; - } #elif KERNEL_VERSION(3, 5, 0) <= LINUX_VERSION_CODE & defined(DO_FORK) typedef long (*do_fork_hack) (unsigned long, unsigned long, unsigned long, int __user *, int __user *); -static do_fork_hack __dune_do_fork = (do_fork_hack) DO_FORK; +static do_fork_hack __dune_do_fork = (do_fork_hack)DO_FORK; static inline long dune_do_fork(unsigned long clone_flags, unsigned long stack_start, struct pt_regs *regs, unsigned long stack_size, @@ -94,13 +92,12 @@ dune_do_fork(unsigned long clone_flags, unsigned long stack_start, memcpy(me, &tmp, sizeof(struct pt_regs)); return ret; - } #elif defined(DO_FORK) typedef long (*do_fork_hack) (unsigned long, unsigned long, struct pt_regs *, unsigned long, int __user *, int __user *); -static do_fork_hack dune_do_fork = (do_fork_hack) DO_FORK; +static do_fork_hack dune_do_fork = (do_fork_hack)DO_FORK; #endif #if KERNEL_VERSION(3, 19, 0) > LINUX_VERSION_CODE @@ -108,10 +105,12 @@ static inline unsigned long __read_cr4(void) { return read_cr4(); } + static inline void cr4_set_bits(unsigned long mask) { write_cr4(read_cr4() | mask); } + static inline void cr4_clear_bits(unsigned long mask) { write_cr4(read_cr4() & ~mask); diff --git a/kern/core.c b/kern/core.c index 1c826d0..70e2124 100644 --- a/kern/core.c +++ b/kern/core.c @@ -67,7 +67,7 @@ static int dune_enter(struct dune_config *conf, int64_t *ret) } static long dune_dev_ioctl(struct file *filp, - unsigned int ioctl, unsigned long arg) + unsigned int ioctl, unsigned long arg) { long r = -EINVAL; struct dune_config conf; @@ -75,7 +75,7 @@ static long dune_dev_ioctl(struct file *filp, switch (ioctl) { case DUNE_ENTER: - r = copy_from_user(&conf, (int __user *) arg, + r = copy_from_user(&conf, (int __user *)arg, sizeof(struct dune_config)); if (r) { r = -EIO; @@ -96,7 +96,7 @@ static long dune_dev_ioctl(struct file *filp, case DUNE_GET_SYSCALL: rdmsrl(MSR_LSTAR, r); - pr_info("R %lx\n", (unsigned long) r); + pr_info("R %lx\n", (unsigned long)r); break; case DUNE_GET_LAYOUT: diff --git a/kern/dune.h b/kern/dune.h index 89612f4..7e05a38 100644 --- a/kern/dune.h +++ b/kern/dune.h @@ -24,7 +24,6 @@ // XXX: Must match libdune/dune.h #define DUNE_SIGNAL_INTR_BASE 200 -//TODO: Add __packed and remove __attribute__ at the end struct dune_config { __s64 ret; __u64 rax; @@ -48,16 +47,14 @@ struct dune_config { __u64 cr3; __s64 status; __u64 vcpu; -} __attribute__((packed)); +} __packed; -//TODO: Add __packed and remove __attribute__ at the end struct dune_layout { __u64 phys_limit; __u64 base_map; __u64 base_stack; -} __attribute__((packed)); +} __packed; -//TODO: Add __packed and remove __attribute__ at the end struct dune_trap_regs { __u64 rax; __u64 rbx; @@ -77,11 +74,10 @@ struct dune_trap_regs { __u64 r15; __u64 rip; __u64 rflags; -} __attribute__((packed)); +} __packed; typedef void (*dune_trap_notify_func)(struct dune_trap_regs*, void*); -//TODO: Add __packed and remove __attribute__ at the end struct dune_trap_config { __u64 trigger_rip; dune_trap_notify_func notify_func; @@ -89,12 +85,12 @@ struct dune_trap_config { __u64 regs_size; void *priv; __u8 delay; -} __attribute__((packed)); +} __packed; /* 1 gigabyte */ -#define GPA_STACK_SIZE ((unsigned long) 1 << 30) +#define GPA_STACK_SIZE ((unsigned long)1 << 30) /* 63 gigabytes */ -#define GPA_MAP_SIZE (((unsigned long) 1 << 36) - GPA_STACK_SIZE) +#define GPA_MAP_SIZE (((unsigned long)1 << 36) - GPA_STACK_SIZE) #define LG_ALIGN(addr) ((addr + (1 << 30) - 1) & ~((1 << 30) - 1)) #endif /* __ASSEMBLY__ */ diff --git a/kern/preempttrap.c b/kern/preempttrap.c index 2cd1732..a13ec6a 100644 --- a/kern/preempttrap.c +++ b/kern/preempttrap.c @@ -55,9 +55,9 @@ static void notifier_sched_in(struct preempt_notifier *notifier, int cpu) if (sizeof(struct dune_trap_regs) == trap_conf.regs_size) { copy_to_user((void __user *)trap_conf.regs, &trap_regs, sizeof(struct dune_trap_regs)); - regs->ip = (__u64) trap_conf.notify_func; - regs->di = (__u64) trap_conf.regs; - regs->si = (__u64) trap_conf.priv; + regs->ip = (__u64)trap_conf.notify_func; + regs->di = (__u64)trap_conf.regs; + regs->si = (__u64)trap_conf.priv; /* Go past the red zone mandated by the System V * x86-64 ABI. */ @@ -67,7 +67,7 @@ static void notifier_sched_in(struct preempt_notifier *notifier, int cpu) } static void notifier_sched_out(struct preempt_notifier *notifier, - struct task_struct *next) + struct task_struct *next) { } @@ -85,7 +85,7 @@ long dune_trap_enable(unsigned long arg) unsigned long r; r = copy_from_user(&trap_conf, (void __user *)arg, - sizeof(struct dune_trap_config)); + sizeof(struct dune_trap_config)); if (r) { r = -EIO; goto out; diff --git a/kern/vmx.c b/kern/vmx.c index 0c7764e..a1d517c 100644 --- a/kern/vmx.c +++ b/kern/vmx.c @@ -24,7 +24,7 @@ * This driver is a research prototype and as such has the following * limitations: * - * FIXME: Backward compatability is currently a non-goal, and only recent + * FIXME: Backward compatibility is currently a non-goal, and only recent * full-featured (EPT, PCID, VPID, etc.) Intel hardware is supported by this * driver. * @@ -182,7 +182,7 @@ static inline void ept_sync_individual_addr(u64 eptp, gpa_t gpa) { if (cpu_has_vmx_invept_individual_addr()) __invept(VMX_EPT_EXTENT_INDIVIDUAL_ADDR, - eptp, gpa); + eptp, gpa); else ept_sync_context(eptp); } @@ -275,7 +275,7 @@ static __always_inline u64 vmcs_read64(unsigned long field) #ifdef CONFIG_X86_64 return vmcs_readl(field); #else - return vmcs_readl(field) | ((u64)vmcs_readl(field+1) << 32); + return vmcs_readl(field) | ((u64)vmcs_readl(field + 1) << 32); #endif } @@ -311,7 +311,7 @@ static void vmcs_write64(unsigned long field, u64 value) vmcs_writel(field, value); #ifndef CONFIG_X86_64 asm volatile (""); - vmcs_writel(field+1, value >> 32); + vmcs_writel(field + 1, value >> 32); #endif } @@ -433,7 +433,7 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf) #ifdef CONFIG_X86_64 /* IA-32 SDM Vol 3B: 64-bit CPUs always have VMX_BASIC_MSR[48]==0. */ - if (vmx_msr_high & (1u<<16)) + if (vmx_msr_high & (1u << 16)) return -EIO; #endif @@ -515,7 +515,7 @@ static void vmx_setup_constant_host_state(void) vmcs_write16(HOST_DS_SELECTOR, __KERNEL_DS); /* 22.2.4 */ vmcs_write16(HOST_ES_SELECTOR, __KERNEL_DS); /* 22.2.4 */ vmcs_write16(HOST_SS_SELECTOR, __KERNEL_DS); /* 22.2.4 */ - vmcs_write16(HOST_TR_SELECTOR, GDT_ENTRY_TSS*8); /* 22.2.4 */ + vmcs_write16(HOST_TR_SELECTOR, GDT_ENTRY_TSS * 8); /* 22.2.4 */ native_store_idt(&dt); vmcs_writel(HOST_IDTR_BASE, dt.address); /* 22.2.4 */ @@ -533,7 +533,7 @@ static void vmx_setup_constant_host_state(void) if (vmcs_config.vmexit_ctrl & VM_EXIT_LOAD_IA32_PAT) { rdmsr(MSR_IA32_CR_PAT, low32, high32); - vmcs_write64(HOST_IA32_PAT, low32 | ((u64) high32 << 32)); + vmcs_write64(HOST_IA32_PAT, low32 | ((u64)high32 << 32)); } vmcs_write16(HOST_FS_SELECTOR, 0); /* 22.2.4 */ @@ -645,7 +645,8 @@ static void vmx_get_cpu(struct vmx_vcpu *vcpu) if (vcpu->cpu != cur_cpu) { if (vcpu->cpu >= 0) smp_call_function_single(vcpu->cpu, - __vmx_get_cpu_helper, (void *) vcpu, 1); + __vmx_get_cpu_helper, + (void *)vcpu, 1); else vmcs_clear(vcpu->vmcs); @@ -699,7 +700,7 @@ static void __vmx_sync_individual_addr_helper(void *ptr) void vmx_ept_sync_vcpu(struct vmx_vcpu *vcpu) { smp_call_function_single(vcpu->cpu, - __vmx_sync_helper, (void *) vcpu, 1); + __vmx_sync_helper, (void *)vcpu, 1); } /** @@ -715,7 +716,8 @@ void vmx_ept_sync_individual_addr(struct vmx_vcpu *vcpu, gpa_t gpa) args.gpa = gpa; smp_call_function_single(vcpu->cpu, - __vmx_sync_individual_addr_helper, (void *) &args, 1); + __vmx_sync_individual_addr_helper, + (void *)&args, 1); } #define STACK_DEPTH 12 @@ -739,25 +741,25 @@ static void vmx_dump_cpu(struct vmx_vcpu *vcpu) pr_info("vmx: --- Begin VCPU Dump ---\n"); pr_info("vmx: CPU %d VPID %d\n", vcpu->cpu, vcpu->vpid); pr_info("vmx: RIP 0x%016llx RFLAGS 0x%08lx\n", - vcpu->regs[VCPU_REGS_RIP], flags); + vcpu->regs[VCPU_REGS_RIP], flags); pr_info("vmx: RAX 0x%016llx RCX 0x%016llx\n", - vcpu->regs[VCPU_REGS_RAX], vcpu->regs[VCPU_REGS_RCX]); + vcpu->regs[VCPU_REGS_RAX], vcpu->regs[VCPU_REGS_RCX]); pr_info("vmx: RDX 0x%016llx RBX 0x%016llx\n", - vcpu->regs[VCPU_REGS_RDX], vcpu->regs[VCPU_REGS_RBX]); + vcpu->regs[VCPU_REGS_RDX], vcpu->regs[VCPU_REGS_RBX]); pr_info("vmx: RSP 0x%016llx RBP 0x%016llx\n", - vcpu->regs[VCPU_REGS_RSP], vcpu->regs[VCPU_REGS_RBP]); + vcpu->regs[VCPU_REGS_RSP], vcpu->regs[VCPU_REGS_RBP]); pr_info("vmx: RSI 0x%016llx RDI 0x%016llx\n", - vcpu->regs[VCPU_REGS_RSI], vcpu->regs[VCPU_REGS_RDI]); + vcpu->regs[VCPU_REGS_RSI], vcpu->regs[VCPU_REGS_RDI]); pr_info("vmx: R8 0x%016llx R9 0x%016llx\n", - vcpu->regs[VCPU_REGS_R8], vcpu->regs[VCPU_REGS_R9]); + vcpu->regs[VCPU_REGS_R8], vcpu->regs[VCPU_REGS_R9]); pr_info("vmx: R10 0x%016llx R11 0x%016llx\n", - vcpu->regs[VCPU_REGS_R10], vcpu->regs[VCPU_REGS_R11]); + vcpu->regs[VCPU_REGS_R10], vcpu->regs[VCPU_REGS_R11]); pr_info("vmx: R12 0x%016llx R13 0x%016llx\n", - vcpu->regs[VCPU_REGS_R12], vcpu->regs[VCPU_REGS_R13]); + vcpu->regs[VCPU_REGS_R12], vcpu->regs[VCPU_REGS_R13]); pr_info("vmx: R14 0x%016llx R15 0x%016llx\n", - vcpu->regs[VCPU_REGS_R14], vcpu->regs[VCPU_REGS_R15]); + vcpu->regs[VCPU_REGS_R14], vcpu->regs[VCPU_REGS_R15]); pr_info("vmx: FS.base 0x%016lx GS.base 0x%016lx\n", - vmcs_readl(GUEST_FS_BASE), vmcs_readl(GUEST_GS_BASE)); + vmcs_readl(GUEST_FS_BASE), vmcs_readl(GUEST_GS_BASE)); pr_info("vmx: Dumping Stack Contents...\n"); sp = (unsigned long *) vcpu->regs[VCPU_REGS_RSP]; @@ -938,10 +940,10 @@ static void vmx_setup_vmcs(struct vmx_vcpu *vcpu) /* Control */ vmcs_write32(PIN_BASED_VM_EXEC_CONTROL, - vmcs_config.pin_based_exec_ctrl); + vmcs_config.pin_based_exec_ctrl); vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, - vmcs_config.cpu_based_exec_ctrl); + vmcs_config.cpu_based_exec_ctrl); if (cpu_has_secondary_exec_ctrls()) { vmcs_write32(SECONDARY_VM_EXEC_CONTROL, @@ -961,7 +963,7 @@ static void vmx_setup_vmcs(struct vmx_vcpu *vcpu) u64 host_pat; rdmsr(MSR_IA32_CR_PAT, msr_low, msr_high); - host_pat = msr_low | ((u64) msr_high << 32); + host_pat = msr_low | ((u64)msr_high << 32); /* Write the default value follow host pat */ vmcs_write64(GUEST_IA32_PAT, host_pat); /* Keep arch.pat sync with GUEST_IA32_PAT */ @@ -1063,7 +1065,7 @@ static void vmx_setup_registers(struct vmx_vcpu *vcpu, struct dune_config *conf) * vmx_copy_registers_to_conf - copy registers to dune_config */ static void vmx_copy_registers_to_conf(struct vmx_vcpu *vcpu, - struct dune_config *conf) + struct dune_config *conf) { conf->rax = vcpu->regs[VCPU_REGS_RAX]; conf->rbx = vcpu->regs[VCPU_REGS_RBX]; @@ -1096,7 +1098,7 @@ static struct vmx_vcpu *vmx_create_vcpu(struct dune_config *conf) if (conf->vcpu) { /* This Dune configuration already has a VCPU. */ - vcpu = (struct vmx_vcpu *) conf->vcpu; + vcpu = (struct vmx_vcpu *)conf->vcpu; vmx_get_cpu(vcpu); vmx_setup_registers(vcpu, conf); vmx_put_cpu(vcpu); @@ -1112,7 +1114,7 @@ static struct vmx_vcpu *vmx_create_vcpu(struct dune_config *conf) list_add(&vcpu->list, &vcpus); vcpu->conf = conf; - conf->vcpu = (u64) vcpu; + conf->vcpu = (u64)vcpu; vcpu->vmcs = vmx_alloc_vmcs(); if (!vcpu->vmcs) @@ -1122,7 +1124,7 @@ static struct vmx_vcpu *vmx_create_vcpu(struct dune_config *conf) goto fail_vpid; vcpu->cpu = -1; - vcpu->syscall_tbl = (void *) &dune_syscall_tbl; + vcpu->syscall_tbl = (void *)&dune_syscall_tbl; spin_lock_init(&vcpu->ept_lock); if (vmx_init_ept(vcpu)) @@ -1244,7 +1246,7 @@ static void make_pt_regs(struct vmx_vcpu *vcpu, struct pt_regs *regs, /* * NOTE: Since Dune processes use the kernel's LSTAR * syscall address, we need special logic to handle - * certain system calls (fork, clone, etc.) The specifc + * certain system calls (fork, clone, etc.) The specific * issue is that we can not jump to a high address * in a child process since it is not running in Dune. * Our solution is to adopt a special Dune convention @@ -1259,8 +1261,8 @@ static void make_pt_regs(struct vmx_vcpu *vcpu, struct pt_regs *regs, #if KERNEL_VERSION(4, 1, 0) <= LINUX_VERSION_CODE static long dune_sys_clone(unsigned long clone_flags, unsigned long newsp, - void __user *parent_tid, void __user *child_tid, - unsigned long tls) + void __user *parent_tid, void __user *child_tid, + unsigned long tls) { struct vmx_vcpu *vcpu; struct pt_regs regs; @@ -1319,14 +1321,14 @@ static long dune_sys_vfork(void) static void vmx_init_syscall(void) { - memcpy(dune_syscall_tbl, (void *) SYSCALL_TBL, + memcpy(dune_syscall_tbl, (void *)SYSCALL_TBL, sizeof(sys_call_ptr_t) * NUM_SYSCALLS); - dune_syscall_tbl[__NR_exit] = (void *) &dune_exit; - dune_syscall_tbl[__NR_exit_group] = (void *) &dune_exit_group; - dune_syscall_tbl[__NR_clone] = (void *) &dune_sys_clone; - dune_syscall_tbl[__NR_fork] = (void *) &dune_sys_fork; - dune_syscall_tbl[__NR_vfork] = (void *) &dune_sys_vfork; + dune_syscall_tbl[__NR_exit] = (void *)&dune_exit; + dune_syscall_tbl[__NR_exit_group] = (void *)&dune_exit_group; + dune_syscall_tbl[__NR_clone] = (void *)&dune_sys_clone; + dune_syscall_tbl[__NR_fork] = (void *)&dune_sys_fork; + dune_syscall_tbl[__NR_vfork] = (void *)&dune_sys_vfork; } #ifdef CONFIG_X86_64 @@ -1613,6 +1615,7 @@ int vmx_launch(struct dune_config *conf, int64_t *ret_code) u32 exit_intr_info; struct vmx_vcpu *vcpu = vmx_create_vcpu(conf); + if (!vcpu) return -ENOMEM; @@ -1640,11 +1643,9 @@ int vmx_launch(struct dune_config *conf, int64_t *ret_code) } if (signal_pending(current)) { - local_irq_enable(); vmx_put_cpu(vcpu); - vcpu->ret_code = DUNE_RET_SIGNAL; break; } diff --git a/kern/vmx.h b/kern/vmx.h index be5fb4a..8643f63 100644 --- a/kern/vmx.h +++ b/kern/vmx.h @@ -81,22 +81,21 @@ struct vmx_vcpu { unsigned long guest_kernel_gs_base; }; -extern __init int vmx_init(void); -extern void vmx_exit(void); -extern void vmx_cleanup(void); +__init int vmx_init(void); +void vmx_exit(void); +void vmx_cleanup(void); -extern int vmx_launch(struct dune_config *conf, int64_t *ret_code); +int vmx_launch(struct dune_config *conf, int64_t *ret_code); -extern int vmx_init_ept(struct vmx_vcpu *vcpu); -extern int vmx_create_ept(struct vmx_vcpu *vcpu); -extern void vmx_destroy_ept(struct vmx_vcpu *vcpu); +int vmx_init_ept(struct vmx_vcpu *vcpu); +int vmx_create_ept(struct vmx_vcpu *vcpu); +void vmx_destroy_ept(struct vmx_vcpu *vcpu); -extern int -vmx_do_ept_fault(struct vmx_vcpu *vcpu, unsigned long gpa, - unsigned long gva, int fault_flags); +int vmx_do_ept_fault(struct vmx_vcpu *vcpu, unsigned long gpa, + unsigned long gva, int fault_flags); -extern void vmx_ept_sync_vcpu(struct vmx_vcpu *vcpu); -extern void vmx_ept_sync_individual_addr(struct vmx_vcpu *vcpu, gpa_t gpa); +void vmx_ept_sync_vcpu(struct vmx_vcpu *vcpu); +void vmx_ept_sync_individual_addr(struct vmx_vcpu *vcpu, gpa_t gpa); static __always_inline unsigned long vmcs_readl(unsigned long field) {