aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm/vmx.c
diff options
context:
space:
mode:
authorAvi Kivity <avi@qumranet.com>2007-06-07 12:18:30 -0400
committerAvi Kivity <avi@qumranet.com>2007-07-16 05:05:46 -0400
commitd9e368d61263055eceac2966bb7ea31b89da3425 (patch)
tree9d507b851ea7bd667cdd50dde640e47e0d4773e9 /drivers/kvm/vmx.c
parent39c3b86e5c193e09f69f0e99c93600a4999ffc60 (diff)
KVM: Flush remote tlbs when reducing shadow pte permissions
When a vcpu causes a shadow tlb entry to have reduced permissions, it must also clear the tlb on remote vcpus. We do that by: - setting a bit on the vcpu that requests a tlb flush before the next entry - if the vcpu is currently executing, we send an ipi to make sure it exits before we continue Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'drivers/kvm/vmx.c')
-rw-r--r--drivers/kvm/vmx.c22
1 files changed, 15 insertions, 7 deletions
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index a1f51b9d482d..b969db1e0830 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -1972,6 +1972,11 @@ static int dm_request_for_irq_injection(struct kvm_vcpu *vcpu,
1972 (vmcs_readl(GUEST_RFLAGS) & X86_EFLAGS_IF)); 1972 (vmcs_readl(GUEST_RFLAGS) & X86_EFLAGS_IF));
1973} 1973}
1974 1974
1975static void vmx_flush_tlb(struct kvm_vcpu *vcpu)
1976{
1977 vmcs_writel(GUEST_CR3, vmcs_readl(GUEST_CR3));
1978}
1979
1975static int vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) 1980static int vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
1976{ 1981{
1977 u8 fail; 1982 u8 fail;
@@ -1997,9 +2002,15 @@ again:
1997 */ 2002 */
1998 vmcs_writel(HOST_CR0, read_cr0()); 2003 vmcs_writel(HOST_CR0, read_cr0());
1999 2004
2005 local_irq_disable();
2006
2007 vcpu->guest_mode = 1;
2008 if (vcpu->requests)
2009 if (test_and_clear_bit(KVM_TLB_FLUSH, &vcpu->requests))
2010 vmx_flush_tlb(vcpu);
2011
2000 asm ( 2012 asm (
2001 /* Store host registers */ 2013 /* Store host registers */
2002 "pushf \n\t"
2003#ifdef CONFIG_X86_64 2014#ifdef CONFIG_X86_64
2004 "push %%rax; push %%rbx; push %%rdx;" 2015 "push %%rax; push %%rbx; push %%rdx;"
2005 "push %%rsi; push %%rdi; push %%rbp;" 2016 "push %%rsi; push %%rdi; push %%rbp;"
@@ -2091,7 +2102,6 @@ again:
2091 "pop %%ecx; popa \n\t" 2102 "pop %%ecx; popa \n\t"
2092#endif 2103#endif
2093 "setbe %0 \n\t" 2104 "setbe %0 \n\t"
2094 "popf \n\t"
2095 : "=q" (fail) 2105 : "=q" (fail)
2096 : "r"(vcpu->launched), "d"((unsigned long)HOST_RSP), 2106 : "r"(vcpu->launched), "d"((unsigned long)HOST_RSP),
2097 "c"(vcpu), 2107 "c"(vcpu),
@@ -2115,6 +2125,9 @@ again:
2115 [cr2]"i"(offsetof(struct kvm_vcpu, cr2)) 2125 [cr2]"i"(offsetof(struct kvm_vcpu, cr2))
2116 : "cc", "memory" ); 2126 : "cc", "memory" );
2117 2127
2128 vcpu->guest_mode = 0;
2129 local_irq_enable();
2130
2118 ++vcpu->stat.exits; 2131 ++vcpu->stat.exits;
2119 2132
2120 vcpu->interrupt_window_open = (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0; 2133 vcpu->interrupt_window_open = (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0;
@@ -2167,11 +2180,6 @@ out:
2167 return r; 2180 return r;
2168} 2181}
2169 2182
2170static void vmx_flush_tlb(struct kvm_vcpu *vcpu)
2171{
2172 vmcs_writel(GUEST_CR3, vmcs_readl(GUEST_CR3));
2173}
2174
2175static void vmx_inject_page_fault(struct kvm_vcpu *vcpu, 2183static void vmx_inject_page_fault(struct kvm_vcpu *vcpu,
2176 unsigned long addr, 2184 unsigned long addr,
2177 u32 err_code) 2185 u32 err_code)