Skip to contentSkip to conversation

KVM: VMX: Add ept_sync_context in flush_tlb

PATCH Applied Yang, Sheng 2 participants 6 messages Jun 18, 2008 – Jul 6, 2008

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 KVM: VMX: Add ept_sync_context in flush_tlb

From 54dc26e44f1c0aa460bef409b799f36dae56a911 Mon Sep 17 00:00:00 2001
From: Sheng Yang <[email protected]>
Date: Wed, 18 Jun 2008 11:23:13 +0800
Subject: [PATCH] KVM: VMX: Add ept_sync_context in flush_tlb

Fix a potention issue caused by kvm_mmu_slot_remove_write_access(). The old behavior don't sync EPT TLB with modified EPT entry, which result in inconsistent content of EPT TLB and EPT table.

---
 arch/x86/kvm/vmx.c |   18 ++++++++++++------
 1 files changed, 12 insertions(+), 6 deletions(-)
arch/x86/kvm/vmx.c +4 -3
index 6e4278d..5e2a800 100644
@@ -83,6 +83,7 @@ struct vcpu_vmx {
 		} irq;
 	} rmode;
 	int vpid;
+	u64 eptp;
 };
 
 static inline struct vcpu_vmx *to_vmx(struct kvm_vcpu *vcpu)
@@ -364,24 +365,24 @@ static inline void ept_sync_global(void)
 		__invept(VMX_EPT_EXTENT_GLOBAL, 0, 0);
 }
 
-static inline void ept_sync_context(u64 eptp)
+static inline void ept_sync_context(struct vcpu_vmx *vmx)
 {
 	if (vm_need_ept()) {
 		if (cpu_has_vmx_invept_context())
-			__invept(VMX_EPT_EXTENT_CONTEXT, eptp, 0);
+			__invept(VMX_EPT_EXTENT_CONTEXT, vmx->eptp, 0);
 		else
 			ept_sync_global();
 	}
 }
 
-static inline void ept_sync_individual_addr(u64 eptp, gpa_t gpa)
+static inline void ept_sync_individual_addr(struct vcpu_vmx *vmx, 

gpa_t gpa)
{
if (vm_need_ept()) {
if (cpu_has_vmx_invept_individual_addr())
__invept(VMX_EPT_EXTENT_INDIVIDUAL_ADDR,
- eptp, gpa);
+ vmx->eptp, gpa);
else
- ept_sync_context(eptp);
+ ept_sync_context(vmx);
}
}

@@ -1407,6 +1408,8 @@ static void exit_lmode(struct kvm_vcpu *vcpu)
static void vmx_flush_tlb(struct kvm_vcpu *vcpu)
{
vpid_sync_vcpu_all(to_vmx(vcpu));
+ if (vm_need_ept())
+ ept_sync_context(to_vmx(vcpu));
}

static void vmx_decache_cr4_guest_bits(struct kvm_vcpu *vcpu)
@@ -1517,12 +1520,15 @@ static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
{
unsigned long guest_cr3;
u64 eptp;
+ struct vcpu_vmx *vmx;

+ vmx = to_vmx(vcpu);
guest_cr3 = cr3;
if (vm_need_ept()) {
eptp = construct_eptp(cr3); vmcs_write64(EPT_POINTER, eptp);
- ept_sync_context(eptp);
+ vmx->eptp = eptp;
+ ept_sync_context(vmx);
ept_load_pdptrs(vcpu);
guest_cr3 = is_paging(vcpu) ? vcpu->arch.cr3 :
VMX_EPT_IDENTITY_PAGETABLE_ADDR;
--
1.5.5

From 54dc26e44f1c0aa460bef409b799f36dae56a911 Mon Sep 17 00:00:00 2001
From: Sheng Yang <[email protected]>
Date: Wed, 18 Jun 2008 11:23:13 +0800
Subject: [PATCH] KVM: VMX: Add ept_sync_context in flush_tlb

Fix a potention issue caused by kvm_mmu_slot_remove_write_access(). The old behavior don't sync EPT TLB with modified EPT entry, which result in inconsistent content of EPT TLB and EPT table.

---
 arch/x86/kvm/vmx.c |   18 ++++++++++++------
 1 files changed, 12 insertions(+), 6 deletions(-)
arch/x86/kvm/vmx.c +12 -6
index 6e4278d..5e2a800 100644
@@ -83,6 +83,7 @@ struct vcpu_vmx {
 		} irq;
 	} rmode;
 	int vpid;
+	u64 eptp;
 };
 
 static inline struct vcpu_vmx *to_vmx(struct kvm_vcpu *vcpu)
@@ -364,24 +365,24 @@ static inline void ept_sync_global(void)
 		__invept(VMX_EPT_EXTENT_GLOBAL, 0, 0);
 }
 
-static inline void ept_sync_context(u64 eptp)
+static inline void ept_sync_context(struct vcpu_vmx *vmx)
 {
 	if (vm_need_ept()) {
 		if (cpu_has_vmx_invept_context())
-			__invept(VMX_EPT_EXTENT_CONTEXT, eptp, 0);
+			__invept(VMX_EPT_EXTENT_CONTEXT, vmx->eptp, 0);
 		else
 			ept_sync_global();
 	}
 }
 
-static inline void ept_sync_individual_addr(u64 eptp, gpa_t gpa)
+static inline void ept_sync_individual_addr(struct vcpu_vmx *vmx, gpa_t gpa)
 {
 	if (vm_need_ept()) {
 		if (cpu_has_vmx_invept_individual_addr())
 			__invept(VMX_EPT_EXTENT_INDIVIDUAL_ADDR,
-					eptp, gpa);
+					vmx->eptp, gpa);
 		else
-			ept_sync_context(eptp);
+			ept_sync_context(vmx);
 	}
 }
 
@@ -1407,6 +1408,8 @@ static void exit_lmode(struct kvm_vcpu *vcpu)
 static void vmx_flush_tlb(struct kvm_vcpu *vcpu)
 {
 	vpid_sync_vcpu_all(to_vmx(vcpu));
+	if (vm_need_ept())
+		ept_sync_context(to_vmx(vcpu));
 }
 
 static void vmx_decache_cr4_guest_bits(struct kvm_vcpu *vcpu)
@@ -1517,12 +1520,15 @@ static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
 {
 	unsigned long guest_cr3;
 	u64 eptp;
+	struct vcpu_vmx *vmx;
 
+	vmx = to_vmx(vcpu);
 	guest_cr3 = cr3;
 	if (vm_need_ept()) {
 		eptp = construct_eptp(cr3);
 		vmcs_write64(EPT_POINTER, eptp);
-		ept_sync_context(eptp);
+		vmx->eptp = eptp;
+		ept_sync_context(vmx);
 		ept_load_pdptrs(vcpu);
 		guest_cr3 = is_paging(vcpu) ? vcpu->arch.cr3 :
 			VMX_EPT_IDENTITY_PAGETABLE_ADDR;
Signature · 1 line
1.5.5
#1 lore raw
Quoted 9 lines · Sheng

From 54dc26e44f1c0aa460bef409b799f36dae56a911 Mon Sep 17 00:00:00 2001
From: Sheng Yang <[email protected]>
Date: Wed, 18 Jun 2008 11:23:13 +0800
Subject: [PATCH] KVM: VMX: Add ept_sync_context in flush_tlb

Fix a potention issue caused by kvm_mmu_slot_remove_write_access(). The old behavior don't sync EPT TLB with modified EPT entry, which result in inconsistent content of EPT TLB and EPT table.

arch/x86/kvm/vmx.c static void exit_lmode(struct kvm_vcpu *vcpu) · line 1414

Quoted 7 lines
arch/x86/kvm/vmx.c +2 -0
@@ -1407,6 +1408,8 @@ static void exit_lmode(struct kvm_vcpu *vcpu)
 static void vmx_flush_tlb(struct kvm_vcpu *vcpu)
 {
 	vpid_sync_vcpu_all(to_vmx(vcpu));
+	if (vm_need_ept())
+		ept_sync_context(to_vmx(vcpu));
 }
 

So we're flushing both the vpid tlb and the ept context? What does an ept context flush mean exactly? tlb entries for gpa->hpa?

Signature · 1 line
error compiling committee.c: too many arguments to function
#2 lore raw
Quoted 11 lines · On Wednesday 25 June 2008 20:02:17 Avi Kivity wrote:
Quoted 10 lines · Sheng

From 54dc26e44f1c0aa460bef409b799f36dae56a911 Mon Sep 17 00:00:00 2001
From: Sheng Yang <[email protected]>
Date: Wed, 18 Jun 2008 11:23:13 +0800
Subject: [PATCH] KVM: VMX: Add ept_sync_context in flush_tlb

Fix a potention issue caused by kvm_mmu_slot_remove_write_access(). The old behavior don't sync EPT TLB with modified EPT entry, which result in inconsistent content of EPT TLB and EPT table.

Quoted 10 lines

arch/x86/kvm/vmx.c static void exit_lmode(struct kvm_vcpu *vcpu) · line 1413

Quoted 7 lines
arch/x86/kvm/vmx.c +2 -0
@@ -1407,6 +1408,8 @@ static void exit_lmode(struct kvm_vcpu *vcpu)
 static void vmx_flush_tlb(struct kvm_vcpu *vcpu)
 {
 	vpid_sync_vcpu_all(to_vmx(vcpu));
+	if (vm_need_ept())
+		ept_sync_context(to_vmx(vcpu));
 }

So we're flushing both the vpid tlb and the ept context? What does an ept context flush mean exactly? tlb entries for gpa->hpa?

Yeah, the entries for gpa->hpa. So if we don't do this, cpu may see rw entry rather than ro, then write to it directly rather than fall into KVM.

Signature · 2 lines
Thanks
Yang, Sheng
#3 lore raw
Quoted 26 lines · Sheng
Quoted 12 lines · On Wednesday 25 June 2008 20:02:17 Avi Kivity wrote:
Quoted 10 lines · Sheng

From 54dc26e44f1c0aa460bef409b799f36dae56a911 Mon Sep 17 00:00:00 2001
From: Sheng Yang <[email protected]>
Date: Wed, 18 Jun 2008 11:23:13 +0800
Subject: [PATCH] KVM: VMX: Add ept_sync_context in flush_tlb

Fix a potention issue caused by kvm_mmu_slot_remove_write_access(). The old behavior don't sync EPT TLB with modified EPT entry, which result in inconsistent content of EPT TLB and EPT table.

Quoted 11 lines

arch/x86/kvm/vmx.c static void exit_lmode(struct kvm_vcpu *vcpu) · line 1414

Quoted 8 lines
arch/x86/kvm/vmx.c +2 -0
@@ -1407,6 +1408,8 @@ static void exit_lmode(struct kvm_vcpu *vcpu)
 static void vmx_flush_tlb(struct kvm_vcpu *vcpu)
 {
 	vpid_sync_vcpu_all(to_vmx(vcpu));
+	if (vm_need_ept())
+		ept_sync_context(to_vmx(vcpu));
 }
 

So we're flushing both the vpid tlb and the ept context? What does an ept context flush mean exactly? tlb entries for gpa->hpa?

Quoted 3 lines

Yeah, the entries for gpa->hpa. So if we don't do this, cpu may see rw entry rather than ro, then write to it directly rather than fall into KVM.

I see. Back to the patch, can't you replace vmx->eptp by construct_eptp(vcpu->arch.mmu.root_hpa)?

Signature · 1 line
error compiling committee.c: too many arguments to function
#4 lore raw
Quoted 3 lines · On Sunday 29 June 2008 18:09:20 Avi Kivity wrote:

I see. Back to the patch, can't you replace vmx->eptp by construct_eptp(vcpu->arch.mmu.root_hpa)?

Modified follow Avi's advice. Sorry for miss the mail...

From 251b611f7e90833aa07184e69ffe133fbcd83c76 Mon Sep 17 00:00:00 2001
From: Sheng Yang <[email protected]>
Date: Sun, 6 Jul 2008 19:16:51 +0800
Subject: [PATCH] KVM: VMX: Add ept_sync_context in flush_tlb

Fix a potention issue caused by kvm_mmu_slot_remove_write_access(). The
old behavior don't sync EPT TLB with modified EPT entry, which result in inconsistent content of EPT TLB and EPT table.

---
 arch/x86/kvm/vmx.c |   26 ++++++++++++++------------
 1 files changed, 14 insertions(+), 12 deletions(-)
arch/x86/kvm/vmx.c +14 -0
index d425246..09bc642 100644
@@ -1415,9 +1415,23 @@ static void exit_lmode(struct kvm_vcpu *vcpu)
 
 #endif
 
+static u64 construct_eptp(unsigned long root_hpa)
+{
+	u64 eptp;
+
+	/* TODO write the value reading from MSR */
+	eptp = VMX_EPT_DEFAULT_MT |
+		VMX_EPT_DEFAULT_GAW << VMX_EPT_GAW_EPTP_SHIFT;
+	eptp |= (root_hpa & PAGE_MASK);
+
+	return eptp;
+}
+
 static void vmx_flush_tlb(struct kvm_vcpu *vcpu)
 {
 	vpid_sync_vcpu_all(to_vmx(vcpu));
+	if (vm_need_ept())
+		ept_sync_context(construct_eptp(vcpu->arch.mmu.root_hpa));
 }
 
 static void vmx_decache_cr4_guest_bits(struct kvm_vcpu *vcpu)
@@ -1512,18 +1526,6 @@ static void vmx_set_cr0(struct kvm_vcpu *vcpu, 

unsigned long cr0)
vmx_fpu_activate(vcpu);
}

-static u64 construct_eptp(unsigned long root_hpa)
-{
- u64 eptp;
-
- /* TODO write the value reading from MSR */
- eptp = VMX_EPT_DEFAULT_MT |
- VMX_EPT_DEFAULT_GAW << VMX_EPT_GAW_EPTP_SHIFT;
- eptp |= (root_hpa & PAGE_MASK);
-
- return eptp;
-}
-
static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) {
unsigned long guest_cr3;
--
1.5.5.4

From 251b611f7e90833aa07184e69ffe133fbcd83c76 Mon Sep 17 00:00:00 2001
From: Sheng Yang <[email protected]>
Date: Sun, 6 Jul 2008 19:16:51 +0800
Subject: [PATCH] KVM: VMX: Add ept_sync_context in flush_tlb

Fix a potention issue caused by kvm_mmu_slot_remove_write_access(). The old behavior don't sync EPT TLB with modified EPT entry, which result in inconsistent content of EPT TLB and EPT table.

---
 arch/x86/kvm/vmx.c |   26 ++++++++++++++------------
 1 files changed, 14 insertions(+), 12 deletions(-)
arch/x86/kvm/vmx.c +14 -12
index d425246..09bc642 100644
@@ -1415,9 +1415,23 @@ static void exit_lmode(struct kvm_vcpu *vcpu)
 
 #endif
 
+static u64 construct_eptp(unsigned long root_hpa)
+{
+	u64 eptp;
+
+	/* TODO write the value reading from MSR */
+	eptp = VMX_EPT_DEFAULT_MT |
+		VMX_EPT_DEFAULT_GAW << VMX_EPT_GAW_EPTP_SHIFT;
+	eptp |= (root_hpa & PAGE_MASK);
+
+	return eptp;
+}
+
 static void vmx_flush_tlb(struct kvm_vcpu *vcpu)
 {
 	vpid_sync_vcpu_all(to_vmx(vcpu));
+	if (vm_need_ept())
+		ept_sync_context(construct_eptp(vcpu->arch.mmu.root_hpa));
 }
 
 static void vmx_decache_cr4_guest_bits(struct kvm_vcpu *vcpu)
@@ -1512,18 +1526,6 @@ static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
 		vmx_fpu_activate(vcpu);
 }
 
-static u64 construct_eptp(unsigned long root_hpa)
-{
-	u64 eptp;
-
-	/* TODO write the value reading from MSR */
-	eptp = VMX_EPT_DEFAULT_MT |
-		VMX_EPT_DEFAULT_GAW << VMX_EPT_GAW_EPTP_SHIFT;
-	eptp |= (root_hpa & PAGE_MASK);
-
-	return eptp;
-}
-
 static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
 {
 	unsigned long guest_cr3;
Signature · 1 line
1.5.5.4
Applied
#5 lore raw
Quoted 8 lines · Sheng
Quoted 3 lines · On Sunday 29 June 2008 18:09:20 Avi Kivity wrote:

I see. Back to the patch, can't you replace vmx->eptp by construct_eptp(vcpu->arch.mmu.root_hpa)?

Modified follow Avi's advice. Sorry for miss the mail...

Quoted 10 lines

From 251b611f7e90833aa07184e69ffe133fbcd83c76 Mon Sep 17 00:00:00 2001
From: Sheng Yang <[email protected]>
Date: Sun, 6 Jul 2008 19:16:51 +0800
Subject: [PATCH] KVM: VMX: Add ept_sync_context in flush_tlb

Fix a potention issue caused by kvm_mmu_slot_remove_write_access(). The old behavior don't sync EPT TLB with modified EPT entry, which result in inconsistent content of EPT TLB and EPT table.

Applied, thanks.

Quoted 15 lines
arch/x86/kvm/vmx.c +12 -2
+static u64 construct_eptp(unsigned long root_hpa)
+{
+	u64 eptp;
+
+	/* TODO write the value reading from MSR */
+	eptp = VMX_EPT_DEFAULT_MT |
+		VMX_EPT_DEFAULT_GAW << VMX_EPT_GAW_EPTP_SHIFT;
+	eptp |= (root_hpa & PAGE_MASK);
+
+	return eptp;
+}
+
-static u64 construct_eptp(unsigned long root_hpa)
-{

arch/x86/kvm/vmx.c static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) · line 1526

Quoted 10 lines
arch/x86/kvm/vmx.c +0 -10
-	u64 eptp;
-
-	/* TODO write the value reading from MSR */
-	eptp = VMX_EPT_DEFAULT_MT |
-		VMX_EPT_DEFAULT_GAW << VMX_EPT_GAW_EPTP_SHIFT;
-	eptp |= (root_hpa & PAGE_MASK);
-
-	return eptp;
-}
-

I added a forward declaration rather than move the code to make it clear there are no changes here.

Signature · 1 line
error compiling committee.c: too many arguments to function