linux/arch/x86/kvm
David Woodhouse 5ec3289b31 KVM: x86/xen: Compatibility fixes for shared runstate area
The guest runstate area can be arbitrarily byte-aligned. In fact, even
when a sane 32-bit guest aligns the overall structure nicely, the 64-bit
fields in the structure end up being unaligned due to the fact that the
32-bit ABI only aligns them to 32 bits.

So setting the ->state_entry_time field to something|XEN_RUNSTATE_UPDATE
is buggy, because if it's unaligned then we can't update the whole field
atomically; the low bytes might be observable before the _UPDATE bit is.
Xen actually updates the *byte* containing that top bit, on its own. KVM
should do the same.

In addition, we cannot assume that the runstate area fits within a single
page. One option might be to make the gfn_to_pfn cache cope with regions
that cross a page — but getting a contiguous virtual kernel mapping of a
discontiguous set of IOMEM pages is a distinctly non-trivial exercise,
and it seems this is the *only* current use case for the GPC which would
benefit from it.

An earlier version of the runstate code did use a gfn_to_hva cache for
this purpose, but it still had the single-page restriction because it
used the uhva directly — because it needs to be able to do so atomically
when the vCPU is being scheduled out, so it used pagefault_disable()
around the accesses and didn't just use kvm_write_guest_cached() which
has a fallback path.

So... use a pair of GPCs for the first and potential second page covering
the runstate area. We can get away with locking both at once because
nothing else takes more than one GPC lock at a time so we can invent
a trivial ordering rule.

The common case where it's all in the same page is kept as a fast path,
but in both cases, the actual guest structure (compat or not) is built
up from the fields in @vx, following preset pointers to the state and
times fields. The only difference is whether those pointers point to
the kernel stack (in the split case) or to guest memory directly via
the GPC.  The fast path is also fixed to use a byte access for the
XEN_RUNSTATE_UPDATE bit, then the only real difference is the dual
memcpy.

Finally, Xen also does write the runstate area immediately when it's
configured. Flip the kvm_xen_update_runstate() and …_guest() functions
and call the latter directly when the runstate area is set. This means
that other ioctls which modify the runstate also write it immediately
to the guest when they do so, which is also intended.

Update the xen_shinfo_test to exercise the pathological case where the
XEN_RUNSTATE_UPDATE flag in the top byte of the state_entry_time is
actually in a different page to the rest of the 64-bit word.

Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2022-11-30 10:56:08 -05:00
..
mmu KVM: x86: avoid memslot check in NX hugepage recovery if it cannot succeed 2022-11-18 11:30:12 -05:00
svm KVM: nSVM: hyper-v: Enable L2 TLB flush 2022-11-18 12:59:18 -05:00
vmx KVM: x86: Make kvm_hv_get_assist_page() return 0/-errno 2022-11-18 12:59:18 -05:00
.gitignore KVM: x86: use a separate asm-offsets.c file 2022-11-09 12:10:17 -05:00
cpuid.c KVM: x86: Advertise PREFETCHIT0/1 CPUID to user space 2022-11-28 13:33:30 -05:00
cpuid.h KVM: x86: Add dedicated helper to get CPUID entry with significant index 2022-07-14 11:38:32 -04:00
debugfs.c KVM: x86: Reduce refcount if single_open() fails in kvm_mmu_rmaps_stat_open() 2022-10-27 04:41:54 -04:00
emulate.c KVM: x86: move SMM exit to a new file 2022-11-09 12:31:18 -05:00
fpu.h KVM: x86: Move FPU register accessors into fpu.h 2021-06-17 13:09:24 -04:00
hyperv.c KVM: x86: Expose Hyper-V L2 TLB flush feature 2022-11-18 12:59:19 -05:00
hyperv.h KVM: nSVM: hyper-v: Enable L2 TLB flush 2022-11-18 12:59:18 -05:00
i8254.c KVM: x86: PIT: Preserve state of speaker port data bit 2022-06-08 13:06:20 -04:00
i8254.h KVM: x86: PIT: Preserve state of speaker port data bit 2022-06-08 13:06:20 -04:00
i8259.c KVM: x86/i8259: Remove a dead store of irq in a conditional block 2022-04-02 05:41:19 -04:00
ioapic.c KVM: x86/ioapic: Remove unused "addr" and "length" of ioapic_read_indirect() 2022-02-10 13:47:13 -05:00
ioapic.h x86/kvm: remove unused ack_notifier callbacks 2021-11-18 07:05:57 -05:00
irq_comm.c KVM: x86/xen: Make kvm_xen_set_evtchn() reusable from other places 2022-04-02 05:41:14 -04:00
irq.c KVM: replace direct irq.h inclusion 2022-11-09 12:31:37 -05:00
irq.h x86/kvm: remove unused ack_notifier callbacks 2021-11-18 07:05:57 -05:00
Kconfig KVM: allow compiling out SMM support 2022-11-09 12:31:19 -05:00
kvm_cache_regs.h KVM: x86: start moving SMM-related functions to new files 2022-11-09 12:31:16 -05:00
kvm_emulate.h KVM: x86: do not define SMM-related constants if SMM disabled 2022-11-09 12:31:21 -05:00
kvm_onhyperv.c KVM: x86: Uninline and export hv_track_root_tdp() 2022-02-10 13:47:19 -05:00
kvm_onhyperv.h KVM: x86: Uninline and export hv_track_root_tdp() 2022-02-10 13:47:19 -05:00
kvm-asm-offsets.c KVM: SVM: move MSR_IA32_SPEC_CTRL save/restore to assembly 2022-11-09 12:25:53 -05:00
lapic.c KVM: x86: start moving SMM-related functions to new files 2022-11-09 12:31:16 -05:00
lapic.h KVM: x86: start moving SMM-related functions to new files 2022-11-09 12:31:16 -05:00
Makefile KVM: x86: Introduce .hv_inject_synthetic_vmexit_post_tlb_flush() nested hook 2022-11-18 12:59:13 -05:00
mmu.h KVM: SVM: Disable SEV-ES support if MMIO caching is disable 2022-08-10 15:08:25 -04:00
mtrr.c
pmu.c KVM: x86/pmu: Defer counter emulated overflow via pmc->prev_counter 2022-11-09 12:31:36 -05:00
pmu.h KVM: x86/pmu: Defer reprogram_counter() to kvm_pmu_handle_event() 2022-11-09 12:31:36 -05:00
reverse_cpuid.h KVM: x86: Advertise PREFETCHIT0/1 CPUID to user space 2022-11-28 13:33:30 -05:00
smm.c KVM: x86: smm: preserve interrupt shadow in SMRAM 2022-11-09 12:31:26 -05:00
smm.h KVM: x86: smm: preserve interrupt shadow in SMRAM 2022-11-09 12:31:26 -05:00
trace.h KVM: x86/xen: Add CPL to Xen hypercall tracepoint 2022-11-28 13:31:01 -05:00
tss.h
x86.c KVM: x86: hyper-v: Introduce TLB flush fifo 2022-11-18 12:59:04 -05:00
x86.h KVM: x86: Track supported PERF_CAPABILITIES in kvm_caps 2022-11-09 12:31:11 -05:00
xen.c KVM: x86/xen: Compatibility fixes for shared runstate area 2022-11-30 10:56:08 -05:00
xen.h KVM: x86/xen: Compatibility fixes for shared runstate area 2022-11-30 10:56:08 -05:00