WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] Make shadow translate mode work for unprivileged, unipro

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Make shadow translate mode work for unprivileged, uniprocessor guests
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 25 Jan 2006 23:46:07 +0000
Delivery-date: Wed, 25 Jan 2006 23:55:33 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User sos22@xxxxxxxxxxxxxxxxxxxx
# Node ID 43c294aea9ecbace908d321829a9f31e2c6f7a29
# Parent  860fa26845c242eac64dbef60bc2fec42cfacc8c
Make shadow translate mode work for unprivileged, uniprocessor guests
with no devices on plain 32 bit non-PAE hosts.

Signed-off-by: Steven Smith, sos22@xxxxxxxxx

diff -r 860fa26845c2 -r 43c294aea9ec tools/libxc/xc_linux_build.c
--- a/tools/libxc/xc_linux_build.c      Wed Jan 25 16:14:19 2006
+++ b/tools/libxc/xc_linux_build.c      Wed Jan 25 16:15:11 2006
@@ -60,16 +60,18 @@
     return 0;
 }
 
-#define alloc_pt(ltab, vltab)                                           \
+#define alloc_pt(ltab, vltab, pltab)                                    \
 do {                                                                    \
-    ltab = (uint64_t)page_array[ppt_alloc++] << PAGE_SHIFT;                  \
+    pltab = ppt_alloc++;                                                \
+    ltab = (uint64_t)page_array[pltab] << PAGE_SHIFT;                   \
+    pltab <<= PAGE_SHIFT;                                               \
     if ( vltab != NULL )                                                \
         munmap(vltab, PAGE_SIZE);                                       \
     if ( (vltab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,       \
                                        PROT_READ|PROT_WRITE,            \
                                        ltab >> PAGE_SHIFT)) == NULL )   \
         goto error_out;                                                 \
-    memset(vltab, 0, PAGE_SIZE);                                        \
+    memset(vltab, 0x0, PAGE_SIZE);                                      \
 } while ( 0 )
 
 #if defined(__i386__)
@@ -80,33 +82,42 @@
                            unsigned long v_end,
                            unsigned long *page_array,
                            unsigned long vpt_start,
-                           unsigned long vpt_end)
+                           unsigned long vpt_end,
+                           unsigned shadow_mode_enabled)
 {
     l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
     l2_pgentry_t *vl2tab=NULL, *vl2e=NULL;
-    unsigned long l1tab = 0;
-    unsigned long l2tab = 0;
+    unsigned long l1tab = 0, pl1tab;
+    unsigned long l2tab = 0, pl2tab;
     unsigned long ppt_alloc;
     unsigned long count;
 
     ppt_alloc = (vpt_start - dsi_v_start) >> PAGE_SHIFT;
-    alloc_pt(l2tab, vl2tab);
+    alloc_pt(l2tab, vl2tab, pl2tab);
     vl2e = &vl2tab[l2_table_offset(dsi_v_start)];
     ctxt->ctrlreg[3] = l2tab;
 
     for ( count = 0; count < ((v_end - dsi_v_start) >> PAGE_SHIFT); count++ )
-    {    
+    {
         if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 )
         {
-            alloc_pt(l1tab, vl1tab);
+            alloc_pt(l1tab, vl1tab, pl1tab);
             vl1e = &vl1tab[l1_table_offset(dsi_v_start + (count<<PAGE_SHIFT))];
-            *vl2e++ = l1tab | L2_PROT;
-        }
-
-        *vl1e = (page_array[count] << PAGE_SHIFT) | L1_PROT;
-        if ( (count >= ((vpt_start-dsi_v_start)>>PAGE_SHIFT)) && 
-             (count <  ((vpt_end  -dsi_v_start)>>PAGE_SHIFT)) )
-            *vl1e &= ~_PAGE_RW;
+            if (shadow_mode_enabled)
+                *vl2e = pl1tab | L2_PROT;
+            else
+                *vl2e = l1tab | L2_PROT;
+            vl2e++;
+        }
+
+        if (shadow_mode_enabled) {
+            *vl1e = (count << PAGE_SHIFT) | L1_PROT;
+        } else {
+            *vl1e = (page_array[count] << PAGE_SHIFT) | L1_PROT;
+            if ( (count >= ((vpt_start-dsi_v_start)>>PAGE_SHIFT)) && 
+                 (count <  ((vpt_end  -dsi_v_start)>>PAGE_SHIFT)) )
+                *vl1e &= ~_PAGE_RW;
+        }
         vl1e++;
     }
     munmap(vl1tab, PAGE_SIZE);
