summaryrefslogtreecommitdiff
path: root/arch/x86/kernel/kvm.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-10-06 11:28:34 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2017-10-06 11:28:34 -0700
commit8d473320eebf938e9c2e3ce569e524554006362c (patch)
tree6205a419705129a1013f3f8a8db75dd5b50a827a /arch/x86/kernel/kvm.c
parentd109d83fc8c325dd92d0c3c0a2db2048699773be (diff)
parente42eef4ba38806b18c4a74f0c276fb2e0b548173 (diff)
downloadlinux-rt-8d473320eebf938e9c2e3ce569e524554006362c.tar.gz
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull KVM fixes from Radim Krčmář: - fix PPC XIVE interrupt delivery - fix x86 RCU breakage from asynchronous page faults when built without PREEMPT_COUNT - fix x86 build with -frecord-gcc-switches - fix x86 build without X86_LOCAL_APIC * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: KVM: add X86_LOCAL_APIC dependency x86/kvm: Move kvm_fastop_exception to .fixup section kvm/x86: Avoid async PF preempting the kernel incorrectly KVM: PPC: Book3S: Fix server always zero from kvmppc_xive_get_xive()
Diffstat (limited to 'arch/x86/kernel/kvm.c')
-rw-r--r--arch/x86/kernel/kvm.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index e675704fa6f7..8bb9594d0761 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -117,7 +117,11 @@ static struct kvm_task_sleep_node *_find_apf_task(struct kvm_task_sleep_head *b,
return NULL;
}
-void kvm_async_pf_task_wait(u32 token)
+/*
+ * @interrupt_kernel: Is this called from a routine which interrupts the kernel
+ * (other than user space)?
+ */
+void kvm_async_pf_task_wait(u32 token, int interrupt_kernel)
{
u32 key = hash_32(token, KVM_TASK_SLEEP_HASHBITS);
struct kvm_task_sleep_head *b = &async_pf_sleepers[key];
@@ -140,8 +144,10 @@ void kvm_async_pf_task_wait(u32 token)
n.token = token;
n.cpu = smp_processor_id();
- n.halted = is_idle_task(current) || preempt_count() > 1 ||
- rcu_preempt_depth();
+ n.halted = is_idle_task(current) ||
+ (IS_ENABLED(CONFIG_PREEMPT_COUNT)
+ ? preempt_count() > 1 || rcu_preempt_depth()
+ : interrupt_kernel);
init_swait_queue_head(&n.wq);
hlist_add_head(&n.link, &b->list);
raw_spin_unlock(&b->lock);
@@ -269,7 +275,7 @@ do_async_page_fault(struct pt_regs *regs, unsigned long error_code)
case KVM_PV_REASON_PAGE_NOT_PRESENT:
/* page is swapped out by the host. */
prev_state = exception_enter();
- kvm_async_pf_task_wait((u32)read_cr2());
+ kvm_async_pf_task_wait((u32)read_cr2(), !user_mode(regs));
exception_exit(prev_state);
break;
case KVM_PV_REASON_PAGE_READY: