# HG changeset patch # User yamahata@xxxxxxxxxxxxx # Date 1179396611 -32400 # Node ID 55a3d398e30b6c2b49c233183357afb17bfa98d3 # Parent e9847aca3b9abe4d20cb04a07a151a25e9f87eb3 make libxc domain builder set up firmware instead of xen hyperviser. PATCHNAME: make_libxc_domain_builder_set_up_firmware Signed-off-by: Isaku Yamahata diff -r e9847aca3b9a -r 55a3d398e30b tools/libxc/ia64/Makefile --- a/tools/libxc/ia64/Makefile Fri Apr 06 19:18:16 2007 +0900 +++ b/tools/libxc/ia64/Makefile Thu May 17 19:10:11 2007 +0900 @@ -3,3 +3,46 @@ GUEST_SRCS-y += ia64/xc_ia64_hvm_build.c GUEST_SRCS-y += ia64/xc_ia64_hvm_build.c GUEST_SRCS-y += ia64/xc_ia64_linux_save.c GUEST_SRCS-y += ia64/xc_ia64_linux_restore.c + +GUEST_SRCS-y += ia64/xc_dom_ia64_util.c +DOMFW_SRCS_BASE := dom_fw_common.c dom_fw_domu.c dom_fw_asm.S +DOMFW_SRCS := $(addprefix ia64/, $(DOMFW_SRCS_BASE)) +$(DOMFW_SRCS): + ln -sf ../$(XEN_ROOT)/xen/arch/ia64/xen/$(@F) $@ + +# XXX kludge: libxc/Makefile doesn't understand .S. +GUEST_SRCS-y += $(patsubst %.S, %.c, $(DOMFW_SRCS)) +%.o: %.S + $(CC) $(CFLAGS) -c $< -o $@ +%.opic: %.S + $(CC) $(CPPFLAGS) -DPIC $(CFLAGS) -fPIC -c -o $@ $< + + +CFLAGS += -Iia64 + +DOMFW_ASM_HDRS_BASE := bundle.h dom_fw.h dom_fw_common.h dom_fw_domu.h +DOMFW_ASM_HDRS := $(addprefix ia64/asm/, $(DOMFW_ASM_HDRS_BASE)) +$(DOMFW_ASM_HDRS): ia64/asm + ln -sf ../../$(XEN_ROOT)/xen/include/asm-ia64/$(@F) $@ +build: $(DOMFW_ASM_HDR) + +.PHONY: mk-symlinks-acpi ia64-clean + +IA64_HDR_DIRS := ia64/asm ia64/xen ia64/acpi ia64/acpi/platform +$(IA64_HDR_DIRS): + mkdir -p $@ + +IA64_EMPTY_FILES := ia64/asm/acpi.h ia64/xen/list.h +$(IA64_EMPTY_FILES): $(IA64_HDR_DIRS) + echo "/* automatically created dummy empty header file. */" > $@ + +mk-symlinks-acpi: $(IA64_HDR_DIRS) $(IA64_EMPTY_FILES) $(DOMFW_ASM_HDRS) + ( cd ia64/acpi && ln -sf ../../$(XEN_ROOT)/xen/include/acpi/*.h .) + ( cd ia64/acpi/platform && ln -sf ../../../$(XEN_ROOT)/xen/include/acpi/platform/*.h .) + ( cd ia64/acpi/platform/ && ln -sf ../../aclinux.h .) + ( cd ia64/xen && ln -sf ../../$(XEN_ROOT)/xen/include/xen/acpi.h .) +build: mk-symlinks-acpi + +clean: ia64-clean +ia64-clean: + rm -rf $(DOMFW_SRCS) $(DOMFW_ASM_HDRS) $(IA64_EMPTY_FILES) $(IA64_HDR_DIRS) diff -r e9847aca3b9a -r 55a3d398e30b tools/libxc/ia64/xc_dom_ia64_util.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/libxc/ia64/xc_dom_ia64_util.c Thu May 17 19:10:11 2007 +0900 @@ -0,0 +1,174 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright (c) 2007 Isaku Yamahata + * VA Linux Systems Japan K.K. + * + */ + +#include "xg_private.h" +#include "xc_dom.h" +#include "asm/dom_fw.h" +#include "asm/dom_fw_common.h" +#include "ia64/xc_dom_ia64_util.h" + +uint32_t +xen_ia64_version(struct xc_dom_image *dom) +{ + return xc_version(dom->guest_xc, XENVER_version, NULL); +} + +int +xen_ia64_fpswa_revision(struct xc_dom_image *dom, unsigned int *revision) +{ + int ret = -1; + DECLARE_HYPERCALL; + hypercall.op = __HYPERVISOR_ia64_dom0vp_op; + hypercall.arg[0] = IA64_DOM0VP_fpswa_revision; + hypercall.arg[1] = (unsigned long)revision; + + if (lock_pages(revision, sizeof(*revision)) != 0) { + PERROR("Could not lock memory for xen fpswa hypercall"); + goto out; + } + + ret = do_xen_hypercall(dom->guest_xc, &hypercall); + + unlock_pages(revision, sizeof(*revision)); +out: + return ret; +} + +int xen_ia64_is_running_on_sim(struct xc_dom_image *dom) +{ + /* + * This is only used by dom_fw_init() as + * "!xen_ia64_is_dom0() || xen_ia64_is_running_on_sim()". + * So this doesn't affect the result. + */ + return 0; +} + +int +xen_ia64_is_dom0(struct xc_dom_image *unused) +{ + /* libxc is for non-dom0 domain builder */ + return 0; +} + +void* +xen_ia64_dom_fw_map(struct xc_dom_image *dom, unsigned long mpaddr) +{ + unsigned long page_size = XC_DOM_PAGE_SIZE(dom); + void* ret; + + ret = xc_map_foreign_range(dom->guest_xc, dom->guest_domid, + page_size, PROT_READ | PROT_WRITE, + mpaddr / page_size); + if (ret != NULL) + ret = (void*)((unsigned long)ret | (mpaddr & (page_size - 1))); + return ret; +} + +void +xen_ia64_dom_fw_unmap(struct xc_dom_image *dom, void *vaddr) +{ + unsigned long page_size = XC_DOM_PAGE_SIZE(dom); + munmap((void*)((unsigned long)vaddr & ~(page_size - 1)), page_size); +} + +int +xen_ia64_is_vcpu_allocated(struct xc_dom_image *dom, uint32_t vcpu) +{ + // return d->vcpu[vcpu] != NULL; + + int rc; + xc_vcpuinfo_t info; + + rc = xc_vcpu_getinfo(dom->guest_xc, dom->guest_domid, + vcpu, &info); + if (rc == 0) + return 1; + + if (rc != -ESRCH) + PERROR("Could not get vcpu info"); + return 0; +} + +int +xen_ia64_dom_fw_setup(struct xc_dom_image *d, uint64_t brkimm, + unsigned long bp_mpa, unsigned long maxmem) +{ + int rc = 0; + void *imva_hypercall_base = NULL; + void *imva_tables_base = NULL; + struct fake_acpi_tables *imva = NULL; + struct xen_ia64_boot_param *bp = NULL; + + BUILD_BUG_ON(sizeof(struct fw_tables) > + (FW_TABLES_END_PADDR - FW_TABLES_BASE_PADDR)); + + /* Create page for hypercalls. */ + imva_hypercall_base = xen_ia64_dom_fw_map(d, FW_HYPERCALL_BASE_PADDR); + if (imva_hypercall_base == NULL) { + rc = -errno; + goto out; + } + + /* Create page for FW tables. */ + imva_tables_base = xen_ia64_dom_fw_map(d, FW_TABLES_BASE_PADDR); + if (imva_tables_base == NULL) { + rc = -errno; + goto out; + } + + /* Create page for acpi tables. */ + imva = (struct fake_acpi_tables *) + xen_ia64_dom_fw_map(d, FW_ACPI_BASE_PADDR); + if (imva == NULL) { + rc = -errno; + goto out; + } + dom_fw_fake_acpi(d, imva); + + /* Create page for boot_param. */ + bp = xen_ia64_dom_fw_map(d, bp_mpa); + if (bp == NULL) { + rc = -errno; + goto out; + } + rc = dom_fw_init(d, brkimm, bp, imva_tables_base, + (unsigned long)imva_hypercall_base, maxmem); + out: + if (imva_hypercall_base != NULL) + xen_ia64_dom_fw_unmap(d, imva_hypercall_base); + if (imva_tables_base != NULL) + xen_ia64_dom_fw_unmap(d, imva_tables_base); + if (imva != NULL) + xen_ia64_dom_fw_unmap(d, imva); + if (bp != NULL) + xen_ia64_dom_fw_unmap(d, bp); + return rc; +} + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff -r e9847aca3b9a -r 55a3d398e30b tools/libxc/ia64/xc_dom_ia64_util.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/libxc/ia64/xc_dom_ia64_util.h Thu May 17 19:10:11 2007 +0900 @@ -0,0 +1,19 @@ +#ifndef XC_IA64_DOM_IA64_UTIL_H +#define XC_IA64_DOM_IA64_UTIL_H + +struct xc_dom_image; +uint32_t xen_ia64_version(struct xc_dom_image *dom); +void* xen_ia64_dom_fw_map(struct xc_dom_image *dom, unsigned long mpaddr); +void xen_ia64_dom_fw_unmap(struct xc_dom_image *dom, void *addr); +int xen_ia64_fpswa_revision(struct xc_dom_image *dom, unsigned int *revision); +int xen_ia64_is_vcpu_allocated(struct xc_dom_image *dom, uint32_t vcpu); +int xen_ia64_is_running_on_sim(struct xc_dom_image *dom); +int xen_ia64_is_dom0(struct xc_dom_image *dom); + +int +xen_ia64_dom_fw_setup(struct xc_dom_image *d, uint64_t brkimm, + unsigned long bp_mpa, unsigned long maxmem); +#define efi_systable_init_dom0(tables) assert(0) +#define complete_dom0_memmap(d, tables, maxmem, num_mds) ({assert(0);0;}) + +#endif /* XC_IA64_DOM_IA64_UTIL_H */ diff -r e9847aca3b9a -r 55a3d398e30b tools/libxc/xc_dom_ia64.c --- a/tools/libxc/xc_dom_ia64.c Fri Apr 06 19:18:16 2007 +0900 +++ b/tools/libxc/xc_dom_ia64.c Thu May 17 19:10:11 2007 +0900 @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -19,6 +20,9 @@ #include "xg_private.h" #include "xc_dom.h" #include "xenctrl.h" + +#include +#include "ia64/xc_dom_ia64_util.h" /* ------------------------------------------------------------------------ */ @@ -48,6 +52,13 @@ static int start_info_ia64(struct xc_dom start_info->store_evtchn = dom->xenstore_evtchn; start_info->console.domU.mfn = dom->console_pfn; start_info->console.domU.evtchn = dom->console_evtchn; + + /* + * domain_start and domain_size are abused for arch_setup hypercall + * so that we need to clear them here. + */ + XEN_IA64_MEMMAP_INFO_NUM_PAGES(bp) = 0; + XEN_IA64_MEMMAP_INFO_PFN(bp) = 0; if ( dom->ramdisk_blob ) { @@ -77,7 +88,7 @@ static int shared_info_ia64(struct xc_do for (i = 0; i < MAX_VIRT_CPUS; i++) shared_info->vcpu_info[i].evtchn_upcall_mask = 1; shared_info->arch.start_info_pfn = dom->start_info_pfn; - shared_info->arch.memmap_info_num_pages = 1; + shared_info->arch.memmap_info_num_pages = 1; //XXX shared_info->arch.memmap_info_pfn = dom->start_info_pfn - 1; return 0; } @@ -153,6 +164,7 @@ static int ia64_setup_memmap(struct xc_d static int ia64_setup_memmap(struct xc_dom_image *dom) { unsigned int page_size = XC_DOM_PAGE_SIZE(dom); + unsigned long memmap_info_num_pages; unsigned long memmap_info_pfn; xen_ia64_memmap_info_t* memmap_info; unsigned int num_mds; @@ -162,11 +174,12 @@ static int ia64_setup_memmap(struct xc_d struct xen_ia64_boot_param* bp; /* setup memmap page */ + memmap_info_num_pages = 1; memmap_info_pfn = dom->start_info_pfn - 1; - xc_dom_printf("%s: memmap: mfn 0x%" PRIpfn "\n", - __FUNCTION__, memmap_info_pfn); + xc_dom_printf("%s: memmap: mfn 0x%" PRIpfn " pages 0x%lx\n", + __FUNCTION__, memmap_info_pfn, memmap_info_num_pages); memmap_info = xc_map_foreign_range(dom->guest_xc, dom->guest_domid, - page_size, + page_size * memmap_info_num_pages, PROT_READ | PROT_WRITE, memmap_info_pfn); if (NULL == memmap_info) @@ -184,10 +197,17 @@ static int ia64_setup_memmap(struct xc_d md[num_mds].attribute = EFI_MEMORY_WB; num_mds++; memmap_info->efi_memmap_size = num_mds * sizeof(md[0]); - munmap(memmap_info, page_size); - - /* kludge: we need to pass memmap_info page's pfn somehow. - * we use xen_ia64_boot_param::efi_memmap for this purpose */ + munmap(memmap_info, page_size * memmap_info_num_pages); + assert(nr_mds <= + (page_size * memmap_info_num_pages - + offsetof(*memmap_info, memdesc))/sizeof(*md)); + + /* + * kludge: we need to pass memmap_info page's pfn and other magic pages + * somehow. + * we use xen_ia64_boot_param::efi_memmap::{efi_memmap, efi_memmap_size} + * for this purpose + */ start_info = xc_map_foreign_range(dom->guest_xc, dom->guest_domid, page_size, PROT_READ | PROT_WRITE, @@ -196,9 +216,8 @@ static int ia64_setup_memmap(struct xc_d return -1; bp = (struct xen_ia64_boot_param*)(start_info + sizeof(start_info_t)); memset(bp, 0, sizeof(*bp)); - bp->efi_memmap = memmap_info_pfn; - /* 4 = memmap info page, start info page, xenstore page and console page */ - bp->efi_memmap_size = 4 * PAGE_SIZE; + XEN_IA64_MEMMAP_INFO_NUM_PAGES(bp) = memmap_info_num_pages; + XEN_IA64_MEMMAP_INFO_PFN(bp) = memmap_info_pfn; munmap(start_info, page_size); return 0; } @@ -211,6 +230,20 @@ int arch_setup_bootearly(struct xc_dom_i xc_dom_printf("%s: setup firmware\n", __FUNCTION__); rc = ia64_setup_memmap(dom); + if (rc) + return rc; + + memset(&domctl, 0, sizeof(domctl)); + domctl.cmd = XEN_DOMCTL_arch_setup; + domctl.domain = dom->guest_domid; + domctl.u.arch_setup.flags = XEN_DOMAINSETUP_query; + rc = do_domctl(dom->guest_xc, &domctl); + if (rc) + return rc; + rc = xen_ia64_dom_fw_setup(dom, domctl.u.arch_setup.hypercall_imm, + (dom->start_info_pfn << PAGE_SHIFT) + + sizeof(start_info_t), + dom->total_pages << PAGE_SHIFT); if (rc) return rc;