# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1186565643 -3600
# Node ID 511c41a550458d50ae0adb9de2b392ae8a8e4379
# Parent 0f541efbb6d6e3883d103647ff6c8c0d332199dc
hvm: More cleanups around paging interfaces.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
xen/arch/x86/hvm/hvm.c | 36 ++++++++++++++---------------------
xen/arch/x86/hvm/svm/svm.c | 15 --------------
xen/arch/x86/mm/hap/hap.c | 38 ++++++++++++-------------------------
xen/include/asm-x86/hvm/svm/asid.h | 5 ----
4 files changed, 29 insertions(+), 65 deletions(-)
diff -r 0f541efbb6d6 -r 511c41a55045 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c Tue Aug 07 17:30:09 2007 +0100
+++ b/xen/arch/x86/hvm/hvm.c Wed Aug 08 10:34:03 2007 +0100
@@ -527,30 +527,26 @@ int hvm_set_cr3(unsigned long value)
if ( paging_mode_hap(v->domain) )
{
+ /* HAP mode. HAP-specific code does all the hard work. */
v->arch.hvm_vcpu.guest_cr[3] = value;
- hvm_update_guest_cr3(v, value);
- goto success;
- }
-
- if ( !hvm_paging_enabled(v) )
- {
+ paging_update_cr3(v);
+ }
+ else if ( !hvm_paging_enabled(v) )
+ {
+ /* Shadow-mode, paging disabled. Just update guest CR3 value. */
v->arch.hvm_vcpu.guest_cr[3] = value;
- goto success;
- }
-
- if ( value == v->arch.hvm_vcpu.guest_cr[3] )
- {
- /*
- * This is simple TLB flush, implying the guest has removed some
- * translation or changed page attributes. Invalidate the shadow.
- */
+ }
+ else if ( value == v->arch.hvm_vcpu.guest_cr[3] )
+ {
+ /* Shadow-mode TLB flush. Invalidate the shadow. */
mfn = get_mfn_from_gpfn(value >> PAGE_SHIFT);
if ( mfn != pagetable_get_pfn(v->arch.guest_table) )
goto bad_cr3;
+ paging_update_cr3(v);
}
else
{
- /* Make a shadow. Check that the PDBR is valid first. */
+ /* Shadow-mode CR3 change. Check PDBR and then make a new shadow. */
HVM_DBG_LOG(DBG_LEVEL_VMMU, "CR3 value = %lx", value);
mfn = get_mfn_from_gpfn(value >> PAGE_SHIFT);
if ( !mfn_valid(mfn) || !get_page(mfn_to_page(mfn), v->domain) )
@@ -564,11 +560,9 @@ int hvm_set_cr3(unsigned long value)
v->arch.hvm_vcpu.guest_cr[3] = value;
HVM_DBG_LOG(DBG_LEVEL_VMMU, "Update CR3 value = %lx", value);
- }
-
- paging_update_cr3(v);
-
- success:
+ paging_update_cr3(v);
+ }
+
return 1;
bad_cr3:
diff -r 0f541efbb6d6 -r 511c41a55045 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c Tue Aug 07 17:30:09 2007 +0100
+++ b/xen/arch/x86/hvm/svm/svm.c Wed Aug 08 10:34:03 2007 +0100
@@ -481,7 +481,6 @@ int svm_vmcb_restore(struct vcpu *v, str
}
paging_update_paging_modes(v);
- svm_asid_g_update_paging(v);
return 0;
@@ -1680,10 +1679,7 @@ static int svm_set_cr0(unsigned long val
vmcb->cr0 |= X86_CR0_PG | X86_CR0_WP;
if ( (value ^ old_value) & X86_CR0_PG )
- {
paging_update_paging_modes(v);
- svm_asid_g_update_paging(v);
- }
return 1;
}
@@ -1770,8 +1766,6 @@ static int mov_to_cr(int gpreg, int cr,
v->arch.hvm_vcpu.guest_cr[4] = value;
vmcb->cr4 = value | (HVM_CR4_HOST_MASK & ~X86_CR4_PAE);
paging_update_paging_modes(v);
- /* signal paging update to ASID handler */
- svm_asid_g_update_paging (v);
break;
}
@@ -1796,8 +1790,6 @@ static int mov_to_cr(int gpreg, int cr,
if ( old_base_mfn )
put_page(mfn_to_page(old_base_mfn));
paging_update_paging_modes(v);
- /* signal paging update to ASID handler */
- svm_asid_g_update_paging (v);
HVM_DBG_LOG(DBG_LEVEL_VMMU,
"Update CR3 value = %lx, mfn = %lx",
@@ -1821,11 +1813,7 @@ static int mov_to_cr(int gpreg, int cr,
* all TLB entries except global entries.
*/
if ((old_cr ^ value) & (X86_CR4_PSE | X86_CR4_PGE | X86_CR4_PAE))
- {
paging_update_paging_modes(v);
- /* signal paging update to ASID handler */
- svm_asid_g_update_paging (v);
- }
break;
case 8:
@@ -2206,8 +2194,7 @@ void svm_handle_invlpg(const short invlp
HVMTRACE_3D(INVLPG, v, (invlpga?1:0), g_vaddr, (invlpga?regs->ecx:0));
paging_invlpg(v, g_vaddr);
- /* signal invplg to ASID handler */
- svm_asid_g_invlpg (v, g_vaddr);
+ svm_asid_g_invlpg(v, g_vaddr);
}
diff -r 0f541efbb6d6 -r 511c41a55045 xen/arch/x86/mm/hap/hap.c
--- a/xen/arch/x86/mm/hap/hap.c Tue Aug 07 17:30:09 2007 +0100
+++ b/xen/arch/x86/mm/hap/hap.c Wed Aug 08 10:34:03 2007 +0100
@@ -603,38 +603,22 @@ static int hap_invlpg(struct vcpu *v, un
return 0;
}
-/*
- * HAP guests do not need to take any action on CR3 writes (they are still
- * intercepted, so that Xen's copy of the guest's CR3 can be kept in sync.)
- */
static void hap_update_cr3(struct vcpu *v, int do_locking)
{
+ hvm_update_guest_cr3(v, v->arch.hvm_vcpu.guest_cr[3]);
}
static void hap_update_paging_modes(struct vcpu *v)
{
- struct domain *d;
-
- d = v->domain;
+ struct domain *d = v->domain;
+
hap_lock(d);
- /* update guest paging mode. Note that we rely on hvm functions to detect
- * guest's paging mode. So, make sure the shadow registers (CR0, CR4, EFER)
- * reflect guest's status correctly.
- */
- if ( hvm_paging_enabled(v) )
- {
- if ( hvm_long_mode_enabled(v) )
- v->arch.paging.mode = &hap_paging_long_mode;
- else if ( hvm_pae_enabled(v) )
- v->arch.paging.mode = &hap_paging_pae_mode;
- else
- v->arch.paging.mode = &hap_paging_protected_mode;
- }
- else
- {
- v->arch.paging.mode = &hap_paging_real_mode;
- }
+ v->arch.paging.mode =
+ !hvm_paging_enabled(v) ? &hap_paging_real_mode :
+ hvm_long_mode_enabled(v) ? &hap_paging_long_mode :
+ hvm_pae_enabled(v) ? &hap_paging_pae_mode :
+ &hap_paging_protected_mode;
v->arch.paging.translate_enabled = hvm_paging_enabled(v);
@@ -643,7 +627,11 @@ static void hap_update_paging_modes(stru
mfn_t mmfn = hap_make_monitor_table(v);
v->arch.monitor_table = pagetable_from_mfn(mmfn);
make_cr3(v, mfn_x(mmfn));
- }
+ hvm_update_host_cr3(v);
+ }
+
+ /* CR3 is effectively updated by a mode change. Flush ASIDs, etc. */
+ hvm_update_guest_cr3(v, v->arch.hvm_vcpu.guest_cr[3]);
hap_unlock(d);
}
diff -r 0f541efbb6d6 -r 511c41a55045 xen/include/asm-x86/hvm/svm/asid.h
--- a/xen/include/asm-x86/hvm/svm/asid.h Tue Aug 07 17:30:09 2007 +0100
+++ b/xen/include/asm-x86/hvm/svm/asid.h Wed Aug 08 10:34:03 2007 +0100
@@ -32,11 +32,6 @@ void svm_asid_inv_asid(struct vcpu *v);
void svm_asid_inv_asid(struct vcpu *v);
void svm_asid_inc_generation(void);
-static inline void svm_asid_g_update_paging(struct vcpu *v)
-{
- svm_asid_inv_asid(v);
-}
-
static inline void svm_asid_g_invlpg(struct vcpu *v, unsigned long g_vaddr)
{
#if 0
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|