From patchwork Mon Aug 5 12:43:01 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11076825 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A3CC213A4 for ; Mon, 5 Aug 2019 12:44:56 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 908D72860C for ; Mon, 5 Aug 2019 12:44:56 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 84874288F7; Mon, 5 Aug 2019 12:44:56 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id C5A362860C for ; Mon, 5 Aug 2019 12:44:52 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1hucKZ-0000cK-TU; Mon, 05 Aug 2019 12:43:15 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1hucKY-0000cF-Ed for xen-devel@lists.xenproject.org; Mon, 05 Aug 2019 12:43:14 +0000 X-Inumbo-ID: 951605a6-b77e-11e9-8a3d-638e0cad4229 Received: from esa5.hc3370-68.iphmx.com (unknown [216.71.155.168]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id 951605a6-b77e-11e9-8a3d-638e0cad4229; Mon, 05 Aug 2019 12:43:11 +0000 (UTC) Authentication-Results: esa5.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none; spf=None smtp.pra=andrew.cooper3@citrix.com; spf=Pass smtp.mailfrom=Andrew.Cooper3@citrix.com; spf=None smtp.helo=postmaster@mail.citrix.com Received-SPF: None (esa5.hc3370-68.iphmx.com: no sender authenticity information available from domain of andrew.cooper3@citrix.com) identity=pra; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="andrew.cooper3@citrix.com"; x-conformance=sidf_compatible Received-SPF: Pass (esa5.hc3370-68.iphmx.com: domain of Andrew.Cooper3@citrix.com designates 162.221.158.21 as permitted sender) identity=mailfrom; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="Andrew.Cooper3@citrix.com"; x-conformance=sidf_compatible; x-record-type="v=spf1"; x-record-text="v=spf1 ip4:209.167.231.154 ip4:178.63.86.133 ip4:195.66.111.40/30 ip4:85.115.9.32/28 ip4:199.102.83.4 ip4:192.28.146.160 ip4:192.28.146.107 ip4:216.52.6.88 ip4:216.52.6.188 ip4:162.221.158.21 ip4:162.221.156.83 ~all" Received-SPF: None (esa5.hc3370-68.iphmx.com: no sender authenticity information available from domain of postmaster@mail.citrix.com) identity=helo; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="postmaster@mail.citrix.com"; x-conformance=sidf_compatible IronPort-SDR: WReaJLVIY5EDwPZubsCpn+9OBhe1qwqb8OPKg9X7rkj5z9x2IwK3VfqC+FFtM3WN/PWklG2GA9 X42NkDBpx17BDuP/GKLHiTE5DIJoouURcr7ZuhF/7Mvras37WAjgc1yoEJSHO5dAumvdQq7DI1 qUfL5T3BuR8HaC6RGC3aWqIEdGzporT7Y4bMXEObGN1EM3ZDz13kxVflOs4hoJaVWl1A5+itT8 yK+IkQ7+d7PlDG7GqjVHR2WyEH43JBUvCWFBtFleENyfIp1HU1jvzTodkdab8yM0OohA+BhCfK MS0= X-SBRS: 2.7 X-MesageID: 3986069 X-Ironport-Server: esa5.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.64,349,1559534400"; d="scan'208";a="3986069" From: Andrew Cooper To: Xen-devel Date: Mon, 5 Aug 2019 13:43:01 +0100 Message-ID: <20190805124301.12887-5-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20190805124301.12887-1-andrew.cooper3@citrix.com> References: <20190805124301.12887-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 Subject: [Xen-devel] [PATCH 4/4] x86/desc: Build boot_{,compat_}gdt[] in C X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Andrew Cooper , Wei Liu , Jan Beulich , =?utf-8?q?Roger_Pau_Monn=C3=A9?= Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP ... where we can at least get the compiler to fill in the surrounding space without having to do it manually. This also reults in the symbols having proper type/size information in the debug symbols. Reorder 'raw' in the seg_desc_t union to allow for easier initialisation. Leave a comment explaining the various restrictions we have on altering the GDT layout. No functional change. Signed-off-by: Andrew Cooper Reviewed-by: Roger Pau Monné --- CC: Jan Beulich CC: Wei Liu CC: Roger Pau Monné There is plenty more cleanup which can be done in the future. As we are 64-bit, there is no need for load_TR() to keep the TSS in sync between the two GDTs, which means it can drop all sgdt/lgdt instructions. Also, __HYPERVISOR_CS32 is unused and could be dropped. As is demonstrated by the required includes, asm/desc.h is a tangle in need of some cleanup. The SYSEXIT GDT requirements are: R0 long code, R0 data, R3 compat code, R3 data, R3 long code, R3 data. We could make Xen compatible by shifting the R0 code/data down by one slot, moving R0 compat code elsewhere and replacing it with another R3 data. However, this seems like a fairly pointless exercise, as the only thing it will do is change the magic numbers which developers have become accustom to seeing in backtraces. --- xen/arch/x86/Makefile | 1 + xen/arch/x86/boot/head.S | 1 - xen/arch/x86/boot/x86_64.S | 33 -------------------- xen/arch/x86/desc.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++ xen/include/asm-x86/desc.h | 2 +- 5 files changed, 77 insertions(+), 35 deletions(-) create mode 100644 xen/arch/x86/desc.c diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile index 5e3840084b..2443fd2cc5 100644 --- a/xen/arch/x86/Makefile +++ b/xen/arch/x86/Makefile @@ -21,6 +21,7 @@ obj-$(CONFIG_PV) += compat.o x86_64/compat.o obj-$(CONFIG_KEXEC) += crash.o obj-y += debug.o obj-y += delay.o +obj-y += desc.o obj-bin-y += dmi_scan.init.o obj-y += domctl.o obj-y += domain.o diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S index ab2d52a79d..782deac0d4 100644 --- a/xen/arch/x86/boot/head.S +++ b/xen/arch/x86/boot/head.S @@ -2,7 +2,6 @@ #include #include #include -#include #include #include #include diff --git a/xen/arch/x86/boot/x86_64.S b/xen/arch/x86/boot/x86_64.S index 3909363ca3..f762dfea11 100644 --- a/xen/arch/x86/boot/x86_64.S +++ b/xen/arch/x86/boot/x86_64.S @@ -43,44 +43,11 @@ ENTRY(__high_start) multiboot_ptr: .long 0 - .word 0 -GLOBAL(boot_gdtr) - .word LAST_RESERVED_GDT_BYTE - .quad boot_gdt - FIRST_RESERVED_GDT_BYTE - GLOBAL(stack_start) .quad cpu0_stack .section .data.page_aligned, "aw", @progbits .align PAGE_SIZE, 0 -GLOBAL(boot_gdt) - .quad 0x0000000000000000 /* unused */ - .quad 0x00af9a000000ffff /* 0xe008 ring 0 code, 64-bit mode */ - .quad 0x00cf92000000ffff /* 0xe010 ring 0 data */ - .quad 0x0000000000000000 /* reserved */ - .quad 0x00cffa000000ffff /* 0xe023 ring 3 code, compatibility */ - .quad 0x00cff2000000ffff /* 0xe02b ring 3 data */ - .quad 0x00affa000000ffff /* 0xe033 ring 3 code, 64-bit mode */ - .quad 0x00cf9a000000ffff /* 0xe038 ring 0 code, compatibility */ - .fill (PER_CPU_GDT_ENTRY - __HYPERVISOR_CS32 / 8 - 1), 8, 0 - .quad 0x0000910000000000 /* per-CPU entry (limit == cpu) */ - - .align PAGE_SIZE, 0 -/* NB. Even rings != 0 get access to the full 4Gb, as only the */ -/* (compatibility) machine->physical mapping table lives there. */ -GLOBAL(boot_compat_gdt) - .quad 0x0000000000000000 /* unused */ - .quad 0x00af9a000000ffff /* 0xe008 ring 0 code, 64-bit mode */ - .quad 0x00cf92000000ffff /* 0xe010 ring 0 data */ - .quad 0x00cfba000000ffff /* 0xe019 ring 1 code, compatibility */ - .quad 0x00cfb2000000ffff /* 0xe021 ring 1 data */ - .quad 0x00cffa000000ffff /* 0xe02b ring 3 code, compatibility */ - .quad 0x00cff2000000ffff /* 0xe033 ring 3 data */ - .quad 0x00cf9a000000ffff /* 0xe038 ring 0 code, compatibility */ - .fill (PER_CPU_GDT_ENTRY - __HYPERVISOR_CS32 / 8 - 1), 8, 0 - .quad 0x0000910000000000 /* per-CPU entry (limit == cpu) */ - .align PAGE_SIZE, 0 - /* * Mapping of first 2 megabytes of memory. This is mapped with 4kB mappings * to avoid type conflicts with fixed-range MTRRs covering the lowest megabyte diff --git a/xen/arch/x86/desc.c b/xen/arch/x86/desc.c new file mode 100644 index 0000000000..c5dad90cdd --- /dev/null +++ b/xen/arch/x86/desc.c @@ -0,0 +1,75 @@ +#include +#include +#include +#include + +#include + +/* + * Native and Compat GDTs used by Xen. + * + * The R1 and R3 descriptors are fixed in Xen's ABI for PV guests. All other + * descriptors are in principle variable, with the following restrictions. + * + * All R0 descriptors must line up in both GDTs to allow for correct + * interrupt/exception handling. + * + * The SYSCALL/SYSRET GDT layout requires: + * - R0 long mode code followed by R0 data. + * - R3 compat code, followed by R3 data, followed by R3 long mode code. + * + * The SYSENTER GDT layout requirements are compatible with SYSCALL. Xen does + * not use the SYSEXIT instruction, and does not provide a compatible GDT. + * + * These tables are used directly by CPU0, and used as the template for the + * GDTs of other CPUs. Everything from the TSS onwards is unique per CPU. + */ +__section(".data.page_aligned") __aligned(PAGE_SIZE) +seg_desc_t boot_gdt[PAGE_SIZE / sizeof(seg_desc_t)] = +{ + [ 1] = { 0x00af9a000000ffff }, /* 0xe008 - Ring 0 code, 64bit mode */ + [ 2] = { 0x00cf92000000ffff }, /* 0xe010 - Ring 0 data */ + /* 0xe018 - reserved */ + [ 4] = { 0x00cffa000000ffff }, /* 0xe023 - Ring 3 code, compatibility */ + [ 5] = { 0x00cff2000000ffff }, /* 0xe02b - Ring 3 data */ + [ 6] = { 0x00affa000000ffff }, /* 0xe033 - Ring 3 code, 64-bit mode */ + [ 7] = { 0x00cf9a000000ffff }, /* 0xe038 - Ring 0 code, compatibility */ + /* 0xe040 - TSS */ + /* 0xe050 - LDT */ + [12] = { 0x0000910000000000 }, /* 0xe060 - per-CPU entry (limit == cpu) */ +}; + +__section(".data.page_aligned") __aligned(PAGE_SIZE) +seg_desc_t boot_compat_gdt[PAGE_SIZE / sizeof(seg_desc_t)] = +{ + [ 1] = { 0x00af9a000000ffff }, /* 0xe008 - Ring 0 code, 64-bit mode */ + [ 2] = { 0x00cf92000000ffff }, /* 0xe010 - Ring 0 data */ + [ 3] = { 0x00cfba000000ffff }, /* 0xe019 - Ring 1 code, compatibility */ + [ 4] = { 0x00cfb2000000ffff }, /* 0xe021 - Ring 1 data */ + [ 5] = { 0x00cffa000000ffff }, /* 0xe02b - Ring 3 code, compatibility */ + [ 6] = { 0x00cff2000000ffff }, /* 0xe033 - Ring 3 data */ + [ 7] = { 0x00cf9a000000ffff }, /* 0xe038 - Ring 0 code, compatibility */ + /* 0xe040 - TSS */ + /* 0xe050 - LDT */ + [12] = { 0x0000910000000000 }, /* 0xe060 - per-CPU entry (limit == cpu) */ +}; + +/* + * Used by each CPU as it starts up, to enter C with a suitable %cs. + * References boot_cpu_gdt_table for a short period, until the CPUs switch + * onto their per-CPU GDTs. + */ +struct desc_ptr boot_gdtr = { + .limit = LAST_RESERVED_GDT_BYTE, + .base = (unsigned long)(boot_gdt - FIRST_RESERVED_GDT_ENTRY), +}; + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/asm-x86/desc.h b/xen/include/asm-x86/desc.h index 0be9348d29..0ebdcd05a9 100644 --- a/xen/include/asm-x86/desc.h +++ b/xen/include/asm-x86/desc.h @@ -103,10 +103,10 @@ #define SYS_DESC_trap_gate 15 typedef union { + uint64_t raw; struct { uint32_t a, b; }; - uint64_t raw; } seg_desc_t; typedef union {