@@ -127,12 +138,13 @@
                                unsigned long v_end,
                                unsigned long *page_array,
                                unsigned long vpt_start,
-                               unsigned long vpt_end)
+                               unsigned long vpt_end,
+                               unsigned shadow_mode_enabled)
 {
     l1_pgentry_64_t *vl1tab = NULL, *vl1e = NULL;
     l2_pgentry_64_t *vl2tab = NULL, *vl2e = NULL;
     l3_pgentry_64_t *vl3tab = NULL, *vl3e = NULL;
-    uint64_t l1tab, l2tab, l3tab;
+    uint64_t l1tab, l2tab, l3tab, pl1tab, pl2tab, pl3tab;
     unsigned long ppt_alloc, count, nmfn;
 
     /* First allocate page for page dir. */
@@ -149,7 +161,7 @@
         page_array[ppt_alloc] = nmfn;
     }
 
-    alloc_pt(l3tab, vl3tab);
+    alloc_pt(l3tab, vl3tab, pl3tab);
     vl3e = &vl3tab[l3_table_offset_pae(dsi_v_start)];
     ctxt->ctrlreg[3] = l3tab;
 
@@ -159,22 +171,32 @@
         {
             if ( !((unsigned long)vl2e & (PAGE_SIZE-1)) )
             {
-                alloc_pt(l2tab, vl2tab);
+                alloc_pt(l2tab, vl2tab, pl2tab);
                 vl2e = &vl2tab[l2_table_offset_pae(
                     dsi_v_start + (count << PAGE_SHIFT))];
-                *vl3e++ = l2tab | L3_PROT;
+                if (shadow_mode_enabled)
+                    *vl3e = pl2tab | L3_PROT;
+                else
+                    *vl3e++ = l2tab | L3_PROT;
             }
 
-            alloc_pt(l1tab, vl1tab);
+            alloc_pt(l1tab, vl1tab, pl1tab);
             vl1e = &vl1tab[l1_table_offset_pae(
                 dsi_v_start + (count << PAGE_SHIFT))];
-            *vl2e++ = l1tab | L2_PROT;
+            if (shadow_mode_enabled)
+                *vl2e = pl1tab | L2_PROT;
+            else
+                *vl2e++ = l1tab | L2_PROT;
         }
         
-        *vl1e = ((uint64_t)page_array[count] << PAGE_SHIFT) | L1_PROT;
-        if ( (count >= ((vpt_start-dsi_v_start)>>PAGE_SHIFT)) &&
-             (count <  ((vpt_end  -dsi_v_start)>>PAGE_SHIFT)) ) 
-            *vl1e &= ~_PAGE_RW;
+        if (shadow_mode_enabled) {
+            *vl1e = (count << PAGE_SHIFT) | L1_PROT;
+        } else {
+            *vl1e = ((uint64_t)page_array[count] << PAGE_SHIFT) | L1_PROT;
+            if ( (count >= ((vpt_start-dsi_v_start)>>PAGE_SHIFT)) &&
+                 (count <  ((vpt_end  -dsi_v_start)>>PAGE_SHIFT)) ) 
+                *vl1e &= ~_PAGE_RW;
+        }
         vl1e++;
     }
      
@@ -203,7 +225,8 @@
                               unsigned long v_end,
                               unsigned long *page_array,
                               unsigned long vpt_start,
-                              unsigned long vpt_end)
+                              unsigned long vpt_end,
+                              int shadow_mode_enabled)
 {
     l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
     l2_pgentry_t *vl2tab=NULL, *vl2e=NULL;
@@ -247,11 +270,15 @@
             vl2e++;
         }
         
