1ad879127SKrish Sadhukhan /* 2ad879127SKrish Sadhukhan * Framework for testing nested virtualization 3ad879127SKrish Sadhukhan */ 4ad879127SKrish Sadhukhan 57d36db35SAvi Kivity #include "svm.h" 67d36db35SAvi Kivity #include "libcflat.h" 77d36db35SAvi Kivity #include "processor.h" 8b46094b4SPaolo Bonzini #include "desc.h" 97d36db35SAvi Kivity #include "msr.h" 107d36db35SAvi Kivity #include "vm.h" 117d36db35SAvi Kivity #include "smp.h" 127d36db35SAvi Kivity #include "types.h" 135aca024eSPaolo Bonzini #include "alloc_page.h" 14306bb7dbSCathy Avery #include "isr.h" 15306bb7dbSCathy Avery #include "apic.h" 16916635a8SSean Christopherson #include "vmalloc.h" 177d36db35SAvi Kivity 181535bf0fSJoerg Roedel /* for the nested page table*/ 191535bf0fSJoerg Roedel u64 *pte[2048]; 20ad879127SKrish Sadhukhan u64 *pde[4]; 21ad879127SKrish Sadhukhan u64 *pdpe; 22ad879127SKrish Sadhukhan u64 *pml4e; 231535bf0fSJoerg Roedel 24096cf7feSPaolo Bonzini struct vmcb *vmcb; 25096cf7feSPaolo Bonzini 26ad879127SKrish Sadhukhan u64 *npt_get_pte(u64 address) 271535bf0fSJoerg Roedel { 28ad879127SKrish Sadhukhan int i1, i2; 29ad879127SKrish Sadhukhan 30ad879127SKrish Sadhukhan address >>= 12; 31ad879127SKrish Sadhukhan i1 = (address >> 9) & 0x7ff; 32ad879127SKrish Sadhukhan i2 = address & 0x1ff; 33ad879127SKrish Sadhukhan 34ad879127SKrish Sadhukhan return &pte[i1][i2]; 351535bf0fSJoerg Roedel } 361535bf0fSJoerg Roedel 37ad879127SKrish Sadhukhan u64 *npt_get_pde(u64 address) 38f6a2ca45SPaolo Bonzini { 39f6a2ca45SPaolo Bonzini int i1, i2; 40f6a2ca45SPaolo Bonzini 41f6a2ca45SPaolo Bonzini address >>= 21; 42f6a2ca45SPaolo Bonzini i1 = (address >> 9) & 0x3; 43f6a2ca45SPaolo Bonzini i2 = address & 0x1ff; 44f6a2ca45SPaolo Bonzini 45f6a2ca45SPaolo Bonzini return &pde[i1][i2]; 46f6a2ca45SPaolo Bonzini } 47f6a2ca45SPaolo Bonzini 48ad879127SKrish Sadhukhan u64 *npt_get_pdpe(void) 498594b943SJoerg Roedel { 50ad879127SKrish Sadhukhan return pdpe; 51ad879127SKrish Sadhukhan } 528594b943SJoerg Roedel 53c6405e37SNadav Amit u64 *npt_get_pml4e(void) 54c6405e37SNadav Amit { 55c6405e37SNadav Amit return pml4e; 56c6405e37SNadav Amit } 57c6405e37SNadav Amit 58ad879127SKrish Sadhukhan bool smp_supported(void) 59ad879127SKrish Sadhukhan { 60ad879127SKrish Sadhukhan return cpu_count() > 1; 61ad879127SKrish Sadhukhan } 628594b943SJoerg Roedel 63ad879127SKrish Sadhukhan bool default_supported(void) 64ad879127SKrish Sadhukhan { 65ad879127SKrish Sadhukhan return true; 66ad879127SKrish Sadhukhan } 67ad879127SKrish Sadhukhan 68f6972bd6SLara Lazier bool vgif_supported(void) 69f6972bd6SLara Lazier { 70f6972bd6SLara Lazier return this_cpu_has(X86_FEATURE_VGIF); 71f6972bd6SLara Lazier } 72f6972bd6SLara Lazier 73537d39dfSMaxim Levitsky bool lbrv_supported(void) 74537d39dfSMaxim Levitsky { 75537d39dfSMaxim Levitsky return this_cpu_has(X86_FEATURE_LBRV); 76537d39dfSMaxim Levitsky } 77537d39dfSMaxim Levitsky 78a8503d50SMaxim Levitsky bool tsc_scale_supported(void) 79a8503d50SMaxim Levitsky { 80a8503d50SMaxim Levitsky return this_cpu_has(X86_FEATURE_TSCRATEMSR); 81a8503d50SMaxim Levitsky } 82a8503d50SMaxim Levitsky 83*8650dffeSMaxim Levitsky bool pause_filter_supported(void) 84*8650dffeSMaxim Levitsky { 85*8650dffeSMaxim Levitsky return this_cpu_has(X86_FEATURE_PAUSEFILTER); 86*8650dffeSMaxim Levitsky } 87*8650dffeSMaxim Levitsky 88*8650dffeSMaxim Levitsky bool pause_threshold_supported(void) 89*8650dffeSMaxim Levitsky { 90*8650dffeSMaxim Levitsky return this_cpu_has(X86_FEATURE_PFTHRESHOLD); 91*8650dffeSMaxim Levitsky } 92*8650dffeSMaxim Levitsky 93*8650dffeSMaxim Levitsky 94ad879127SKrish Sadhukhan void default_prepare(struct svm_test *test) 95ad879127SKrish Sadhukhan { 96096cf7feSPaolo Bonzini vmcb_ident(vmcb); 97ad879127SKrish Sadhukhan } 98ad879127SKrish Sadhukhan 99ad879127SKrish Sadhukhan void default_prepare_gif_clear(struct svm_test *test) 100ad879127SKrish Sadhukhan { 101ad879127SKrish Sadhukhan } 102ad879127SKrish Sadhukhan 103ad879127SKrish Sadhukhan bool default_finished(struct svm_test *test) 104ad879127SKrish Sadhukhan { 105ad879127SKrish Sadhukhan return true; /* one vmexit */ 106ad879127SKrish Sadhukhan } 107ad879127SKrish Sadhukhan 108ad879127SKrish Sadhukhan bool npt_supported(void) 109ad879127SKrish Sadhukhan { 110ad879127SKrish Sadhukhan return this_cpu_has(X86_FEATURE_NPT); 111ad879127SKrish Sadhukhan } 112ad879127SKrish Sadhukhan 113ad879127SKrish Sadhukhan int get_test_stage(struct svm_test *test) 114ad879127SKrish Sadhukhan { 115ad879127SKrish Sadhukhan barrier(); 116ad879127SKrish Sadhukhan return test->scratch; 117ad879127SKrish Sadhukhan } 118ad879127SKrish Sadhukhan 119ad879127SKrish Sadhukhan void set_test_stage(struct svm_test *test, int s) 120ad879127SKrish Sadhukhan { 121ad879127SKrish Sadhukhan barrier(); 122ad879127SKrish Sadhukhan test->scratch = s; 123ad879127SKrish Sadhukhan barrier(); 124ad879127SKrish Sadhukhan } 125ad879127SKrish Sadhukhan 126ad879127SKrish Sadhukhan void inc_test_stage(struct svm_test *test) 127ad879127SKrish Sadhukhan { 128ad879127SKrish Sadhukhan barrier(); 129ad879127SKrish Sadhukhan test->scratch++; 130ad879127SKrish Sadhukhan barrier(); 1318594b943SJoerg Roedel } 1328594b943SJoerg Roedel 1337d36db35SAvi Kivity static void vmcb_set_seg(struct vmcb_seg *seg, u16 selector, 1347d36db35SAvi Kivity u64 base, u32 limit, u32 attr) 1357d36db35SAvi Kivity { 1367d36db35SAvi Kivity seg->selector = selector; 1377d36db35SAvi Kivity seg->attrib = attr; 1387d36db35SAvi Kivity seg->limit = limit; 1397d36db35SAvi Kivity seg->base = base; 1407d36db35SAvi Kivity } 1417d36db35SAvi Kivity 142ad879127SKrish Sadhukhan inline void vmmcall(void) 143ad879127SKrish Sadhukhan { 144ad879127SKrish Sadhukhan asm volatile ("vmmcall" : : : "memory"); 145ad879127SKrish Sadhukhan } 146ad879127SKrish Sadhukhan 1478660d1b5SKrish Sadhukhan static test_guest_func guest_main; 1488660d1b5SKrish Sadhukhan 1498660d1b5SKrish Sadhukhan void test_set_guest(test_guest_func func) 1508660d1b5SKrish Sadhukhan { 1518660d1b5SKrish Sadhukhan guest_main = func; 1528660d1b5SKrish Sadhukhan } 1538660d1b5SKrish Sadhukhan 154ad879127SKrish Sadhukhan static void test_thunk(struct svm_test *test) 155ad879127SKrish Sadhukhan { 1568660d1b5SKrish Sadhukhan guest_main(test); 157ad879127SKrish Sadhukhan vmmcall(); 158ad879127SKrish Sadhukhan } 159ad879127SKrish Sadhukhan 160ad879127SKrish Sadhukhan u8 *io_bitmap; 161ad879127SKrish Sadhukhan u8 io_bitmap_area[16384]; 162ad879127SKrish Sadhukhan 163ad879127SKrish Sadhukhan u8 *msr_bitmap; 164ad879127SKrish Sadhukhan u8 msr_bitmap_area[MSR_BITMAP_SIZE + PAGE_SIZE]; 165ad879127SKrish Sadhukhan 166ad879127SKrish Sadhukhan void vmcb_ident(struct vmcb *vmcb) 1677d36db35SAvi Kivity { 1687d36db35SAvi Kivity u64 vmcb_phys = virt_to_phys(vmcb); 1697d36db35SAvi Kivity struct vmcb_save_area *save = &vmcb->save; 1707d36db35SAvi Kivity struct vmcb_control_area *ctrl = &vmcb->control; 1717d36db35SAvi Kivity u32 data_seg_attr = 3 | SVM_SELECTOR_S_MASK | SVM_SELECTOR_P_MASK 1727d36db35SAvi Kivity | SVM_SELECTOR_DB_MASK | SVM_SELECTOR_G_MASK; 1737d36db35SAvi Kivity u32 code_seg_attr = 9 | SVM_SELECTOR_S_MASK | SVM_SELECTOR_P_MASK 1747d36db35SAvi Kivity | SVM_SELECTOR_L_MASK | SVM_SELECTOR_G_MASK; 1757d36db35SAvi Kivity struct descriptor_table_ptr desc_table_ptr; 1767d36db35SAvi Kivity 1777d36db35SAvi Kivity memset(vmcb, 0, sizeof(*vmcb)); 1782c6589bcSPeter Shier asm volatile ("vmsave %0" : : "a"(vmcb_phys) : "memory"); 1797d36db35SAvi Kivity vmcb_set_seg(&save->es, read_es(), 0, -1U, data_seg_attr); 1807d36db35SAvi Kivity vmcb_set_seg(&save->cs, read_cs(), 0, -1U, code_seg_attr); 1817d36db35SAvi Kivity vmcb_set_seg(&save->ss, read_ss(), 0, -1U, data_seg_attr); 1827d36db35SAvi Kivity vmcb_set_seg(&save->ds, read_ds(), 0, -1U, data_seg_attr); 1837d36db35SAvi Kivity sgdt(&desc_table_ptr); 1847d36db35SAvi Kivity vmcb_set_seg(&save->gdtr, 0, desc_table_ptr.base, desc_table_ptr.limit, 0); 1857d36db35SAvi Kivity sidt(&desc_table_ptr); 1867d36db35SAvi Kivity vmcb_set_seg(&save->idtr, 0, desc_table_ptr.base, desc_table_ptr.limit, 0); 1877d36db35SAvi Kivity ctrl->asid = 1; 1887d36db35SAvi Kivity save->cpl = 0; 1897d36db35SAvi Kivity save->efer = rdmsr(MSR_EFER); 1907d36db35SAvi Kivity save->cr4 = read_cr4(); 1917d36db35SAvi Kivity save->cr3 = read_cr3(); 1927d36db35SAvi Kivity save->cr0 = read_cr0(); 1937d36db35SAvi Kivity save->dr7 = read_dr7(); 1947d36db35SAvi Kivity save->dr6 = read_dr6(); 1957d36db35SAvi Kivity save->cr2 = read_cr2(); 1967d36db35SAvi Kivity save->g_pat = rdmsr(MSR_IA32_CR_PAT); 1977d36db35SAvi Kivity save->dbgctl = rdmsr(MSR_IA32_DEBUGCTLMSR); 198eb8a146bSMaxim Levitsky ctrl->intercept = (1ULL << INTERCEPT_VMRUN) | 199eb8a146bSMaxim Levitsky (1ULL << INTERCEPT_VMMCALL) | 200eb8a146bSMaxim Levitsky (1ULL << INTERCEPT_SHUTDOWN); 2013d46571bSPaolo Bonzini ctrl->iopm_base_pa = virt_to_phys(io_bitmap); 20206a8c023STambe, William ctrl->msrpm_base_pa = virt_to_phys(msr_bitmap); 2031535bf0fSJoerg Roedel 2041535bf0fSJoerg Roedel if (npt_supported()) { 2051535bf0fSJoerg Roedel ctrl->nested_ctl = 1; 2061535bf0fSJoerg Roedel ctrl->nested_cr3 = (u64)pml4e; 207c803b19bSNadav Amit ctrl->tlb_ctl = TLB_CONTROL_FLUSH_ALL_ASID; 2081535bf0fSJoerg Roedel } 2097d36db35SAvi Kivity } 2107d36db35SAvi Kivity 211a43baea0SPaolo Bonzini struct regs regs; 212a43baea0SPaolo Bonzini 213ad879127SKrish Sadhukhan struct regs get_regs(void) 214ad879127SKrish Sadhukhan { 215ad879127SKrish Sadhukhan return regs; 216ad879127SKrish Sadhukhan } 217ad879127SKrish Sadhukhan 218a43baea0SPaolo Bonzini // rax handled specially below 219a43baea0SPaolo Bonzini 220a43baea0SPaolo Bonzini 2218660d1b5SKrish Sadhukhan struct svm_test *v2_test; 2228660d1b5SKrish Sadhukhan 2238660d1b5SKrish Sadhukhan 2248660d1b5SKrish Sadhukhan u64 guest_stack[10000]; 2258660d1b5SKrish Sadhukhan 226a6495564SKrish Sadhukhan int __svm_vmrun(u64 rip) 2278660d1b5SKrish Sadhukhan { 228a6495564SKrish Sadhukhan vmcb->save.rip = (ulong)rip; 2298660d1b5SKrish Sadhukhan vmcb->save.rsp = (ulong)(guest_stack + ARRAY_SIZE(guest_stack)); 2308660d1b5SKrish Sadhukhan regs.rdi = (ulong)v2_test; 2318660d1b5SKrish Sadhukhan 2328660d1b5SKrish Sadhukhan asm volatile ( 23344480895SKrish Sadhukhan ASM_PRE_VMRUN_CMD 23444480895SKrish Sadhukhan "vmrun %%rax\n\t" \ 23544480895SKrish Sadhukhan ASM_POST_VMRUN_CMD 2368660d1b5SKrish Sadhukhan : 2378660d1b5SKrish Sadhukhan : "a" (virt_to_phys(vmcb)) 2387b87cad0SPaolo Bonzini : "memory", "r15"); 2398660d1b5SKrish Sadhukhan 2408660d1b5SKrish Sadhukhan return (vmcb->control.exit_code); 2418660d1b5SKrish Sadhukhan } 2428660d1b5SKrish Sadhukhan 243a6495564SKrish Sadhukhan int svm_vmrun(void) 244a6495564SKrish Sadhukhan { 245a6495564SKrish Sadhukhan return __svm_vmrun((u64)test_thunk); 246a6495564SKrish Sadhukhan } 247a6495564SKrish Sadhukhan 2480c22fd44SPaolo Bonzini extern u8 vmrun_rip; 24944480895SKrish Sadhukhan 250440c4fc3SBill Wendling static noinline void test_run(struct svm_test *test) 2517d36db35SAvi Kivity { 2527d36db35SAvi Kivity u64 vmcb_phys = virt_to_phys(vmcb); 2537d36db35SAvi Kivity 2541500aca4SPaolo Bonzini irq_disable(); 255cf851077SSean Christopherson vmcb_ident(vmcb); 256cf851077SSean Christopherson 2577d36db35SAvi Kivity test->prepare(test); 2588660d1b5SKrish Sadhukhan guest_main = test->guest_func; 2597d36db35SAvi Kivity vmcb->save.rip = (ulong)test_thunk; 2607d36db35SAvi Kivity vmcb->save.rsp = (ulong)(guest_stack + ARRAY_SIZE(guest_stack)); 261a43baea0SPaolo Bonzini regs.rdi = (ulong)test; 2627d36db35SAvi Kivity do { 263ad879127SKrish Sadhukhan struct svm_test *the_test = test; 264e7bce343SPaolo Bonzini u64 the_vmcb = vmcb_phys; 2657d36db35SAvi Kivity asm volatile ( 2662c6589bcSPeter Shier "clgi;\n\t" // semi-colon needed for LLVM compatibility 2672e7dd780SCathy Avery "sti \n\t" 268e7bce343SPaolo Bonzini "call *%c[PREPARE_GIF_CLEAR](%[test]) \n \t" 269e7bce343SPaolo Bonzini "mov %[vmcb_phys], %%rax \n\t" 27044480895SKrish Sadhukhan ASM_PRE_VMRUN_CMD 27144480895SKrish Sadhukhan ".global vmrun_rip\n\t" \ 27244480895SKrish Sadhukhan "vmrun_rip: vmrun %%rax\n\t" \ 27344480895SKrish Sadhukhan ASM_POST_VMRUN_CMD 2742e7dd780SCathy Avery "cli \n\t" 2757d36db35SAvi Kivity "stgi" 276e7bce343SPaolo Bonzini : // inputs clobbered by the guest: 27786d24fa6SBill Wendling "=D" (the_test), // first argument register 27886d24fa6SBill Wendling "=b" (the_vmcb) // callee save register! 279e7bce343SPaolo Bonzini : [test] "0" (the_test), 280e7bce343SPaolo Bonzini [vmcb_phys] "1"(the_vmcb), 281ad879127SKrish Sadhukhan [PREPARE_GIF_CLEAR] "i" (offsetof(struct svm_test, prepare_gif_clear)) 282e7bce343SPaolo Bonzini : "rax", "rcx", "rdx", "rsi", 2837d36db35SAvi Kivity "r8", "r9", "r10", "r11" , "r12", "r13", "r14", "r15", 2847d36db35SAvi Kivity "memory"); 2857d36db35SAvi Kivity ++test->exits; 2867d36db35SAvi Kivity } while (!test->finished(test)); 2871500aca4SPaolo Bonzini irq_enable(); 2887d36db35SAvi Kivity 289a299895bSThomas Huth report(test->succeeded(test), "%s", test->name); 29048f67910SCathy Avery 29148f67910SCathy Avery if (test->on_vcpu) 29248f67910SCathy Avery test->on_vcpu_done = true; 29348f67910SCathy Avery } 29448f67910SCathy Avery 29548f67910SCathy Avery static void set_additional_vcpu_msr(void *msr_efer) 29648f67910SCathy Avery { 29748f67910SCathy Avery void *hsave = alloc_page(); 29848f67910SCathy Avery 29948f67910SCathy Avery wrmsr(MSR_VM_HSAVE_PA, virt_to_phys(hsave)); 300779fd1faSSean Christopherson wrmsr(MSR_EFER, (ulong)msr_efer | EFER_SVME); 3017d36db35SAvi Kivity } 3027d36db35SAvi Kivity 303ad879127SKrish Sadhukhan static void setup_svm(void) 304095274b4SPrasad Joshi { 305ad879127SKrish Sadhukhan void *hsave = alloc_page(); 306ad879127SKrish Sadhukhan u64 *page, address; 307ad879127SKrish Sadhukhan int i,j; 308095274b4SPrasad Joshi 309ad879127SKrish Sadhukhan wrmsr(MSR_VM_HSAVE_PA, virt_to_phys(hsave)); 310ad879127SKrish Sadhukhan wrmsr(MSR_EFER, rdmsr(MSR_EFER) | EFER_SVME); 3117d36db35SAvi Kivity 31248c13f32SKrish Sadhukhan io_bitmap = (void *) ALIGN((ulong)io_bitmap_area, PAGE_SIZE); 3137d36db35SAvi Kivity 314ad879127SKrish Sadhukhan msr_bitmap = (void *) ALIGN((ulong)msr_bitmap_area, PAGE_SIZE); 315e7bce343SPaolo Bonzini 316ad879127SKrish Sadhukhan if (!npt_supported()) 317bcd9774aSPaolo Bonzini return; 318bcd9774aSPaolo Bonzini 31948f67910SCathy Avery for (i = 1; i < cpu_count(); i++) 32048f67910SCathy Avery on_cpu(i, (void *)set_additional_vcpu_msr, (void *)rdmsr(MSR_EFER)); 32148f67910SCathy Avery 322ad879127SKrish Sadhukhan printf("NPT detected - running all tests with NPT enabled\n"); 3234c8eb156SJoerg Roedel 3244c8eb156SJoerg Roedel /* 325ad879127SKrish Sadhukhan * Nested paging supported - Build a nested page table 326ad879127SKrish Sadhukhan * Build the page-table bottom-up and map everything with 4k 327ad879127SKrish Sadhukhan * pages to get enough granularity for the NPT unit-tests. 3284c8eb156SJoerg Roedel */ 3294c8eb156SJoerg Roedel 330ad879127SKrish Sadhukhan address = 0; 3314c8eb156SJoerg Roedel 332ad879127SKrish Sadhukhan /* PTE level */ 333ad879127SKrish Sadhukhan for (i = 0; i < 2048; ++i) { 334ad879127SKrish Sadhukhan page = alloc_page(); 3358594b943SJoerg Roedel 336ad879127SKrish Sadhukhan for (j = 0; j < 512; ++j, address += 4096) 337ad879127SKrish Sadhukhan page[j] = address | 0x067ULL; 3388594b943SJoerg Roedel 339ad879127SKrish Sadhukhan pte[i] = page; 3408594b943SJoerg Roedel } 3418594b943SJoerg Roedel 342ad879127SKrish Sadhukhan /* PDE level */ 343ad879127SKrish Sadhukhan for (i = 0; i < 4; ++i) { 344ad879127SKrish Sadhukhan page = alloc_page(); 3458594b943SJoerg Roedel 346ad879127SKrish Sadhukhan for (j = 0; j < 512; ++j) 347ad879127SKrish Sadhukhan page[j] = (u64)pte[(i * 512) + j] | 0x027ULL; 3488594b943SJoerg Roedel 349ad879127SKrish Sadhukhan pde[i] = page; 3508594b943SJoerg Roedel } 3518594b943SJoerg Roedel 352ad879127SKrish Sadhukhan /* PDPe level */ 353ad879127SKrish Sadhukhan pdpe = alloc_page(); 354ad879127SKrish Sadhukhan for (i = 0; i < 4; ++i) 355ad879127SKrish Sadhukhan pdpe[i] = ((u64)(pde[i])) | 0x27; 356ea975120SJoerg Roedel 357ad879127SKrish Sadhukhan /* PML4e level */ 358ad879127SKrish Sadhukhan pml4e = alloc_page(); 359ad879127SKrish Sadhukhan pml4e[0] = ((u64)pdpe) | 0x27; 360ea975120SJoerg Roedel } 361ea975120SJoerg Roedel 36250d27547SPaolo Bonzini int matched; 36350d27547SPaolo Bonzini 36450d27547SPaolo Bonzini static bool 36550d27547SPaolo Bonzini test_wanted(const char *name, char *filters[], int filter_count) 36650d27547SPaolo Bonzini { 36750d27547SPaolo Bonzini int i; 36850d27547SPaolo Bonzini bool positive = false; 36950d27547SPaolo Bonzini bool match = false; 37050d27547SPaolo Bonzini char clean_name[strlen(name) + 1]; 37150d27547SPaolo Bonzini char *c; 37250d27547SPaolo Bonzini const char *n; 37350d27547SPaolo Bonzini 37450d27547SPaolo Bonzini /* Replace spaces with underscores. */ 37550d27547SPaolo Bonzini n = name; 37650d27547SPaolo Bonzini c = &clean_name[0]; 37750d27547SPaolo Bonzini do *c++ = (*n == ' ') ? '_' : *n; 37850d27547SPaolo Bonzini while (*n++); 37950d27547SPaolo Bonzini 38050d27547SPaolo Bonzini for (i = 0; i < filter_count; i++) { 38150d27547SPaolo Bonzini const char *filter = filters[i]; 38250d27547SPaolo Bonzini 38350d27547SPaolo Bonzini if (filter[0] == '-') { 38450d27547SPaolo Bonzini if (simple_glob(clean_name, filter + 1)) 38550d27547SPaolo Bonzini return false; 38650d27547SPaolo Bonzini } else { 38750d27547SPaolo Bonzini positive = true; 38850d27547SPaolo Bonzini match |= simple_glob(clean_name, filter); 38950d27547SPaolo Bonzini } 39050d27547SPaolo Bonzini } 39150d27547SPaolo Bonzini 39250d27547SPaolo Bonzini if (!positive || match) { 39350d27547SPaolo Bonzini matched++; 39450d27547SPaolo Bonzini return true; 39550d27547SPaolo Bonzini } else { 39650d27547SPaolo Bonzini return false; 39750d27547SPaolo Bonzini } 39850d27547SPaolo Bonzini } 39950d27547SPaolo Bonzini 4007d36db35SAvi Kivity int main(int ac, char **av) 4017d36db35SAvi Kivity { 402916635a8SSean Christopherson /* Omit PT_USER_MASK to allow tested host.CR4.SMEP=1. */ 403916635a8SSean Christopherson pteval_t opt_mask = 0; 404ad879127SKrish Sadhukhan int i = 0; 4057d36db35SAvi Kivity 40650d27547SPaolo Bonzini ac--; 40750d27547SPaolo Bonzini av++; 40850d27547SPaolo Bonzini 409916635a8SSean Christopherson __setup_vm(&opt_mask); 4107d36db35SAvi Kivity 411badc98caSKrish Sadhukhan if (!this_cpu_has(X86_FEATURE_SVM)) { 4127d36db35SAvi Kivity printf("SVM not availble\n"); 41332b9603cSRadim Krčmář return report_summary(); 4147d36db35SAvi Kivity } 4157d36db35SAvi Kivity 4167d36db35SAvi Kivity setup_svm(); 4177d36db35SAvi Kivity 4187d36db35SAvi Kivity vmcb = alloc_page(); 4197d36db35SAvi Kivity 420ad879127SKrish Sadhukhan for (; svm_tests[i].name != NULL; i++) { 4218660d1b5SKrish Sadhukhan if (!test_wanted(svm_tests[i].name, av, ac)) 4227d36db35SAvi Kivity continue; 4238660d1b5SKrish Sadhukhan if (svm_tests[i].supported && !svm_tests[i].supported()) 4248660d1b5SKrish Sadhukhan continue; 4258660d1b5SKrish Sadhukhan if (svm_tests[i].v2 == NULL) { 42648f67910SCathy Avery if (svm_tests[i].on_vcpu) { 42748f67910SCathy Avery if (cpu_count() <= svm_tests[i].on_vcpu) 42848f67910SCathy Avery continue; 42948f67910SCathy Avery on_cpu_async(svm_tests[i].on_vcpu, (void *)test_run, &svm_tests[i]); 43048f67910SCathy Avery while (!svm_tests[i].on_vcpu_done) 43148f67910SCathy Avery cpu_relax(); 43248f67910SCathy Avery } 43348f67910SCathy Avery else 4348660d1b5SKrish Sadhukhan test_run(&svm_tests[i]); 4358660d1b5SKrish Sadhukhan } else { 4368660d1b5SKrish Sadhukhan vmcb_ident(vmcb); 4378660d1b5SKrish Sadhukhan v2_test = &(svm_tests[i]); 4388660d1b5SKrish Sadhukhan svm_tests[i].v2(); 4398660d1b5SKrish Sadhukhan } 4407d36db35SAvi Kivity } 4417d36db35SAvi Kivity 44250d27547SPaolo Bonzini if (!matched) 44350d27547SPaolo Bonzini report(matched, "command line didn't match any tests!"); 44450d27547SPaolo Bonzini 445a43ed2acSAndrew Jones return report_summary(); 4467d36db35SAvi Kivity } 447