Skip to content

Commit c822a07

Browse files
committed
Merge tag 'kvm-x86-asyncpf_abi-6.9' of https://github.com/kvm-x86/linux into HEAD
Guest-side KVM async #PF ABI cleanup for 6.9 Delete kvm_vcpu_pv_apf_data.enabled to fix a goof in KVM's async #PF ABI where the enabled field pushes the size of "struct kvm_vcpu_pv_apf_data" from 64 to 68 bytes, i.e. beyond a single cache line. The enabled field is purely a guest-side flag that Linux-as-a-guest uses to track whether or not the guest has enabled async #PF support. The actual flag that is passed to the host, i.e. to KVM proper, is a single bit in a synthetic MSR, MSR_KVM_ASYNC_PF_EN, i.e. is in a location completely unrelated to the shared kvm_vcpu_pv_apf_data structure. Simply drop the the field and use a dedicated guest-side per-CPU variable to fix the ABI, as opposed to fixing the documentation to match reality. KVM has never consumed kvm_vcpu_pv_apf_data.enabled, so the odds of the ABI change breaking anything are extremely low.
2 parents 1d55934 + df01f0a commit c822a07

File tree

3 files changed

+15
-16
lines changed

3 files changed

+15
-16
lines changed

Documentation/virt/kvm/x86/msr.rst

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,8 @@ data:
193193
Asynchronous page fault (APF) control MSR.
194194

195195
Bits 63-6 hold 64-byte aligned physical address of a 64 byte memory area
196-
which must be in guest RAM and must be zeroed. This memory is expected
197-
to hold a copy of the following structure::
196+
which must be in guest RAM. This memory is expected to hold the
197+
following structure::
198198

199199
struct kvm_vcpu_pv_apf_data {
200200
/* Used for 'page not present' events delivered via #PF */
@@ -204,7 +204,6 @@ data:
204204
__u32 token;
205205

206206
__u8 pad[56];
207-
__u32 enabled;
208207
};
209208

210209
Bits 5-4 of the MSR are reserved and should be zero. Bit 0 is set to 1
@@ -232,14 +231,14 @@ data:
232231
as regular page fault, guest must reset 'flags' to '0' before it does
233232
something that can generate normal page fault.
234233

235-
Bytes 5-7 of 64 byte memory location ('token') will be written to by the
234+
Bytes 4-7 of 64 byte memory location ('token') will be written to by the
236235
hypervisor at the time of APF 'page ready' event injection. The content
237-
of these bytes is a token which was previously delivered as 'page not
238-
present' event. The event indicates the page in now available. Guest is
239-
supposed to write '0' to 'token' when it is done handling 'page ready'
240-
event and to write 1' to MSR_KVM_ASYNC_PF_ACK after clearing the location;
241-
writing to the MSR forces KVM to re-scan its queue and deliver the next
242-
pending notification.
236+
of these bytes is a token which was previously delivered in CR2 as
237+
'page not present' event. The event indicates the page is now available.
238+
Guest is supposed to write '0' to 'token' when it is done handling
239+
'page ready' event and to write '1' to MSR_KVM_ASYNC_PF_ACK after
240+
clearing the location; writing to the MSR forces KVM to re-scan its
241+
queue and deliver the next pending notification.
243242

244243
Note, MSR_KVM_ASYNC_PF_INT MSR specifying the interrupt vector for 'page
245244
ready' APF delivery needs to be written to before enabling APF mechanism

arch/x86/include/uapi/asm/kvm_para.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,6 @@ struct kvm_vcpu_pv_apf_data {
142142
__u32 token;
143143

144144
__u8 pad[56];
145-
__u32 enabled;
146145
};
147146

148147
#define KVM_PV_EOI_BIT 0

arch/x86/kernel/kvm.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ static int __init parse_no_stealacc(char *arg)
6565

6666
early_param("no-steal-acc", parse_no_stealacc);
6767

68+
static DEFINE_PER_CPU_READ_MOSTLY(bool, async_pf_enabled);
6869
static DEFINE_PER_CPU_DECRYPTED(struct kvm_vcpu_pv_apf_data, apf_reason) __aligned(64);
6970
DEFINE_PER_CPU_DECRYPTED(struct kvm_steal_time, steal_time) __aligned(64) __visible;
7071
static int has_steal_clock = 0;
@@ -244,7 +245,7 @@ noinstr u32 kvm_read_and_reset_apf_flags(void)
244245
{
245246
u32 flags = 0;
246247

247-
if (__this_cpu_read(apf_reason.enabled)) {
248+
if (__this_cpu_read(async_pf_enabled)) {
248249
flags = __this_cpu_read(apf_reason.flags);
249250
__this_cpu_write(apf_reason.flags, 0);
250251
}
@@ -295,7 +296,7 @@ DEFINE_IDTENTRY_SYSVEC(sysvec_kvm_asyncpf_interrupt)
295296

296297
inc_irq_stat(irq_hv_callback_count);
297298

298-
if (__this_cpu_read(apf_reason.enabled)) {
299+
if (__this_cpu_read(async_pf_enabled)) {
299300
token = __this_cpu_read(apf_reason.token);
300301
kvm_async_pf_task_wake(token);
301302
__this_cpu_write(apf_reason.token, 0);
@@ -362,7 +363,7 @@ static void kvm_guest_cpu_init(void)
362363
wrmsrl(MSR_KVM_ASYNC_PF_INT, HYPERVISOR_CALLBACK_VECTOR);
363364

364365
wrmsrl(MSR_KVM_ASYNC_PF_EN, pa);
365-
__this_cpu_write(apf_reason.enabled, 1);
366+
__this_cpu_write(async_pf_enabled, true);
366367
pr_debug("setup async PF for cpu %d\n", smp_processor_id());
367368
}
368369

@@ -383,11 +384,11 @@ static void kvm_guest_cpu_init(void)
383384

384385
static void kvm_pv_disable_apf(void)
385386
{
386-
if (!__this_cpu_read(apf_reason.enabled))
387+
if (!__this_cpu_read(async_pf_enabled))
387388
return;
388389

389390
wrmsrl(MSR_KVM_ASYNC_PF_EN, 0);
390-
__this_cpu_write(apf_reason.enabled, 0);
391+
__this_cpu_write(async_pf_enabled, false);
391392

392393
pr_debug("disable async PF for cpu %d\n", smp_processor_id());
393394
}

0 commit comments

Comments
 (0)