-        *vl1e = (page_array[count] << PAGE_SHIFT) | L1_PROT;
-        if ( (count >= ((vpt_start-dsi_v_start)>>PAGE_SHIFT)) &&
-             (count <  ((vpt_end  -dsi_v_start)>>PAGE_SHIFT)) ) 
-        {
-            *vl1e &= ~_PAGE_RW;
+        if (shadow_mode_enable) {
+            *vl1e = (count << PAGE_SHIFT) | L1_PROT;
+        } else {
+            *vl1e = (page_array[count] << PAGE_SHIFT) | L1_PROT;
+            if ( (count >= ((vpt_start-dsi_v_start)>>PAGE_SHIFT)) &&
+                 (count <  ((vpt_end  -dsi_v_start)>>PAGE_SHIFT)) ) 
+                {
+                    *vl1e &= ~_PAGE_RW;
+                }
         }
         vl1e++;
     }
@@ -458,6 +485,8 @@
     unsigned long vpt_start;
     unsigned long vpt_end;
     unsigned long v_end;
+    unsigned shadow_mode_enabled;
+    unsigned long guest_store_mfn, guest_console_mfn, guest_shared_info_mfn;
 
     rc = probeimageformat(image, image_size, &load_funcs);
     if ( rc != 0 )
@@ -558,7 +587,7 @@
         goto error_out;
     }
 
-    if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL )
+    if ( (page_array = malloc((nr_pages + 1) * sizeof(unsigned long))) == NULL 
)
     {
         PERROR("Could not allocate memory");
         goto error_out;
@@ -593,24 +622,8 @@
     if ( (mmu = xc_init_mmu_updates(xc_handle, dom)) == NULL )
         goto error_out;
 
-    /* setup page tables */
-#if defined(__i386__)
-    if (dsi.pae_kernel)
-        rc = setup_pg_tables_pae(xc_handle, dom, ctxt,
-                                 dsi.v_start, v_end,
-                                 page_array, vpt_start, vpt_end);
-    else
-        rc = setup_pg_tables(xc_handle, dom, ctxt,
-                             dsi.v_start, v_end,
-                             page_array, vpt_start, vpt_end);
-#endif
-#if defined(__x86_64__)
-    rc = setup_pg_tables_64(xc_handle, dom, ctxt,
-                            dsi.v_start, v_end,
-                            page_array, vpt_start, vpt_end);
-#endif
-    if (0 != rc)
-        goto error_out;
+    shadow_mode_enabled = !!strstr(dsi.xen_guest_string,
+                                   "SHADOW=translate");
 
     /* Write the phys->machine and machine->phys table entries. */
     physmap_pfn = (vphysmap_start - dsi.v_start) >> PAGE_SHIFT;
@@ -618,7 +631,10 @@
         xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
         page_array[physmap_pfn++]);
 
