| From 6ba661787594868512a71c129062ebd57d0c01e7 Mon Sep 17 00:00:00 2001 |
| From: Marcelo Tosatti <mtosatti@redhat.com> |
| Date: Tue, 25 Aug 2009 01:13:10 -0300 |
| Subject: KVM guest: do not batch pte updates from interrupt context |
| |
| From: Marcelo Tosatti <mtosatti@redhat.com> |
| |
| commit 6ba661787594868512a71c129062ebd57d0c01e7 upstream. |
| |
| Commit b8bcfe997e4 made paravirt pte updates synchronous in interrupt |
| context. |
| |
| Unfortunately the KVM pv mmu code caches the lazy/nonlazy mode |
| internally, so a pte update from interrupt context during a lazy mmu |
| operation can be batched while it should be performed synchronously. |
| |
| https://bugzilla.redhat.com/show_bug.cgi?id=518022 |
| |
| Drop the internal mode variable and use paravirt_get_lazy_mode(), which |
| returns the correct state. |
| |
| Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> |
| Signed-off-by: Avi Kivity <avi@redhat.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| arch/x86/kernel/kvm.c | 7 +------ |
| 1 file changed, 1 insertion(+), 6 deletions(-) |
| |
| --- a/arch/x86/kernel/kvm.c |
| +++ b/arch/x86/kernel/kvm.c |
| @@ -34,7 +34,6 @@ |
| struct kvm_para_state { |
| u8 mmu_queue[MMU_QUEUE_SIZE]; |
| int mmu_queue_len; |
| - enum paravirt_lazy_mode mode; |
| }; |
| |
| static DEFINE_PER_CPU(struct kvm_para_state, para_state); |
| @@ -77,7 +76,7 @@ static void kvm_deferred_mmu_op(void *bu |
| { |
| struct kvm_para_state *state = kvm_para_state(); |
| |
| - if (state->mode != PARAVIRT_LAZY_MMU) { |
| + if (paravirt_get_lazy_mode() != PARAVIRT_LAZY_MMU) { |
| kvm_mmu_op(buffer, len); |
| return; |
| } |
| @@ -185,10 +184,7 @@ static void kvm_release_pt(unsigned long |
| |
| static void kvm_enter_lazy_mmu(void) |
| { |
| - struct kvm_para_state *state = kvm_para_state(); |
| - |
| paravirt_enter_lazy_mmu(); |
| - state->mode = paravirt_get_lazy_mode(); |
| } |
| |
| static void kvm_leave_lazy_mmu(void) |
| @@ -197,7 +193,6 @@ static void kvm_leave_lazy_mmu(void) |
| |
| mmu_queue_flush(state); |
| paravirt_leave_lazy_mmu(); |
| - state->mode = paravirt_get_lazy_mode(); |
| } |
| |
| static void __init paravirt_ops_setup(void) |