Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1721088

[patch V3 26/44] x86/gdt: Use bitfields for initialization

From Thomas Gleixner <tglx@linutronix.de>
Newsgroups linux.kernel
Subject [patch V3 26/44] x86/gdt: Use bitfields for initialization
Date 2017-08-28 09:00 +0200
Message-ID <ujmbG-2dY-59@gated-at.bofh.it> (permalink)
References <ujmbD-2dY-5@gated-at.bofh.it>
Organization linux.* mail to news gateway

Show all headers | View raw


The GDT entry related code uses partially bitfields and macros which
initialize the two 16 bit parts of the entry by magic shift and mask
operations.

Clean it up and use the bitfields to initialize and access entries.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/entry/vdso/vma.c        |    2 -
 arch/x86/include/asm/desc.h      |   26 ++++++++++++++---------
 arch/x86/include/asm/desc_defs.h |   44 +++++++++++++++++----------------------
 arch/x86/math-emu/fpu_system.h   |    2 -
 4 files changed, 38 insertions(+), 36 deletions(-)

--- a/arch/x86/entry/vdso/vma.c
+++ b/arch/x86/entry/vdso/vma.c
@@ -351,7 +351,7 @@ static void vgetcpu_cpu_init(void *arg)
 	 * and 8 bits for the node)
 	 */
 	d.limit0 = cpu | ((node & 0xf) << 12);
-	d.limit = node >> 4;
+	d.limit1 = node >> 4;
 	d.type = 5;		/* RO data, expand down, accessed */
 	d.dpl = 3;		/* Visible to user code */
 	d.s = 1;		/* Not a system segment */
--- a/arch/x86/include/asm/desc.h
+++ b/arch/x86/include/asm/desc.h
@@ -23,7 +23,7 @@ static inline void fill_ldt(struct desc_
 	desc->s			= 1;
 	desc->dpl		= 0x3;
 	desc->p			= info->seg_not_present ^ 1;
-	desc->limit		= (info->limit & 0xf0000) >> 16;
+	desc->limit1		= (info->limit & 0xf0000) >> 16;
 	desc->avl		= info->useable;
 	desc->d			= info->seg_32bit;
 	desc->g			= info->limit_in_pages;
@@ -170,14 +170,20 @@ static inline void pack_descriptor(struc
 				   unsigned long limit, unsigned char type,
 				   unsigned char flags)
 {
-	desc->a = ((base & 0xffff) << 16) | (limit & 0xffff);
-	desc->b = (base & 0xff000000) | ((base & 0xff0000) >> 16) |
-		(limit & 0x000f0000) | ((type & 0xff) << 8) |
-		((flags & 0xf) << 20);
-	desc->p = 1;
+	desc->limit0		= (u16) limit;
+	desc->base0		= (u16) base;
+	desc->base1		= (base >> 16) & 0xFF;
+	desc->type		= type & 0x0F;
+	desc->s			= 0;
+	desc->dpl		= 0;
+	desc->p			= 1;
+	desc->limit1		= (limit >> 16) & 0xF;
+	desc->avl		= (flags >> 0) & 0x01;
+	desc->l			= (flags >> 1) & 0x01;
+	desc->d			= (flags >> 2) & 0x01;
+	desc->g			= (flags >> 3) & 0x01;
 }
 
-
 static inline void set_tssldt_descriptor(void *d, unsigned long addr,
 					 unsigned type, unsigned size)
 {
@@ -195,7 +201,7 @@ static inline void set_tssldt_descriptor
 	desc->base2		= (addr >> 24) & 0xFF;
 	desc->base3		= (u32) (addr >> 32);
 #else
-	pack_descriptor((struct desc_struct *)d, addr, size, 0x80 | type, 0);
+	pack_descriptor((struct desc_struct *)d, addr, size, type, 0);
 #endif
 }
 
@@ -395,13 +401,13 @@ static inline void set_desc_base(struct
 
 static inline unsigned long get_desc_limit(const struct desc_struct *desc)
 {
-	return desc->limit0 | (desc->limit << 16);
+	return desc->limit0 | (desc->limit1 << 16);
 }
 
 static inline void set_desc_limit(struct desc_struct *desc, unsigned long limit)
 {
 	desc->limit0 = limit & 0xffff;
-	desc->limit = (limit >> 16) & 0xf;
+	desc->limit1 = (limit >> 16) & 0xf;
 }
 
 #ifdef CONFIG_X86_64
--- a/arch/x86/include/asm/desc_defs.h
+++ b/arch/x86/include/asm/desc_defs.h
@@ -11,34 +11,30 @@
 
 #include <linux/types.h>
 
-/*
- * FIXME: Accessing the desc_struct through its fields is more elegant,
- * and should be the one valid thing to do. However, a lot of open code
- * still touches the a and b accessors, and doing this allow us to do it
- * incrementally. We keep the signature as a struct, rather than a union,
- * so we can get rid of it transparently in the future -- glommer
- */
 /* 8 byte segment descriptor */
 struct desc_struct {
-	union {
-		struct {
-			unsigned int a;
-			unsigned int b;
-		};
-		struct {
-			u16 limit0;
-			u16 base0;
-			unsigned base1: 8, type: 4, s: 1, dpl: 2, p: 1;
-			unsigned limit: 4, avl: 1, l: 1, d: 1, g: 1, base2: 8;
-		};
-	};
+	u16	limit0;
+	u16	base0;
+	u16	base1: 8, type: 4, s: 1, dpl: 2, p: 1;
+	u16	limit1: 4, avl: 1, l: 1, d: 1, g: 1, base2: 8;
 } __attribute__((packed));
 
-#define GDT_ENTRY_INIT(flags, base, limit) { { { \
-		.a = ((limit) & 0xffff) | (((base) & 0xffff) << 16), \
-		.b = (((base) & 0xff0000) >> 16) | (((flags) & 0xf0ff) << 8) | \
-			((limit) & 0xf0000) | ((base) & 0xff000000), \
-	} } }
+#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,		\
+	}
 
 enum {
 	GATE_INTERRUPT = 0xE,
--- a/arch/x86/math-emu/fpu_system.h
+++ b/arch/x86/math-emu/fpu_system.h
@@ -49,7 +49,7 @@ static inline unsigned long seg_get_base
 
 static inline unsigned long seg_get_limit(struct desc_struct *d)
 {
-	return ((unsigned long)d->limit << 16) | d->limit0;
+	return ((unsigned long)d->limit1 << 16) | d->limit0;
 }
 
 static inline unsigned long seg_get_granularity(struct desc_struct *d)

Back to linux.kernel | Previous | NextNext in thread | Find similar | Unroll thread


Thread

[patch V3 26/44] x86/gdt: Use bitfields for initialization Thomas Gleixner <tglx@linutronix.de> - 2017-08-28 09:00 +0200
  [tip:x86/apic] x86/gdt: Use bitfields for initialization tip-bot for Thomas Gleixner <tipbot@zytor.com> - 2017-08-29 13:30 +0200

csiph-web