1 #include "libcflat.h" 2 #include "apic.h" 3 #include "processor.h" 4 #include "msr.h" 5 #include "x86/vm.h" 6 #include "asm/setup.h" 7 8 #ifdef __x86_64__ 9 enum TEST_REGISTER { 10 TEST_REGISTER_GDTR_BASE, 11 TEST_REGISTER_IDTR_BASE, 12 TEST_REGISTER_TR_BASE, 13 TEST_REGISTER_LDT_BASE, 14 TEST_REGISTER_MSR /* upper 32 bits = msr address */ 15 }; 16 17 static u64 get_test_register_value(u64 test_register) 18 { 19 struct descriptor_table_ptr dt_ptr; 20 u32 msr = test_register >> 32; 21 22 /* 23 * Note: value for LDT and TSS base might not reflect the actual base 24 * that the CPU currently uses, because the (hidden) base value can't be 25 * directly read. 26 */ 27 switch ((u32)test_register) { 28 case TEST_REGISTER_GDTR_BASE: 29 sgdt(&dt_ptr); 30 return dt_ptr.base; 31 case TEST_REGISTER_IDTR_BASE: 32 sidt(&dt_ptr); 33 return dt_ptr.base; 34 case TEST_REGISTER_TR_BASE: 35 return get_gdt_entry_base(get_tss_descr()); 36 case TEST_REGISTER_LDT_BASE: 37 return get_gdt_entry_base(get_ldt_descr()); 38 case TEST_REGISTER_MSR: 39 return rdmsr(msr); 40 default: 41 assert(0); 42 return 0; 43 } 44 } 45 46 enum SET_REGISTER_MODE { 47 SET_REGISTER_MODE_UNSAFE, 48 SET_REGISTER_MODE_SAFE, 49 SET_REGISTER_MODE_FEP, 50 }; 51 52 static bool set_test_register_value(u64 test_register, int test_mode, u64 value) 53 { 54 struct descriptor_table_ptr dt_ptr; 55 u32 msr = test_register >> 32; 56 u16 sel; 57 58 switch ((u32)test_register) { 59 case TEST_REGISTER_GDTR_BASE: 60 sgdt(&dt_ptr); 61 dt_ptr.base = value; 62 63 switch (test_mode) { 64 case SET_REGISTER_MODE_UNSAFE: 65 lgdt(&dt_ptr); 66 return true; 67 case SET_REGISTER_MODE_SAFE: 68 return lgdt_safe(&dt_ptr) == 0; 69 case SET_REGISTER_MODE_FEP: 70 return lgdt_fep_safe(&dt_ptr) == 0; 71 } 72 case TEST_REGISTER_IDTR_BASE: 73 sidt(&dt_ptr); 74 dt_ptr.base = value; 75 76 switch (test_mode) { 77 case SET_REGISTER_MODE_UNSAFE: 78 lidt(&dt_ptr); 79 return true; 80 case SET_REGISTER_MODE_SAFE: 81 return lidt_safe(&dt_ptr) == 0; 82 case SET_REGISTER_MODE_FEP: 83 return lidt_fep_safe(&dt_ptr) == 0; 84 } 85 case TEST_REGISTER_TR_BASE: 86 sel = str(); 87 set_gdt_entry_base(sel, value); 88 clear_tss_busy(sel); 89 90 switch (test_mode) { 91 case SET_REGISTER_MODE_UNSAFE: 92 ltr(sel); 93 return true; 94 case SET_REGISTER_MODE_SAFE: 95 return ltr_safe(sel) == 0; 96 case SET_REGISTER_MODE_FEP: 97 return ltr_fep_safe(sel) == 0; 98 } 99 100 case TEST_REGISTER_LDT_BASE: 101 sel = sldt(); 102 set_gdt_entry_base(sel, value); 103 104 switch (test_mode) { 105 case SET_REGISTER_MODE_UNSAFE: 106 lldt(sel); 107 return true; 108 case SET_REGISTER_MODE_SAFE: 109 return lldt_safe(sel) == 0; 110 case SET_REGISTER_MODE_FEP: 111 return lldt_fep_safe(sel) == 0; 112 } 113 case TEST_REGISTER_MSR: 114 switch (test_mode) { 115 case SET_REGISTER_MODE_UNSAFE: 116 wrmsr(msr, value); 117 return true; 118 case SET_REGISTER_MODE_SAFE: 119 return wrmsr_safe(msr, value) == 0; 120 case SET_REGISTER_MODE_FEP: 121 return wrmsr_fep_safe(msr, value) == 0; 122 } 123 default: 124 assert(false); 125 return 0; 126 } 127 } 128 129 static void test_register_write(const char *register_name, u64 test_register, 130 bool force_emulation, u64 test_value, 131 bool expect_success) 132 { 133 int test_mode = (force_emulation ? SET_REGISTER_MODE_FEP : SET_REGISTER_MODE_SAFE); 134 u64 old_value, expected_value; 135 bool success; 136 137 old_value = get_test_register_value(test_register); 138 expected_value = expect_success ? test_value : old_value; 139 140 /* 141 * TODO: A successful write to the MSR_GS_BASE corrupts it, and that 142 * breaks the wrmsr_safe macro (it uses GS for per-CPU data). 143 */ 144 if ((test_register >> 32) == MSR_GS_BASE && expect_success) 145 test_mode = SET_REGISTER_MODE_UNSAFE; 146 147 /* Write the test value*/ 148 success = set_test_register_value(test_register, test_mode, test_value); 149 report(success == expect_success, 150 "Write to %s with value %lx did %s%s as expected", 151 register_name, test_value, 152 success == expect_success ? "" : "NOT ", 153 (expect_success ? "succeed" : "fail")); 154 155 /* 156 * Check that the value was really written. Don't test TR and LDTR, 157 * because it's not possible to read them directly. 158 */ 159 if (success == expect_success && 160 test_register != TEST_REGISTER_TR_BASE && 161 test_register != TEST_REGISTER_LDT_BASE) { 162 u64 new_value = get_test_register_value(test_register); 163 164 report(new_value == expected_value, 165 "%s set to %lx as expected (actual value %lx)", 166 register_name, expected_value, new_value); 167 } 168 169 170 /* 171 * Restore the old value directly without safety wrapper, to avoid test 172 * crashes related to temporary clobbered GDT/IDT/etc bases. 173 */ 174 set_test_register_value(test_register, SET_REGISTER_MODE_UNSAFE, old_value); 175 } 176 177 static void test_register(const char *register_name, u64 test_register, 178 bool force_emulation) 179 { 180 /* Canonical 48 bit value should always succeed */ 181 test_register_write(register_name, test_register, force_emulation, 182 CANONICAL_48_VAL, true); 183 184 /* 57-canonical value will work on CPUs that *support* LA57 */ 185 test_register_write(register_name, test_register, force_emulation, 186 CANONICAL_57_VAL, this_cpu_has(X86_FEATURE_LA57)); 187 188 /* Non 57 canonical value should never work */ 189 test_register_write(register_name, test_register, force_emulation, 190 NONCANONICAL, false); 191 } 192 193 194 #define TEST_REGISTER(name, force_emulation) \ 195 test_register(#name, TEST_REGISTER_ ##name, force_emulation) 196 197 #define __TEST_MSR(msr_name, address, force_emulation) \ 198 test_register(msr_name, ((u64)TEST_REGISTER_MSR | \ 199 ((u64)(address) << 32)), force_emulation) 200 201 #define TEST_MSR(msr_name, force_emulation) \ 202 __TEST_MSR(#msr_name, msr_name, force_emulation) 203 204 static void __test_invpcid(u64 test_value, bool expect_success) 205 { 206 struct invpcid_desc desc; 207 208 memset(&desc, 0, sizeof(desc)); 209 bool success; 210 211 desc.addr = test_value; 212 desc.pcid = 10; /* Arbitrary number*/ 213 214 success = invpcid_safe(0, &desc) == 0; 215 216 report(success == expect_success, 217 "Tested invpcid type 0 with 0x%lx value - %s", 218 test_value, success ? "success" : "failure"); 219 } 220 221 static void test_invpcid(void) 222 { 223 /* 224 * Note that this test tests the kvm's behavior only when ept=0. 225 * Otherwise invpcid is not intercepted. 226 * 227 * Also KVM's x86 emulator doesn't support invpcid, thus testing invpcid 228 * with FEP is pointless. 229 */ 230 assert(write_cr4_safe(read_cr4() | X86_CR4_PCIDE) == 0); 231 232 __test_invpcid(CANONICAL_48_VAL, true); 233 __test_invpcid(CANONICAL_57_VAL, this_cpu_has(X86_FEATURE_LA57)); 234 __test_invpcid(NONCANONICAL, false); 235 } 236 237 static void __test_canonical_checks(bool force_emulation) 238 { 239 printf("\nRunning canonical test %s forced emulation:\n", 240 force_emulation ? "with" : "without"); 241 242 /* Direct DT addresses */ 243 TEST_REGISTER(GDTR_BASE, force_emulation); 244 TEST_REGISTER(IDTR_BASE, force_emulation); 245 246 /* Indirect DT addresses */ 247 TEST_REGISTER(TR_BASE, force_emulation); 248 TEST_REGISTER(LDT_BASE, force_emulation); 249 250 /* x86_64 extended segment bases */ 251 TEST_MSR(MSR_FS_BASE, force_emulation); 252 TEST_MSR(MSR_GS_BASE, force_emulation); 253 TEST_MSR(MSR_KERNEL_GS_BASE, force_emulation); 254 255 /* 256 * SYSENTER ESP/EIP MSRs have canonical checks only on Intel, because 257 * only on Intel these instructions were extended to 64 bit. 258 * 259 * KVM emulation however ignores canonical checks for these MSRs, even 260 * on Intel, to support cross-vendor migration. This includes nested 261 * virtualization. 262 * 263 * Thus, the checks only work when run on bare metal, without forced 264 * emulation. Unfortunately, there is no foolproof way to detect bare 265 * metal from within this test. E.g. checking HYPERVISOR in CPUID is 266 * useless because that only detects if _this_ code is running in a VM, 267 * it doesn't detect if the "host" is itself a VM. 268 * 269 * TODO: Enable testing of SYSENTER MSRs on bare metal. 270 */ 271 if (false && is_intel() && !force_emulation) { 272 TEST_MSR(MSR_IA32_SYSENTER_ESP, force_emulation); 273 TEST_MSR(MSR_IA32_SYSENTER_EIP, force_emulation); 274 } else { 275 report_skip("skipping MSR_IA32_SYSENTER_ESP/MSR_IA32_SYSENTER_EIP %s", 276 (is_intel() ? "due to known errata in KVM" : "due to AMD host")); 277 } 278 279 /* SYSCALL target MSRs */ 280 TEST_MSR(MSR_CSTAR, force_emulation); 281 TEST_MSR(MSR_LSTAR, force_emulation); 282 283 /* PEBS DS area */ 284 if (this_cpu_has(X86_FEATURE_DS)) 285 TEST_MSR(MSR_IA32_DS_AREA, force_emulation); 286 else 287 report_skip("Skipping MSR_IA32_DS_AREA - PEBS not supported"); 288 289 /* PT filter ranges */ 290 if (this_cpu_has(X86_FEATURE_INTEL_PT)) { 291 int n_ranges = cpuid_indexed(0x14, 0x1).a & 0x7; 292 int i; 293 294 for (i = 0 ; i < n_ranges ; i++) { 295 wrmsr(MSR_IA32_RTIT_CTL, (1ull << (RTIT_CTL_ADDR0_OFFSET+i*4))); 296 __TEST_MSR("MSR_IA32_RTIT_ADDR_A", 297 MSR_IA32_RTIT_ADDR0_A + i*2, force_emulation); 298 __TEST_MSR("MSR_IA32_RTIT_ADDR_B", 299 MSR_IA32_RTIT_ADDR0_B + i*2, force_emulation); 300 } 301 } else { 302 report_skip("Skipping MSR_IA32_RTIT_ADDR* - Intel PT is not supported"); 303 } 304 305 /* Test that INVPCID type 0 #GPs correctly */ 306 if (this_cpu_has(X86_FEATURE_INVPCID)) 307 test_invpcid(); 308 else 309 report_skip("Skipping INVPCID - not supported"); 310 } 311 312 static void test_canonical_checks(void) 313 { 314 __test_canonical_checks(false); 315 316 if (is_fep_available()) 317 __test_canonical_checks(true); 318 else 319 report_skip("Force emulation prefix not enabled"); 320 } 321 #endif 322 323 int main(int ac, char **av) 324 { 325 int vector = write_cr4_safe(read_cr4() | X86_CR4_LA57); 326 bool is_64bit = rdmsr(MSR_EFER) & EFER_LMA; 327 int expected = !is_64bit && this_cpu_has(X86_FEATURE_LA57) ? 0 : GP_VECTOR; 328 329 report(vector == expected, "%s when CR4.LA57 %ssupported (in %u-bit mode)", 330 expected ? "#GP" : "No fault", 331 this_cpu_has(X86_FEATURE_LA57) ? "un" : "", is_64bit ? 64 : 32); 332 333 #ifdef __x86_64__ 334 /* set dummy LDTR pointer */ 335 set_gdt_entry(FIRST_SPARE_SEL, 0xffaabb, 0xffff, 0x82, 0); 336 lldt(FIRST_SPARE_SEL); 337 338 test_canonical_checks(); 339 340 if (is_64bit && this_cpu_has(X86_FEATURE_LA57)) { 341 printf("Switching to 5 level paging mode and rerunning canonical tests.\n"); 342 setup_5level_page_table(); 343 } 344 #endif 345 346 return report_summary(); 347 } 348