lkml.org 
[lkml]   [2017]   [Aug]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch V3 26/44] x86/gdt: Use bitfields for initialization
    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)

    \
     
     \ /
      Last update: 2017-08-28 08:58    [W:4.134 / U:0.136 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site