1 // SPDX-License-Identifier: GPL-2.0-only
10 #include "processor.h"
11 #include "test_util.h"
14 struct kvm_vcpu
*vcpu
;
16 bool has_xavic_errata
;
19 static void xapic_guest_code(void)
26 uint64_t val
= (u64
)xapic_read_reg(APIC_IRR
) |
27 (u64
)xapic_read_reg(APIC_IRR
+ 0x10) << 32;
29 xapic_write_reg(APIC_ICR2
, val
>> 32);
30 xapic_write_reg(APIC_ICR
, val
);
35 #define X2APIC_RSVD_BITS_MASK (GENMASK_ULL(31, 20) | \
36 GENMASK_ULL(17, 16) | \
39 static void x2apic_guest_code(void)
46 uint64_t val
= x2apic_read_reg(APIC_IRR
) |
47 x2apic_read_reg(APIC_IRR
+ 0x10) << 32;
49 if (val
& X2APIC_RSVD_BITS_MASK
) {
50 x2apic_write_reg_fault(APIC_ICR
, val
);
52 x2apic_write_reg(APIC_ICR
, val
);
53 GUEST_ASSERT_EQ(x2apic_read_reg(APIC_ICR
), val
);
59 static void ____test_icr(struct xapic_vcpu
*x
, uint64_t val
)
61 struct kvm_vcpu
*vcpu
= x
->vcpu
;
62 struct kvm_lapic_state xapic
;
67 * Tell the guest what ICR value to write. Use the IRR to pass info,
68 * all bits are valid and should not be modified by KVM (ignoring the
69 * fact that vectors 0-15 are technically illegal).
71 vcpu_ioctl(vcpu
, KVM_GET_LAPIC
, &xapic
);
72 *((u32
*)&xapic
.regs
[APIC_IRR
]) = val
;
73 *((u32
*)&xapic
.regs
[APIC_IRR
+ 0x10]) = val
>> 32;
74 vcpu_ioctl(vcpu
, KVM_SET_LAPIC
, &xapic
);
77 TEST_ASSERT_EQ(get_ucall(vcpu
, &uc
), UCALL_SYNC
);
78 TEST_ASSERT_EQ(uc
.args
[1], val
);
80 vcpu_ioctl(vcpu
, KVM_GET_LAPIC
, &xapic
);
81 icr
= (u64
)(*((u32
*)&xapic
.regs
[APIC_ICR
])) |
82 (u64
)(*((u32
*)&xapic
.regs
[APIC_ICR2
])) << 32;
84 if (!x
->has_xavic_errata
)
85 val
&= (-1u | (0xffull
<< (32 + 24)));
86 } else if (val
& X2APIC_RSVD_BITS_MASK
) {
90 if (x
->has_xavic_errata
)
91 TEST_ASSERT_EQ(icr
& ~APIC_ICR_BUSY
, val
& ~APIC_ICR_BUSY
);
93 TEST_ASSERT_EQ(icr
, val
& ~APIC_ICR_BUSY
);
96 static void __test_icr(struct xapic_vcpu
*x
, uint64_t val
)
99 * The BUSY bit is reserved on both AMD and Intel, but only AMD treats
100 * it is as _must_ be zero. Intel simply ignores the bit. Don't test
101 * the BUSY bit for x2APIC, as there is no single correct behavior.
104 ____test_icr(x
, val
| APIC_ICR_BUSY
);
106 ____test_icr(x
, val
& ~(u64
)APIC_ICR_BUSY
);
109 static void test_icr(struct xapic_vcpu
*x
)
111 struct kvm_vcpu
*vcpu
= x
->vcpu
;
114 icr
= APIC_DEST_SELF
| APIC_INT_ASSERT
| APIC_DM_FIXED
;
115 for (i
= 0; i
<= 0xff; i
++)
116 __test_icr(x
, icr
| i
);
118 icr
= APIC_INT_ASSERT
| APIC_DM_FIXED
;
119 for (i
= 0; i
<= 0xff; i
++)
120 __test_icr(x
, icr
| i
);
123 * Send all flavors of IPIs to non-existent vCPUs. TODO: use number of
124 * vCPUs, not vcpu.id + 1. Arbitrarily use vector 0xff.
126 icr
= APIC_INT_ASSERT
| 0xff;
127 for (i
= 0; i
< 0xff; i
++) {
130 for (j
= 0; j
< 8; j
++)
131 __test_icr(x
, i
<< (32 + 24) | icr
| (j
<< 8));
134 /* And again with a shorthand destination for all types of IPIs. */
135 icr
= APIC_DEST_ALLBUT
| APIC_INT_ASSERT
;
136 for (i
= 0; i
< 8; i
++)
137 __test_icr(x
, icr
| (i
<< 8));
139 /* And a few garbage value, just make sure it's an IRQ (blocked). */
140 __test_icr(x
, 0xa5a5a5a5a5a5a5a5 & ~APIC_DM_FIXED_MASK
);
141 __test_icr(x
, 0x5a5a5a5a5a5a5a5a & ~APIC_DM_FIXED_MASK
);
142 __test_icr(x
, -1ull & ~APIC_DM_FIXED_MASK
);
145 static void __test_apic_id(struct kvm_vcpu
*vcpu
, uint64_t apic_base
)
147 uint32_t apic_id
, expected
;
148 struct kvm_lapic_state xapic
;
150 vcpu_set_msr(vcpu
, MSR_IA32_APICBASE
, apic_base
);
152 vcpu_ioctl(vcpu
, KVM_GET_LAPIC
, &xapic
);
154 expected
= apic_base
& X2APIC_ENABLE
? vcpu
->id
: vcpu
->id
<< 24;
155 apic_id
= *((u32
*)&xapic
.regs
[APIC_ID
]);
157 TEST_ASSERT(apic_id
== expected
,
158 "APIC_ID not set back to %s format; wanted = %x, got = %x",
159 (apic_base
& X2APIC_ENABLE
) ? "x2APIC" : "xAPIC",
164 * Verify that KVM switches the APIC_ID between xAPIC and x2APIC when userspace
165 * stuffs MSR_IA32_APICBASE. Setting the APIC_ID when x2APIC is enabled and
166 * when the APIC transitions for DISABLED to ENABLED is architectural behavior
167 * (on Intel), whereas the x2APIC => xAPIC transition behavior is KVM ABI since
168 * attempted to transition from x2APIC to xAPIC without disabling the APIC is
169 * architecturally disallowed.
171 static void test_apic_id(void)
173 const uint32_t NR_VCPUS
= 3;
174 struct kvm_vcpu
*vcpus
[NR_VCPUS
];
179 vm
= vm_create_with_vcpus(NR_VCPUS
, NULL
, vcpus
);
180 vm_enable_cap(vm
, KVM_CAP_X2APIC_API
, KVM_X2APIC_API_USE_32BIT_IDS
);
182 for (i
= 0; i
< NR_VCPUS
; i
++) {
183 apic_base
= vcpu_get_msr(vcpus
[i
], MSR_IA32_APICBASE
);
185 TEST_ASSERT(apic_base
& MSR_IA32_APICBASE_ENABLE
,
186 "APIC not in ENABLED state at vCPU RESET");
187 TEST_ASSERT(!(apic_base
& X2APIC_ENABLE
),
188 "APIC not in xAPIC mode at vCPU RESET");
190 __test_apic_id(vcpus
[i
], apic_base
);
191 __test_apic_id(vcpus
[i
], apic_base
| X2APIC_ENABLE
);
192 __test_apic_id(vcpus
[i
], apic_base
);
198 static void test_x2apic_id(void)
200 struct kvm_lapic_state lapic
= {};
201 struct kvm_vcpu
*vcpu
;
205 vm
= vm_create_with_one_vcpu(&vcpu
, NULL
);
206 vcpu_set_msr(vcpu
, MSR_IA32_APICBASE
, MSR_IA32_APICBASE_ENABLE
| X2APIC_ENABLE
);
209 * Try stuffing a modified x2APIC ID, KVM should ignore the value and
210 * always return the vCPU's default/readonly x2APIC ID.
212 for (i
= 0; i
<= 0xff; i
++) {
213 *(u32
*)(lapic
.regs
+ APIC_ID
) = i
<< 24;
214 *(u32
*)(lapic
.regs
+ APIC_SPIV
) = APIC_SPIV_APIC_ENABLED
;
215 vcpu_ioctl(vcpu
, KVM_SET_LAPIC
, &lapic
);
217 vcpu_ioctl(vcpu
, KVM_GET_LAPIC
, &lapic
);
218 TEST_ASSERT(*((u32
*)&lapic
.regs
[APIC_ID
]) == vcpu
->id
<< 24,
219 "x2APIC ID should be fully readonly");
225 int main(int argc
, char *argv
[])
227 struct xapic_vcpu x
= {
233 vm
= vm_create_with_one_vcpu(&x
.vcpu
, x2apic_guest_code
);
238 * Use a second VM for the xAPIC test so that x2APIC can be hidden from
239 * the guest in order to test AVIC. KVM disallows changing CPUID after
240 * KVM_RUN and AVIC is disabled if _any_ vCPU is allowed to use x2APIC.
242 vm
= vm_create_with_one_vcpu(&x
.vcpu
, xapic_guest_code
);
246 * AMD's AVIC implementation is buggy (fails to clear the ICR BUSY bit),
247 * and also diverges from KVM with respect to ICR2[23:0] (KVM and Intel
248 * drops writes, AMD does not). Account for the errata when checking
249 * that KVM reads back what was written.
251 x
.has_xavic_errata
= host_cpu_is_amd
&&
252 get_kvm_amd_param_bool("avic");
254 vcpu_clear_cpuid_feature(x
.vcpu
, X86_FEATURE_X2APIC
);
256 virt_pg_map(vm
, APIC_DEFAULT_GPA
, APIC_DEFAULT_GPA
);