Make SMP guests work in shadow translate mode.
authorsos22@douglas.cl.cam.ac.uk <sos22@douglas.cl.cam.ac.uk>
Thu, 26 Jan 2006 17:00:40 +0000 (18:00 +0100)
committersos22@douglas.cl.cam.ac.uk <sos22@douglas.cl.cam.ac.uk>
Thu, 26 Jan 2006 17:00:40 +0000 (18:00 +0100)
Signed-off-by: Steven Smith, sos22@cam.ac.uk
tools/libxc/xc_linux_build.c
xen/arch/x86/domain.c
xen/arch/x86/mm.c

index c0b0568811bf680f753e435ed5ed567cfe8a9a34..ac0c734aabcc579bb6927f318aaf4840ada61de9 100644 (file)
@@ -98,7 +98,10 @@ static int setup_pg_tables(int xc_handle, uint32_t dom,
     ppt_alloc = (vpt_start - dsi_v_start) >> PAGE_SHIFT;
     alloc_pt(l2tab, vl2tab, pl2tab);
     vl2e = &vl2tab[l2_table_offset(dsi_v_start)];
-    ctxt->ctrlreg[3] = l2tab;
+    if (shadow_mode_enabled)
+        ctxt->ctrlreg[3] = pl2tab;
+    else
+        ctxt->ctrlreg[3] = l2tab;
 
     for ( count = 0; count < ((v_end - dsi_v_start) >> PAGE_SHIFT); count++ )
     {
@@ -166,7 +169,10 @@ static int setup_pg_tables_pae(int xc_handle, uint32_t dom,
 
     alloc_pt(l3tab, vl3tab, pl3tab);
     vl3e = &vl3tab[l3_table_offset_pae(dsi_v_start)];
-    ctxt->ctrlreg[3] = l3tab;
+    if (shadow_mode_enabled)
+        ctxt->ctrlreg[3] = pl3tab;
+    else
+        ctxt->ctrlreg[3] = l3tab;
 
     for ( count = 0; count < ((v_end - dsi_v_start) >> PAGE_SHIFT); count++)
     {
@@ -246,7 +252,10 @@ static int setup_pg_tables_64(int xc_handle, uint32_t dom,
     ppt_alloc = (vpt_start - dsi_v_start) >> PAGE_SHIFT;
     alloc_pt(l4tab, vl4tab);
     vl4e = &vl4tab[l4_table_offset(dsi_v_start)];
-    ctxt->ctrlreg[3] = l4tab;
+    if (shadow_mode_enabled)
+        ctxt->ctrlreg[3] = pl4tab;
+    else
+        ctxt->ctrlreg[3] = l4tab;
     
     for ( count = 0; count < ((v_end-dsi_v_start)>>PAGE_SHIFT); count++)
     {
index 4fd39ad9038d5766abcab73a9415498a113c45b5..858586f76931866c099a223068f8b7ebaa178b0f 100644 (file)
@@ -348,6 +348,7 @@ int arch_set_info_guest(
     struct domain *d = v->domain;
     unsigned long phys_basetab;
     int i, rc;
+    unsigned got_basetab_type;
 
     /*
      * This is sufficient! If the descriptor DPL differs from CS RPL then we'll
@@ -401,23 +402,32 @@ int arch_set_info_guest(
         d->vm_assist = c->vm_assist;
 
     phys_basetab = c->ctrlreg[3];
+    phys_basetab =
+        (__gpfn_to_mfn(d, phys_basetab >> PAGE_SHIFT) << PAGE_SHIFT) |
+        (phys_basetab & ~PAGE_MASK);
+
     v->arch.guest_table = mk_pagetable(phys_basetab);
 
     if ( shadow_mode_refcounts(d) )
     {
         if ( !get_page(pfn_to_page(phys_basetab>>PAGE_SHIFT), d) )
             return -EINVAL;
+        got_basetab_type = 0;
     }
     else if ( !(c->flags & VGCF_VMX_GUEST) )
     {
         if ( !get_page_and_type(pfn_to_page(phys_basetab>>PAGE_SHIFT), d,
                                 PGT_base_page_table) )
             return -EINVAL;
+        got_basetab_type = 1;
     }
 
     if ( (rc = (int)set_gdt(v, c->gdt_frames, c->gdt_ents)) != 0 )
     {
-        put_page_and_type(pfn_to_page(phys_basetab>>PAGE_SHIFT));
+        if (got_basetab_type)
+            put_page_and_type(pfn_to_page(phys_basetab>>PAGE_SHIFT));
+        else
+            put_page(pfn_to_page(phys_basetab>>PAGE_SHIFT));
         return rc;
     }
 
index 6ef37a7850523b9674a57657fa5ca067c0c4dbc2..ff073176f1402a8e396a4747a4bd9a04de4898ea 100644 (file)
@@ -2153,9 +2153,7 @@ int do_mmu_update(
         case MMU_MACHPHYS_UPDATE:
 
             if (shadow_mode_translate(FOREIGNDOM)) {
-                /* We don't allow translate mode guests to have their
-                   M2P tables mutated while they're running. */
-                okay = 0;
+                MEM_LOG("can't mutate m2p table of translate mode guest");
                 break;
             }
 
@@ -2637,7 +2635,7 @@ long set_gdt(struct vcpu *v,
 
     /* Check the pages in the new GDT. */
     for ( i = 0; i < nr_pages; i++ ) {
-        pfn = frames[i];
+        pfn = frames[i] = __gpfn_to_mfn(d, frames[i]);
         if ((pfn >= max_page) ||
             !get_page_and_type(pfn_to_page(pfn), d, PGT_gdt_page) )
             goto fail;
@@ -2669,7 +2667,6 @@ long do_set_gdt(unsigned long *frame_list, unsigned int entries)
     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 )
@@ -2678,11 +2675,6 @@ long do_set_gdt(unsigned long *frame_list, unsigned int entries)
     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);
 
     if ( (ret = set_gdt(current, frames, entries)) == 0 )