Skip to contentSkip to conversation

shadow-fixes.patch

PATCH In review Arun Sharma 2 participants 3 messages May 28, 2005 – May 30, 2005

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 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.

xen/arch/x86/shadow.c +8 -3
@@ -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);
#1 lore raw

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:[email protected]]
Sent: Saturday, May 28, 2005 3:34 PM
To: Ian Pratt; Keir Fraser
Cc: [email protected]
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.

xen/arch/x86/shadow.c +8 -3
@@ -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);
#2 lore raw
Quoted 7 lines · Michael A Fetterman

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