mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git
synced 2026-10-28 12:53:14 +01:00
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull kvm fixes from Paolo Bonzini:
"Even more x86 fixes:
- Avoid a false positive panic in the #PF handler, if the kernel
triggers a page fault within the asynchronous page fault handler
before the flags are reset.
This can happen for example because of a perf NMI.
- Always reset a vCPU's MMU pointer back to the root MMU when loading
nested guest state fails during RSM or KVM_SET_NESTED_STATE.
Otherwise KVM tries to run a non-nested guest with a nested MMU,
which can result in a NULL pointer dereference attempting to get
the nested MMU's pgd (EPTP or nested CR3)"
* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm:
KVM: nVMX: Reset MMU back to the root MMU if loading L2 state fails for !VM-Entry
x86/kvm: Don't consume async #PF flags on a kernel #PF in NMI context
This commit is contained in:
commit
9aa622dbaa
2 files changed
+32
-4
No files matched your search
+29
-3
@@ -265,11 +265,39 @@ noinstr u32 kvm_read_and_reset_apf_flags(void)
|
||||
}
|
||||
EXPORT_SYMBOL_FOR_KVM(kvm_read_and_reset_apf_flags);
|
||||
|
||||
static __always_inline bool kvm_apf_reason_pending(void)
|
||||
{
|
||||
return __this_cpu_read(async_pf_enabled) &&
|
||||
__this_cpu_read(apf_reason.flags);
|
||||
}
|
||||
|
||||
noinstr bool __kvm_handle_async_pf(struct pt_regs *regs, u32 token)
|
||||
{
|
||||
u32 flags = kvm_read_and_reset_apf_flags();
|
||||
irqentry_state_t state;
|
||||
u32 flags;
|
||||
|
||||
if (!kvm_apf_reason_pending())
|
||||
return false;
|
||||
|
||||
/*
|
||||
* The guest does not enable KVM_ASYNC_PF_SEND_ALWAYS, so the host
|
||||
* delivers async #PF only to user mode (or as a #PF VM-exit, which KVM
|
||||
* reads itself). A #PF from kernel mode can still arrive between that
|
||||
* delivery and the read of the reason flags, inside an NMI that
|
||||
* interrupted it, for instance perf reading user memory for a call
|
||||
* chain. Such a fault is not async, so leave the async PF flags
|
||||
* untouched for the outer handler. Outside NMI context, on the other
|
||||
* hand, async PF flags on a kernel-mode fault mean the host is broken.
|
||||
*/
|
||||
if (!user_mode(regs)) {
|
||||
if (likely(in_nmi()))
|
||||
return false;
|
||||
state = irqentry_enter(regs);
|
||||
instrumentation_begin();
|
||||
panic("Host injected async #PF in kernel mode\n");
|
||||
}
|
||||
|
||||
flags = kvm_read_and_reset_apf_flags();
|
||||
if (!flags)
|
||||
return false;
|
||||
|
||||
@@ -285,8 +313,6 @@ noinstr bool __kvm_handle_async_pf(struct pt_regs *regs, u32 token)
|
||||
panic("Host injected async #PF in interrupt disabled region\n");
|
||||
|
||||
if (flags & KVM_PV_REASON_PAGE_NOT_PRESENT) {
|
||||
if (unlikely(!(user_mode(regs))))
|
||||
panic("Host injected async #PF in kernel mode\n");
|
||||
/* Page is swapped out by the host. */
|
||||
kvm_async_pf_task_wait_schedule(token);
|
||||
} else {
|
||||
|
||||
@@ -3770,8 +3770,10 @@ vmentry_fail_vmexit_guest_mode:
|
||||
vmentry_fail_vmexit:
|
||||
vmx_switch_vmcs(vcpu, &vmx->vmcs01);
|
||||
|
||||
if (!from_vmentry)
|
||||
if (!from_vmentry) {
|
||||
nested_ept_uninit_mmu_context(vcpu);
|
||||
return NVMX_VMENTRY_VMEXIT;
|
||||
}
|
||||
|
||||
nested_put_vmcs12_pages(vcpu);
|
||||
|
||||
|
||||
Reference in new issue
Block a user