From patchwork Mon Jun 16 11:45:00 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Campbell X-Patchwork-Id: 31953 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-yk0-f198.google.com (mail-yk0-f198.google.com [209.85.160.198]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 6931B206A0 for ; Mon, 16 Jun 2014 11:46:46 +0000 (UTC) Received: by mail-yk0-f198.google.com with SMTP id 9sf14673051ykp.5 for ; Mon, 16 Jun 2014 04:46:46 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:date:message-id:in-reply-to :references:mime-version:cc:subject:precedence:list-id :list-unsubscribe:list-post:list-help:list-subscribe:sender :errors-to:x-original-sender:x-original-authentication-results :mailing-list:list-archive:content-type:content-transfer-encoding; bh=gjBrMi3Ce1NBOqj4cNqe1+ur+eVCazAbvfC55Skt3aY=; b=lToBaPqaVNI7PIHOBxiWZrW+6VLAs+oWKFTKfvGI+wUdyOb6AbKST+s9dt4YyiY/sc dhDVKccc5aWCbKSKrIdDfKPsk9VnqAAnLa2FAWje05uSDACH+oPbRsQXAx4AgfEH/uHZ egPwtDZyr03dfu/DH54V6Oe1Gur3NVJJm71NpFuJAv3AUHBOVSaPc7ok3P8rcLi8iMtx 3cNgTF3oXixFY7JnbLhpDMBsSK/IeQaJWePwiWmPk/dZwRrC+e0cq7JNPnxQo0L9zMin D79sN4qtVZQxfaYV55Ro+qUps/Gxp73XvpgZbUk5txn4D3Q8iMTd0+s/sY76RNOdCE+A 17vQ== X-Gm-Message-State: ALoCoQk6hPf9Z0cDL1ARmqx140vZyescLIqYdCcm33TEwt5OuZiWuDoHZCVlJ00zq+kl9kTejHU5 X-Received: by 10.58.69.78 with SMTP id c14mr1270862veu.41.1402919206196; Mon, 16 Jun 2014 04:46:46 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.88.80 with SMTP id s74ls71919qgd.50.gmail; Mon, 16 Jun 2014 04:46:46 -0700 (PDT) X-Received: by 10.58.32.135 with SMTP id j7mr154878vei.55.1402919205974; Mon, 16 Jun 2014 04:46:45 -0700 (PDT) Received: from mail-ve0-f174.google.com (mail-ve0-f174.google.com [209.85.128.174]) by mx.google.com with ESMTPS id ao15si1903301vdc.104.2014.06.16.04.46.45 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 16 Jun 2014 04:46:45 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.128.174 as permitted sender) client-ip=209.85.128.174; Received: by mail-ve0-f174.google.com with SMTP id jx11so3108203veb.19 for ; Mon, 16 Jun 2014 04:46:45 -0700 (PDT) X-Received: by 10.58.178.2 with SMTP id cu2mr117721vec.70.1402919205857; Mon, 16 Jun 2014 04:46:45 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.221.54.6 with SMTP id vs6csp128507vcb; Mon, 16 Jun 2014 04:46:45 -0700 (PDT) X-Received: by 10.51.17.66 with SMTP id gc2mr25032309igd.5.1402919205231; Mon, 16 Jun 2014 04:46:45 -0700 (PDT) Received: from lists.xen.org (lists.xen.org. [50.57.142.19]) by mx.google.com with ESMTPS id bc6si10893316igb.0.2014.06.16.04.46.44 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Mon, 16 Jun 2014 04:46:45 -0700 (PDT) Received-SPF: none (google.com: xen-devel-bounces@lists.xen.org does not designate permitted sender hosts) client-ip=50.57.142.19; Received: from localhost ([127.0.0.1] helo=lists.xen.org) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1WwVLh-0003TT-1q; Mon, 16 Jun 2014 11:45:17 +0000 Received: from mail6.bemta5.messagelabs.com ([195.245.231.135]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1WwVLb-0003Mx-3b for xen-devel@lists.xen.org; Mon, 16 Jun 2014 11:45:11 +0000 Received: from [85.158.139.211:16751] by server-12.bemta-5.messagelabs.com id 4E/12-27841-5C8DE935; Mon, 16 Jun 2014 11:45:09 +0000 X-Env-Sender: Ian.Campbell@citrix.com X-Msg-Ref: server-6.tower-206.messagelabs.com!1402919104!10179946!4 X-Originating-IP: [66.165.176.63] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: VHJ1c3RlZCBJUDogNjYuMTY1LjE3Ni42MyA9PiAzMDYwNDg=\n X-StarScan-Received: X-StarScan-Version: 6.11.3; banners=-,-,- X-VirusChecked: Checked Received: (qmail 5602 invoked from network); 16 Jun 2014 11:45:09 -0000 Received: from smtp02.citrix.com (HELO SMTP02.CITRIX.COM) (66.165.176.63) by server-6.tower-206.messagelabs.com with RC4-SHA encrypted SMTP; 16 Jun 2014 11:45:09 -0000 X-IronPort-AV: E=Sophos;i="5.01,486,1400025600"; d="scan'208";a="143697247" Received: from accessns.citrite.net (HELO FTLPEX01CL02.citrite.net) ([10.9.154.239]) by FTLPIPO02.CITRIX.COM with ESMTP; 16 Jun 2014 11:45:04 +0000 Received: from ukmail1.uk.xensource.com (10.80.16.128) by smtprelay.citrix.com (10.13.107.79) with Microsoft SMTP Server id 14.3.181.6; Mon, 16 Jun 2014 07:45:04 -0400 Received: from marilith-n13-p0.uk.xensource.com ([10.80.229.115] helo=marilith-n13.uk.xensource.com.) by ukmail1.uk.xensource.com with esmtp (Exim 4.69) (envelope-from ) id 1WwVLU-000152-16; Mon, 16 Jun 2014 12:45:04 +0100 From: Ian Campbell To: Date: Mon, 16 Jun 2014 12:45:00 +0100 Message-ID: <1402919103-29642-7-git-send-email-ian.campbell@citrix.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1402919079.14907.22.camel@kazak.uk.xensource.com> References: <1402919079.14907.22.camel@kazak.uk.xensource.com> MIME-Version: 1.0 X-DLP: MIA1 Cc: Ian Campbell , stefano.stabellini@eu.citrix.com, Naresh Bhat , julien.grall@linaro.org, tim@xen.org, Roy Franz , Fu Wei Subject: [Xen-devel] [PATCH 07/10] xen: arm: store per-boot module type instead of relying on index X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: List-Unsubscribe: , List-Post: , List-Help: , List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: ian.campbell@citrix.com X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.128.174 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Archive: This is more natural and better matches how multiboot is actually supposed to work. Signed-off-by: Ian Campbell --- xen/arch/arm/bootfdt.c | 49 +++++++++++++++---------------------------- xen/arch/arm/domain_build.c | 20 +++++++++++------- xen/arch/arm/kernel.c | 15 ++++++------- xen/arch/arm/setup.c | 47 ++++++++++++++++++++++++++++++++++++----- xen/include/asm-arm/setup.h | 29 +++++++++++++++++-------- 5 files changed, 100 insertions(+), 60 deletions(-) diff --git a/xen/arch/arm/bootfdt.c b/xen/arch/arm/bootfdt.c index e48a64b..e983aa7 100644 --- a/xen/arch/arm/bootfdt.c +++ b/xen/arch/arm/bootfdt.c @@ -165,23 +165,22 @@ static void __init process_multiboot_node(const void *fdt, int node, { const struct fdt_property *prop; const __be32 *cell; - int nr; - struct bootmodule *mod; + bootmodulekind kind; + paddr_t start, size; + const char *cmdline; int len; if ( fdt_node_check_compatible(fdt, node, "xen,linux-zimage") == 0 || fdt_node_check_compatible(fdt, node, "multiboot,kernel") == 0 ) - nr = MOD_KERNEL; + kind = BOOTMOD_KERNEL; else if ( fdt_node_check_compatible(fdt, node, "xen,linux-initrd") == 0 || fdt_node_check_compatible(fdt, node, "multiboot,ramdisk") == 0 ) - nr = MOD_INITRD; + kind = BOOTMOD_RAMDISK; else if ( fdt_node_check_compatible(fdt, node, "xen,xsm-policy") == 0 ) - nr = MOD_XSM; + kind = BOOTMOD_XSM; else panic("%s not a known xen multiboot type\n", name); - mod = &bootinfo.modules.module[nr]; - prop = fdt_get_property(fdt, node, "reg", &len); if ( !prop ) panic("node %s missing `reg' property\n", name); @@ -191,22 +190,19 @@ static void __init process_multiboot_node(const void *fdt, int node, name); cell = (const __be32 *)prop->data; - device_tree_get_reg(&cell, address_cells, size_cells, - &mod->start, &mod->size); + device_tree_get_reg(&cell, address_cells, size_cells, &start, &size); prop = fdt_get_property(fdt, node, "bootargs", &len); if ( prop ) { - if ( len > sizeof(mod->cmdline) ) - panic("module %d command line too long\n", nr); - - safe_strcpy(mod->cmdline, prop->data); + if ( len > BOOTMOD_MAX_CMDLINE ) + panic("module %s command line too long\n", name); + cmdline = prop->data; } else - mod->cmdline[0] = 0; + cmdline = NULL; - if ( nr > bootinfo.modules.nr_mods ) - bootinfo.modules.nr_mods = nr; + add_boot_module(kind, start, size, cmdline); } static void __init process_chosen_node(const void *fdt, int node, @@ -214,7 +210,6 @@ static void __init process_chosen_node(const void *fdt, int node, u32 address_cells, u32 size_cells) { const struct fdt_property *prop; - struct bootmodule *mod = &bootinfo.modules.module[MOD_INITRD]; paddr_t start, end; int len; @@ -253,10 +248,7 @@ static void __init process_chosen_node(const void *fdt, int node, printk("Initrd %"PRIpaddr"-%"PRIpaddr"\n", start, end); - mod->start = start; - mod->size = end - start; - - bootinfo.modules.nr_mods = max(MOD_INITRD, bootinfo.modules.nr_mods); + add_boot_module(BOOTMOD_RAMDISK, start, end-start, NULL); } static int __init early_scan_node(const void *fdt, @@ -286,7 +278,7 @@ static void __init early_print_info(void) mi->bank[i].start, mi->bank[i].start + mi->bank[i].size - 1); printk("\n"); - for ( i = 1 ; i < mods->nr_mods + 1; i++ ) + for ( i = 1 ; i < mods->nr_mods; i++ ) printk("MODULE[%d]: %"PRIpaddr" - %"PRIpaddr" %s\n", i, mods->module[i].start, @@ -314,18 +306,13 @@ static void __init early_print_info(void) */ size_t __init boot_fdt_info(const void *fdt, paddr_t paddr) { - struct bootmodule *mod; int ret; ret = fdt_check_header(fdt); if ( ret < 0 ) panic("No valid device tree\n"); - mod = &bootinfo.modules.module[MOD_FDT]; - mod->start = paddr; - mod->size = fdt_totalsize(fdt); - - bootinfo.modules.nr_mods = max(MOD_FDT, bootinfo.modules.nr_mods); + add_boot_module(BOOTMOD_FDT, paddr, fdt_totalsize(fdt), NULL); device_tree_for_each_node((void *)fdt, early_scan_node, NULL); early_print_info(); @@ -345,10 +332,8 @@ const char *boot_fdt_cmdline(const void *fdt) prop = fdt_get_property(fdt, node, "xen,xen-bootargs", NULL); if ( prop == NULL ) { - struct bootmodule *dom0_mod = NULL; - - if ( bootinfo.modules.nr_mods >= MOD_KERNEL ) - dom0_mod = &bootinfo.modules.module[MOD_KERNEL]; + struct bootmodule *dom0_mod = + boot_module_find_by_kind(BOOTMOD_KERNEL); if (fdt_get_property(fdt, node, "xen,dom0-bootargs", NULL) || ( dom0_mod && dom0_mod->cmdline[0] ) ) diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c index 5eef8a3..c1a54e5 100644 --- a/xen/arch/arm/domain_build.c +++ b/xen/arch/arm/domain_build.c @@ -161,9 +161,10 @@ static int write_properties(struct domain *d, struct kernel_info *kinfo, int res = 0; int had_dom0_bootargs = 0; - if ( bootinfo.modules.nr_mods >= MOD_KERNEL && - bootinfo.modules.module[MOD_KERNEL].cmdline[0] ) - bootargs = &bootinfo.modules.module[MOD_KERNEL].cmdline[0]; + struct bootmodule *mod = boot_module_find_by_kind(BOOTMOD_KERNEL); + + if ( mod && mod->cmdline[0] ) + bootargs = &mod->cmdline[0]; dt_for_each_property_node (node, prop) { @@ -210,6 +211,8 @@ static int write_properties(struct domain *d, struct kernel_info *kinfo, if ( dt_node_path_is_equal(node, "/chosen") ) { + struct bootmodule *mod = boot_module_find_by_kind(BOOTMOD_RAMDISK); + if ( bootargs ) { res = fdt_property(kinfo->fdt, "bootargs", bootargs, @@ -222,7 +225,7 @@ static int write_properties(struct domain *d, struct kernel_info *kinfo, * If the bootloader provides an initrd, we must create a placeholder * for the initrd properties. The values will be replaced later. */ - if ( bootinfo.modules.module[MOD_INITRD].size ) + if ( mod && mod->size ) { u64 a = 0; res = fdt_property(kinfo->fdt, "linux,initrd-start", &a, sizeof(a)); @@ -976,18 +979,21 @@ static void dtb_load(struct kernel_info *kinfo) static void initrd_load(struct kernel_info *kinfo) { + struct bootmodule *mod = boot_module_find_by_kind(BOOTMOD_RAMDISK); paddr_t load_addr = kinfo->initrd_paddr; - paddr_t paddr = bootinfo.modules.module[MOD_INITRD].start; - paddr_t len = bootinfo.modules.module[MOD_INITRD].size; + paddr_t paddr, len; unsigned long offs; int node; int res; __be32 val[2]; __be32 *cellp; - if ( !len ) + if ( !mod || !mod->size ) return; + paddr = mod->start; + len = mod->size; + printk("Loading dom0 initrd from %"PRIpaddr" to 0x%"PRIpaddr"-0x%"PRIpaddr"\n", paddr, load_addr, load_addr + len); diff --git a/xen/arch/arm/kernel.c b/xen/arch/arm/kernel.c index ce5b95a..230ff8f 100644 --- a/xen/arch/arm/kernel.c +++ b/xen/arch/arm/kernel.c @@ -68,8 +68,8 @@ static void place_modules(struct kernel_info *info, paddr_t kernbase, paddr_t kernend) { /* Align DTB and initrd size to 2Mb. Linux only requires 4 byte alignment */ - const paddr_t initrd_len = - ROUNDUP(bootinfo.modules.module[MOD_INITRD].size, MB(2)); + const struct bootmodule *mod = boot_module_find_by_kind(BOOTMOD_RAMDISK); + const paddr_t initrd_len = ROUNDUP(mod ? mod->size : 0, MB(2)); const paddr_t dtb_len = ROUNDUP(fdt_totalsize(info->fdt), MB(2)); const paddr_t modsize = initrd_len + dtb_len; @@ -372,20 +372,21 @@ err: int kernel_probe(struct kernel_info *info) { + struct bootmodule *mod = boot_module_find_by_kind(BOOTMOD_KERNEL); int rc; paddr_t start, size; - start = bootinfo.modules.module[MOD_KERNEL].start; - size = bootinfo.modules.module[MOD_KERNEL].size; - - if ( !size ) + if ( !mod || !mod->size ) { printk(XENLOG_ERR "Missing kernel boot module?\n"); return -ENOENT; } - printk("Loading kernel from boot module %d\n", MOD_KERNEL); + start = mod->start; + size = mod->size; + + printk("Loading kernel from boot module @ %"PRIpaddr"\n", start); #ifdef CONFIG_ARM_64 rc = kernel_zimage64_probe(info, start, size); diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c index f1ae408..4c9dd3d 100644 --- a/xen/arch/arm/setup.c +++ b/xen/arch/arm/setup.c @@ -183,17 +183,56 @@ static void dt_unreserved_regions(paddr_t s, paddr_t e, cb(s, e); } +void add_boot_module(bootmodulekind kind, paddr_t start, paddr_t size, + const char *cmdline) +{ + struct bootmodules *mods = &bootinfo.modules; + struct bootmodule *mod; + + if ( mods->nr_mods == MAX_MODULES ) + { + printk("Ignoring boot module at %"PRIpaddr"-%"PRIpaddr" (too many)\n", + start, start + size); + return; + } + + mod = &mods->module[mods->nr_mods++]; + mod->kind = kind; + mod->start = start; + mod->size = size; + if ( cmdline ) + safe_strcpy(mod->cmdline, cmdline); + else + mod->cmdline[0] = 0; + +} + +struct bootmodule * __init boot_module_find_by_kind(bootmodulekind kind) +{ + struct bootmodules *mods = &bootinfo.modules; + struct bootmodule *mod; + int i; + for (i = 0 ; i < mods->nr_mods ; i++ ) + { + mod = &mods->module[i]; + if ( mod->kind == kind ) + return mod; + } + return NULL; +} + void __init discard_initial_modules(void) { struct bootmodules *mi = &bootinfo.modules; int i; - for ( i = MOD_DISCARD_FIRST; i <= mi->nr_mods; i++ ) + for ( i = 0; i <= mi->nr_mods; i++ ) { paddr_t s = mi->module[i].start; paddr_t e = s + PAGE_ALIGN(mi->module[i].size); - dt_unreserved_regions(s, e, init_domheap_pages, 0); + if ( mi->module[i].kind > BOOTMOD_LAST_PRESERVE ) + dt_unreserved_regions(s, e, init_domheap_pages, 0); } mi->nr_mods = 0; @@ -360,9 +399,7 @@ static paddr_t __init get_xen_paddr(void) printk("Placing Xen at 0x%"PRIpaddr"-0x%"PRIpaddr"\n", paddr, paddr + min_size); - bootinfo.modules.module[MOD_XEN].start = paddr; - bootinfo.modules.module[MOD_XEN].size = min_size; - + add_boot_module(BOOTMOD_XEN, paddr, min_size, NULL); return paddr; } diff --git a/xen/include/asm-arm/setup.h b/xen/include/asm-arm/setup.h index 85aa866..57c98cb 100644 --- a/xen/include/asm-arm/setup.h +++ b/xen/include/asm-arm/setup.h @@ -5,14 +5,19 @@ #define NR_MEM_BANKS 8 -#define MOD_XEN 0 -#define MOD_FDT 1 -#define MOD_KERNEL 2 -#define MOD_INITRD 3 -#define MOD_XSM 4 -#define NR_MODULES 5 +#define MAX_MODULES 5 /* Current maximum useful modules */ + +typedef enum { + BOOTMOD_XEN, + BOOTMOD_FDT, + /* Everything up to here is not freed after start of day */ + BOOTMOD_LAST_PRESERVE = BOOTMOD_FDT, + BOOTMOD_KERNEL, + BOOTMOD_RAMDISK, + BOOTMOD_XSM, + BOOTMOD_UNKNOWN +} bootmodulekind; -#define MOD_DISCARD_FIRST MOD_FDT struct membank { paddr_t start; @@ -24,16 +29,18 @@ struct meminfo { struct membank bank[NR_MEM_BANKS]; }; +#define BOOTMOD_MAX_CMDLINE 1024 struct bootmodule { + bootmodulekind kind; paddr_t start; paddr_t size; - char cmdline[1024]; + char cmdline[BOOTMOD_MAX_CMDLINE]; }; struct bootmodules { int nr_mods; /* Module 0 is Xen itself, followed by the provided modules-proper */ - struct bootmodule module[NR_MODULES]; + struct bootmodule module[MAX_MODULES]; }; struct bootinfo { @@ -56,6 +63,10 @@ void discard_initial_modules(void); size_t __init boot_fdt_info(const void *fdt, paddr_t paddr); const char __init *boot_fdt_cmdline(const void *fdt); +void add_boot_module(bootmodulekind kind, paddr_t start, paddr_t size, + const char *cmdline); +struct bootmodule *boot_module_find_by_kind(bootmodulekind kind); + #endif /* * Local variables: