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" 167d36db35SAvi Kivity 171535bf0fSJoerg Roedel /* for the nested page table*/ 181535bf0fSJoerg Roedel u64 *pte[2048]; 19ad879127SKrish Sadhukhan u64 *pde[4]; 20ad879127SKrish Sadhukhan u64 *pdpe; 21ad879127SKrish Sadhukhan u64 *pml4e; 221535bf0fSJoerg Roedel 23096cf7feSPaolo Bonzini struct vmcb *vmcb; 24096cf7feSPaolo Bonzini 25ad879127SKrish Sadhukhan u64 *npt_get_pte(u64 address) 261535bf0fSJoerg Roedel { 27ad879127SKrish Sadhukhan int i1, i2; 28ad879127SKrish Sadhukhan 29ad879127SKrish Sadhukhan address >>= 12; 30ad879127SKrish Sadhukhan i1 = (address >> 9) & 0x7ff; 31ad879127SKrish Sadhukhan i2 = address & 0x1ff; 32ad879127SKrish Sadhukhan 33ad879127SKrish Sadhukhan return &pte[i1][i2]; 341535bf0fSJoerg Roedel } 351535bf0fSJoerg Roedel 36ad879127SKrish Sadhukhan u64 *npt_get_pde(u64 address) 37f6a2ca45SPaolo Bonzini { 38f6a2ca45SPaolo Bonzini int i1, i2; 39f6a2ca45SPaolo Bonzini 40f6a2ca45SPaolo Bonzini address >>= 21; 41f6a2ca45SPaolo Bonzini i1 = (address >> 9) & 0x3; 42f6a2ca45SPaolo Bonzini i2 = address & 0x1ff; 43f6a2ca45SPaolo Bonzini 44f6a2ca45SPaolo Bonzini return &pde[i1][i2]; 45f6a2ca45SPaolo Bonzini } 46f6a2ca45SPaolo Bonzini 47ad879127SKrish Sadhukhan u64 *npt_get_pdpe(void) 488594b943SJoerg Roedel { 49ad879127SKrish Sadhukhan return pdpe; 50ad879127SKrish Sadhukhan } 518594b943SJoerg Roedel 52ad879127SKrish Sadhukhan bool smp_supported(void) 53ad879127SKrish Sadhukhan { 54ad879127SKrish Sadhukhan return cpu_count() > 1; 55ad879127SKrish Sadhukhan } 568594b943SJoerg Roedel 57ad879127SKrish Sadhukhan bool default_supported(void) 58ad879127SKrish Sadhukhan { 59ad879127SKrish Sadhukhan return true; 60ad879127SKrish Sadhukhan } 61ad879127SKrish Sadhukhan 62ad879127SKrish Sadhukhan void default_prepare(struct svm_test *test) 63ad879127SKrish Sadhukhan { 64096cf7feSPaolo Bonzini vmcb_ident(vmcb); 65ad879127SKrish Sadhukhan } 66ad879127SKrish Sadhukhan 67ad879127SKrish Sadhukhan void default_prepare_gif_clear(struct svm_test *test) 68ad879127SKrish Sadhukhan { 69ad879127SKrish Sadhukhan } 70ad879127SKrish Sadhukhan 71ad879127SKrish Sadhukhan bool default_finished(struct svm_test *test) 72ad879127SKrish Sadhukhan { 73ad879127SKrish Sadhukhan return true; /* one vmexit */ 74ad879127SKrish Sadhukhan } 75ad879127SKrish Sadhukhan 76ad879127SKrish Sadhukhan bool npt_supported(void) 77ad879127SKrish Sadhukhan { 78ad879127SKrish Sadhukhan return this_cpu_has(X86_FEATURE_NPT); 79ad879127SKrish Sadhukhan } 80ad879127SKrish Sadhukhan 81ad879127SKrish Sadhukhan int get_test_stage(struct svm_test *test) 82ad879127SKrish Sadhukhan { 83ad879127SKrish Sadhukhan barrier(); 84ad879127SKrish Sadhukhan return test->scratch; 85ad879127SKrish Sadhukhan } 86ad879127SKrish Sadhukhan 87ad879127SKrish Sadhukhan void set_test_stage(struct svm_test *test, int s) 88ad879127SKrish Sadhukhan { 89ad879127SKrish Sadhukhan barrier(); 90ad879127SKrish Sadhukhan test->scratch = s; 91ad879127SKrish Sadhukhan barrier(); 92ad879127SKrish Sadhukhan } 93ad879127SKrish Sadhukhan 94ad879127SKrish Sadhukhan void inc_test_stage(struct svm_test *test) 95ad879127SKrish Sadhukhan { 96ad879127SKrish Sadhukhan barrier(); 97ad879127SKrish Sadhukhan test->scratch++; 98ad879127SKrish Sadhukhan barrier(); 998594b943SJoerg Roedel } 1008594b943SJoerg Roedel 1017d36db35SAvi Kivity static void vmcb_set_seg(struct vmcb_seg *seg, u16 selector, 1027d36db35SAvi Kivity u64 base, u32 limit, u32 attr) 1037d36db35SAvi Kivity { 1047d36db35SAvi Kivity seg->selector = selector; 1057d36db35SAvi Kivity seg->attrib = attr; 1067d36db35SAvi Kivity seg->limit = limit; 1077d36db35SAvi Kivity seg->base = base; 1087d36db35SAvi Kivity } 1097d36db35SAvi Kivity 110ad879127SKrish Sadhukhan inline void vmmcall(void) 111ad879127SKrish Sadhukhan { 112ad879127SKrish Sadhukhan asm volatile ("vmmcall" : : : "memory"); 113ad879127SKrish Sadhukhan } 114ad879127SKrish Sadhukhan 1158660d1b5SKrish Sadhukhan static test_guest_func guest_main; 1168660d1b5SKrish Sadhukhan 1178660d1b5SKrish Sadhukhan void test_set_guest(test_guest_func func) 1188660d1b5SKrish Sadhukhan { 1198660d1b5SKrish Sadhukhan guest_main = func; 1208660d1b5SKrish Sadhukhan } 1218660d1b5SKrish Sadhukhan 122ad879127SKrish Sadhukhan static void test_thunk(struct svm_test *test) 123ad879127SKrish Sadhukhan { 1248660d1b5SKrish Sadhukhan guest_main(test); 125ad879127SKrish Sadhukhan vmmcall(); 126ad879127SKrish Sadhukhan } 127ad879127SKrish Sadhukhan 128ad879127SKrish Sadhukhan u8 *io_bitmap; 129ad879127SKrish Sadhukhan u8 io_bitmap_area[16384]; 130ad879127SKrish Sadhukhan 131ad879127SKrish Sadhukhan u8 *msr_bitmap; 132ad879127SKrish Sadhukhan u8 msr_bitmap_area[MSR_BITMAP_SIZE + PAGE_SIZE]; 133ad879127SKrish Sadhukhan 134ad879127SKrish Sadhukhan void vmcb_ident(struct vmcb *vmcb) 1357d36db35SAvi Kivity { 1367d36db35SAvi Kivity u64 vmcb_phys = virt_to_phys(vmcb); 1377d36db35SAvi Kivity struct vmcb_save_area *save = &vmcb->save; 1387d36db35SAvi Kivity struct vmcb_control_area *ctrl = &vmcb->control; 1397d36db35SAvi Kivity u32 data_seg_attr = 3 | SVM_SELECTOR_S_MASK | SVM_SELECTOR_P_MASK 1407d36db35SAvi Kivity | SVM_SELECTOR_DB_MASK | SVM_SELECTOR_G_MASK; 1417d36db35SAvi Kivity u32 code_seg_attr = 9 | SVM_SELECTOR_S_MASK | SVM_SELECTOR_P_MASK 1427d36db35SAvi Kivity | SVM_SELECTOR_L_MASK | SVM_SELECTOR_G_MASK; 1437d36db35SAvi Kivity struct descriptor_table_ptr desc_table_ptr; 1447d36db35SAvi Kivity 1457d36db35SAvi Kivity memset(vmcb, 0, sizeof(*vmcb)); 1462c6589bcSPeter Shier asm volatile ("vmsave %0" : : "a"(vmcb_phys) : "memory"); 1477d36db35SAvi Kivity vmcb_set_seg(&save->es, read_es(), 0, -1U, data_seg_attr); 1487d36db35SAvi Kivity vmcb_set_seg(&save->cs, read_cs(), 0, -1U, code_seg_attr); 1497d36db35SAvi Kivity vmcb_set_seg(&save->ss, read_ss(), 0, -1U, data_seg_attr); 1507d36db35SAvi Kivity vmcb_set_seg(&save->ds, read_ds(), 0, -1U, data_seg_attr); 1517d36db35SAvi Kivity sgdt(&desc_table_ptr); 1527d36db35SAvi Kivity vmcb_set_seg(&save->gdtr, 0, desc_table_ptr.base, desc_table_ptr.limit, 0); 1537d36db35SAvi Kivity sidt(&desc_table_ptr); 1547d36db35SAvi Kivity vmcb_set_seg(&save->idtr, 0, desc_table_ptr.base, desc_table_ptr.limit, 0); 1557d36db35SAvi Kivity ctrl->asid = 1; 1567d36db35SAvi Kivity save->cpl = 0; 1577d36db35SAvi Kivity save->efer = rdmsr(MSR_EFER); 1587d36db35SAvi Kivity save->cr4 = read_cr4(); 1597d36db35SAvi Kivity save->cr3 = read_cr3(); 1607d36db35SAvi Kivity save->cr0 = read_cr0(); 1617d36db35SAvi Kivity save->dr7 = read_dr7(); 1627d36db35SAvi Kivity save->dr6 = read_dr6(); 1637d36db35SAvi Kivity save->cr2 = read_cr2(); 1647d36db35SAvi Kivity save->g_pat = rdmsr(MSR_IA32_CR_PAT); 1657d36db35SAvi Kivity save->dbgctl = rdmsr(MSR_IA32_DEBUGCTLMSR); 1667d36db35SAvi Kivity ctrl->intercept = (1ULL << INTERCEPT_VMRUN) | (1ULL << INTERCEPT_VMMCALL); 1673d46571bSPaolo Bonzini ctrl->iopm_base_pa = virt_to_phys(io_bitmap); 16806a8c023STambe, William ctrl->msrpm_base_pa = virt_to_phys(msr_bitmap); 1691535bf0fSJoerg Roedel 1701535bf0fSJoerg Roedel if (npt_supported()) { 1711535bf0fSJoerg Roedel ctrl->nested_ctl = 1; 1721535bf0fSJoerg Roedel ctrl->nested_cr3 = (u64)pml4e; 173*c803b19bSNadav Amit ctrl->tlb_ctl = TLB_CONTROL_FLUSH_ALL_ASID; 1741535bf0fSJoerg Roedel } 1757d36db35SAvi Kivity } 1767d36db35SAvi Kivity 177a43baea0SPaolo Bonzini struct regs regs; 178a43baea0SPaolo Bonzini 179ad879127SKrish Sadhukhan struct regs get_regs(void) 180ad879127SKrish Sadhukhan { 181ad879127SKrish Sadhukhan return regs; 182ad879127SKrish Sadhukhan } 183ad879127SKrish Sadhukhan 184a43baea0SPaolo Bonzini // rax handled specially below 185a43baea0SPaolo Bonzini 186a43baea0SPaolo Bonzini #define SAVE_GPR_C \ 187a43baea0SPaolo Bonzini "xchg %%rbx, regs+0x8\n\t" \ 188a43baea0SPaolo Bonzini "xchg %%rcx, regs+0x10\n\t" \ 189a43baea0SPaolo Bonzini "xchg %%rdx, regs+0x18\n\t" \ 190a43baea0SPaolo Bonzini "xchg %%rbp, regs+0x28\n\t" \ 191a43baea0SPaolo Bonzini "xchg %%rsi, regs+0x30\n\t" \ 192a43baea0SPaolo Bonzini "xchg %%rdi, regs+0x38\n\t" \ 193a43baea0SPaolo Bonzini "xchg %%r8, regs+0x40\n\t" \ 194a43baea0SPaolo Bonzini "xchg %%r9, regs+0x48\n\t" \ 195a43baea0SPaolo Bonzini "xchg %%r10, regs+0x50\n\t" \ 196a43baea0SPaolo Bonzini "xchg %%r11, regs+0x58\n\t" \ 197a43baea0SPaolo Bonzini "xchg %%r12, regs+0x60\n\t" \ 198a43baea0SPaolo Bonzini "xchg %%r13, regs+0x68\n\t" \ 199a43baea0SPaolo Bonzini "xchg %%r14, regs+0x70\n\t" \ 200a43baea0SPaolo Bonzini "xchg %%r15, regs+0x78\n\t" 201a43baea0SPaolo Bonzini 202a43baea0SPaolo Bonzini #define LOAD_GPR_C SAVE_GPR_C 203a43baea0SPaolo Bonzini 2048660d1b5SKrish Sadhukhan struct svm_test *v2_test; 2058660d1b5SKrish Sadhukhan struct vmcb *vmcb; 2068660d1b5SKrish Sadhukhan 2078660d1b5SKrish Sadhukhan #define ASM_VMRUN_CMD \ 2088660d1b5SKrish Sadhukhan "vmload %%rax\n\t" \ 2098660d1b5SKrish Sadhukhan "mov regs+0x80, %%r15\n\t" \ 2108660d1b5SKrish Sadhukhan "mov %%r15, 0x170(%%rax)\n\t" \ 2118660d1b5SKrish Sadhukhan "mov regs, %%r15\n\t" \ 2128660d1b5SKrish Sadhukhan "mov %%r15, 0x1f8(%%rax)\n\t" \ 2138660d1b5SKrish Sadhukhan LOAD_GPR_C \ 2148660d1b5SKrish Sadhukhan "vmrun %%rax\n\t" \ 2158660d1b5SKrish Sadhukhan SAVE_GPR_C \ 2168660d1b5SKrish Sadhukhan "mov 0x170(%%rax), %%r15\n\t" \ 2178660d1b5SKrish Sadhukhan "mov %%r15, regs+0x80\n\t" \ 2188660d1b5SKrish Sadhukhan "mov 0x1f8(%%rax), %%r15\n\t" \ 2198660d1b5SKrish Sadhukhan "mov %%r15, regs\n\t" \ 2208660d1b5SKrish Sadhukhan "vmsave %%rax\n\t" \ 2218660d1b5SKrish Sadhukhan 2228660d1b5SKrish Sadhukhan u64 guest_stack[10000]; 2238660d1b5SKrish Sadhukhan 2248660d1b5SKrish Sadhukhan int svm_vmrun(void) 2258660d1b5SKrish Sadhukhan { 2268660d1b5SKrish Sadhukhan vmcb->save.rip = (ulong)test_thunk; 2278660d1b5SKrish Sadhukhan vmcb->save.rsp = (ulong)(guest_stack + ARRAY_SIZE(guest_stack)); 2288660d1b5SKrish Sadhukhan regs.rdi = (ulong)v2_test; 2298660d1b5SKrish Sadhukhan 2308660d1b5SKrish Sadhukhan asm volatile ( 2318660d1b5SKrish Sadhukhan ASM_VMRUN_CMD 2328660d1b5SKrish Sadhukhan : 2338660d1b5SKrish Sadhukhan : "a" (virt_to_phys(vmcb)) 2348660d1b5SKrish Sadhukhan : "memory"); 2358660d1b5SKrish Sadhukhan 2368660d1b5SKrish Sadhukhan return (vmcb->control.exit_code); 2378660d1b5SKrish Sadhukhan } 2388660d1b5SKrish Sadhukhan 2398660d1b5SKrish Sadhukhan static void test_run(struct svm_test *test) 2407d36db35SAvi Kivity { 2417d36db35SAvi Kivity u64 vmcb_phys = virt_to_phys(vmcb); 2427d36db35SAvi Kivity 2431500aca4SPaolo Bonzini irq_disable(); 2447d36db35SAvi Kivity test->prepare(test); 2458660d1b5SKrish Sadhukhan guest_main = test->guest_func; 2467d36db35SAvi Kivity vmcb->save.rip = (ulong)test_thunk; 2477d36db35SAvi Kivity vmcb->save.rsp = (ulong)(guest_stack + ARRAY_SIZE(guest_stack)); 248a43baea0SPaolo Bonzini regs.rdi = (ulong)test; 2497d36db35SAvi Kivity do { 250ad879127SKrish Sadhukhan struct svm_test *the_test = test; 251e7bce343SPaolo Bonzini u64 the_vmcb = vmcb_phys; 2527d36db35SAvi Kivity asm volatile ( 2532c6589bcSPeter Shier "clgi;\n\t" // semi-colon needed for LLVM compatibility 2542e7dd780SCathy Avery "sti \n\t" 255e7bce343SPaolo Bonzini "call *%c[PREPARE_GIF_CLEAR](%[test]) \n \t" 256e7bce343SPaolo Bonzini "mov %[vmcb_phys], %%rax \n\t" 2578660d1b5SKrish Sadhukhan ASM_VMRUN_CMD 2582e7dd780SCathy Avery "cli \n\t" 2597d36db35SAvi Kivity "stgi" 260e7bce343SPaolo Bonzini : // inputs clobbered by the guest: 26186d24fa6SBill Wendling "=D" (the_test), // first argument register 26286d24fa6SBill Wendling "=b" (the_vmcb) // callee save register! 263e7bce343SPaolo Bonzini : [test] "0" (the_test), 264e7bce343SPaolo Bonzini [vmcb_phys] "1"(the_vmcb), 265ad879127SKrish Sadhukhan [PREPARE_GIF_CLEAR] "i" (offsetof(struct svm_test, prepare_gif_clear)) 266e7bce343SPaolo Bonzini : "rax", "rcx", "rdx", "rsi", 2677d36db35SAvi Kivity "r8", "r9", "r10", "r11" , "r12", "r13", "r14", "r15", 2687d36db35SAvi Kivity "memory"); 2697d36db35SAvi Kivity ++test->exits; 2707d36db35SAvi Kivity } while (!test->finished(test)); 2711500aca4SPaolo Bonzini irq_enable(); 2727d36db35SAvi Kivity 273a299895bSThomas Huth report(test->succeeded(test), "%s", test->name); 2747d36db35SAvi Kivity } 2757d36db35SAvi Kivity 276ad879127SKrish Sadhukhan static void setup_svm(void) 277095274b4SPrasad Joshi { 278ad879127SKrish Sadhukhan void *hsave = alloc_page(); 279ad879127SKrish Sadhukhan u64 *page, address; 280ad879127SKrish Sadhukhan int i,j; 281095274b4SPrasad Joshi 282ad879127SKrish Sadhukhan wrmsr(MSR_VM_HSAVE_PA, virt_to_phys(hsave)); 283ad879127SKrish Sadhukhan wrmsr(MSR_EFER, rdmsr(MSR_EFER) | EFER_SVME); 284ad879127SKrish Sadhukhan wrmsr(MSR_EFER, rdmsr(MSR_EFER) | EFER_NX); 2857d36db35SAvi Kivity 286ad879127SKrish Sadhukhan io_bitmap = (void *) (((ulong)io_bitmap_area + 4095) & ~4095); 2877d36db35SAvi Kivity 288ad879127SKrish Sadhukhan msr_bitmap = (void *) ALIGN((ulong)msr_bitmap_area, PAGE_SIZE); 289e7bce343SPaolo Bonzini 290ad879127SKrish Sadhukhan if (!npt_supported()) 291bcd9774aSPaolo Bonzini return; 292bcd9774aSPaolo Bonzini 293ad879127SKrish Sadhukhan printf("NPT detected - running all tests with NPT enabled\n"); 2944c8eb156SJoerg Roedel 2954c8eb156SJoerg Roedel /* 296ad879127SKrish Sadhukhan * Nested paging supported - Build a nested page table 297ad879127SKrish Sadhukhan * Build the page-table bottom-up and map everything with 4k 298ad879127SKrish Sadhukhan * pages to get enough granularity for the NPT unit-tests. 2994c8eb156SJoerg Roedel */ 3004c8eb156SJoerg Roedel 301ad879127SKrish Sadhukhan address = 0; 3024c8eb156SJoerg Roedel 303ad879127SKrish Sadhukhan /* PTE level */ 304ad879127SKrish Sadhukhan for (i = 0; i < 2048; ++i) { 305ad879127SKrish Sadhukhan page = alloc_page(); 3068594b943SJoerg Roedel 307ad879127SKrish Sadhukhan for (j = 0; j < 512; ++j, address += 4096) 308ad879127SKrish Sadhukhan page[j] = address | 0x067ULL; 3098594b943SJoerg Roedel 310ad879127SKrish Sadhukhan pte[i] = page; 3118594b943SJoerg Roedel } 3128594b943SJoerg Roedel 313ad879127SKrish Sadhukhan /* PDE level */ 314ad879127SKrish Sadhukhan for (i = 0; i < 4; ++i) { 315ad879127SKrish Sadhukhan page = alloc_page(); 3168594b943SJoerg Roedel 317ad879127SKrish Sadhukhan for (j = 0; j < 512; ++j) 318ad879127SKrish Sadhukhan page[j] = (u64)pte[(i * 512) + j] | 0x027ULL; 3198594b943SJoerg Roedel 320ad879127SKrish Sadhukhan pde[i] = page; 3218594b943SJoerg Roedel } 3228594b943SJoerg Roedel 323ad879127SKrish Sadhukhan /* PDPe level */ 324ad879127SKrish Sadhukhan pdpe = alloc_page(); 325ad879127SKrish Sadhukhan for (i = 0; i < 4; ++i) 326ad879127SKrish Sadhukhan pdpe[i] = ((u64)(pde[i])) | 0x27; 327ea975120SJoerg Roedel 328ad879127SKrish Sadhukhan /* PML4e level */ 329ad879127SKrish Sadhukhan pml4e = alloc_page(); 330ad879127SKrish Sadhukhan pml4e[0] = ((u64)pdpe) | 0x27; 331ea975120SJoerg Roedel } 332ea975120SJoerg Roedel 33350d27547SPaolo Bonzini int matched; 33450d27547SPaolo Bonzini 33550d27547SPaolo Bonzini static bool 33650d27547SPaolo Bonzini test_wanted(const char *name, char *filters[], int filter_count) 33750d27547SPaolo Bonzini { 33850d27547SPaolo Bonzini int i; 33950d27547SPaolo Bonzini bool positive = false; 34050d27547SPaolo Bonzini bool match = false; 34150d27547SPaolo Bonzini char clean_name[strlen(name) + 1]; 34250d27547SPaolo Bonzini char *c; 34350d27547SPaolo Bonzini const char *n; 34450d27547SPaolo Bonzini 34550d27547SPaolo Bonzini /* Replace spaces with underscores. */ 34650d27547SPaolo Bonzini n = name; 34750d27547SPaolo Bonzini c = &clean_name[0]; 34850d27547SPaolo Bonzini do *c++ = (*n == ' ') ? '_' : *n; 34950d27547SPaolo Bonzini while (*n++); 35050d27547SPaolo Bonzini 35150d27547SPaolo Bonzini for (i = 0; i < filter_count; i++) { 35250d27547SPaolo Bonzini const char *filter = filters[i]; 35350d27547SPaolo Bonzini 35450d27547SPaolo Bonzini if (filter[0] == '-') { 35550d27547SPaolo Bonzini if (simple_glob(clean_name, filter + 1)) 35650d27547SPaolo Bonzini return false; 35750d27547SPaolo Bonzini } else { 35850d27547SPaolo Bonzini positive = true; 35950d27547SPaolo Bonzini match |= simple_glob(clean_name, filter); 36050d27547SPaolo Bonzini } 36150d27547SPaolo Bonzini } 36250d27547SPaolo Bonzini 36350d27547SPaolo Bonzini if (!positive || match) { 36450d27547SPaolo Bonzini matched++; 36550d27547SPaolo Bonzini return true; 36650d27547SPaolo Bonzini } else { 36750d27547SPaolo Bonzini return false; 36850d27547SPaolo Bonzini } 36950d27547SPaolo Bonzini } 37050d27547SPaolo Bonzini 3717d36db35SAvi Kivity int main(int ac, char **av) 3727d36db35SAvi Kivity { 373ad879127SKrish Sadhukhan int i = 0; 3747d36db35SAvi Kivity 37550d27547SPaolo Bonzini ac--; 37650d27547SPaolo Bonzini av++; 37750d27547SPaolo Bonzini 3787d36db35SAvi Kivity setup_vm(); 3797d36db35SAvi Kivity 380badc98caSKrish Sadhukhan if (!this_cpu_has(X86_FEATURE_SVM)) { 3817d36db35SAvi Kivity printf("SVM not availble\n"); 38232b9603cSRadim Krčmář return report_summary(); 3837d36db35SAvi Kivity } 3847d36db35SAvi Kivity 3857d36db35SAvi Kivity setup_svm(); 3867d36db35SAvi Kivity 3877d36db35SAvi Kivity vmcb = alloc_page(); 3887d36db35SAvi Kivity 389ad879127SKrish Sadhukhan for (; svm_tests[i].name != NULL; i++) { 3908660d1b5SKrish Sadhukhan if (!test_wanted(svm_tests[i].name, av, ac)) 3917d36db35SAvi Kivity continue; 3928660d1b5SKrish Sadhukhan if (svm_tests[i].supported && !svm_tests[i].supported()) 3938660d1b5SKrish Sadhukhan continue; 3948660d1b5SKrish Sadhukhan if (svm_tests[i].v2 == NULL) { 3958660d1b5SKrish Sadhukhan test_run(&svm_tests[i]); 3968660d1b5SKrish Sadhukhan } else { 3978660d1b5SKrish Sadhukhan vmcb_ident(vmcb); 3988660d1b5SKrish Sadhukhan v2_test = &(svm_tests[i]); 3998660d1b5SKrish Sadhukhan svm_tests[i].v2(); 4008660d1b5SKrish Sadhukhan } 4017d36db35SAvi Kivity } 4027d36db35SAvi Kivity 40350d27547SPaolo Bonzini if (!matched) 40450d27547SPaolo Bonzini report(matched, "command line didn't match any tests!"); 40550d27547SPaolo Bonzini 406a43ed2acSAndrew Jones return report_summary(); 4077d36db35SAvi Kivity } 408