diff options
| -rw-r--r-- | arch/x86/kernel/kvm.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index 08b973f64032..9c2bd8bd4b4c 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c | |||
| @@ -43,6 +43,7 @@ | |||
| 43 | #include <asm/apicdef.h> | 43 | #include <asm/apicdef.h> |
| 44 | #include <asm/hypervisor.h> | 44 | #include <asm/hypervisor.h> |
| 45 | #include <asm/kvm_guest.h> | 45 | #include <asm/kvm_guest.h> |
| 46 | #include <asm/context_tracking.h> | ||
| 46 | 47 | ||
| 47 | static int kvmapf = 1; | 48 | static int kvmapf = 1; |
| 48 | 49 | ||
| @@ -121,6 +122,8 @@ void kvm_async_pf_task_wait(u32 token) | |||
| 121 | struct kvm_task_sleep_node n, *e; | 122 | struct kvm_task_sleep_node n, *e; |
| 122 | DEFINE_WAIT(wait); | 123 | DEFINE_WAIT(wait); |
| 123 | 124 | ||
| 125 | rcu_irq_enter(); | ||
| 126 | |||
| 124 | spin_lock(&b->lock); | 127 | spin_lock(&b->lock); |
| 125 | e = _find_apf_task(b, token); | 128 | e = _find_apf_task(b, token); |
| 126 | if (e) { | 129 | if (e) { |
| @@ -128,6 +131,8 @@ void kvm_async_pf_task_wait(u32 token) | |||
| 128 | hlist_del(&e->link); | 131 | hlist_del(&e->link); |
| 129 | kfree(e); | 132 | kfree(e); |
| 130 | spin_unlock(&b->lock); | 133 | spin_unlock(&b->lock); |
| 134 | |||
| 135 | rcu_irq_exit(); | ||
| 131 | return; | 136 | return; |
| 132 | } | 137 | } |
| 133 | 138 | ||
| @@ -152,13 +157,16 @@ void kvm_async_pf_task_wait(u32 token) | |||
| 152 | /* | 157 | /* |
| 153 | * We cannot reschedule. So halt. | 158 | * We cannot reschedule. So halt. |
| 154 | */ | 159 | */ |
| 160 | rcu_irq_exit(); | ||
| 155 | native_safe_halt(); | 161 | native_safe_halt(); |
| 162 | rcu_irq_enter(); | ||
| 156 | local_irq_disable(); | 163 | local_irq_disable(); |
| 157 | } | 164 | } |
| 158 | } | 165 | } |
| 159 | if (!n.halted) | 166 | if (!n.halted) |
| 160 | finish_wait(&n.wq, &wait); | 167 | finish_wait(&n.wq, &wait); |
| 161 | 168 | ||
| 169 | rcu_irq_exit(); | ||
| 162 | return; | 170 | return; |
| 163 | } | 171 | } |
| 164 | EXPORT_SYMBOL_GPL(kvm_async_pf_task_wait); | 172 | EXPORT_SYMBOL_GPL(kvm_async_pf_task_wait); |
| @@ -252,10 +260,10 @@ do_async_page_fault(struct pt_regs *regs, unsigned long error_code) | |||
| 252 | break; | 260 | break; |
| 253 | case KVM_PV_REASON_PAGE_NOT_PRESENT: | 261 | case KVM_PV_REASON_PAGE_NOT_PRESENT: |
| 254 | /* page is swapped out by the host. */ | 262 | /* page is swapped out by the host. */ |
| 255 | rcu_irq_enter(); | 263 | exception_enter(regs); |
| 256 | exit_idle(); | 264 | exit_idle(); |
| 257 | kvm_async_pf_task_wait((u32)read_cr2()); | 265 | kvm_async_pf_task_wait((u32)read_cr2()); |
| 258 | rcu_irq_exit(); | 266 | exception_exit(regs); |
| 259 | break; | 267 | break; |
| 260 | case KVM_PV_REASON_PAGE_READY: | 268 | case KVM_PV_REASON_PAGE_READY: |
| 261 | rcu_irq_enter(); | 269 | rcu_irq_enter(); |