-    for ( count = 0; count < nr_pages; count++ )
+    if (shadow_mode_enabled)
+        page_array[nr_pages] = shared_info_frame;
+
+    for ( count = 0; count < nr_pages + shadow_mode_enabled; count++ )
     {
         if ( xc_add_mmu_update(
             xc_handle, mmu,
@@ -640,20 +656,58 @@
         }
     }
     munmap(physmap, PAGE_SIZE);
-    
+
+    /* Send the page update requests down to the hypervisor. */
+    if ( xc_finish_mmu_updates(xc_handle, mmu) )
+        goto error_out;
+
+    if (shadow_mode_enabled) {
+        /* Enable shadow translate mode */
+        if (xc_shadow_control(xc_handle, dom,
+                              DOM0_SHADOW_CONTROL_OP_ENABLE_TRANSLATE,
+                              NULL, 0, NULL) < 0) {
+            PERROR("Could not enable translation mode");
+            goto error_out;
+        }
+    }
+
+    /* setup page tables */
+#if defined(__i386__)
+    if (dsi.pae_kernel)
+        rc = setup_pg_tables_pae(xc_handle, dom, ctxt,
+                                 dsi.v_start, v_end,
+                                 page_array, vpt_start, vpt_end,
+                                 shadow_mode_enabled);
+    else
+        rc = setup_pg_tables(xc_handle, dom, ctxt,
+                             dsi.v_start, v_end,
+                             page_array, vpt_start, vpt_end,
+                             shadow_mode_enabled);
+#endif
+#if defined(__x86_64__)
+    rc = setup_pg_tables_64(xc_handle, dom, ctxt,
+                            dsi.v_start, v_end,
+                            page_array, vpt_start, vpt_end,
+                            shadow_mode_enabled);
+#endif
+    if (0 != rc)
+        goto error_out;
+
 #if defined(__i386__)
     /*
      * Pin down l2tab addr as page dir page - causes hypervisor to provide
      * correct protection for the page
      */
-    if (dsi.pae_kernel) {
-        if ( pin_table(xc_handle, MMUEXT_PIN_L3_TABLE,
-                       ctxt->ctrlreg[3] >> PAGE_SHIFT, dom) )
-            goto error_out;
-    } else {
-        if ( pin_table(xc_handle, MMUEXT_PIN_L2_TABLE,
-                       ctxt->ctrlreg[3] >> PAGE_SHIFT, dom) )
-            goto error_out;
+    if (!shadow_mode_enabled) {
+        if (dsi.pae_kernel) {
+            if ( pin_table(xc_handle, MMUEXT_PIN_L3_TABLE,
+                           ctxt->ctrlreg[3] >> PAGE_SHIFT, dom) )
+                goto error_out;
+        } else {
+            if ( pin_table(xc_handle, MMUEXT_PIN_L2_TABLE,
+                           ctxt->ctrlreg[3] >> PAGE_SHIFT, dom) )
+                goto error_out;
+        }
     }
 #endif
 
@@ -672,24 +726,34 @@
     if ( xc_clear_domain_page(xc_handle, dom, *store_mfn) ||
          xc_clear_domain_page(xc_handle, dom, *console_mfn) )
         goto error_out;
+    if (shadow_mode_enabled) {
+        guest_store_mfn = (vstoreinfo_start-dsi.v_start) >> PAGE_SHIFT;
+        guest_console_mfn = (vconsole_start-dsi.v_start) >> PAGE_SHIFT;
+        guest_shared_info_mfn = nr_pages;
+    } else {
+        guest_store_mfn = *store_mfn;
+        guest_console_mfn = *console_mfn;
+        guest_shared_info_mfn = shared_info_frame;
+    }
 
     start_info = xc_map_foreign_range(
         xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
         page_array[(vstartinfo_start-dsi.v_start)>>PAGE_SHIFT]);
+    /*shared_info, start_info */
     memset(start_info, 0, sizeof(*start_info));
     rc = xc_version(xc_handle, XENVER_version, NULL);
     sprintf(start_info->magic, "xen-%i.%i-x86_%d%s",
             rc >> 16, rc & (0xFFFF), (unsigned int)sizeof(long)*8,
             dsi.pae_kernel ? "p" : "");
     start_info->nr_pages     = nr_pages;
-    start_info->shared_info  = shared_info_frame << PAGE_SHIFT;
+    start_info->shared_info  = guest_shared_info_mfn << PAGE_SHIFT;
     start_info->flags        = flags;
     start_info->pt_base      = vpt_start;
     start_info->nr_pt_frames = nr_pt_pages;
     start_info->mfn_list     = vphysmap_start;
-    start_info->store_mfn    = *store_mfn;
+    start_info->store_mfn    = guest_store_mfn;
     start_info->store_evtchn = store_evtchn;
-    start_info->console_mfn   = *console_mfn;
+    start_info->console_mfn   = guest_console_mfn;
     start_info->console_evtchn = console_evtchn;
     if ( initrd_len != 0 )
     {
diff -r 860fa26845c2 -r 43c294aea9ec xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Wed Jan 25 16:14:19 2006
+++ b/xen/arch/x86/mm.c Wed Jan 25 16:15:11 2006
@@ -1826,6 +1826,8 @@
             break;
 
         case MMUEXT_NEW_BASEPTR:
+            if (shadow_mode_translate(current->domain))
+                mfn = __gpfn_to_mfn(current->domain, mfn);
             okay = new_guest_cr3(mfn);
             percpu_info[cpu].deferred_ops &= ~DOP_FLUSH_TLB;
             break;
@@ -2680,6 +2682,7 @@
     int nr_pages = (entries + 511) / 512;
     unsigned long frames[16];
     long ret;
+    int x;
 
     /* Rechecked in set_gdt, but ensures a sane limit for copy_from_user(). */
     if ( entries > FIRST_RESERVED_GDT_ENTRY )
@@ -2687,6 +2690,11 @@
     
     if ( copy_from_user(frames, frame_list, nr_pages * sizeof(unsigned long)) )
         return -EFAULT;
+
+    if (shadow_mode_translate(current->domain)) {
+        for (x = 0; x < nr_pages; x++)
+            frames[x] = __gpfn_to_mfn(current->domain, frames[x]);
+    }
 
     LOCK_BIGLOCK(current->domain);
 
diff -r 860fa26845c2 -r 43c294aea9ec xen/arch/x86/shadow32.c
--- a/xen/arch/x86/shadow32.c   Wed Jan 25 16:14:19 2006
+++ b/xen/arch/x86/shadow32.c   Wed Jan 25 16:15:11 2006
@@ -1391,7 +1391,7 @@
     case DOM0_SHADOW_CONTROL_OP_ENABLE_TRANSLATE:
         free_shadow_pages(d);
         rc = __shadow_mode_enable(
-            d, d->arch.shadow_mode|SHM_enable|SHM_refcounts|SHM_translate);
+            d, 
d->arch.shadow_mode|SHM_enable|SHM_refcounts|SHM_translate|SHM_wr_pt_pte);
         break;
 
     default:
@@ -2643,7 +2643,8 @@
     __guest_get_l2e(v, va, &gpde);
     if ( unlikely(!(l2e_get_flags(gpde) & _PAGE_PRESENT)) )
     {
-        SH_VVLOG("shadow_fault - EXIT: L1 not present");
+        SH_VVLOG("shadow_fault - EXIT: L2 not present (%x)",
+                 l2e_get_intpte(gpde));
         perfc_incrc(shadow_fault_bail_pde_not_present);
         goto fail;
     }
@@ -2655,8 +2656,9 @@
     orig_gpte = gpte = linear_pg_table[l1_linear_offset(va)];
     if ( unlikely(!(l1e_get_flags(gpte) & _PAGE_PRESENT)) )
     {
-        SH_VVLOG("shadow_fault - EXIT: gpte not present (%" PRIpte ")",
-                 l1e_get_intpte(gpte));
+        SH_VVLOG("shadow_fault - EXIT: gpte not present (%" PRIpte ") (gpde %" 
PRIpte ")",
+                 l1e_get_intpte(gpte),
+                 l2e_get_intpte(gpde));
         perfc_incrc(shadow_fault_bail_pte_not_present);
         goto fail;
     }
diff -r 860fa26845c2 -r 43c294aea9ec xen/include/asm-x86/shadow.h
--- a/xen/include/asm-x86/shadow.h      Wed Jan 25 16:14:19 2006
+++ b/xen/include/asm-x86/shadow.h      Wed Jan 25 16:15:11 2006
@@ -490,7 +490,7 @@
 #ifndef NDEBUG
     else if ( mfn < max_page )
     {
-        SH_VLOG("mark_dirty OOR! mfn=%x pfn=%lx max=%x (dom %p)",
+        SH_VLOG("mark_dirty OOR! mfn=%lx pfn=%lx max=%x (dom %p)",
                mfn, pfn, d->arch.shadow_dirty_bitmap_size, d);
         SH_VLOG("dom=%p caf=%08x taf=%" PRtype_info, 
                 page_get_owner(pfn_to_page(mfn)),

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] Make shadow translate mode work for unprivileged, uniprocessor guests, Xen patchbot -unstable <=