Xen Test Framework
util.c
Go to the documentation of this file.
1 #include "test.h"
2 
3 static void decode_test_exinfo(char *str, size_t n, exinfo_t ex)
4 {
5  if ( ex == VMERR_SUCCESS )
6  {
7  strcpy(str, "VMsucceed");
8  return;
9  }
10 
11  if ( ex == VMERR_INVALID )
12  {
13  strcpy(str, "VMfailInvalid");
14  return;
15  }
16 
17  unsigned int high = ex & ~0xffffff;
18 
19  if ( high == VMERR_VALID(0) )
20  {
21  unsigned int low = ex & 0xffffff;
22 
23  snprintf(str, n, "VMfailValid(%u) %s",
24  low, vmx_insn_err_strerror(low));
25  return;
26  }
27 
28  if ( high == EXINFO_EXPECTED )
29  {
30  snprintf(str, n, "%pe", _p(ex));
31  return;
32  }
33 
34  strcpy(str, "<bad>");
35 }
36 
37 void check(const char *func, exinfo_t got, exinfo_t exp)
38 {
39  char gotstr[48], expstr[48];
40 
41  if ( got == exp )
42  return;
43 
44  decode_test_exinfo(gotstr, ARRAY_SIZE(gotstr), got);
45  decode_test_exinfo(expstr, ARRAY_SIZE(expstr), exp);
46 
47  xtf_failure("Failure in %s()\n"
48  " Expected 0x%08x: %s\n"
49  " Got 0x%08x: %s\n",
50  func, exp, expstr, got, gotstr);
51 }
52 
54 
55 void vmx_collect_data(void)
56 {
57  msr_vmx_basic_t basic = { rdmsr(MSR_VMX_BASIC) };
58 
59  vmcs_revid = basic.vmcs_rev_id;
60 }
61 
62 /*
63  * Read the VM Instruction Error code from the VMCS. It is the callers
64  * responsibility to ensure that the VMCS is valid in context.
65  */
67 {
68  unsigned long err;
69 
70  asm ("vmread %[field], %[value]"
71  : [value] "=rm" (err)
72  : [field] "r" (VMCS_VM_INSN_ERR + 0ul));
73 
74  return VMERR_VALID(err);
75 }
76 
78 {
79  exinfo_t ex = 0;
80  bool fail_valid = false, fail_invalid = false;
81 
82  asm volatile ("1: vmxon %[paddr];"
83  ASM_FLAG_OUT(, "setc %[fail_invalid];")
84  ASM_FLAG_OUT(, "setz %[fail_valid];")
85  "2:"
86  _ASM_EXTABLE_HANDLER(1b, 2b, %P[rec])
87  : "+D" (ex),
88  ASM_FLAG_OUT("=@ccc", [fail_invalid] "+rm") (fail_invalid),
89  ASM_FLAG_OUT("=@ccz", [fail_valid] "+rm") (fail_valid)
90  : [paddr] "m" (paddr),
91  [rec] "p" (ex_record_fault_edi));
92 
93  if ( ex )
94  return ex;
95  else if ( fail_invalid )
96  return VMERR_INVALID;
97  else if ( fail_valid )
98  return get_vmx_insn_err();
99  else
100  return VMERR_SUCCESS;
101 }
102 
104 {
105  exinfo_t ex = 0;
106  bool fail_valid = false, fail_invalid = false;
107 
108  asm volatile ("1: vmptrld %[paddr];"
109  ASM_FLAG_OUT(, "setc %[fail_invalid];")
110  ASM_FLAG_OUT(, "setz %[fail_valid];")
111  "2:"
112  _ASM_EXTABLE_HANDLER(1b, 2b, %P[rec])
113  : "+D" (ex),
114  ASM_FLAG_OUT("=@ccc", [fail_invalid] "+rm") (fail_invalid),
115  ASM_FLAG_OUT("=@ccz", [fail_valid] "+rm") (fail_valid)
116  : [paddr] "m" (paddr),
117  [rec] "p" (ex_record_fault_edi));
118 
119  if ( ex )
120  return ex;
121  else if ( fail_invalid )
122  return VMERR_INVALID;
123  else if ( fail_valid )
124  return get_vmx_insn_err();
125  else
126  return VMERR_SUCCESS;
127 }
128 
130 {
131  exinfo_t ex = 0;
132  bool fail_valid = false, fail_invalid = false;
133 
134  asm volatile ("1: vmxon %[paddr];"
135  ASM_FLAG_OUT(, "setc %[fail_invalid];")
136  ASM_FLAG_OUT(, "setz %[fail_valid];")
137  "2:"
138  _ASM_EXTABLE_HANDLER(1b, 2b, %P[rec])
139  : "+D" (ex),
140  ASM_FLAG_OUT("=@ccc", [fail_invalid] "+rm") (fail_invalid),
141  ASM_FLAG_OUT("=@ccz", [fail_valid] "+rm") (fail_valid)
142  : [paddr] "m" (paddr),
143  [rec] "p" (ex_record_fault_edi));
144 
145  if ( ex )
146  return ex;
147  else if ( fail_invalid )
148  return VMERR_INVALID;
149  else if ( fail_valid )
150  return get_vmx_insn_err();
151  else
152  return VMERR_SUCCESS;
153 }
154 
155 /*
156  * Local variables:
157  * mode: C
158  * c-file-style: "BSD"
159  * c-basic-offset: 4
160  * tab-width: 4
161  * indent-tabs-mode: nil
162  * End:
163  */
void vmx_collect_data(void)
Collect real information about the VT-x environment, for use by test.
Definition: util.c:55
unsigned int exinfo_t
Packed exception and error code information.
Definition: exinfo.h:19
static uint64_t rdmsr(uint32_t idx)
Thin wrapper around an rdmsr instruction.
Definition: msr.h:19
int snprintf(char *buf, size_t size, const char *fmt,...)
Definition: stdio.c:3
void check(const char *func, exinfo_t got, exinfo_t exp)
Compare an expectation against what really happenend, printing human-readable information in case of ...
Definition: util.c:37
#define ARRAY_SIZE(a)
Definition: lib.h:8
bool ex_record_fault_edi(struct cpu_regs *regs, const struct extable_entry *ex)
Record the current fault in %edi.
Definition: extable.c:16
static exinfo_t get_vmx_insn_err(void)
Definition: util.c:66
uint32_t vmcs_revid
Hardware VMCS Revision ID.
Definition: util.c:53
exinfo_t stub_vmptrld(uint64_t paddr)
Definition: util.c:103
#define VMERR_VALID(x)
Definition: test.h:17
#define __user_text
Definition: compiler.h:33
#define ASM_FLAG_OUT(yes, no)
Definition: compiler-gcc.h:24
#define VMERR_INVALID
Definition: test.h:16
#define EXINFO_EXPECTED
Definition: exinfo.h:21
const char * vmx_insn_err_strerror(unsigned int err)
Error string for VMX Instruction Errors.
Definition: vmx.c:10
static void decode_test_exinfo(char *str, size_t n, exinfo_t ex)
Definition: util.c:3
void xtf_failure(const char *fmt,...)
Report a test failure.
Definition: report.c:94
__UINT64_TYPE__ uint64_t
Definition: stdint.h:17
exinfo_t stub_vmxon(uint64_t paddr)
Definition: util.c:77
static unsigned int str(void)
Definition: lib.h:366
exinfo_t stub_vmxon_user(uint64_t paddr)
Definition: util.c:129
__UINT32_TYPE__ uint32_t
Definition: stdint.h:16
#define strcpy(d, s)
Definition: libc.h:21
#define _p(v)
Express an abitrary integer v as void *.
Definition: numbers.h:48
#define MSR_VMX_BASIC
Definition: msr-index.h:43
#define VMCS_VM_INSN_ERR
Definition: x86-vmx.h:41
#define _ASM_EXTABLE_HANDLER(fault, fixup, handler)
Create an exception table entry with custom handler.
Definition: extable.h:38
#define VMERR_SUCCESS
Definition: test.h:15
uint32_t vmcs_rev_id
Definition: msr.h:98