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" 116f5ce7c1SManali Shukla #include "fwcfg.h" 127d36db35SAvi Kivity #include "smp.h" 137d36db35SAvi Kivity #include "types.h" 145aca024eSPaolo Bonzini #include "alloc_page.h" 15306bb7dbSCathy Avery #include "isr.h" 16306bb7dbSCathy Avery #include "apic.h" 177d36db35SAvi Kivity 181535bf0fSJoerg Roedel /* for the nested page table*/ 19ad879127SKrish Sadhukhan u64 *pml4e; 201535bf0fSJoerg Roedel 21096cf7feSPaolo Bonzini struct vmcb *vmcb; 22096cf7feSPaolo Bonzini 23ad879127SKrish Sadhukhan u64 *npt_get_pte(u64 address) 241535bf0fSJoerg Roedel { 256f5ce7c1SManali Shukla return get_pte(npt_get_pml4e(), (void*)address); 261535bf0fSJoerg Roedel } 271535bf0fSJoerg Roedel 28ad879127SKrish Sadhukhan u64 *npt_get_pde(u64 address) 29f6a2ca45SPaolo Bonzini { 306f5ce7c1SManali Shukla struct pte_search search; 316f5ce7c1SManali Shukla search = find_pte_level(npt_get_pml4e(), (void*)address, 2); 326f5ce7c1SManali Shukla return search.pte; 33f6a2ca45SPaolo Bonzini } 34f6a2ca45SPaolo Bonzini 356f5ce7c1SManali Shukla u64 *npt_get_pdpe(u64 address) 368594b943SJoerg Roedel { 376f5ce7c1SManali Shukla struct pte_search search; 386f5ce7c1SManali Shukla search = find_pte_level(npt_get_pml4e(), (void*)address, 3); 396f5ce7c1SManali Shukla return search.pte; 40ad879127SKrish Sadhukhan } 418594b943SJoerg Roedel 42c6405e37SNadav Amit u64 *npt_get_pml4e(void) 43c6405e37SNadav Amit { 44c6405e37SNadav Amit return pml4e; 45c6405e37SNadav Amit } 46c6405e37SNadav Amit 47ad879127SKrish Sadhukhan bool smp_supported(void) 48ad879127SKrish Sadhukhan { 49ad879127SKrish Sadhukhan return cpu_count() > 1; 50ad879127SKrish Sadhukhan } 518594b943SJoerg Roedel 52ad879127SKrish Sadhukhan bool default_supported(void) 53ad879127SKrish Sadhukhan { 54ad879127SKrish Sadhukhan return true; 55ad879127SKrish Sadhukhan } 56ad879127SKrish Sadhukhan 57f6972bd6SLara Lazier bool vgif_supported(void) 58f6972bd6SLara Lazier { 59f6972bd6SLara Lazier return this_cpu_has(X86_FEATURE_VGIF); 60f6972bd6SLara Lazier } 61f6972bd6SLara Lazier 62537d39dfSMaxim Levitsky bool lbrv_supported(void) 63537d39dfSMaxim Levitsky { 64537d39dfSMaxim Levitsky return this_cpu_has(X86_FEATURE_LBRV); 65537d39dfSMaxim Levitsky } 66537d39dfSMaxim Levitsky 67a8503d50SMaxim Levitsky bool tsc_scale_supported(void) 68a8503d50SMaxim Levitsky { 69a8503d50SMaxim Levitsky return this_cpu_has(X86_FEATURE_TSCRATEMSR); 70a8503d50SMaxim Levitsky } 71a8503d50SMaxim Levitsky 728650dffeSMaxim Levitsky bool pause_filter_supported(void) 738650dffeSMaxim Levitsky { 748650dffeSMaxim Levitsky return this_cpu_has(X86_FEATURE_PAUSEFILTER); 758650dffeSMaxim Levitsky } 768650dffeSMaxim Levitsky 778650dffeSMaxim Levitsky bool pause_threshold_supported(void) 788650dffeSMaxim Levitsky { 798650dffeSMaxim Levitsky return this_cpu_has(X86_FEATURE_PFTHRESHOLD); 808650dffeSMaxim Levitsky } 818650dffeSMaxim Levitsky 828650dffeSMaxim Levitsky 83ad879127SKrish Sadhukhan void default_prepare(struct svm_test *test) 84ad879127SKrish Sadhukhan { 85096cf7feSPaolo Bonzini vmcb_ident(vmcb); 86ad879127SKrish Sadhukhan } 87ad879127SKrish Sadhukhan 88ad879127SKrish Sadhukhan void default_prepare_gif_clear(struct svm_test *test) 89ad879127SKrish Sadhukhan { 90ad879127SKrish Sadhukhan } 91ad879127SKrish Sadhukhan 92ad879127SKrish Sadhukhan bool default_finished(struct svm_test *test) 93ad879127SKrish Sadhukhan { 94ad879127SKrish Sadhukhan return true; /* one vmexit */ 95ad879127SKrish Sadhukhan } 96ad879127SKrish Sadhukhan 97ad879127SKrish Sadhukhan bool npt_supported(void) 98ad879127SKrish Sadhukhan { 99ad879127SKrish Sadhukhan return this_cpu_has(X86_FEATURE_NPT); 100ad879127SKrish Sadhukhan } 101ad879127SKrish Sadhukhan 102*08200397SSantosh Shukla bool vnmi_supported(void) 103*08200397SSantosh Shukla { 104*08200397SSantosh Shukla return this_cpu_has(X86_FEATURE_VNMI); 105*08200397SSantosh Shukla } 106*08200397SSantosh Shukla 107ad879127SKrish Sadhukhan int get_test_stage(struct svm_test *test) 108ad879127SKrish Sadhukhan { 109ad879127SKrish Sadhukhan barrier(); 110ad879127SKrish Sadhukhan return test->scratch; 111ad879127SKrish Sadhukhan } 112ad879127SKrish Sadhukhan 113ad879127SKrish Sadhukhan void set_test_stage(struct svm_test *test, int s) 114ad879127SKrish Sadhukhan { 115ad879127SKrish Sadhukhan barrier(); 116ad879127SKrish Sadhukhan test->scratch = s; 117ad879127SKrish Sadhukhan barrier(); 118ad879127SKrish Sadhukhan } 119ad879127SKrish Sadhukhan 120ad879127SKrish Sadhukhan void inc_test_stage(struct svm_test *test) 121ad879127SKrish Sadhukhan { 122ad879127SKrish Sadhukhan barrier(); 123ad879127SKrish Sadhukhan test->scratch++; 124ad879127SKrish Sadhukhan barrier(); 1258594b943SJoerg Roedel } 1268594b943SJoerg Roedel 1277d36db35SAvi Kivity static void vmcb_set_seg(struct vmcb_seg *seg, u16 selector, 1287d36db35SAvi Kivity u64 base, u32 limit, u32 attr) 1297d36db35SAvi Kivity { 1307d36db35SAvi Kivity seg->selector = selector; 1317d36db35SAvi Kivity seg->attrib = attr; 1327d36db35SAvi Kivity seg->limit = limit; 1337d36db35SAvi Kivity seg->base = base; 1347d36db35SAvi Kivity } 1357d36db35SAvi Kivity 136ad879127SKrish Sadhukhan inline void vmmcall(void) 137ad879127SKrish Sadhukhan { 138ad879127SKrish Sadhukhan asm volatile ("vmmcall" : : : "memory"); 139ad879127SKrish Sadhukhan } 140ad879127SKrish Sadhukhan 1418660d1b5SKrish Sadhukhan static test_guest_func guest_main; 1428660d1b5SKrish Sadhukhan 1438660d1b5SKrish Sadhukhan void test_set_guest(test_guest_func func) 1448660d1b5SKrish Sadhukhan { 1458660d1b5SKrish Sadhukhan guest_main = func; 1468660d1b5SKrish Sadhukhan } 1478660d1b5SKrish Sadhukhan 148ad879127SKrish Sadhukhan static void test_thunk(struct svm_test *test) 149ad879127SKrish Sadhukhan { 1508660d1b5SKrish Sadhukhan guest_main(test); 151ad879127SKrish Sadhukhan vmmcall(); 152ad879127SKrish Sadhukhan } 153ad879127SKrish Sadhukhan 154ad879127SKrish Sadhukhan u8 *io_bitmap; 155ad879127SKrish Sadhukhan u8 io_bitmap_area[16384]; 156ad879127SKrish Sadhukhan 157ad879127SKrish Sadhukhan u8 *msr_bitmap; 158ad879127SKrish Sadhukhan u8 msr_bitmap_area[MSR_BITMAP_SIZE + PAGE_SIZE]; 159ad879127SKrish Sadhukhan 160ad879127SKrish Sadhukhan void vmcb_ident(struct vmcb *vmcb) 1617d36db35SAvi Kivity { 1627d36db35SAvi Kivity u64 vmcb_phys = virt_to_phys(vmcb); 1637d36db35SAvi Kivity struct vmcb_save_area *save = &vmcb->save; 1647d36db35SAvi Kivity struct vmcb_control_area *ctrl = &vmcb->control; 1657d36db35SAvi Kivity u32 data_seg_attr = 3 | SVM_SELECTOR_S_MASK | SVM_SELECTOR_P_MASK 1667d36db35SAvi Kivity | SVM_SELECTOR_DB_MASK | SVM_SELECTOR_G_MASK; 1677d36db35SAvi Kivity u32 code_seg_attr = 9 | SVM_SELECTOR_S_MASK | SVM_SELECTOR_P_MASK 1687d36db35SAvi Kivity | SVM_SELECTOR_L_MASK | SVM_SELECTOR_G_MASK; 1697d36db35SAvi Kivity struct descriptor_table_ptr desc_table_ptr; 1707d36db35SAvi Kivity 1717d36db35SAvi Kivity memset(vmcb, 0, sizeof(*vmcb)); 1722c6589bcSPeter Shier asm volatile ("vmsave %0" : : "a"(vmcb_phys) : "memory"); 1737d36db35SAvi Kivity vmcb_set_seg(&save->es, read_es(), 0, -1U, data_seg_attr); 1747d36db35SAvi Kivity vmcb_set_seg(&save->cs, read_cs(), 0, -1U, code_seg_attr); 1757d36db35SAvi Kivity vmcb_set_seg(&save->ss, read_ss(), 0, -1U, data_seg_attr); 1767d36db35SAvi Kivity vmcb_set_seg(&save->ds, read_ds(), 0, -1U, data_seg_attr); 1777d36db35SAvi Kivity sgdt(&desc_table_ptr); 1787d36db35SAvi Kivity vmcb_set_seg(&save->gdtr, 0, desc_table_ptr.base, desc_table_ptr.limit, 0); 1797d36db35SAvi Kivity sidt(&desc_table_ptr); 1807d36db35SAvi Kivity vmcb_set_seg(&save->idtr, 0, desc_table_ptr.base, desc_table_ptr.limit, 0); 1817d36db35SAvi Kivity ctrl->asid = 1; 1827d36db35SAvi Kivity save->cpl = 0; 1837d36db35SAvi Kivity save->efer = rdmsr(MSR_EFER); 1847d36db35SAvi Kivity save->cr4 = read_cr4(); 1857d36db35SAvi Kivity save->cr3 = read_cr3(); 1867d36db35SAvi Kivity save->cr0 = read_cr0(); 1877d36db35SAvi Kivity save->dr7 = read_dr7(); 1887d36db35SAvi Kivity save->dr6 = read_dr6(); 1897d36db35SAvi Kivity save->cr2 = read_cr2(); 1907d36db35SAvi Kivity save->g_pat = rdmsr(MSR_IA32_CR_PAT); 1917d36db35SAvi Kivity save->dbgctl = rdmsr(MSR_IA32_DEBUGCTLMSR); 192eb8a146bSMaxim Levitsky ctrl->intercept = (1ULL << INTERCEPT_VMRUN) | 193eb8a146bSMaxim Levitsky (1ULL << INTERCEPT_VMMCALL) | 194eb8a146bSMaxim Levitsky (1ULL << INTERCEPT_SHUTDOWN); 1953d46571bSPaolo Bonzini ctrl->iopm_base_pa = virt_to_phys(io_bitmap); 19606a8c023STambe, William ctrl->msrpm_base_pa = virt_to_phys(msr_bitmap); 1971535bf0fSJoerg Roedel 1981535bf0fSJoerg Roedel if (npt_supported()) { 1991535bf0fSJoerg Roedel ctrl->nested_ctl = 1; 2001535bf0fSJoerg Roedel ctrl->nested_cr3 = (u64)pml4e; 201c803b19bSNadav Amit ctrl->tlb_ctl = TLB_CONTROL_FLUSH_ALL_ASID; 2021535bf0fSJoerg Roedel } 2037d36db35SAvi Kivity } 2047d36db35SAvi Kivity 205a43baea0SPaolo Bonzini struct regs regs; 206a43baea0SPaolo Bonzini 207ad879127SKrish Sadhukhan struct regs get_regs(void) 208ad879127SKrish Sadhukhan { 209ad879127SKrish Sadhukhan return regs; 210ad879127SKrish Sadhukhan } 211ad879127SKrish Sadhukhan 212a43baea0SPaolo Bonzini // rax handled specially below 213a43baea0SPaolo Bonzini 214a43baea0SPaolo Bonzini 2158660d1b5SKrish Sadhukhan struct svm_test *v2_test; 2168660d1b5SKrish Sadhukhan 2178660d1b5SKrish Sadhukhan 2188660d1b5SKrish Sadhukhan u64 guest_stack[10000]; 2198660d1b5SKrish Sadhukhan 220a6495564SKrish Sadhukhan int __svm_vmrun(u64 rip) 2218660d1b5SKrish Sadhukhan { 222a6495564SKrish Sadhukhan vmcb->save.rip = (ulong)rip; 2238660d1b5SKrish Sadhukhan vmcb->save.rsp = (ulong)(guest_stack + ARRAY_SIZE(guest_stack)); 2248660d1b5SKrish Sadhukhan regs.rdi = (ulong)v2_test; 2258660d1b5SKrish Sadhukhan 2268660d1b5SKrish Sadhukhan asm volatile ( 22744480895SKrish Sadhukhan ASM_PRE_VMRUN_CMD 22844480895SKrish Sadhukhan "vmrun %%rax\n\t" \ 22944480895SKrish Sadhukhan ASM_POST_VMRUN_CMD 2308660d1b5SKrish Sadhukhan : 2318660d1b5SKrish Sadhukhan : "a" (virt_to_phys(vmcb)) 2327b87cad0SPaolo Bonzini : "memory", "r15"); 2338660d1b5SKrish Sadhukhan 2348660d1b5SKrish Sadhukhan return (vmcb->control.exit_code); 2358660d1b5SKrish Sadhukhan } 2368660d1b5SKrish Sadhukhan 237a6495564SKrish Sadhukhan int svm_vmrun(void) 238a6495564SKrish Sadhukhan { 239a6495564SKrish Sadhukhan return __svm_vmrun((u64)test_thunk); 240a6495564SKrish Sadhukhan } 241a6495564SKrish Sadhukhan 2420c22fd44SPaolo Bonzini extern u8 vmrun_rip; 24344480895SKrish Sadhukhan 244440c4fc3SBill Wendling static noinline void test_run(struct svm_test *test) 2457d36db35SAvi Kivity { 2467d36db35SAvi Kivity u64 vmcb_phys = virt_to_phys(vmcb); 2477d36db35SAvi Kivity 2481500aca4SPaolo Bonzini irq_disable(); 249cf851077SSean Christopherson vmcb_ident(vmcb); 250cf851077SSean Christopherson 2517d36db35SAvi Kivity test->prepare(test); 2528660d1b5SKrish Sadhukhan guest_main = test->guest_func; 2537d36db35SAvi Kivity vmcb->save.rip = (ulong)test_thunk; 2547d36db35SAvi Kivity vmcb->save.rsp = (ulong)(guest_stack + ARRAY_SIZE(guest_stack)); 255a43baea0SPaolo Bonzini regs.rdi = (ulong)test; 2567d36db35SAvi Kivity do { 257ad879127SKrish Sadhukhan struct svm_test *the_test = test; 258e7bce343SPaolo Bonzini u64 the_vmcb = vmcb_phys; 2597d36db35SAvi Kivity asm volatile ( 2602c6589bcSPeter Shier "clgi;\n\t" // semi-colon needed for LLVM compatibility 2612e7dd780SCathy Avery "sti \n\t" 262e7bce343SPaolo Bonzini "call *%c[PREPARE_GIF_CLEAR](%[test]) \n \t" 263e7bce343SPaolo Bonzini "mov %[vmcb_phys], %%rax \n\t" 26444480895SKrish Sadhukhan ASM_PRE_VMRUN_CMD 26544480895SKrish Sadhukhan ".global vmrun_rip\n\t" \ 26644480895SKrish Sadhukhan "vmrun_rip: vmrun %%rax\n\t" \ 26744480895SKrish Sadhukhan ASM_POST_VMRUN_CMD 2682e7dd780SCathy Avery "cli \n\t" 2697d36db35SAvi Kivity "stgi" 270e7bce343SPaolo Bonzini : // inputs clobbered by the guest: 27186d24fa6SBill Wendling "=D" (the_test), // first argument register 27286d24fa6SBill Wendling "=b" (the_vmcb) // callee save register! 273e7bce343SPaolo Bonzini : [test] "0" (the_test), 274e7bce343SPaolo Bonzini [vmcb_phys] "1"(the_vmcb), 275ad879127SKrish Sadhukhan [PREPARE_GIF_CLEAR] "i" (offsetof(struct svm_test, prepare_gif_clear)) 276e7bce343SPaolo Bonzini : "rax", "rcx", "rdx", "rsi", 2777d36db35SAvi Kivity "r8", "r9", "r10", "r11" , "r12", "r13", "r14", "r15", 2787d36db35SAvi Kivity "memory"); 2797d36db35SAvi Kivity ++test->exits; 2807d36db35SAvi Kivity } while (!test->finished(test)); 2811500aca4SPaolo Bonzini irq_enable(); 2827d36db35SAvi Kivity 283a299895bSThomas Huth report(test->succeeded(test), "%s", test->name); 28448f67910SCathy Avery 28548f67910SCathy Avery if (test->on_vcpu) 28648f67910SCathy Avery test->on_vcpu_done = true; 28748f67910SCathy Avery } 28848f67910SCathy Avery 28948f67910SCathy Avery static void set_additional_vcpu_msr(void *msr_efer) 29048f67910SCathy Avery { 29148f67910SCathy Avery void *hsave = alloc_page(); 29248f67910SCathy Avery 29348f67910SCathy Avery wrmsr(MSR_VM_HSAVE_PA, virt_to_phys(hsave)); 294779fd1faSSean Christopherson wrmsr(MSR_EFER, (ulong)msr_efer | EFER_SVME); 2957d36db35SAvi Kivity } 2967d36db35SAvi Kivity 2976f5ce7c1SManali Shukla static void setup_npt(void) 2986f5ce7c1SManali Shukla { 2996f5ce7c1SManali Shukla u64 size = fwcfg_get_u64(FW_CFG_RAM_SIZE); 3006f5ce7c1SManali Shukla 3016f5ce7c1SManali Shukla /* Ensure all <4gb is mapped, e.g. if there's no RAM above 4gb. */ 3026f5ce7c1SManali Shukla if (size < BIT_ULL(32)) 3036f5ce7c1SManali Shukla size = BIT_ULL(32); 3046f5ce7c1SManali Shukla 3056f5ce7c1SManali Shukla pml4e = alloc_page(); 3066f5ce7c1SManali Shukla 3076f5ce7c1SManali Shukla /* NPT accesses are treated as "user" accesses. */ 3086f5ce7c1SManali Shukla __setup_mmu_range(pml4e, 0, size, X86_MMU_MAP_USER); 3096f5ce7c1SManali Shukla } 3106f5ce7c1SManali Shukla 311ad879127SKrish Sadhukhan static void setup_svm(void) 312095274b4SPrasad Joshi { 313ad879127SKrish Sadhukhan void *hsave = alloc_page(); 3146f5ce7c1SManali Shukla int i; 315095274b4SPrasad Joshi 316ad879127SKrish Sadhukhan wrmsr(MSR_VM_HSAVE_PA, virt_to_phys(hsave)); 317ad879127SKrish Sadhukhan wrmsr(MSR_EFER, rdmsr(MSR_EFER) | EFER_SVME); 3187d36db35SAvi Kivity 31948c13f32SKrish Sadhukhan io_bitmap = (void *) ALIGN((ulong)io_bitmap_area, PAGE_SIZE); 3207d36db35SAvi Kivity 321ad879127SKrish Sadhukhan msr_bitmap = (void *) ALIGN((ulong)msr_bitmap_area, PAGE_SIZE); 322e7bce343SPaolo Bonzini 323ad879127SKrish Sadhukhan if (!npt_supported()) 324bcd9774aSPaolo Bonzini return; 325bcd9774aSPaolo Bonzini 32648f67910SCathy Avery for (i = 1; i < cpu_count(); i++) 32748f67910SCathy Avery on_cpu(i, (void *)set_additional_vcpu_msr, (void *)rdmsr(MSR_EFER)); 32848f67910SCathy Avery 329ad879127SKrish Sadhukhan printf("NPT detected - running all tests with NPT enabled\n"); 3304c8eb156SJoerg Roedel 3314c8eb156SJoerg Roedel /* 332ad879127SKrish Sadhukhan * Nested paging supported - Build a nested page table 333ad879127SKrish Sadhukhan * Build the page-table bottom-up and map everything with 4k 334ad879127SKrish Sadhukhan * pages to get enough granularity for the NPT unit-tests. 3354c8eb156SJoerg Roedel */ 3364c8eb156SJoerg Roedel 3376f5ce7c1SManali Shukla setup_npt(); 338ea975120SJoerg Roedel } 339ea975120SJoerg Roedel 34050d27547SPaolo Bonzini int matched; 34150d27547SPaolo Bonzini 34250d27547SPaolo Bonzini static bool 34350d27547SPaolo Bonzini test_wanted(const char *name, char *filters[], int filter_count) 34450d27547SPaolo Bonzini { 34550d27547SPaolo Bonzini int i; 34650d27547SPaolo Bonzini bool positive = false; 34750d27547SPaolo Bonzini bool match = false; 34850d27547SPaolo Bonzini char clean_name[strlen(name) + 1]; 34950d27547SPaolo Bonzini char *c; 35050d27547SPaolo Bonzini const char *n; 35150d27547SPaolo Bonzini 35250d27547SPaolo Bonzini /* Replace spaces with underscores. */ 35350d27547SPaolo Bonzini n = name; 35450d27547SPaolo Bonzini c = &clean_name[0]; 35550d27547SPaolo Bonzini do *c++ = (*n == ' ') ? '_' : *n; 35650d27547SPaolo Bonzini while (*n++); 35750d27547SPaolo Bonzini 35850d27547SPaolo Bonzini for (i = 0; i < filter_count; i++) { 35950d27547SPaolo Bonzini const char *filter = filters[i]; 36050d27547SPaolo Bonzini 36150d27547SPaolo Bonzini if (filter[0] == '-') { 36250d27547SPaolo Bonzini if (simple_glob(clean_name, filter + 1)) 36350d27547SPaolo Bonzini return false; 36450d27547SPaolo Bonzini } else { 36550d27547SPaolo Bonzini positive = true; 36650d27547SPaolo Bonzini match |= simple_glob(clean_name, filter); 36750d27547SPaolo Bonzini } 36850d27547SPaolo Bonzini } 36950d27547SPaolo Bonzini 37050d27547SPaolo Bonzini if (!positive || match) { 37150d27547SPaolo Bonzini matched++; 37250d27547SPaolo Bonzini return true; 37350d27547SPaolo Bonzini } else { 37450d27547SPaolo Bonzini return false; 37550d27547SPaolo Bonzini } 37650d27547SPaolo Bonzini } 37750d27547SPaolo Bonzini 378712840d5SManali Shukla int run_svm_tests(int ac, char **av, struct svm_test *svm_tests) 3797d36db35SAvi Kivity { 380ad879127SKrish Sadhukhan int i = 0; 3817d36db35SAvi Kivity 38250d27547SPaolo Bonzini ac--; 38350d27547SPaolo Bonzini av++; 38450d27547SPaolo Bonzini 385badc98caSKrish Sadhukhan if (!this_cpu_has(X86_FEATURE_SVM)) { 386912c0d72SThomas Huth printf("SVM not available\n"); 38732b9603cSRadim Krčmář return report_summary(); 3887d36db35SAvi Kivity } 3897d36db35SAvi Kivity 3907d36db35SAvi Kivity setup_svm(); 3917d36db35SAvi Kivity 3927d36db35SAvi Kivity vmcb = alloc_page(); 3937d36db35SAvi Kivity 394ad879127SKrish Sadhukhan for (; svm_tests[i].name != NULL; i++) { 3958660d1b5SKrish Sadhukhan if (!test_wanted(svm_tests[i].name, av, ac)) 3967d36db35SAvi Kivity continue; 3978660d1b5SKrish Sadhukhan if (svm_tests[i].supported && !svm_tests[i].supported()) 3988660d1b5SKrish Sadhukhan continue; 3998660d1b5SKrish Sadhukhan if (svm_tests[i].v2 == NULL) { 40048f67910SCathy Avery if (svm_tests[i].on_vcpu) { 40148f67910SCathy Avery if (cpu_count() <= svm_tests[i].on_vcpu) 40248f67910SCathy Avery continue; 40348f67910SCathy Avery on_cpu_async(svm_tests[i].on_vcpu, (void *)test_run, &svm_tests[i]); 40448f67910SCathy Avery while (!svm_tests[i].on_vcpu_done) 40548f67910SCathy Avery cpu_relax(); 40648f67910SCathy Avery } 40748f67910SCathy Avery else 4088660d1b5SKrish Sadhukhan test_run(&svm_tests[i]); 4098660d1b5SKrish Sadhukhan } else { 4108660d1b5SKrish Sadhukhan vmcb_ident(vmcb); 4118660d1b5SKrish Sadhukhan v2_test = &(svm_tests[i]); 4128660d1b5SKrish Sadhukhan svm_tests[i].v2(); 4138660d1b5SKrish Sadhukhan } 4147d36db35SAvi Kivity } 4157d36db35SAvi Kivity 41650d27547SPaolo Bonzini if (!matched) 41750d27547SPaolo Bonzini report(matched, "command line didn't match any tests!"); 41850d27547SPaolo Bonzini 419a43ed2acSAndrew Jones return report_summary(); 4207d36db35SAvi Kivity } 421