1. Indexing guest_pt[] can fault. Need to use __copy_from_user. This was preventing FreeBSD 5.4 and RHEL3 install kernel from booting. 2. Read-only page tables should remain read only on a VMX domain. Linux 2.6 depends on getting a write fault on a L2 page table page. Signed-off-by: Arun Sharma <arun.sharma@intel.com> --- 1.114/xen/arch/x86/shadow.c 2005-05-25 03:36:57 -07:00 +++ edited/xen/arch/x86/shadow.c 2005-05-28 15:19:23 -07:00 @@ -1906,7 +1906,7 @@ unsigned long gpfn, unsigned index) { unsigned long smfn = __shadow_status(d, gpfn, PGT_snapshot); - l1_pgentry_t *snapshot; // could be L1s or L2s or ... + l1_pgentry_t *snapshot, gpte; // could be L1s or L2s or ... int entries_match; perfc_incrc(snapshot_entry_matches_calls); @@ -1916,10 +1916,14 @@ snapshot = map_domain_mem(smfn << PAGE_SHIFT); + if (__copy_from_user(&gpte, &guest_pt[index], + sizeof(gpte))) + return 0; + // This could probably be smarter, but this is sufficent for // our current needs. // - entries_match = !l1e_has_changed(&guest_pt[index], &snapshot[index], + entries_match = !l1e_has_changed(&gpte, &snapshot[index], PAGE_FLAG_MASK); unmap_domain_mem(snapshot); @@ -2600,7 +2604,8 @@ if ( unlikely(!(l1e_get_flags(gpte) & _PAGE_RW)) ) { - if ( shadow_mode_page_writable(d, l1e_get_pfn(gpte)) ) + if ( shadow_mode_page_writable(d, l1e_get_pfn(gpte)) + && !shadow_mode_external(d)) { allow_writes = 1; l1e_add_flags(&gpte, _PAGE_RW); _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Re #1, below: can you provide a call stack when snapshot_entry_match faults? Seems like it''s only ever called from __shadow_out_of_sync(), and that function tests for possible faulting conditions before invoking snapshot_entry_match(). I''m not sure I see how you could be seeing this. Re #2: I think the bug is that external mode should not set the SHM_write_all flag... I''ll commit that fix shortly. Michael -----Original Message----- From: Arun Sharma [mailto:arun.sharma@intel.com] Sent: Saturday, May 28, 2005 3:34 PM To: Ian Pratt; Keir Fraser Cc: xen-devel@lists.xensource.com Subject: [PATCH] shadow-fixes.patch 1. Indexing guest_pt[] can fault. Need to use __copy_from_user. This was preventing FreeBSD 5.4 and RHEL3 install kernel from booting. 2. Read-only page tables should remain read only on a VMX domain. Linux 2.6 depends on getting a write fault on a L2 page table page. Signed-off-by: Arun Sharma <arun.sharma@intel.com> --- 1.114/xen/arch/x86/shadow.c 2005-05-25 03:36:57 -07:00 +++ edited/xen/arch/x86/shadow.c 2005-05-28 15:19:23 -07:00 @@ -1906,7 +1906,7 @@ unsigned long gpfn, unsigned index) { unsigned long smfn = __shadow_status(d, gpfn, PGT_snapshot); - l1_pgentry_t *snapshot; // could be L1s or L2s or ... + l1_pgentry_t *snapshot, gpte; // could be L1s or L2s or ... int entries_match; perfc_incrc(snapshot_entry_matches_calls); @@ -1916,10 +1916,14 @@ snapshot = map_domain_mem(smfn << PAGE_SHIFT); + if (__copy_from_user(&gpte, &guest_pt[index], + sizeof(gpte))) + return 0; + // This could probably be smarter, but this is sufficent for // our current needs. // - entries_match = !l1e_has_changed(&guest_pt[index], &snapshot[index], + entries_match = !l1e_has_changed(&gpte, &snapshot[index], PAGE_FLAG_MASK); unmap_domain_mem(snapshot); @@ -2600,7 +2604,8 @@ if ( unlikely(!(l1e_get_flags(gpte) & _PAGE_RW)) ) { - if ( shadow_mode_page_writable(d, l1e_get_pfn(gpte)) ) + if ( shadow_mode_page_writable(d, l1e_get_pfn(gpte)) + && !shadow_mode_external(d)) { allow_writes = 1; l1e_add_flags(&gpte, _PAGE_RW); _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Michael A Fetterman wrote:> Re #1, below: can you provide a call stack when snapshot_entry_match faults? > Seems like it''s only ever called from __shadow_out_of_sync(), and that > function > tests for possible faulting conditions before invoking > snapshot_entry_match(). > I''m not sure I see how you could be seeing this. >This is what the stack trace looked like: (XEN) EIP: e008:[<ff125037>] (XEN) EFLAGS: 00010246 CONTEXT: hypervisor (XEN) eax: fefa2000 ebx: fe31b000 ecx: ffbce0e0 edx: 00000000 (XEN) esi: c0000000 edi: ffbdb080 ebp: 000000b1 esp: ff103f04 (XEN) ds: e010 es: e010 fs: e010 gs: e010 ss: e010 cs: e008 (XEN) cr0: 00000004 cr3: 00000384 (XEN) Xen stack trace from esp=ff103f04: (XEN) 3d6e4000 00000c1b c0000000 ffbdb080 fe31b000 bff1b2c4 00000000 ffbdb080 (XEN) ffbda080 ffbcb080 c6cb1000 [ff124b20] ffbda080 c6cb1000 ffbda080 [ff12f601] (XEN) 07ccc063 00c1b063 01b05063 0000681e ffbda080 c6cb1000 ffbda080 [ff12f04d] (XEN) ffbda080 c6cb1000 00000002 ffbf7080 ffbda080 004c4b43 00000000 61402178 (XEN) bffff700 bffff6f8 bffff6d8 00000000 bffff6a0 00000001 00185000 c6cbd000 (XEN) c35e4448 00000100 c76daa84 [ff13600d] c6cbd000 ffffffff c6cbd000 c35e4448 (XEN) 00000100 c76daa84 c6cb1000 00000002 c36a5000 00130000 00000000 0000e008 (XEN) 00000202 00000010 00000010 00000000 00000000 00000000 ffbda080 (XEN) Xen call trace from esp=ff103f04: (XEN) [<ff124b20>] [<ff12f601>] [<ff12f04d>] [<ff13600d>] I remember va=c6cb1000 and it was a vmexit due to invlpg -> shadow_invlpg -> __shadow_sync_va -> __shadow_out_of_sync() I think the issue is, even though you''ve verified that it has a valid L2 entry, update_hl2e() hasn''t been called. So linear pagetable can still fault. -Arun _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel