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 
26 static unsigned long stub_cpuid(void)
27 {
28  unsigned long fault = 0, tmp;
29 
30  asm volatile("1: cpuid; 2:"
31  _ASM_EXTABLE_HANDLER(1b, 2b, %P[rec])
32  : "=a" (tmp), "+D" (fault)
33  : "a" (0), [rec] "p" (ex_record_fault_edi)
34  : "ebx", "ecx", "edx");
35 
36  return fault;
37 }
38 
39 static unsigned long stub_force_cpuid(void)
40 {
41  unsigned long fault = 0, tmp;
42 
43  asm volatile(_ASM_XEN_FEP
44  "1: cpuid; 2:"
45  _ASM_EXTABLE_HANDLER(1b, 2b, %P[rec])
46  : "=a" (tmp), "+D" (fault)
47  : "a" (0), [rec] "p" (ex_record_fault_edi)
48  : "ebx", "ecx", "edx");
49 
50  return fault;
51 }
52 
53 static unsigned long __user_text stub_user_cpuid(void)
54 {
55  unsigned long fault = 0, tmp;
56 
57  asm volatile("1: cpuid; 2:"
58  _ASM_EXTABLE_HANDLER(1b, 2b, %P[rec])
59  : "=a" (tmp), "+D" (fault)
60  : "a" (0), [rec] "p" (ex_record_fault_edi)
61  : "ebx", "ecx", "edx");
62 
63  return fault;
64 }
65 
66 static unsigned long __user_text stub_user_force_cpuid(void)
67 {
68  unsigned long fault = 0, tmp;
69 
70  asm volatile(_ASM_XEN_FEP
71  "1: cpuid; 2:"
72  _ASM_EXTABLE_HANDLER(1b, 2b, %P[rec])
73  : "=a" (tmp), "+D" (fault)
74  : "a" (0), [rec] "p" (ex_record_fault_edi)
75  : "ebx", "ecx", "edx");
76 
77  return fault;
78 }
79 
80 static void test_cpuid(bool exp_faulting)
81 {
82  /*
83  * Kernel cpuids should never fault
84  */
85  if ( stub_cpuid() )
86  xtf_failure("Fail: kernel cpuid faulted\n");
87 
88  if ( IS_DEFINED(CONFIG_PV) && stub_force_cpuid() )
89  xtf_failure("Fail: kernel pv cpuid faulted\n");
90 
91  if ( xtf_has_fep && stub_force_cpuid() )
92  xtf_failure("Fail: kernel emulated cpuid faulted\n");
93 
94  /*
95  * User cpuids should raise #GP[0] if faulting is enabled.
96  */
97  unsigned long exp = exp_faulting ? EXINFO_SYM(GP, 0) : 0;
98  const char *exp_fail_str = exp_faulting ? "didn't fault" : "faulted";
99 
100  if ( exec_user(stub_user_cpuid) != exp )
101  xtf_failure("Fail: user cpuid %s\n", exp_fail_str);
102 
103  if ( IS_DEFINED(CONFIG_PV) && exec_user(stub_user_force_cpuid) != exp )
104  xtf_failure("Fail: user pv cpuid %s\n", exp_fail_str);
105 
107  xtf_failure("Fail: user emulated cpuid %s\n", exp_fail_str);
108 }
109 
110 void test_main(void)
111 {
112  uint64_t platform_info, features_enable;
113 
114  if ( IS_DEFINED(CONFIG_HVM) && !xtf_has_fep )
115  xtf_skip("FEP support not detected - some tests will be skipped\n");
116 
117  /* No faulting. CPUID should work without faulting anywhere. */
118  printk("Testing CPUID without faulting enabled\n");
119  test_cpuid(false);
120 
121  /* Probe for CPUID Faulting support. */
122  if ( rdmsr_safe(MSR_INTEL_PLATFORM_INFO, &platform_info) ||
123  !(platform_info & PLATFORM_INFO_CPUID_FAULTING) )
124  return xtf_skip("Skip: CPUID Faulting unavailable\n");
125 
126  if ( rdmsr_safe(MSR_INTEL_MISC_FEATURES_ENABLES, &features_enable) )
127  return xtf_error("Error: Fault accessing MISC_FEATURES_ENABLES\n");
128 
129  /* Attempt to enable CPUID Faulting. */
131  features_enable | MISC_FEATURES_CPUID_FAULTING) )
132  return xtf_failure("Fail: Unable to enable CPUID Faulting\n");
133 
134  /* Faulting active. CPUID should fault ouside of the kernel. */
135  printk("Testing CPUID with faulting enabled\n");
136  test_cpuid(true);
137 
138  /* Try disabling faulting. */
139  if ( wrmsr_safe(MSR_INTEL_MISC_FEATURES_ENABLES, features_enable) )
140  return xtf_failure("Fail: Unable to disable CPUID Faulting\n");
141 
142  /* Double check that CPUID no longer faults. */
143  printk("Retesting CPUID without faulting enabled\n");
144  test_cpuid(false);
145 
146  xtf_success(NULL);
147 }
148 
149 /*
150  * Local variables:
151  * mode: C
152  * c-file-style: "BSD"
153  * c-basic-offset: 4
154  * tab-width: 4
155  * indent-tabs-mode: nil
156  * End:
157  */
#define _ASM_XEN_FEP
Xen Forced Emulation Prefix.
Definition: xen.h:150
static unsigned long stub_user_force_cpuid(void)
Definition: main.c:66
#define IS_DEFINED(x)
Evalute whether the CONFIG_ token x is defined.
Definition: macro_magic.h:67
static unsigned long stub_force_cpuid(void)
Definition: main.c:39
#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:80
#define __user_text
Definition: compiler.h:33
#define NULL
Definition: stddef.h:12
void xtf_success(const char *fmt,...)
Report test success.
Definition: report.c:38
static unsigned long stub_cpuid(void)
Definition: main.c:26
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
#define GP
static unsigned long stub_user_cpuid(void)
Definition: main.c:53
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
#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