Xen Test Framework
main.c
Go to the documentation of this file.
1 
22 #include <xtf.h>
23 
24 const char test_title[] = "Guest CPUID Faulting support";
25 
27 
28 unsigned long stub_cpuid(void)
29 {
30  unsigned int fault = 0, tmp;
31 
32  asm volatile("1: cpuid; 2:"
33  _ASM_EXTABLE_HANDLER(1b, 2b, %P[rec])
34  : "=a" (tmp), "+D" (fault)
35  : "a" (0), [rec] "p" (ex_record_fault_edi)
36  : "ebx", "ecx", "edx");
37 
38  return fault;
39 }
40 
41 unsigned long stub_fep_cpuid(void)
42 {
43  unsigned int fault = 0, tmp;
44 
45  asm volatile(_ASM_XEN_FEP
46  "1: cpuid; 2:"
47  _ASM_EXTABLE_HANDLER(1b, 2b, %P[rec])
48  : "=a" (tmp), "+D" (fault)
49  : "a" (0), [rec] "p" (ex_record_fault_edi)
50  : "ebx", "ecx", "edx");
51 
52  return fault;
53 }
54 
55 static void test_cpuid(bool exp_faulting)
56 {
57  /*
58  * Kernel cpuids should never fault
59  */
60  if ( stub_cpuid() )
61  xtf_failure("Fail: kernel cpuid faulted\n");
62 
63  if ( IS_DEFINED(CONFIG_PV) && stub_fep_cpuid() )
64  xtf_failure("Fail: kernel pv cpuid faulted\n");
65 
66  if ( xtf_has_fep && stub_fep_cpuid() )
67  xtf_failure("Fail: kernel emulated cpuid faulted\n");
68 
69  /*
70  * User cpuids should raise #GP[0] if faulting is enabled.
71  */
72  unsigned long exp = exp_faulting ? EXINFO_SYM(GP, 0) : 0;
73  const char *exp_fail_str = exp_faulting ? "didn't fault" : "faulted";
74 
75  if ( exec_user(stub_cpuid) != exp )
76  xtf_failure("Fail: user cpuid %s\n", exp_fail_str);
77 
78  if ( IS_DEFINED(CONFIG_PV) && exec_user(stub_fep_cpuid) != exp )
79  xtf_failure("Fail: user pv cpuid %s\n", exp_fail_str);
80 
81  if ( xtf_has_fep && exec_user(stub_fep_cpuid) != exp )
82  xtf_failure("Fail: user emulated cpuid %s\n", exp_fail_str);
83 }
84 
85 void test_main(void)
86 {
87  uint64_t platform_info, features_enable;
88 
89  if ( IS_DEFINED(CONFIG_HVM) && !xtf_has_fep )
90  xtf_skip("FEP support not detected - some tests will be skipped\n");
91 
92  /* No faulting. CPUID should work without faulting anywhere. */
93  printk("Testing CPUID without faulting enabled\n");
94  test_cpuid(false);
95 
96  /* Probe for CPUID Faulting support. */
97  if ( rdmsr_safe(MSR_INTEL_PLATFORM_INFO, &platform_info) ||
98  !(platform_info & PLATFORM_INFO_CPUID_FAULTING) )
99  return xtf_skip("Skip: CPUID Faulting unavailable\n");
100 
101  if ( rdmsr_safe(MSR_INTEL_MISC_FEATURES_ENABLES, &features_enable) )
102  return xtf_error("Error: Fault accessing MISC_FEATURES_ENABLES\n");
103 
104  /* Attempt to enable CPUID Faulting. */
106  features_enable | MISC_FEATURES_CPUID_FAULTING) )
107  return xtf_failure("Fail: Unable to enable CPUID Faulting\n");
108 
109  /* Faulting active. CPUID should fault ouside of the kernel. */
110  printk("Testing CPUID with faulting enabled\n");
111  test_cpuid(true);
112 
113  /* Try disabling faulting. */
114  if ( wrmsr_safe(MSR_INTEL_MISC_FEATURES_ENABLES, features_enable) )
115  return xtf_failure("Fail: Unable to disable CPUID Faulting\n");
116 
117  /* Double check that CPUID no longer faults. */
118  printk("Retesting CPUID without faulting enabled\n");
119  test_cpuid(false);
120 
121  xtf_success(NULL);
122 }
123 
124 /*
125  * Local variables:
126  * mode: C
127  * c-file-style: "BSD"
128  * c-basic-offset: 4
129  * tab-width: 4
130  * indent-tabs-mode: nil
131  * End:
132  */
#define _ASM_XEN_FEP
Xen Forced Emulation Prefix.
Definition: xen.h:150
#define IS_DEFINED(x)
Evalute whether the CONFIG_ token x is defined.
Definition: macro_magic.h:67
#define MISC_FEATURES_CPUID_FAULTING
Definition: msr-index.h:24
bool ex_record_fault_edi(struct cpu_regs *regs, const struct extable_entry *ex)
Record the current fault in %edi.
Definition: extable.c:16
void printk(const char *fmt,...)
Definition: console.c:134
bool xtf_has_fep
Boolean indicating whether generic Force Emulation Prefix support is available for the test to use...
Definition: setup.c:276
static void test_cpuid(bool exp_faulting)
Definition: main.c:55
unsigned long stub_fep_cpuid(void)
Definition: main.c:41
#define NULL
Definition: stddef.h:12
void xtf_success(const char *fmt,...)
Report test success.
Definition: report.c:38
void test_main(void)
To be implemented by each test, as its entry point.
Definition: main.c:137
void xtf_failure(const char *fmt,...)
Report a test failure.
Definition: report.c:94
__UINT64_TYPE__ uint64_t
Definition: stdint.h:17
bool test_wants_user_mappings
Boolean indicating whether the test wants user mappings or not.
Definition: main.c:26
#define GP
void xtf_skip(const char *fmt,...)
Report a test skip.
Definition: report.c:66
const char test_title[]
The title of the test.
Definition: main.c:14
#define PLATFORM_INFO_CPUID_FAULTING
Definition: msr-index.h:21
static unsigned long exec_user(unsigned long(*fn)(void))
Definition: lib.h:62
unsigned long stub_cpuid(void)
Definition: main.c:28
#define EXINFO_SYM(exc, ec)
Definition: exinfo.h:29
static bool rdmsr_safe(uint32_t idx, uint64_t *val)
Wrapper around rdmsr which safely catches #GP[0].
Definition: msr.h:35
void xtf_error(const char *fmt,...)
Report a test error.
Definition: report.c:80
static bool wrmsr_safe(uint32_t idx, uint64_t val)
Wrapper around wrmsr which safely catches #GP[0].
Definition: msr.h:69
#define _ASM_EXTABLE_HANDLER(fault, fixup, handler)
Create an exception table entry with custom handler.
Definition: extable.h:38
#define MSR_INTEL_PLATFORM_INFO
Definition: msr-index.h:20
#define MSR_INTEL_MISC_FEATURES_ENABLES
Definition: msr-index.h:23