From nobody Sat May 4 16:04:24 2024 Delivered-To: importer@patchew.org Received-SPF: none (zoho.com: 192.237.175.120 is neither permitted nor denied by domain of lists.xenproject.org) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; spf=none (zoho.com: 192.237.175.120 is neither permitted nor denied by domain of lists.xenproject.org) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1573581329; cv=none; d=zoho.com; s=zohoarc; b=TUpfwGToVHpJoNF+gcX+uWFdXiI+Q8cqA016i872J2Mu8l2Rk/2MTJ4DsexMLw+z5iZkTUKfgaogiwyl6P3xlvhjQaFBE9OV/8V6T5pU4qq3D9iD3dYpNDay2rVAwnbIGs0ihESs62lMb6ybWprwP52o2j61lVdjBASfz3Q3scI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1573581329; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=E03qS2fCIt4VpZszFJv96s7u/z2l4+U+iwPbpcF0YmU=; b=NNDNcgdRTr4KIrQ2CghoWYEpLrP71BjQCx1Hd2H8z8mQRg6Cnzrp65ZpJXg9NCFNYWnPMjiFh1QShppZ1fRbnEYLYYJ4jUoWa1m/CmbzRjywEyH+dKtry7A2cT13pBYFe0Gqr2JBPwOYz8AphYTfadMz+avsPGZSf3DwTKGO/ao= ARC-Authentication-Results: i=1; mx.zoho.com; spf=none (zoho.com: 192.237.175.120 is neither permitted nor denied by domain of lists.xenproject.org) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1573581329779144.89963060978914; Tue, 12 Nov 2019 09:55:29 -0800 (PST) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1iUaMi-0003w7-Qs; Tue, 12 Nov 2019 17:54:08 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1iUaMi-0003vB-1Z for xen-devel@lists.xenproject.org; Tue, 12 Nov 2019 17:54:08 +0000 Received: from Galois.linutronix.de (unknown [2a0a:51c0:0:12e:550::1]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id 6aa89974-0575-11ea-b678-bc764e2007e4; Tue, 12 Nov 2019 17:54:05 +0000 (UTC) Received: from [5.158.153.53] (helo=tip-bot2.lab.linutronix.de) by Galois.linutronix.de with esmtpsa (TLS1.2:DHE_RSA_AES_256_CBC_SHA256:256) (Exim 4.80) (envelope-from ) id 1iUaMW-0000ey-9v; Tue, 12 Nov 2019 18:53:56 +0100 Received: from [127.0.1.1] (localhost [IPv6:::1]) by tip-bot2.lab.linutronix.de (Postfix) with ESMTP id DD54E1C0084; Tue, 12 Nov 2019 18:53:55 +0100 (CET) X-Inumbo-ID: 6aa89974-0575-11ea-b678-bc764e2007e4 Date: Tue, 12 Nov 2019 17:53:55 -0000 From: "tip-bot2 for Daniel Kiper" To: linux-tip-commits@vger.kernel.org In-Reply-To: <20191112134640.16035-4-daniel.kiper@oracle.com> References: <20191112134640.16035-4-daniel.kiper@oracle.com> MIME-Version: 1.0 Message-ID: <157358123549.29376.9018722901282041797.tip-bot2@tip-bot2> X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails Precedence: bulk X-Linutronix-Spam-Score: -1.0 X-Linutronix-Spam-Level: - X-Linutronix-Spam-Status: No , -1.0 points, 5.0 required, ALL_TRUSTED=-1, SHORTCIRCUIT=-0.0001 Subject: [Xen-devel] [tip: x86/boot] x86/boot: Introduce setup_indirect X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Reply-To: linux-kernel@vger.kernel.org Cc: linux-efi , linux-doc@vger.kernel.org, Peter Zijlstra , dave.hansen@linux.intel.com, "H. Peter Anvin \(Intel\)" , Ingo Molnar , eric.snowberg@oracle.com, Jonathan Corbet , Daniel Kiper , x86-ml , Ingo Molnar , kanth.ghatraju@oracle.com, xen-devel@lists.xenproject.org, Borislav Petkov , Konrad Rzeszutek Wilk , Ross Philipson , Borislav Petkov , Boris Ostrovsky , Juergen Gross , ard.biesheuvel@linaro.org, rdunlap@infradead.org, linux-kernel@vger.kernel.org, Andy Lutomirski , Thomas Gleixner Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" The following commit has been merged into the x86/boot branch of tip: Commit-ID: b3c72fc9a78e74161f9d05ef7191706060628f8c Gitweb: https://git.kernel.org/tip/b3c72fc9a78e74161f9d05ef719170606= 0628f8c Author: Daniel Kiper AuthorDate: Tue, 12 Nov 2019 14:46:40 +01:00 Committer: Borislav Petkov CommitterDate: Tue, 12 Nov 2019 16:21:15 +01:00 x86/boot: Introduce setup_indirect The setup_data is a bit awkward to use for extremely large data objects, both because the setup_data header has to be adjacent to the data object and because it has a 32-bit length field. However, it is important that intermediate stages of the boot process have a way to identify which chunks of memory are occupied by kernel data. Thus introduce an uniform way to specify such indirect data as setup_indirect struct and SETUP_INDIRECT type. And finally bump setup_header version in arch/x86/boot/header.S. Suggested-by: H. Peter Anvin (Intel) Signed-off-by: Daniel Kiper Signed-off-by: Borislav Petkov Reviewed-by: Ross Philipson Reviewed-by: H. Peter Anvin (Intel) Acked-by: Konrad Rzeszutek Wilk Cc: Andy Lutomirski Cc: ard.biesheuvel@linaro.org Cc: Boris Ostrovsky Cc: dave.hansen@linux.intel.com Cc: eric.snowberg@oracle.com Cc: Ingo Molnar Cc: Jonathan Corbet Cc: Juergen Gross Cc: kanth.ghatraju@oracle.com Cc: linux-doc@vger.kernel.org Cc: linux-efi Cc: Peter Zijlstra Cc: rdunlap@infradead.org Cc: ross.philipson@oracle.com Cc: Thomas Gleixner Cc: x86-ml Cc: xen-devel@lists.xenproject.org Link: https://lkml.kernel.org/r/20191112134640.16035-4-daniel.kiper@oracle.= com --- Documentation/x86/boot.rst | 43 ++++++++++++++++++++++++- arch/x86/boot/compressed/kaslr.c | 12 +++++++- arch/x86/boot/compressed/kernel_info.S | 2 +- arch/x86/boot/header.S | 2 +- arch/x86/include/uapi/asm/bootparam.h | 16 +++++++-- arch/x86/kernel/e820.c | 11 ++++++- arch/x86/kernel/kdebugfs.c | 21 +++++++++--- arch/x86/kernel/ksysfs.c | 31 +++++++++++++----- arch/x86/kernel/setup.c | 6 +++- arch/x86/mm/ioremap.c | 11 ++++++- 10 files changed, 138 insertions(+), 17 deletions(-) diff --git a/Documentation/x86/boot.rst b/Documentation/x86/boot.rst index 6cdd767..90bb8f5 100644 --- a/Documentation/x86/boot.rst +++ b/Documentation/x86/boot.rst @@ -827,6 +827,47 @@ Protocol: 2.09+ sure to consider the case where the linked list already contains entries. =20 + The setup_data is a bit awkward to use for extremely large data objects, + both because the setup_data header has to be adjacent to the data object + and because it has a 32-bit length field. However, it is important that + intermediate stages of the boot process have a way to identify which + chunks of memory are occupied by kernel data. + + Thus setup_indirect struct and SETUP_INDIRECT type were introduced in + protocol 2.15. + + struct setup_indirect { + __u32 type; + __u32 reserved; /* Reserved, must be set to zero. */ + __u64 len; + __u64 addr; + }; + + The type member is a SETUP_INDIRECT | SETUP_* type. However, it cannot be + SETUP_INDIRECT itself since making the setup_indirect a tree structure + could require a lot of stack space in something that needs to parse it + and stack space can be limited in boot contexts. + + Let's give an example how to point to SETUP_E820_EXT data using setup_in= direct. + In this case setup_data and setup_indirect will look like this: + + struct setup_data { + __u64 next =3D 0 or ; + __u32 type =3D SETUP_INDIRECT; + __u32 len =3D sizeof(setup_data); + __u8 data[sizeof(setup_indirect)] =3D struct setup_indirect { + __u32 type =3D SETUP_INDIRECT | SETUP_E820_EXT; + __u32 reserved =3D 0; + __u64 len =3D ; + __u64 addr =3D ; + } + } + +.. note:: + SETUP_INDIRECT | SETUP_NONE objects cannot be properly distinguished + from SETUP_INDIRECT itself. So, this kind of objects cannot be provid= ed + by the bootloaders. + =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D Field name: pref_address Type: read (reloc) @@ -986,7 +1027,7 @@ Field name: setup_type_max Offset/size: 0x000c/4 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D =20 - This field contains maximal allowed type for setup_data. + This field contains maximal allowed type for setup_data and setup_indire= ct structs. =20 =20 The Image Checksum diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/ka= slr.c index 2e53c05..bb9bfef 100644 --- a/arch/x86/boot/compressed/kaslr.c +++ b/arch/x86/boot/compressed/kaslr.c @@ -459,6 +459,18 @@ static bool mem_avoid_overlap(struct mem_vector *img, is_overlapping =3D true; } =20 + if (ptr->type =3D=3D SETUP_INDIRECT && + ((struct setup_indirect *)ptr->data)->type !=3D SETUP_INDIRECT) { + avoid.start =3D ((struct setup_indirect *)ptr->data)->addr; + avoid.size =3D ((struct setup_indirect *)ptr->data)->len; + + if (mem_overlaps(img, &avoid) && (avoid.start < earliest)) { + *overlap =3D avoid; + earliest =3D overlap->start; + is_overlapping =3D true; + } + } + ptr =3D (struct setup_data *)(unsigned long)ptr->next; } =20 diff --git a/arch/x86/boot/compressed/kernel_info.S b/arch/x86/boot/compres= sed/kernel_info.S index 018dacb..f818ee8 100644 --- a/arch/x86/boot/compressed/kernel_info.S +++ b/arch/x86/boot/compressed/kernel_info.S @@ -14,7 +14,7 @@ kernel_info: /* Size total. */ .long kernel_info_end - kernel_info =20 - /* Maximal allowed type for setup_data. */ + /* Maximal allowed type for setup_data and setup_indirect structs. */ .long SETUP_TYPE_MAX =20 kernel_info_var_len_data: diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S index 22dceca..97d9b6d 100644 --- a/arch/x86/boot/header.S +++ b/arch/x86/boot/header.S @@ -300,7 +300,7 @@ _start: # Part 2 of the header, from the old setup.S =20 .ascii "HdrS" # header signature - .word 0x020d # header version number (>=3D 0x0105) + .word 0x020f # header version number (>=3D 0x0105) # or else old loadlin-1.5 will fail) .globl realmode_swtch realmode_swtch: .word 0, 0 # default_switch, SETUPSEG diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/= asm/bootparam.h index dbb4112..949066b 100644 --- a/arch/x86/include/uapi/asm/bootparam.h +++ b/arch/x86/include/uapi/asm/bootparam.h @@ -2,7 +2,7 @@ #ifndef _ASM_X86_BOOTPARAM_H #define _ASM_X86_BOOTPARAM_H =20 -/* setup_data types */ +/* setup_data/setup_indirect types */ #define SETUP_NONE 0 #define SETUP_E820_EXT 1 #define SETUP_DTB 2 @@ -11,8 +11,10 @@ #define SETUP_APPLE_PROPERTIES 5 #define SETUP_JAILHOUSE 6 =20 -/* max(SETUP_*) */ -#define SETUP_TYPE_MAX SETUP_JAILHOUSE +#define SETUP_INDIRECT (1<<31) + +/* SETUP_INDIRECT | max(SETUP_*) */ +#define SETUP_TYPE_MAX (SETUP_INDIRECT | SETUP_JAILHOUSE) =20 /* ram_size flags */ #define RAMDISK_IMAGE_START_MASK 0x07FF @@ -52,6 +54,14 @@ struct setup_data { __u8 data[0]; }; =20 +/* extensible setup indirect data node */ +struct setup_indirect { + __u32 type; + __u32 reserved; /* Reserved, must be set to zero. */ + __u64 len; + __u64 addr; +}; + struct setup_header { __u8 setup_sects; __u16 root_flags; diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 7da2bcd..0bfe9a6 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -999,6 +999,17 @@ void __init e820__reserve_setup_data(void) data =3D early_memremap(pa_data, sizeof(*data)); e820__range_update(pa_data, sizeof(*data)+data->len, E820_TYPE_RAM, E820= _TYPE_RESERVED_KERN); e820__range_update_kexec(pa_data, sizeof(*data)+data->len, E820_TYPE_RAM= , E820_TYPE_RESERVED_KERN); + + if (data->type =3D=3D SETUP_INDIRECT && + ((struct setup_indirect *)data->data)->type !=3D SETUP_INDIRECT) { + e820__range_update(((struct setup_indirect *)data->data)->addr, + ((struct setup_indirect *)data->data)->len, + E820_TYPE_RAM, E820_TYPE_RESERVED_KERN); + e820__range_update_kexec(((struct setup_indirect *)data->data)->addr, + ((struct setup_indirect *)data->data)->len, + E820_TYPE_RAM, E820_TYPE_RESERVED_KERN); + } + pa_data =3D data->next; early_memunmap(data, sizeof(*data)); } diff --git a/arch/x86/kernel/kdebugfs.c b/arch/x86/kernel/kdebugfs.c index edaa30b..64b6da9 100644 --- a/arch/x86/kernel/kdebugfs.c +++ b/arch/x86/kernel/kdebugfs.c @@ -44,7 +44,12 @@ static ssize_t setup_data_read(struct file *file, char _= _user *user_buf, if (count > node->len - pos) count =3D node->len - pos; =20 - pa =3D node->paddr + sizeof(struct setup_data) + pos; + pa =3D node->paddr + pos; + + /* Is it direct data or invalid indirect one? */ + if (!(node->type & SETUP_INDIRECT) || node->type =3D=3D SETUP_INDIRECT) + pa +=3D sizeof(struct setup_data); + p =3D memremap(pa, count, MEMREMAP_WB); if (!p) return -ENOMEM; @@ -108,9 +113,17 @@ static int __init create_setup_data_nodes(struct dentr= y *parent) goto err_dir; } =20 - node->paddr =3D pa_data; - node->type =3D data->type; - node->len =3D data->len; + if (data->type =3D=3D SETUP_INDIRECT && + ((struct setup_indirect *)data->data)->type !=3D SETUP_INDIRECT) { + node->paddr =3D ((struct setup_indirect *)data->data)->addr; + node->type =3D ((struct setup_indirect *)data->data)->type; + node->len =3D ((struct setup_indirect *)data->data)->len; + } else { + node->paddr =3D pa_data; + node->type =3D data->type; + node->len =3D data->len; + } + create_setup_data_node(d, no, node); pa_data =3D data->next; =20 diff --git a/arch/x86/kernel/ksysfs.c b/arch/x86/kernel/ksysfs.c index 7969da9..d0a1912 100644 --- a/arch/x86/kernel/ksysfs.c +++ b/arch/x86/kernel/ksysfs.c @@ -100,7 +100,12 @@ static int __init get_setup_data_size(int nr, size_t *= size) if (!data) return -ENOMEM; if (nr =3D=3D i) { - *size =3D data->len; + if (data->type =3D=3D SETUP_INDIRECT && + ((struct setup_indirect *)data->data)->type !=3D SETUP_INDIRECT) + *size =3D ((struct setup_indirect *)data->data)->len; + else + *size =3D data->len; + memunmap(data); return 0; } @@ -130,7 +135,10 @@ static ssize_t type_show(struct kobject *kobj, if (!data) return -ENOMEM; =20 - ret =3D sprintf(buf, "0x%x\n", data->type); + if (data->type =3D=3D SETUP_INDIRECT) + ret =3D sprintf(buf, "0x%x\n", ((struct setup_indirect *)data->data)->ty= pe); + else + ret =3D sprintf(buf, "0x%x\n", data->type); memunmap(data); return ret; } @@ -142,7 +150,7 @@ static ssize_t setup_data_data_read(struct file *fp, loff_t off, size_t count) { int nr, ret =3D 0; - u64 paddr; + u64 paddr, len; struct setup_data *data; void *p; =20 @@ -157,19 +165,28 @@ static ssize_t setup_data_data_read(struct file *fp, if (!data) return -ENOMEM; =20 - if (off > data->len) { + if (data->type =3D=3D SETUP_INDIRECT && + ((struct setup_indirect *)data->data)->type !=3D SETUP_INDIRECT) { + paddr =3D ((struct setup_indirect *)data->data)->addr; + len =3D ((struct setup_indirect *)data->data)->len; + } else { + paddr +=3D sizeof(*data); + len =3D data->len; + } + + if (off > len) { ret =3D -EINVAL; goto out; } =20 - if (count > data->len - off) - count =3D data->len - off; + if (count > len - off) + count =3D len - off; =20 if (!count) goto out; =20 ret =3D count; - p =3D memremap(paddr + sizeof(*data), data->len, MEMREMAP_WB); + p =3D memremap(paddr, len, MEMREMAP_WB); if (!p) { ret =3D -ENOMEM; goto out; diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 77ea96b..8f48bb8 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -438,6 +438,12 @@ static void __init memblock_x86_reserve_range_setup_da= ta(void) while (pa_data) { data =3D early_memremap(pa_data, sizeof(*data)); memblock_reserve(pa_data, sizeof(*data) + data->len); + + if (data->type =3D=3D SETUP_INDIRECT && + ((struct setup_indirect *)data->data)->type !=3D SETUP_INDIRECT) + memblock_reserve(((struct setup_indirect *)data->data)->addr, + ((struct setup_indirect *)data->data)->len); + pa_data =3D data->next; early_memunmap(data, sizeof(*data)); } diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index a39dcdb..1ff9c20 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c @@ -626,6 +626,17 @@ static bool memremap_is_setup_data(resource_size_t phy= s_addr, paddr_next =3D data->next; len =3D data->len; =20 + if ((phys_addr > paddr) && (phys_addr < (paddr + len))) { + memunmap(data); + return true; + } + + if (data->type =3D=3D SETUP_INDIRECT && + ((struct setup_indirect *)data->data)->type !=3D SETUP_INDIRECT) { + paddr =3D ((struct setup_indirect *)data->data)->addr; + len =3D ((struct setup_indirect *)data->data)->len; + } + memunmap(data); =20 if ((phys_addr > paddr) && (phys_addr < (paddr + len))) _______________________________________________ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel