aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/desc.h13
-rw-r--r--arch/x86/include/asm/stackprotector.h4
-rw-r--r--arch/x86/include/asm/system.h27
-rw-r--r--arch/x86/kernel/apm_32.c18
-rw-r--r--drivers/pnp/pnpbios/bioscalls.c21
5 files changed, 34 insertions, 49 deletions
diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h
index c993e9e0fed4..e8de2f6f5ca5 100644
--- a/arch/x86/include/asm/desc.h
+++ b/arch/x86/include/asm/desc.h
@@ -291,11 +291,24 @@ static inline unsigned long get_desc_base(const struct desc_struct *desc)
291 return desc->base0 | ((desc->base1) << 16) | ((desc->base2) << 24); 291 return desc->base0 | ((desc->base1) << 16) | ((desc->base2) << 24);
292} 292}
293 293
294static inline void set_desc_base(struct desc_struct *desc, unsigned long base)
295{
296 desc->base0 = base & 0xffff;
297 desc->base1 = (base >> 16) & 0xff;
298 desc->base2 = (base >> 24) & 0xff;
299}
300
294static inline unsigned long get_desc_limit(const struct desc_struct *desc) 301static inline unsigned long get_desc_limit(const struct desc_struct *desc)
295{ 302{
296 return desc->limit0 | (desc->limit << 16); 303 return desc->limit0 | (desc->limit << 16);
297} 304}
298 305
306static inline void set_desc_limit(struct desc_struct *desc, unsigned long limit)
307{
308 desc->limit0 = limit & 0xffff;
309 desc->limit = (limit >> 16) & 0xf;
310}
311
299static inline void _set_gate(int gate, unsigned type, void *addr, 312static inline void _set_gate(int gate, unsigned type, void *addr,
300 unsigned dpl, unsigned ist, unsigned seg) 313 unsigned dpl, unsigned ist, unsigned seg)
301{ 314{
diff --git a/arch/x86/include/asm/stackprotector.h b/arch/x86/include/asm/stackprotector.h
index c2d742c6e15f..cdc5e0b126a7 100644
--- a/arch/x86/include/asm/stackprotector.h
+++ b/arch/x86/include/asm/stackprotector.h
@@ -90,9 +90,7 @@ static inline void setup_stack_canary_segment(int cpu)
90 struct desc_struct desc; 90 struct desc_struct desc;
91 91
92 desc = gdt_table[GDT_ENTRY_STACK_CANARY]; 92 desc = gdt_table[GDT_ENTRY_STACK_CANARY];
93 desc.base0 = canary & 0xffff; 93 set_desc_base(&desc, canary);
94 desc.base1 = (canary >> 16) & 0xff;
95 desc.base2 = (canary >> 24) & 0xff;
96 write_gdt_entry(gdt_table, GDT_ENTRY_STACK_CANARY, &desc, DESCTYPE_S); 94 write_gdt_entry(gdt_table, GDT_ENTRY_STACK_CANARY, &desc, DESCTYPE_S);
97#endif 95#endif
98} 96}
diff --git a/arch/x86/include/asm/system.h b/arch/x86/include/asm/system.h
index 643c59b4bc6e..75c49c782e20 100644
--- a/arch/x86/include/asm/system.h
+++ b/arch/x86/include/asm/system.h
@@ -150,33 +150,6 @@ do { \
150#endif 150#endif
151 151
152#ifdef __KERNEL__ 152#ifdef __KERNEL__
153#define _set_base(addr, base) do { unsigned long __pr; \
154__asm__ __volatile__ ("movw %%dx,%1\n\t" \
155 "rorl $16,%%edx\n\t" \
156 "movb %%dl,%2\n\t" \
157 "movb %%dh,%3" \
158 :"=&d" (__pr) \
159 :"m" (*((addr)+2)), \
160 "m" (*((addr)+4)), \
161 "m" (*((addr)+7)), \
162 "0" (base) \
163 ); } while (0)
164
165#define _set_limit(addr, limit) do { unsigned long __lr; \
166__asm__ __volatile__ ("movw %%dx,%1\n\t" \
167 "rorl $16,%%edx\n\t" \
168 "movb %2,%%dh\n\t" \
169 "andb $0xf0,%%dh\n\t" \
170 "orb %%dh,%%dl\n\t" \
171 "movb %%dl,%2" \
172 :"=&d" (__lr) \
173 :"m" (*(addr)), \
174 "m" (*((addr)+6)), \
175 "0" (limit) \
176 ); } while (0)
177
178#define set_base(ldt, base) _set_base(((char *)&(ldt)) , (base))
179#define set_limit(ldt, limit) _set_limit(((char *)&(ldt)) , ((limit)-1))
180 153
181extern void native_load_gs_index(unsigned); 154extern void native_load_gs_index(unsigned);
182 155
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c
index 79302e9a33a4..b5e841bd60d9 100644
--- a/arch/x86/kernel/apm_32.c
+++ b/arch/x86/kernel/apm_32.c
@@ -403,7 +403,7 @@ static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue);
403static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue); 403static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
404static struct apm_user *user_list; 404static struct apm_user *user_list;
405static DEFINE_SPINLOCK(user_list_lock); 405static DEFINE_SPINLOCK(user_list_lock);
406static const struct desc_struct bad_bios_desc = { { { 0, 0x00409200 } } }; 406static struct desc_struct bad_bios_desc = { { { 0, 0x00409200 } } };
407 407
408static const char driver_version[] = "1.16ac"; /* no spaces */ 408static const char driver_version[] = "1.16ac"; /* no spaces */
409 409
@@ -2337,8 +2337,8 @@ static int __init apm_init(void)
2337 * This is for buggy BIOS's that refer to (real mode) segment 0x40 2337 * This is for buggy BIOS's that refer to (real mode) segment 0x40
2338 * even though they are called in protected mode. 2338 * even though they are called in protected mode.
2339 */ 2339 */
2340 set_base(bad_bios_desc, __va((unsigned long)0x40 << 4)); 2340 set_desc_base(&bad_bios_desc, (unsigned long)__va(0x40UL << 4));
2341 _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4)); 2341 set_desc_limit(&bad_bios_desc, 4095 - (0x40 << 4));
2342 2342
2343 /* 2343 /*
2344 * Set up the long jump entry point to the APM BIOS, which is called 2344 * Set up the long jump entry point to the APM BIOS, which is called
@@ -2358,12 +2358,12 @@ static int __init apm_init(void)
2358 * code to that CPU. 2358 * code to that CPU.
2359 */ 2359 */
2360 gdt = get_cpu_gdt_table(0); 2360 gdt = get_cpu_gdt_table(0);
2361 set_base(gdt[APM_CS >> 3], 2361 set_desc_base(&gdt[APM_CS >> 3],
2362 __va((unsigned long)apm_info.bios.cseg << 4)); 2362 (unsigned long)__va((unsigned long)apm_info.bios.cseg << 4));
2363 set_base(gdt[APM_CS_16 >> 3], 2363 set_desc_base(&gdt[APM_CS_16 >> 3],
2364 __va((unsigned long)apm_info.bios.cseg_16 << 4)); 2364 (unsigned long)__va((unsigned long)apm_info.bios.cseg_16 << 4));
2365 set_base(gdt[APM_DS >> 3], 2365 set_desc_base(&gdt[APM_DS >> 3],
2366 __va((unsigned long)apm_info.bios.dseg << 4)); 2366 (unsigned long)__va((unsigned long)apm_info.bios.dseg << 4));
2367 2367
2368 proc_create("apm", 0, NULL, &apm_file_ops); 2368 proc_create("apm", 0, NULL, &apm_file_ops);
2369 2369
diff --git a/drivers/pnp/pnpbios/bioscalls.c b/drivers/pnp/pnpbios/bioscalls.c
index 7e6b5a3b3281..45ad3e9cc362 100644
--- a/drivers/pnp/pnpbios/bioscalls.c
+++ b/drivers/pnp/pnpbios/bioscalls.c
@@ -55,9 +55,9 @@ __asm__(".text \n"
55 55
56#define Q2_SET_SEL(cpu, selname, address, size) \ 56#define Q2_SET_SEL(cpu, selname, address, size) \
57do { \ 57do { \
58struct desc_struct *gdt = get_cpu_gdt_table((cpu)); \ 58 struct desc_struct *gdt = get_cpu_gdt_table((cpu)); \
59set_base(gdt[(selname) >> 3], (u32)(address)); \ 59 set_desc_base(&gdt[(selname) >> 3], (u32)(address)); \
60set_limit(gdt[(selname) >> 3], size); \ 60 set_desc_limit(&gdt[(selname) >> 3], (size) - 1); \
61} while(0) 61} while(0)
62 62
63static struct desc_struct bad_bios_desc; 63static struct desc_struct bad_bios_desc;
@@ -479,16 +479,17 @@ void pnpbios_calls_init(union pnp_bios_install_struct *header)
479 bad_bios_desc.a = 0; 479 bad_bios_desc.a = 0;
480 bad_bios_desc.b = 0x00409200; 480 bad_bios_desc.b = 0x00409200;
481 481
482 set_base(bad_bios_desc, __va((unsigned long)0x40 << 4)); 482 set_desc_base(&bad_bios_desc, (unsigned long)__va(0x40UL << 4));
483 _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4)); 483 set_desc_limit(&bad_bios_desc, 4095 - (0x40 << 4));
484 for_each_possible_cpu(i) { 484 for_each_possible_cpu(i) {
485 struct desc_struct *gdt = get_cpu_gdt_table(i); 485 struct desc_struct *gdt = get_cpu_gdt_table(i);
486 if (!gdt) 486 if (!gdt)
487 continue; 487 continue;
488 set_base(gdt[GDT_ENTRY_PNPBIOS_CS32], &pnp_bios_callfunc); 488 set_desc_base(&gdt[GDT_ENTRY_PNPBIOS_CS32],
489 set_base(gdt[GDT_ENTRY_PNPBIOS_CS16], 489 (unsigned long)&pnp_bios_callfunc);
490 __va(header->fields.pm16cseg)); 490 set_desc_base(&gdt[GDT_ENTRY_PNPBIOS_CS16],
491 set_base(gdt[GDT_ENTRY_PNPBIOS_DS], 491 (unsigned long)__va(header->fields.pm16cseg));
492 __va(header->fields.pm16dseg)); 492 set_desc_base(&gdt[GDT_ENTRY_PNPBIOS_DS],
493 (unsigned long)__va(header->fields.pm16dseg));
493 } 494 }
494} 495}