[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v2 22/23] vixen: dom0 builder support
From: Anthony Liguori <aliguori@xxxxxxxxxx> The dom0 builder requires a number of modifications in order to be able to launch unprivileged guests. The console and store pages must be mapped in a specific location within the guest's initial page table. We also have to setup the start info to be what's expected for unprivileged guests and supress the normal logic to give dom0 increased permissions. We have to pass around the console and store pages which involves touching a number of places including the PVH builder. Signed-off-by: Anthony Liguori <aliguori@xxxxxxxxxx> --- v1 -> v2 - panic in the event of errors --- xen/arch/x86/dom0_build.c | 7 +++- xen/arch/x86/guest/vixen.c | 64 +++++++++++++++++++++++++++++++- xen/arch/x86/hvm/dom0_build.c | 4 +- xen/arch/x86/pv/dom0_build.c | 77 ++++++++++++++++++++++++++++++++++----- xen/arch/x86/setup.c | 12 +++++- xen/include/asm-x86/dom0_build.h | 8 +++- xen/include/asm-x86/guest/vixen.h | 5 ++- xen/include/asm-x86/setup.h | 4 +- 8 files changed, 161 insertions(+), 20 deletions(-) diff --git a/xen/arch/x86/dom0_build.c b/xen/arch/x86/dom0_build.c index 88810db..df9d3f8 100644 --- a/xen/arch/x86/dom0_build.c +++ b/xen/arch/x86/dom0_build.c @@ -464,7 +464,9 @@ int __init dom0_setup_permissions(struct domain *d) int __init construct_dom0(struct domain *d, const module_t *image, unsigned long image_headroom, module_t *initrd, void *(*bootstrap_map)(const module_t *), - char *cmdline) + char *cmdline, + xen_pfn_t store_mfn, uint32_t store_evtchn, + xen_pfn_t console_mfn, uint32_t console_evtchn) { int rc; @@ -484,7 +486,8 @@ int __init construct_dom0(struct domain *d, const module_t *image, #endif rc = (is_hvm_domain(d) ? dom0_construct_pvh : dom0_construct_pv) - (d, image, image_headroom, initrd, bootstrap_map, cmdline); + (d, image, image_headroom, initrd, bootstrap_map, cmdline, + store_mfn, store_evtchn, console_mfn, console_evtchn); if ( rc ) return rc; diff --git a/xen/arch/x86/guest/vixen.c b/xen/arch/x86/guest/vixen.c index d871218..7e367ef 100644 --- a/xen/arch/x86/guest/vixen.c +++ b/xen/arch/x86/guest/vixen.c @@ -345,6 +345,23 @@ bool vixen_ring_process(uint16_t port) return true; } +static int hvm_get_parameter(int idx, uint64_t *value) +{ + struct xen_hvm_param xhv; + int r; + + xhv.domid = DOMID_SELF; + xhv.index = idx; + r = HYPERVISOR_hvm_op(HVMOP_get_param, &xhv); + if (r < 0) { + printk("Cannot get hvm parameter %d: %d!\n", + idx, r); + return r; + } + *value = xhv.value; + return r; +} + static int hvm_set_parameter(int idx, uint64_t value) { struct xen_hvm_param xhv; @@ -468,10 +485,55 @@ bool vixen_has_per_cpu_notifications(void) } void __init -vixen_transform(struct domain *dom0) +vixen_transform(struct domain *dom0, + xen_pfn_t *pstore_mfn, uint32_t *pstore_evtchn, + xen_pfn_t *pconsole_mfn, uint32_t *pconsole_evtchn) { struct xen_add_to_physmap xatp; int i; + uint64_t v = 0; + long rc; + struct evtchn_unmask unmask; + struct evtchn_alloc_unbound alloc; + + /* Setup Xenstore */ + hvm_get_parameter(HVM_PARAM_STORE_EVTCHN, &v); + *pstore_evtchn = unmask.port = v; + HYPERVISOR_event_channel_op(EVTCHNOP_unmask, &unmask); + + hvm_get_parameter(HVM_PARAM_STORE_PFN, &v); + *pstore_mfn = v; + + printk("Vixen Xenstore evtchn is %d, pfn is 0x%" PRIx64 "\n", + *pstore_evtchn, *pstore_mfn); + + /* Setup Xencons */ + alloc.dom = DOMID_SELF; + alloc.remote_dom = DOMID_SELF; + + rc = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &alloc); + if ( rc ) + { + printk("Failed to alloc unbound event channel: %ld\n", rc); + *pconsole_evtchn = 0; + *pconsole_mfn = 0; + } + else + { + void *console_data; + + console_data = alloc_xenheap_page(); + + *pconsole_evtchn = alloc.port; + *pconsole_mfn = virt_to_mfn(console_data); + + memset(console_data, 0, 4096); + vixen_xencons_iface = console_data; + vixen_xencons_port = alloc.port; + } + + printk("Vixen Xencons evtchn is %d, pfn is 0x%" PRIx64 "\n", + *pconsole_evtchn, *pconsole_mfn); /* Setup event channel forwarding */ alloc_direct_apic_vector(&vixen_evtchn_vector, vixen_evtchn_notify); diff --git a/xen/arch/x86/hvm/dom0_build.c b/xen/arch/x86/hvm/dom0_build.c index 4338965..b2ca64f 100644 --- a/xen/arch/x86/hvm/dom0_build.c +++ b/xen/arch/x86/hvm/dom0_build.c @@ -1064,7 +1064,9 @@ int __init dom0_construct_pvh(struct domain *d, const module_t *image, unsigned long image_headroom, module_t *initrd, void *(*bootstrap_map)(const module_t *), - char *cmdline) + char *cmdline, + xen_pfn_t store_mfn, uint32_t store_evtchn, + xen_pfn_t console_mfn, uint32_t console_evtchn) { paddr_t entry, start_info; int rc; diff --git a/xen/arch/x86/pv/dom0_build.c b/xen/arch/x86/pv/dom0_build.c index 09c765a..a554629 100644 --- a/xen/arch/x86/pv/dom0_build.c +++ b/xen/arch/x86/pv/dom0_build.c @@ -7,6 +7,7 @@ #include <xen/console.h> #include <xen/domain.h> #include <xen/domain_page.h> +#include <xen/event.h> #include <xen/init.h> #include <xen/libelf.h> #include <xen/multiboot.h> @@ -276,7 +277,9 @@ int __init dom0_construct_pv(struct domain *d, unsigned long image_headroom, module_t *initrd, void *(*bootstrap_map)(const module_t *), - char *cmdline) + char *cmdline, + xen_pfn_t store_mfn, uint32_t store_evtchn, + xen_pfn_t console_mfn, uint32_t console_evtchn) { int i, cpu, rc, compatible, compat32, order, machine; struct cpu_user_regs *regs; @@ -299,6 +302,7 @@ int __init dom0_construct_pv(struct domain *d, l3_pgentry_t *l3tab = NULL, *l3start = NULL; l2_pgentry_t *l2tab = NULL, *l2start = NULL; l1_pgentry_t *l1tab = NULL, *l1start = NULL; + xen_pfn_t saved_pfn = ~0UL; /* * This fully describes the memory layout of the initial domain. All @@ -441,8 +445,24 @@ int __init dom0_construct_pv(struct domain *d, vphysmap_end = vphysmap_start; vstartinfo_start = round_pgup(vphysmap_end); vstartinfo_end = (vstartinfo_start + - sizeof(struct start_info) + - sizeof(struct dom0_vga_console_info)); + sizeof(struct start_info)); + if ( !is_vixen() ) + vstartinfo_end += sizeof(struct dom0_vga_console_info); + vstartinfo_end = round_pgup(vstartinfo_end); + + if ( is_vixen() ) { + struct page_info *pg; + + saved_pfn = (vstartinfo_end - v_start) / PAGE_SIZE; + + pg = mfn_to_page(store_mfn); + share_xen_page_with_guest(pg, d, XENSHARE_writable); + vstartinfo_end += PAGE_SIZE; + + pg = mfn_to_page(console_mfn); + share_xen_page_with_guest(pg, d, XENSHARE_writable); + vstartinfo_end += PAGE_SIZE; + } vpt_start = round_pgup(vstartinfo_end); for ( nr_pt_pages = 2; ; nr_pt_pages++ ) @@ -634,7 +654,13 @@ int __init dom0_construct_pv(struct domain *d, *l2tab = l2e_from_paddr(__pa(l1start), L2_PROT); l2tab++; } - if ( count < initrd_pfn || count >= initrd_pfn + PFN_UP(initrd_len) ) + if ( count == saved_pfn ) { + mfn = store_mfn; + pfn++; + } else if ( count == saved_pfn + 1 ) { + mfn = console_mfn; + pfn++; + } else if ( count < initrd_pfn || count >= initrd_pfn + PFN_UP(initrd_len) ) mfn = pfn++; else mfn = initrd_mfn++; @@ -737,7 +763,8 @@ int __init dom0_construct_pv(struct domain *d, si->shared_info = virt_to_maddr(d->shared_info); - si->flags = SIF_PRIVILEGED | SIF_INITDOMAIN; + si->flags = is_vixen() ? 0 : (SIF_PRIVILEGED | SIF_INITDOMAIN); + if ( !vinitrd_start && initrd_len ) si->flags |= SIF_MOD_START_PFN; si->flags |= (xen_processor_pmbits << 8) & SIF_PM_MASK; @@ -818,6 +845,30 @@ int __init dom0_construct_pv(struct domain *d, } } + if ( is_vixen() ) + { + dom0_update_physmap(d, saved_pfn, store_mfn, vphysmap_start); + dom0_update_physmap(d, saved_pfn + 1, console_mfn, vphysmap_start); + + rc = evtchn_alloc_proxy(d, store_evtchn, ECS_INTERDOMAIN); + if ( rc ) + { + panic("Vixen: failed to reserve Xenstore event channel %d => %d\n", + store_evtchn, rc); + } + rc = evtchn_alloc_proxy(d, console_evtchn, ECS_INTERDOMAIN); + if ( rc ) + { + panic("Vixen: failed to reserve Console event channel %d => %d\n", + console_evtchn, rc); + } + + si->store_mfn = store_mfn; + si->store_evtchn = store_evtchn; + si->console.domU.mfn = console_mfn; + si->console.domU.evtchn = console_evtchn; + } + if ( initrd_len != 0 ) { si->mod_start = vinitrd_start ?: initrd_pfn; @@ -828,14 +879,15 @@ int __init dom0_construct_pv(struct domain *d, if ( cmdline != NULL ) strlcpy((char *)si->cmd_line, cmdline, sizeof(si->cmd_line)); - if ( fill_console_start_info((void *)(si + 1)) ) + if ( !is_vixen() && fill_console_start_info((void *)(si + 1)) ) { si->console.dom0.info_off = sizeof(struct start_info); si->console.dom0.info_size = sizeof(struct dom0_vga_console_info); } if ( is_pv_32bit_domain(d) ) - xlat_start_info(si, XLAT_start_info_console_dom0); + xlat_start_info(si, is_vixen() ? XLAT_start_info_console_domU : + XLAT_start_info_console_dom0); /* Return to idle domain's page tables. */ mapcache_override_current(NULL); @@ -873,9 +925,11 @@ int __init dom0_construct_pv(struct domain *d, if ( test_bit(XENFEAT_supervisor_mode_kernel, parms.f_required) ) panic("Dom0 requires supervisor-mode execution"); - rc = dom0_setup_permissions(d); - BUG_ON(rc != 0); - + if ( !is_vixen() ) + { + rc = dom0_setup_permissions(d); + BUG_ON(rc != 0); + } if ( elf_check_broken(&elf) ) printk(" Xen warning: dom0 kernel broken ELF: %s\n", elf_check_broken(&elf)); @@ -886,6 +940,9 @@ int __init dom0_construct_pv(struct domain *d, v->is_initialised = 1; clear_bit(_VPF_down, &v->pause_flags); + if ( is_vixen() ) + d->max_pages = d->tot_pages; + return 0; out: diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index 1b89844..c49eeea 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -663,6 +663,8 @@ void __init noreturn __start_xen(unsigned long mbi_p) .stop_bits = 1 }; struct xen_arch_domainconfig config = { .emulation_flags = 0 }; + xen_pfn_t store_mfn = 0, console_mfn = 0; + uint32_t store_evtchn = 0, console_evtchn = 0; /* Critical region without IDT or TSS. Any fault is deadly! */ @@ -1595,6 +1597,9 @@ void __init noreturn __start_xen(unsigned long mbi_p) config.emulation_flags = XEN_X86_EMU_LAPIC|XEN_X86_EMU_IOAPIC; } + if ( is_vixen() ) + config.emulation_flags = XEN_X86_EMU_PIT; + /* Create initial domain 0. */ dom0 = domain_create(dom0_domid, domcr_flags, 0, &config); if ( IS_ERR(dom0) || (alloc_dom0_vcpu0(dom0) == NULL) ) @@ -1604,7 +1609,8 @@ void __init noreturn __start_xen(unsigned long mbi_p) dom0->target = NULL; if ( is_vixen() ) - vixen_transform(dom0); + vixen_transform(dom0, &store_mfn, &store_evtchn, + &console_mfn, &console_evtchn); /* Grab the DOM0 command line. */ cmdline = (char *)(mod[0].string ? __va(mod[0].string) : NULL); @@ -1667,7 +1673,9 @@ void __init noreturn __start_xen(unsigned long mbi_p) if ( construct_dom0(dom0, mod, modules_headroom, (initrdidx > 0) && (initrdidx < mbi->mods_count) ? mod + initrdidx : NULL, - bootstrap_map, cmdline) != 0) + bootstrap_map, cmdline, + store_mfn, store_evtchn, + console_mfn, console_evtchn) != 0) panic("Could not set up DOM0 guest OS"); if ( cpu_has_smap ) diff --git a/xen/include/asm-x86/dom0_build.h b/xen/include/asm-x86/dom0_build.h index d83d2b4..459211c 100644 --- a/xen/include/asm-x86/dom0_build.h +++ b/xen/include/asm-x86/dom0_build.h @@ -18,13 +18,17 @@ int dom0_construct_pv(struct domain *d, const module_t *image, unsigned long image_headroom, module_t *initrd, void *(*bootstrap_map)(const module_t *), - char *cmdline); + char *cmdline, + xen_pfn_t store_mfn, uint32_t store_evtchn, + xen_pfn_t console_mfn, uint32_t console_evtchn); int dom0_construct_pvh(struct domain *d, const module_t *image, unsigned long image_headroom, module_t *initrd, void *(*bootstrap_map)(const module_t *), - char *cmdline); + char *cmdline, + xen_pfn_t store_mfn, uint32_t store_evtchn, + xen_pfn_t console_mfn, uint32_t console_evtchn); unsigned long dom0_paging_pages(const struct domain *d, unsigned long nr_pages); diff --git a/xen/include/asm-x86/guest/vixen.h b/xen/include/asm-x86/guest/vixen.h index 4b59cc7..851281d 100644 --- a/xen/include/asm-x86/guest/vixen.h +++ b/xen/include/asm-x86/guest/vixen.h @@ -86,7 +86,10 @@ bool vixen_has_per_cpu_notifications(void); void vixen_vcpu_initialize(struct vcpu *v); -void __init vixen_transform(struct domain *dom0); +void __init +vixen_transform(struct domain *dom0, + xen_pfn_t *pstore_mfn, uint32_t *pstore_evtchn, + xen_pfn_t *pconsole_mfn, uint32_t *pconsole_evtchn); bool vixen_ring_process(uint16_t port); diff --git a/xen/include/asm-x86/setup.h b/xen/include/asm-x86/setup.h index c5b3d4e..51b207b 100644 --- a/xen/include/asm-x86/setup.h +++ b/xen/include/asm-x86/setup.h @@ -39,7 +39,9 @@ int construct_dom0( const module_t *kernel, unsigned long kernel_headroom, module_t *initrd, void *(*bootstrap_map)(const module_t *), - char *cmdline); + char *cmdline, + xen_pfn_t store_mfn, uint32_t store_evtchn, + xen_pfn_t console_mfn, uint32_t console_evtchn); void setup_io_bitmap(struct domain *d); unsigned long initial_images_nrpages(nodeid_t node); -- 1.9.1 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |