mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-11 08:18:47 +00:00
x86/asm changes for v6.8:
- Replace magic numbers in GDT descriptor definitions & handling: - Introduce symbolic names via macros for descriptor types/fields/flags, and then use these symbolic names. - Clean up definitions a bit, such as GDT_ENTRY_INIT() - Fix/clean up details that became visibly inconsistent after the symbol-based code was introduced: - Unify accessed flag handling - Set the D/B size flag consistently & according to the HW specification Signed-off-by: Ingo Molnar <mingo@kernel.org> -----BEGIN PGP SIGNATURE----- iQJFBAABCgAvFiEEBpT5eoXrXCwVQwEKEnMQ0APhK1gFAmWb1hQRHG1pbmdvQGtl cm5lbC5vcmcACgkQEnMQ0APhK1j7/xAAk2L36n4ZpWqm4oWxMyRDTd713qT+Jzg5 txVr7i8el5RZ8D9WQejzOWemJ/XgirkWuRSFfY+UzZZ+7lmioXWDFLz6PFpyMOwM OG2yyAAZIQzFhe1LxhurN5G7F+q9Nl/CcDnRWv+FUKs829GOGlaqirKfKwgIFzgw GUT0eT5gPfIfEFnzMUrix9+KNIZU6s6Lgg5tVpavNw6bKEimg8Mtn4J45voFbg98 l/PU0RaC28vePTMdoBLv/ZZUHS9K/UdGUq600guzk/Zh2plqxGtqjXtaM5/8giPO JbgQCTP0LaCC0oZf0SAbUW7+TiKD03CP6QzleYyLdhTjLz1CCOswgz0upPjfa/5j nhgsMCk/CEhr6nMwhJiRNhOrFFFJWX00bpcQ2tyyVO156Q+CfhJxuk1XafeQ5MSs K4l97IVc/vPQSEZy5Nh6GdGmWljYxP3Ku4eHRkyVGVYf8YyaD2l6CimaRcdPNqqL w9GLwczLfEzkomfdxsyppwu364O91Lpv6gi6AY4Tj7Hgo1ZMm9ucUO3AsTUz5EJJ aiqX6o7puIJJkU2O3hKviTzNwTojjjicD/Az66re3lHZBND+luP7LjVY2wIomH5i bFPVdSCDmCdTrsTkO3f87FHbCVrbNllKLGChvJ66vyC2nJeIM8UHJ/MxYJsGRhqk 87vU1DWYPrQ= =Y0pg -----END PGP SIGNATURE----- Merge tag 'x86-asm-2024-01-08' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip Pull x86 asm updates from Ingo Molnar: "Replace magic numbers in GDT descriptor definitions & handling: - Introduce symbolic names via macros for descriptor types/fields/flags, and then use these symbolic names. - Clean up definitions a bit, such as GDT_ENTRY_INIT() - Fix/clean up details that became visibly inconsistent after the symbol-based code was introduced: - Unify accessed flag handling - Set the D/B size flag consistently & according to the HW specification" * tag 'x86-asm-2024-01-08' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/asm: Add DB flag to 32-bit percpu GDT entry x86/asm: Always set A (accessed) flag in GDT descriptors x86/asm: Replace magic numbers in GDT descriptors, script-generated change x86/asm: Replace magic numbers in GDT descriptors, preparations x86/asm: Provide new infrastructure for GDT descriptors
This commit is contained in:
commit
106b88d7a9
@ -11,6 +11,7 @@
|
||||
*/
|
||||
|
||||
#include "boot.h"
|
||||
#include <asm/desc_defs.h>
|
||||
#include <asm/segment.h>
|
||||
|
||||
/*
|
||||
@ -67,13 +68,13 @@ static void setup_gdt(void)
|
||||
being 8-byte unaligned. Intel recommends 16 byte alignment. */
|
||||
static const u64 boot_gdt[] __attribute__((aligned(16))) = {
|
||||
/* CS: code, read/execute, 4 GB, base 0 */
|
||||
[GDT_ENTRY_BOOT_CS] = GDT_ENTRY(0xc09b, 0, 0xfffff),
|
||||
[GDT_ENTRY_BOOT_CS] = GDT_ENTRY(DESC_CODE32, 0, 0xfffff),
|
||||
/* DS: data, read/write, 4 GB, base 0 */
|
||||
[GDT_ENTRY_BOOT_DS] = GDT_ENTRY(0xc093, 0, 0xfffff),
|
||||
[GDT_ENTRY_BOOT_DS] = GDT_ENTRY(DESC_DATA32, 0, 0xfffff),
|
||||
/* TSS: 32-bit tss, 104 bytes, base 4096 */
|
||||
/* We only have a TSS here to keep Intel VT happy;
|
||||
we don't actually use it for anything. */
|
||||
[GDT_ENTRY_BOOT_TSS] = GDT_ENTRY(0x0089, 4096, 103),
|
||||
[GDT_ENTRY_BOOT_TSS] = GDT_ENTRY(DESC_TSS32, 4096, 103),
|
||||
};
|
||||
/* Xen HVM incorrectly stores a pointer to the gdt_ptr, instead
|
||||
of the gdt_ptr contents. Thus, make it static so it will
|
||||
|
@ -8,6 +8,56 @@
|
||||
* archs.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Low-level interface mapping flags/field names to bits
|
||||
*/
|
||||
|
||||
/* Flags for _DESC_S (non-system) descriptors */
|
||||
#define _DESC_ACCESSED 0x0001
|
||||
#define _DESC_DATA_WRITABLE 0x0002
|
||||
#define _DESC_CODE_READABLE 0x0002
|
||||
#define _DESC_DATA_EXPAND_DOWN 0x0004
|
||||
#define _DESC_CODE_CONFORMING 0x0004
|
||||
#define _DESC_CODE_EXECUTABLE 0x0008
|
||||
|
||||
/* Common flags */
|
||||
#define _DESC_S 0x0010
|
||||
#define _DESC_DPL(dpl) ((dpl) << 5)
|
||||
#define _DESC_PRESENT 0x0080
|
||||
|
||||
#define _DESC_LONG_CODE 0x2000
|
||||
#define _DESC_DB 0x4000
|
||||
#define _DESC_GRANULARITY_4K 0x8000
|
||||
|
||||
/* System descriptors have a numeric "type" field instead of flags */
|
||||
#define _DESC_SYSTEM(code) (code)
|
||||
|
||||
/*
|
||||
* High-level interface mapping intended usage to low-level combinations
|
||||
* of flags
|
||||
*/
|
||||
|
||||
#define _DESC_DATA (_DESC_S | _DESC_PRESENT | _DESC_ACCESSED | \
|
||||
_DESC_DATA_WRITABLE)
|
||||
#define _DESC_CODE (_DESC_S | _DESC_PRESENT | _DESC_ACCESSED | \
|
||||
_DESC_CODE_READABLE | _DESC_CODE_EXECUTABLE)
|
||||
|
||||
#define DESC_DATA16 (_DESC_DATA)
|
||||
#define DESC_CODE16 (_DESC_CODE)
|
||||
|
||||
#define DESC_DATA32 (_DESC_DATA | _DESC_GRANULARITY_4K | _DESC_DB)
|
||||
#define DESC_DATA32_BIOS (_DESC_DATA | _DESC_DB)
|
||||
|
||||
#define DESC_CODE32 (_DESC_CODE | _DESC_GRANULARITY_4K | _DESC_DB)
|
||||
#define DESC_CODE32_BIOS (_DESC_CODE | _DESC_DB)
|
||||
|
||||
#define DESC_TSS32 (_DESC_SYSTEM(9) | _DESC_PRESENT)
|
||||
|
||||
#define DESC_DATA64 (_DESC_DATA | _DESC_GRANULARITY_4K | _DESC_DB)
|
||||
#define DESC_CODE64 (_DESC_CODE | _DESC_GRANULARITY_4K | _DESC_LONG_CODE)
|
||||
|
||||
#define DESC_USER (_DESC_DPL(3))
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <linux/types.h>
|
||||
@ -22,19 +72,19 @@ struct desc_struct {
|
||||
|
||||
#define GDT_ENTRY_INIT(flags, base, limit) \
|
||||
{ \
|
||||
.limit0 = (u16) (limit), \
|
||||
.limit1 = ((limit) >> 16) & 0x0F, \
|
||||
.base0 = (u16) (base), \
|
||||
.base1 = ((base) >> 16) & 0xFF, \
|
||||
.base2 = ((base) >> 24) & 0xFF, \
|
||||
.type = (flags & 0x0f), \
|
||||
.s = (flags >> 4) & 0x01, \
|
||||
.dpl = (flags >> 5) & 0x03, \
|
||||
.p = (flags >> 7) & 0x01, \
|
||||
.avl = (flags >> 12) & 0x01, \
|
||||
.l = (flags >> 13) & 0x01, \
|
||||
.d = (flags >> 14) & 0x01, \
|
||||
.g = (flags >> 15) & 0x01, \
|
||||
.limit0 = ((limit) >> 0) & 0xFFFF, \
|
||||
.limit1 = ((limit) >> 16) & 0x000F, \
|
||||
.base0 = ((base) >> 0) & 0xFFFF, \
|
||||
.base1 = ((base) >> 16) & 0x00FF, \
|
||||
.base2 = ((base) >> 24) & 0x00FF, \
|
||||
.type = ((flags) >> 0) & 0x000F, \
|
||||
.s = ((flags) >> 4) & 0x0001, \
|
||||
.dpl = ((flags) >> 5) & 0x0003, \
|
||||
.p = ((flags) >> 7) & 0x0001, \
|
||||
.avl = ((flags) >> 12) & 0x0001, \
|
||||
.l = ((flags) >> 13) & 0x0001, \
|
||||
.d = ((flags) >> 14) & 0x0001, \
|
||||
.g = ((flags) >> 15) & 0x0001, \
|
||||
}
|
||||
|
||||
enum {
|
||||
@ -94,6 +144,7 @@ struct gate_struct {
|
||||
|
||||
typedef struct gate_struct gate_desc;
|
||||
|
||||
#ifndef _SETUP
|
||||
static inline unsigned long gate_offset(const gate_desc *g)
|
||||
{
|
||||
#ifdef CONFIG_X86_64
|
||||
@ -108,6 +159,7 @@ static inline unsigned long gate_segment(const gate_desc *g)
|
||||
{
|
||||
return g->segment;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct desc_ptr {
|
||||
unsigned short size;
|
||||
|
@ -420,7 +420,7 @@ static DEFINE_MUTEX(apm_mutex);
|
||||
* This is for buggy BIOS's that refer to (real mode) segment 0x40
|
||||
* even though they are called in protected mode.
|
||||
*/
|
||||
static struct desc_struct bad_bios_desc = GDT_ENTRY_INIT(0x4092,
|
||||
static struct desc_struct bad_bios_desc = GDT_ENTRY_INIT(DESC_DATA32_BIOS,
|
||||
(unsigned long)__va(0x400UL), PAGE_SIZE - 0x400 - 1);
|
||||
|
||||
static const char driver_version[] = "1.16ac"; /* no spaces */
|
||||
|
@ -188,45 +188,37 @@ DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = {
|
||||
* TLS descriptors are currently at a different place compared to i386.
|
||||
* Hopefully nobody expects them at a fixed place (Wine?)
|
||||
*/
|
||||
[GDT_ENTRY_KERNEL32_CS] = GDT_ENTRY_INIT(0xc09b, 0, 0xfffff),
|
||||
[GDT_ENTRY_KERNEL_CS] = GDT_ENTRY_INIT(0xa09b, 0, 0xfffff),
|
||||
[GDT_ENTRY_KERNEL_DS] = GDT_ENTRY_INIT(0xc093, 0, 0xfffff),
|
||||
[GDT_ENTRY_DEFAULT_USER32_CS] = GDT_ENTRY_INIT(0xc0fb, 0, 0xfffff),
|
||||
[GDT_ENTRY_DEFAULT_USER_DS] = GDT_ENTRY_INIT(0xc0f3, 0, 0xfffff),
|
||||
[GDT_ENTRY_DEFAULT_USER_CS] = GDT_ENTRY_INIT(0xa0fb, 0, 0xfffff),
|
||||
[GDT_ENTRY_KERNEL32_CS] = GDT_ENTRY_INIT(DESC_CODE32, 0, 0xfffff),
|
||||
[GDT_ENTRY_KERNEL_CS] = GDT_ENTRY_INIT(DESC_CODE64, 0, 0xfffff),
|
||||
[GDT_ENTRY_KERNEL_DS] = GDT_ENTRY_INIT(DESC_DATA64, 0, 0xfffff),
|
||||
[GDT_ENTRY_DEFAULT_USER32_CS] = GDT_ENTRY_INIT(DESC_CODE32 | DESC_USER, 0, 0xfffff),
|
||||
[GDT_ENTRY_DEFAULT_USER_DS] = GDT_ENTRY_INIT(DESC_DATA64 | DESC_USER, 0, 0xfffff),
|
||||
[GDT_ENTRY_DEFAULT_USER_CS] = GDT_ENTRY_INIT(DESC_CODE64 | DESC_USER, 0, 0xfffff),
|
||||
#else
|
||||
[GDT_ENTRY_KERNEL_CS] = GDT_ENTRY_INIT(0xc09a, 0, 0xfffff),
|
||||
[GDT_ENTRY_KERNEL_DS] = GDT_ENTRY_INIT(0xc092, 0, 0xfffff),
|
||||
[GDT_ENTRY_DEFAULT_USER_CS] = GDT_ENTRY_INIT(0xc0fa, 0, 0xfffff),
|
||||
[GDT_ENTRY_DEFAULT_USER_DS] = GDT_ENTRY_INIT(0xc0f2, 0, 0xfffff),
|
||||
[GDT_ENTRY_KERNEL_CS] = GDT_ENTRY_INIT(DESC_CODE32, 0, 0xfffff),
|
||||
[GDT_ENTRY_KERNEL_DS] = GDT_ENTRY_INIT(DESC_DATA32, 0, 0xfffff),
|
||||
[GDT_ENTRY_DEFAULT_USER_CS] = GDT_ENTRY_INIT(DESC_CODE32 | DESC_USER, 0, 0xfffff),
|
||||
[GDT_ENTRY_DEFAULT_USER_DS] = GDT_ENTRY_INIT(DESC_DATA32 | DESC_USER, 0, 0xfffff),
|
||||
/*
|
||||
* Segments used for calling PnP BIOS have byte granularity.
|
||||
* They code segments and data segments have fixed 64k limits,
|
||||
* the transfer segment sizes are set at run time.
|
||||
*/
|
||||
/* 32-bit code */
|
||||
[GDT_ENTRY_PNPBIOS_CS32] = GDT_ENTRY_INIT(0x409a, 0, 0xffff),
|
||||
/* 16-bit code */
|
||||
[GDT_ENTRY_PNPBIOS_CS16] = GDT_ENTRY_INIT(0x009a, 0, 0xffff),
|
||||
/* 16-bit data */
|
||||
[GDT_ENTRY_PNPBIOS_DS] = GDT_ENTRY_INIT(0x0092, 0, 0xffff),
|
||||
/* 16-bit data */
|
||||
[GDT_ENTRY_PNPBIOS_TS1] = GDT_ENTRY_INIT(0x0092, 0, 0),
|
||||
/* 16-bit data */
|
||||
[GDT_ENTRY_PNPBIOS_TS2] = GDT_ENTRY_INIT(0x0092, 0, 0),
|
||||
[GDT_ENTRY_PNPBIOS_CS32] = GDT_ENTRY_INIT(DESC_CODE32_BIOS, 0, 0xffff),
|
||||
[GDT_ENTRY_PNPBIOS_CS16] = GDT_ENTRY_INIT(DESC_CODE16, 0, 0xffff),
|
||||
[GDT_ENTRY_PNPBIOS_DS] = GDT_ENTRY_INIT(DESC_DATA16, 0, 0xffff),
|
||||
[GDT_ENTRY_PNPBIOS_TS1] = GDT_ENTRY_INIT(DESC_DATA16, 0, 0),
|
||||
[GDT_ENTRY_PNPBIOS_TS2] = GDT_ENTRY_INIT(DESC_DATA16, 0, 0),
|
||||
/*
|
||||
* The APM segments have byte granularity and their bases
|
||||
* are set at run time. All have 64k limits.
|
||||
*/
|
||||
/* 32-bit code */
|
||||
[GDT_ENTRY_APMBIOS_BASE] = GDT_ENTRY_INIT(0x409a, 0, 0xffff),
|
||||
/* 16-bit code */
|
||||
[GDT_ENTRY_APMBIOS_BASE+1] = GDT_ENTRY_INIT(0x009a, 0, 0xffff),
|
||||
/* data */
|
||||
[GDT_ENTRY_APMBIOS_BASE+2] = GDT_ENTRY_INIT(0x4092, 0, 0xffff),
|
||||
[GDT_ENTRY_APMBIOS_BASE] = GDT_ENTRY_INIT(DESC_CODE32_BIOS, 0, 0xffff),
|
||||
[GDT_ENTRY_APMBIOS_BASE+1] = GDT_ENTRY_INIT(DESC_CODE16, 0, 0xffff),
|
||||
[GDT_ENTRY_APMBIOS_BASE+2] = GDT_ENTRY_INIT(DESC_DATA32_BIOS, 0, 0xffff),
|
||||
|
||||
[GDT_ENTRY_ESPFIX_SS] = GDT_ENTRY_INIT(0xc092, 0, 0xfffff),
|
||||
[GDT_ENTRY_PERCPU] = GDT_ENTRY_INIT(0xc092, 0, 0xfffff),
|
||||
[GDT_ENTRY_ESPFIX_SS] = GDT_ENTRY_INIT(DESC_DATA32, 0, 0xfffff),
|
||||
[GDT_ENTRY_PERCPU] = GDT_ENTRY_INIT(DESC_DATA32, 0, 0xfffff),
|
||||
#endif
|
||||
} };
|
||||
EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
|
||||
|
@ -71,9 +71,9 @@ EXPORT_SYMBOL(vmemmap_base);
|
||||
* GDT used on the boot CPU before switching to virtual addresses.
|
||||
*/
|
||||
static struct desc_struct startup_gdt[GDT_ENTRIES] __initdata = {
|
||||
[GDT_ENTRY_KERNEL32_CS] = GDT_ENTRY_INIT(0xc09b, 0, 0xfffff),
|
||||
[GDT_ENTRY_KERNEL_CS] = GDT_ENTRY_INIT(0xa09b, 0, 0xfffff),
|
||||
[GDT_ENTRY_KERNEL_DS] = GDT_ENTRY_INIT(0xc093, 0, 0xfffff),
|
||||
[GDT_ENTRY_KERNEL32_CS] = GDT_ENTRY_INIT(DESC_CODE32, 0, 0xfffff),
|
||||
[GDT_ENTRY_KERNEL_CS] = GDT_ENTRY_INIT(DESC_CODE64, 0, 0xfffff),
|
||||
[GDT_ENTRY_KERNEL_DS] = GDT_ENTRY_INIT(DESC_DATA64, 0, 0xfffff),
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -106,8 +106,8 @@ void __init pcpu_populate_pte(unsigned long addr)
|
||||
static inline void setup_percpu_segment(int cpu)
|
||||
{
|
||||
#ifdef CONFIG_X86_32
|
||||
struct desc_struct d = GDT_ENTRY_INIT(0x8092, per_cpu_offset(cpu),
|
||||
0xFFFFF);
|
||||
struct desc_struct d = GDT_ENTRY_INIT(DESC_DATA32,
|
||||
per_cpu_offset(cpu), 0xFFFFF);
|
||||
|
||||
write_gdt_entry(get_cpu_gdt_rw(cpu), GDT_ENTRY_PERCPU, &d, DESCTYPE_S);
|
||||
#endif
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <linux/elfnote.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/desc_defs.h>
|
||||
#include <asm/segment.h>
|
||||
#include <asm/asm.h>
|
||||
#include <asm/boot.h>
|
||||
@ -148,11 +149,11 @@ SYM_DATA_END(gdt)
|
||||
SYM_DATA_START_LOCAL(gdt_start)
|
||||
.quad 0x0000000000000000 /* NULL descriptor */
|
||||
#ifdef CONFIG_X86_64
|
||||
.quad GDT_ENTRY(0xa09a, 0, 0xfffff) /* PVH_CS_SEL */
|
||||
.quad GDT_ENTRY(DESC_CODE64, 0, 0xfffff) /* PVH_CS_SEL */
|
||||
#else
|
||||
.quad GDT_ENTRY(0xc09a, 0, 0xfffff) /* PVH_CS_SEL */
|
||||
.quad GDT_ENTRY(DESC_CODE32, 0, 0xfffff) /* PVH_CS_SEL */
|
||||
#endif
|
||||
.quad GDT_ENTRY(0xc092, 0, 0xfffff) /* PVH_DS_SEL */
|
||||
.quad GDT_ENTRY(DESC_DATA32, 0, 0xfffff) /* PVH_DS_SEL */
|
||||
SYM_DATA_END_LABEL(gdt_start, SYM_L_LOCAL, gdt_end)
|
||||
|
||||
.balign 16
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/desc_defs.h>
|
||||
#include <asm/segment.h>
|
||||
#include <asm/page_types.h>
|
||||
#include <asm/processor-flags.h>
|
||||
@ -153,5 +154,5 @@ SYM_DATA_START(machine_real_restart_gdt)
|
||||
* base value 0x100; since this is consistent with real mode
|
||||
* semantics we don't have to reload the segments once CR0.PE = 0.
|
||||
*/
|
||||
.quad GDT_ENTRY(0x0093, 0x100, 0xffff)
|
||||
.quad GDT_ENTRY(DESC_DATA16, 0x100, 0xffff)
|
||||
SYM_DATA_END(machine_real_restart_gdt)
|
||||
|
@ -13,8 +13,8 @@ bool efi_no5lvl;
|
||||
static void (*la57_toggle)(void *cr3);
|
||||
|
||||
static const struct desc_struct gdt[] = {
|
||||
[GDT_ENTRY_KERNEL32_CS] = GDT_ENTRY_INIT(0xc09b, 0, 0xfffff),
|
||||
[GDT_ENTRY_KERNEL_CS] = GDT_ENTRY_INIT(0xa09b, 0, 0xfffff),
|
||||
[GDT_ENTRY_KERNEL32_CS] = GDT_ENTRY_INIT(DESC_CODE32, 0, 0xfffff),
|
||||
[GDT_ENTRY_KERNEL_CS] = GDT_ENTRY_INIT(DESC_CODE64, 0, 0xfffff),
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -60,7 +60,7 @@ do { \
|
||||
set_desc_limit(&gdt[(selname) >> 3], (size) - 1); \
|
||||
} while(0)
|
||||
|
||||
static struct desc_struct bad_bios_desc = GDT_ENTRY_INIT(0x4092,
|
||||
static struct desc_struct bad_bios_desc = GDT_ENTRY_INIT(DESC_DATA32_BIOS,
|
||||
(unsigned long)__va(0x400UL), PAGE_SIZE - 0x400 - 1);
|
||||
|
||||
/*
|
||||
|
Loading…
x
Reference in New Issue
Block a user