public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Thomas Gleixner <tglx@linutronix.de>
To: LKML <linux-kernel@vger.kernel.org>
Cc: Ingo Molnar <mingo@kernel.org>, Peter Anvin <hpa@zytor.com>,
	Peter Zijlstra <peterz@infradead.org>,
	Andy Lutomirski <luto@kernel.org>, Borislav Petkov <bp@alien8.de>,
	Steven Rostedt <rostedt@goodmis.org>
Subject: [patch V2 22/44] x86/idt: Unify gate_struct handling for 32/64bit
Date: Fri, 25 Aug 2017 23:47:10 +0200	[thread overview]
Message-ID: <20170825214941.963740833@linutronix.de> (raw)
In-Reply-To: 20170825214648.264521964@linutronix.de

[-- Attachment #1: x86-idt--Unify-gate_struct-handling-for-32-64bit.patch --]
[-- Type: text/plain, Size: 7337 bytes --]

The first 32bits of gate struct are the same for 32 and 64 bit. The 32bit
version uses desc_struct and no designated data structure, so we need
different accessors for 32 and 64 bit. Aside of that the macros which are
necessary to build the 32bit gate descriptor are horrible to read.

Unify the gate structs and switch all code fiddling with it over.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/boot/compressed/eboot.c |    8 ++---
 arch/x86/include/asm/desc.h      |   45 +++++++++++++-----------------
 arch/x86/include/asm/desc_defs.h |   57 +++++++++++++++++++++++++--------------
 arch/x86/kvm/vmx.c               |    2 -
 arch/x86/xen/enlighten_pv.c      |   12 ++++----
 5 files changed, 67 insertions(+), 57 deletions(-)

--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -1058,7 +1058,7 @@ struct boot_params *efi_main(struct efi_
 		desc->s = DESC_TYPE_CODE_DATA;
 		desc->dpl = 0;
 		desc->p = 1;
-		desc->limit = 0xf;
+		desc->limit1 = 0xf;
 		desc->avl = 0;
 		desc->l = 0;
 		desc->d = SEG_OP_SIZE_32BIT;
@@ -1078,7 +1078,7 @@ struct boot_params *efi_main(struct efi_
 	desc->s = DESC_TYPE_CODE_DATA;
 	desc->dpl = 0;
 	desc->p = 1;
-	desc->limit = 0xf;
+	desc->limit1 = 0xf;
 	desc->avl = 0;
 	if (IS_ENABLED(CONFIG_X86_64)) {
 		desc->l = 1;
@@ -1099,7 +1099,7 @@ struct boot_params *efi_main(struct efi_
 	desc->s = DESC_TYPE_CODE_DATA;
 	desc->dpl = 0;
 	desc->p = 1;
-	desc->limit = 0xf;
+	desc->limit1 = 0xf;
 	desc->avl = 0;
 	desc->l = 0;
 	desc->d = SEG_OP_SIZE_32BIT;
@@ -1116,7 +1116,7 @@ struct boot_params *efi_main(struct efi_
 		desc->s = 0;
 		desc->dpl = 0;
 		desc->p = 1;
-		desc->limit = 0x0;
+		desc->limit1 = 0x0;
 		desc->avl = 0;
 		desc->l = 0;
 		desc->d = 0;
--- a/arch/x86/include/asm/desc.h
+++ b/arch/x86/include/asm/desc.h
@@ -84,33 +84,25 @@ static inline phys_addr_t get_cpu_gdt_pa
 	return per_cpu_ptr_to_phys(get_cpu_gdt_rw(cpu));
 }
 
-#ifdef CONFIG_X86_64
-
 static inline void pack_gate(gate_desc *gate, unsigned type, unsigned long func,
 			     unsigned dpl, unsigned ist, unsigned seg)
 {
-	gate->offset_low	= PTR_LOW(func);
+	gate->offset_low	= (u16) func;
+	gate->bits.p		= 1;
+	gate->bits.dpl		= dpl;
+	gate->bits.zero		= 0;
+	gate->bits.type		= type;
+	gate->offset_middle	= (u16) (func >> 16);
+#ifdef CONFIG_X86_64
 	gate->segment		= __KERNEL_CS;
-	gate->ist		= ist;
-	gate->p			= 1;
-	gate->dpl		= dpl;
-	gate->zero0		= 0;
-	gate->zero1		= 0;
-	gate->type		= type;
-	gate->offset_middle	= PTR_MIDDLE(func);
-	gate->offset_high	= PTR_HIGH(func);
-}
-
+	gate->bits.ist		= ist;
+	gate->reserved		= 0;
+	gate->offset_high	= (u32) (func >> 32);
 #else
-static inline void pack_gate(gate_desc *gate, unsigned char type,
-			     unsigned long base, unsigned dpl, unsigned flags,
-			     unsigned short seg)
-{
-	gate->a = (seg << 16) | (base & 0xffff);
-	gate->b = (base & 0xffff0000) | (((0x80 | type | (dpl << 5)) & 0xff) << 8);
-}
-
+	gate->segment		= seg;
+	gate->bits.ist		= 0;
 #endif
+}
 
 static inline int desc_empty(const void *ptr)
 {
@@ -186,7 +178,8 @@ static inline void pack_descriptor(struc
 }
 
 
-static inline void set_tssldt_descriptor(void *d, unsigned long addr, unsigned type, unsigned size)
+static inline void set_tssldt_descriptor(void *d, unsigned long addr,
+					 unsigned type, unsigned size)
 {
 #ifdef CONFIG_X86_64
 	struct ldttss_desc64 *desc = d;
@@ -194,13 +187,13 @@ static inline void set_tssldt_descriptor
 	memset(desc, 0, sizeof(*desc));
 
 	desc->limit0		= size & 0xFFFF;
-	desc->base0		= PTR_LOW(addr);
-	desc->base1		= PTR_MIDDLE(addr) & 0xFF;
+	desc->base0		= (u16) addr;
+	desc->base1		= (addr >> 16) & 0xFF;
 	desc->type		= type;
 	desc->p			= 1;
 	desc->limit1		= (size >> 16) & 0xF;
-	desc->base2		= (PTR_MIDDLE(addr) >> 8) & 0xFF;
-	desc->base3		= PTR_HIGH(addr);
+	desc->base2		= (addr >> 24) & 0xFF;
+	desc->base3		= (u32) (addr >> 32);
 #else
 	pack_descriptor((struct desc_struct *)d, addr, size, 0x80 | type, 0);
 #endif
--- a/arch/x86/include/asm/desc_defs.h
+++ b/arch/x86/include/asm/desc_defs.h
@@ -47,20 +47,6 @@ enum {
 	GATE_TASK = 0x5,
 };
 
-/* 16byte gate */
-struct gate_struct64 {
-	u16 offset_low;
-	u16 segment;
-	unsigned ist : 3, zero0 : 5, type : 5, dpl : 2, p : 1;
-	u16 offset_middle;
-	u32 offset_high;
-	u32 zero1;
-} __attribute__((packed));
-
-#define PTR_LOW(x) ((unsigned long long)(x) & 0xFFFF)
-#define PTR_MIDDLE(x) (((unsigned long long)(x) >> 16) & 0xFFFF)
-#define PTR_HIGH(x) ((unsigned long long)(x) >> 32)
-
 enum {
 	DESC_TSS = 0x9,
 	DESC_LDT = 0x2,
@@ -77,20 +63,51 @@ struct ldttss_desc64 {
 	u32 zero1;
 } __attribute__((packed));
 
+
 #ifdef CONFIG_X86_64
-typedef struct gate_struct64 gate_desc;
 typedef struct ldttss_desc64 ldt_desc;
 typedef struct ldttss_desc64 tss_desc;
-#define gate_offset(g) ((g).offset_low | ((unsigned long)(g).offset_middle << 16) | ((unsigned long)(g).offset_high << 32))
-#define gate_segment(g) ((g).segment)
 #else
-typedef struct desc_struct gate_desc;
 typedef struct desc_struct ldt_desc;
 typedef struct desc_struct tss_desc;
-#define gate_offset(g)		(((g).b & 0xffff0000) | ((g).a & 0x0000ffff))
-#define gate_segment(g)		((g).a >> 16)
 #endif
 
+struct idt_bits {
+	u16		ist	: 3,
+			zero	: 5,
+			type	: 5,
+			dpl	: 2,
+			p	: 1;
+} __attribute__((packed));
+
+struct gate_struct {
+	u16		offset_low;
+	u16		segment;
+	struct idt_bits	bits;
+	u16		offset_middle;
+#ifdef CONFIG_X86_64
+	u32		offset_high;
+	u32		reserved;
+#endif
+} __attribute__((packed));
+
+typedef struct gate_struct gate_desc;
+
+static inline unsigned long gate_offset(const gate_desc *g)
+{
+#ifdef CONFIG_X86_64
+	return g->offset_low | ((unsigned long)g->offset_middle << 16) |
+		((unsigned long) g->offset_high << 32);
+#else
+	return g->offset_low | ((unsigned long)g->offset_middle << 16);
+#endif
+}
+
+static inline unsigned long gate_segment(const gate_desc *g)
+{
+	return g->segment;
+}
+
 struct desc_ptr {
 	unsigned short size;
 	unsigned long address;
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -8786,7 +8786,7 @@ static void vmx_handle_external_intr(str
 
 		vector =  exit_intr_info & INTR_INFO_VECTOR_MASK;
 		desc = (gate_desc *)vmx->host_idt_base + vector;
-		entry = gate_offset(*desc);
+		entry = gate_offset(desc);
 		asm volatile(
 #ifdef CONFIG_X86_64
 			"mov %%" _ASM_SP ", %[sp]\n\t"
--- a/arch/x86/xen/enlighten_pv.c
+++ b/arch/x86/xen/enlighten_pv.c
@@ -584,12 +584,12 @@ static int cvt_gate_to_trap(int vector,
 {
 	unsigned long addr;
 
-	if (val->type != GATE_TRAP && val->type != GATE_INTERRUPT)
+	if (val->bits.type != GATE_TRAP && val->bits.type != GATE_INTERRUPT)
 		return 0;
 
 	info->vector = vector;
 
-	addr = gate_offset(*val);
+	addr = gate_offset(val);
 #ifdef CONFIG_X86_64
 	/*
 	 * Look for known traps using IST, and substitute them
@@ -622,16 +622,16 @@ static int cvt_gate_to_trap(int vector,
 		;
 	else {
 		/* Some other trap using IST? */
-		if (WARN_ON(val->ist != 0))
+		if (WARN_ON(val->bits.ist != 0))
 			return 0;
 	}
 #endif	/* CONFIG_X86_64 */
 	info->address = addr;
 
-	info->cs = gate_segment(*val);
-	info->flags = val->dpl;
+	info->cs = gate_segment(val);
+	info->flags = val->bits.dpl;
 	/* interrupt gates clear IF */
-	if (val->type == GATE_INTERRUPT)
+	if (val->bits.type == GATE_INTERRUPT)
 		info->flags |= 1 << 2;
 
 	return 1;

  parent reply	other threads:[~2017-08-25 22:04 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-08-25 21:46 [patch V2 00/44] x86: Cleanup IDT code Thomas Gleixner
2017-08-25 21:46 ` [patch V2 01/44] x86/irq: Remove vector_used_by_percpu_irq() Thomas Gleixner
2017-08-25 21:46 ` [patch V2 02/44] x86/irq: Unexport used_vectors Thomas Gleixner
2017-08-25 21:46 ` [patch V2 03/44] x86/irq: Get rid of the first_system_vector bogisity Thomas Gleixner
2017-08-25 21:46 ` [patch V2 04/44] x86/irq: Remove duplicated used_vectors definition Thomas Gleixner
2017-08-25 21:46 ` [patch V2 05/44] x86/boot: Move EISA setup to a proper place Thomas Gleixner
2017-08-25 21:46 ` [patch V2 06/44] x86/tracing: Introduce a static key for exception tracing Thomas Gleixner
2017-08-25 21:46 ` [patch V2 07/44] x86/traps: Simplify pagefault tracing logic Thomas Gleixner
2017-08-25 21:46 ` [patch V2 08/44] x86/apic: Remove the duplicated tracing version of local_timer_interrupt Thomas Gleixner
2017-08-25 21:46 ` [patch V2 09/44] x86/apic: Use this_cpu_ptr in local_timer_interrupt Thomas Gleixner
2017-08-25 21:46 ` [patch V2 10/44] x86/irq: Get rid of duplicated trace_x86_platform_ipi() code Thomas Gleixner
2017-08-25 21:46 ` [patch V2 11/44] x86/apic: Remove the duplicated tracing versions of interrupts Thomas Gleixner
2017-08-25 21:47 ` [patch V2 12/44] x86/irqwork: Get rid of duplicated tracing interrupt code Thomas Gleixner
2017-08-25 21:47 ` [patch V2 13/44] x86/mce: Remove " Thomas Gleixner
2017-08-25 21:47 ` [patch V2 14/44] x86/smp: Remove pointless duplicated " Thomas Gleixner
2017-08-25 21:47 ` [patch V2 15/44] x86/smp: Use static key for reschedule interrupt tracing Thomas Gleixner
2017-08-25 21:47 ` [patch V2 16/44] x86/idt: Remove tracing idt completely Thomas Gleixner
2017-08-25 21:47 ` [patch V2 17/44] x86/idt: Cleanup the i386 low level entry macros Thomas Gleixner
2017-08-25 21:47 ` [patch V2 18/44] x86/tracing: Disentangle pagefault and resched IPI tracing key Thomas Gleixner
2017-08-25 21:47 ` [patch V2 19/44] x86/ipi: Make platform IPI depend on APIC Thomas Gleixner
2017-08-25 21:47 ` [patch V2 20/44] x86/irq_work: Make it " Thomas Gleixner
2017-08-25 21:47 ` [patch V2 21/44] x86/tracing: Build tracepoints only when they are used Thomas Gleixner
2017-08-25 21:47 ` Thomas Gleixner [this message]
2017-08-25 21:47 ` [patch V2 23/44] x86/percpu: Use static initializer for GDT entry Thomas Gleixner
2017-08-25 21:47 ` [patch V2 24/44] x86/fpu: Use bitfield accessors for desc_struct Thomas Gleixner
2017-08-25 21:47 ` [patch V2 25/44] x86: Replace access to desc_struct:a/b fields Thomas Gleixner
2017-08-26  2:16   ` Boris Ostrovsky
2017-08-25 21:47 ` [patch V2 26/44] x86/gdt: Use bitfields for initialization Thomas Gleixner
2017-08-25 21:47 ` [patch V2 27/44] x86/ldttss: Cleanup 32bit descriptors Thomas Gleixner
2017-08-25 21:47 ` [patch V2 28/44] x86/idt: Create file for IDT related code Thomas Gleixner
2017-08-25 21:47 ` [patch V2 29/44] x86/idt: Move 32bit idt_descr to C code Thomas Gleixner
2017-08-25 21:47 ` [patch V2 30/44] x86/idt: Remove unused set_trap_gate() Thomas Gleixner
2017-08-25 21:47 ` [patch V2 31/44] x86/idt: Consolidate IDT invalidation Thomas Gleixner
2017-08-25 21:47 ` [patch V2 32/44] x86/idt: Move early IDT handler setup to IDT code Thomas Gleixner
2017-08-25 21:47 ` [patch V2 33/44] x86/idt: Move early IDT setup out of 32bit asm Thomas Gleixner
2017-08-25 21:47 ` [patch V2 34/44] x86/idt: Prepare for table based init Thomas Gleixner
2017-08-25 21:47 ` [patch V2 35/44] x86/idt: Switch early trap init to IDT tables Thomas Gleixner
2017-08-26  2:24   ` Boris Ostrovsky
2017-08-26  8:16     ` Thomas Gleixner
2017-08-26 10:59       ` Juergen Gross
2017-08-26 13:05         ` Thomas Gleixner
2017-08-26 15:07           ` Boris Ostrovsky
2017-08-25 21:47 ` [patch V2 36/44] x86/idt: Move debug stack init to table based Thomas Gleixner
2017-08-25 21:47 ` [patch V2 37/44] x86/idt: Move ist stack based traps to table init Thomas Gleixner
2017-08-25 21:47 ` [patch V2 38/44] x86/idt: Move regular trap init to tables Thomas Gleixner
2017-08-25 21:47 ` [patch V2 39/44] x86/idt: Move APIC gate initialization " Thomas Gleixner
2017-08-25 21:47 ` [patch V2 40/44] x86/idt: Move interrupt gate initialization to IDT code Thomas Gleixner
2017-08-25 21:47 ` [patch V2 41/44] x86/idt: Remove unused functions/inlines Thomas Gleixner
2017-08-25 21:47 ` [patch V2 42/44] x86/idt: Deinline setup functions Thomas Gleixner
2017-08-25 21:47 ` [patch V2 43/44] x86/idt: Simplify alloc_intr_gate Thomas Gleixner
2017-08-25 21:47 ` [patch V2 44/44] x86/idt: Hide set_intr_gate() Thomas Gleixner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170825214941.963740833@linutronix.de \
    --to=tglx@linutronix.de \
    --cc=bp@alien8.de \
    --cc=hpa@zytor.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=mingo@kernel.org \
    --cc=peterz@infradead.org \
    --cc=rostedt@goodmis.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox