aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>2006-05-31 07:25:59 +0100
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>2006-05-31 07:25:59 +0100
commit6726fd1b61adb41cf7499bdc34285e85b994c9f2 (patch)
tree43b421fc67b79b84ad4de7eb32c725749a18b751
parent9fea9fb410db5920a6c075510db5d5c6e3729022 (diff)
downloadxen-6726fd1b61adb41cf7499bdc34285e85b994c9f2.tar.gz
xen-6726fd1b61adb41cf7499bdc34285e85b994c9f2.tar.bz2
xen-6726fd1b61adb41cf7499bdc34285e85b994c9f2.zip
[HVM] Fix shadow mode to not corrupt frame 0's page_info struct.
Signed-off-by: Jun Nakajima <jun.nakajima@intel.com>
-rw-r--r--xen/arch/x86/shadow.c3
-rw-r--r--xen/arch/x86/shadow32.c3
-rw-r--r--xen/include/asm-x86/shadow.h12
3 files changed, 13 insertions, 5 deletions
diff --git a/xen/arch/x86/shadow.c b/xen/arch/x86/shadow.c
index 58690617c5..583373c34a 100644
--- a/xen/arch/x86/shadow.c
+++ b/xen/arch/x86/shadow.c
@@ -1724,7 +1724,8 @@ static int resync_all(struct domain *d, u32 stype)
unshadow_l1 = 1;
else {
need_flush |= error;
- set_guest_back_ptr(d, *sl1e_p, smfn, i);
+ if ( l1e_get_flags(*sl1e_p) & _PAGE_PRESENT )
+ set_guest_back_ptr(d, *sl1e_p, smfn, i);
}
// can't update snapshots of linear page tables -- they
// are used multiple times...
diff --git a/xen/arch/x86/shadow32.c b/xen/arch/x86/shadow32.c
index bef350aa23..5cefdb70a8 100644
--- a/xen/arch/x86/shadow32.c
+++ b/xen/arch/x86/shadow32.c
@@ -2691,7 +2691,8 @@ static int resync_all(struct domain *d, u32 stype)
unshadow_l1 = 1;
else {
need_flush |= error;
- set_guest_back_ptr(d, shadow1[i], smfn, i);
+ if ( l1e_get_flags(shadow1[i]) & _PAGE_PRESENT )
+ set_guest_back_ptr(d, shadow1[i], smfn, i);
}
// can't update snapshots of linear page tables -- they
diff --git a/xen/include/asm-x86/shadow.h b/xen/include/asm-x86/shadow.h
index 28d50466ea..3a9e0cdf84 100644
--- a/xen/include/asm-x86/shadow.h
+++ b/xen/include/asm-x86/shadow.h
@@ -762,10 +762,16 @@ static inline void set_guest_back_ptr(
unsigned long gmfn;
ASSERT(shadow_lock_is_acquired(d));
+ ASSERT( smfn );
gmfn = l1e_get_pfn(spte);
- mfn_to_page(gmfn)->tlbflush_timestamp = smfn;
- mfn_to_page(gmfn)->u.inuse.type_info &= ~PGT_va_mask;
- mfn_to_page(gmfn)->u.inuse.type_info |= (unsigned long) index << PGT_va_shift;
+ ASSERT( gmfn );
+ if ( l1e_get_flags(spte) & _PAGE_RW )
+ {
+ mfn_to_page(gmfn)->tlbflush_timestamp = smfn;
+ mfn_to_page(gmfn)->u.inuse.type_info &= ~PGT_va_mask;
+ mfn_to_page(gmfn)->u.inuse.type_info |=
+ (unsigned long) index << PGT_va_shift;
+ }
}
}