From c8d0b4d1532edb92b642675227cc7e53cb5911a1 Mon Sep 17 00:00:00 2001 From: "sos22@douglas.cl.cam.ac.uk" Date: Thu, 26 Jan 2006 18:00:40 +0100 Subject: [PATCH] Make SMP guests work in shadow translate mode. Signed-off-by: Steven Smith, sos22@cam.ac.uk --- tools/libxc/xc_linux_build.c | 15 ++++++++++++--- xen/arch/x86/domain.c | 12 +++++++++++- xen/arch/x86/mm.c | 12 ++---------- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/tools/libxc/xc_linux_build.c b/tools/libxc/xc_linux_build.c index c0b0568811..ac0c734aab 100644 --- a/tools/libxc/xc_linux_build.c +++ b/tools/libxc/xc_linux_build.c @@ -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++) { diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 4fd39ad903..858586f769 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -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; } diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index 6ef37a7850..ff073176f1 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -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 ) -- 2.30.2