aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/math-emu/get_address.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-02-13 07:05:57 -0500
committerIngo Molnar <mingo@elte.hu>2009-02-13 07:05:57 -0500
commitd040c1614c24162adc3fe106b182596999264e26 (patch)
tree5af02052e633bcde0e33f77cac52ab4685ad07f1 /arch/x86/math-emu/get_address.c
parentd88316c243e5458a1888edbe0353c4dec6e61c73 (diff)
parent7032e8696726354d6180d8a2d17191f958cd93ae (diff)
Merge branch 'x86/core' into x86/headers
Diffstat (limited to 'arch/x86/math-emu/get_address.c')
-rw-r--r--arch/x86/math-emu/get_address.c75
1 files changed, 35 insertions, 40 deletions
diff --git a/arch/x86/math-emu/get_address.c b/arch/x86/math-emu/get_address.c
index d701e2b39e44..6ef5e99380f9 100644
--- a/arch/x86/math-emu/get_address.c
+++ b/arch/x86/math-emu/get_address.c
@@ -29,46 +29,43 @@
29#define FPU_WRITE_BIT 0x10 29#define FPU_WRITE_BIT 0x10
30 30
31static int reg_offset[] = { 31static int reg_offset[] = {
32 offsetof(struct info, ___eax), 32 offsetof(struct pt_regs, ax),
33 offsetof(struct info, ___ecx), 33 offsetof(struct pt_regs, cx),
34 offsetof(struct info, ___edx), 34 offsetof(struct pt_regs, dx),
35 offsetof(struct info, ___ebx), 35 offsetof(struct pt_regs, bx),
36 offsetof(struct info, ___esp), 36 offsetof(struct pt_regs, sp),
37 offsetof(struct info, ___ebp), 37 offsetof(struct pt_regs, bp),
38 offsetof(struct info, ___esi), 38 offsetof(struct pt_regs, si),
39 offsetof(struct info, ___edi) 39 offsetof(struct pt_regs, di)
40}; 40};
41 41
42#define REG_(x) (*(long *)(reg_offset[(x)]+(u_char *) FPU_info)) 42#define REG_(x) (*(long *)(reg_offset[(x)] + (u_char *)FPU_info->regs))
43 43
44static int reg_offset_vm86[] = { 44static int reg_offset_vm86[] = {
45 offsetof(struct info, ___cs), 45 offsetof(struct pt_regs, cs),
46 offsetof(struct info, ___vm86_ds), 46 offsetof(struct kernel_vm86_regs, ds),
47 offsetof(struct info, ___vm86_es), 47 offsetof(struct kernel_vm86_regs, es),
48 offsetof(struct info, ___vm86_fs), 48 offsetof(struct kernel_vm86_regs, fs),
49 offsetof(struct info, ___vm86_gs), 49 offsetof(struct kernel_vm86_regs, gs),
50 offsetof(struct info, ___ss), 50 offsetof(struct pt_regs, ss),
51 offsetof(struct info, ___vm86_ds) 51 offsetof(struct kernel_vm86_regs, ds)
52}; 52};
53 53
54#define VM86_REG_(x) (*(unsigned short *) \ 54#define VM86_REG_(x) (*(unsigned short *) \
55 (reg_offset_vm86[((unsigned)x)]+(u_char *) FPU_info)) 55 (reg_offset_vm86[((unsigned)x)] + (u_char *)FPU_info->regs))
56
57/* This dummy, gs is not saved on the stack. */
58#define ___GS ___ds
59 56
60static int reg_offset_pm[] = { 57static int reg_offset_pm[] = {
61 offsetof(struct info, ___cs), 58 offsetof(struct pt_regs, cs),
62 offsetof(struct info, ___ds), 59 offsetof(struct pt_regs, ds),
63 offsetof(struct info, ___es), 60 offsetof(struct pt_regs, es),
64 offsetof(struct info, ___fs), 61 offsetof(struct pt_regs, fs),
65 offsetof(struct info, ___GS), 62 offsetof(struct pt_regs, ds), /* dummy, not saved on stack */
66 offsetof(struct info, ___ss), 63 offsetof(struct pt_regs, ss),
67 offsetof(struct info, ___ds) 64 offsetof(struct pt_regs, ds)
68}; 65};
69 66
70#define PM_REG_(x) (*(unsigned short *) \ 67#define PM_REG_(x) (*(unsigned short *) \
71 (reg_offset_pm[((unsigned)x)]+(u_char *) FPU_info)) 68 (reg_offset_pm[((unsigned)x)] + (u_char *)FPU_info->regs))
72 69
73/* Decode the SIB byte. This function assumes mod != 0 */ 70/* Decode the SIB byte. This function assumes mod != 0 */
74static int sib(int mod, unsigned long *fpu_eip) 71static int sib(int mod, unsigned long *fpu_eip)
@@ -153,11 +150,9 @@ static long pm_address(u_char FPU_modrm, u_char segment,
153#endif /* PARANOID */ 150#endif /* PARANOID */
154 151
155 switch (segment) { 152 switch (segment) {
156 /* gs isn't used by the kernel, so it still has its
157 user-space value. */
158 case PREFIX_GS_ - 1: 153 case PREFIX_GS_ - 1:
159 /* N.B. - movl %seg, mem is a 2 byte write regardless of prefix */ 154 /* user gs handling can be lazy, use special accessors */
160 savesegment(gs, addr->selector); 155 addr->selector = get_user_gs(FPU_info->regs);
161 break; 156 break;
162 default: 157 default:
163 addr->selector = PM_REG_(segment); 158 addr->selector = PM_REG_(segment);
@@ -349,34 +344,34 @@ void __user *FPU_get_address_16(u_char FPU_modrm, unsigned long *fpu_eip,
349 } 344 }
350 switch (rm) { 345 switch (rm) {
351 case 0: 346 case 0:
352 address += FPU_info->___ebx + FPU_info->___esi; 347 address += FPU_info->regs->bx + FPU_info->regs->si;
353 break; 348 break;
354 case 1: 349 case 1:
355 address += FPU_info->___ebx + FPU_info->___edi; 350 address += FPU_info->regs->bx + FPU_info->regs->di;
356 break; 351 break;
357 case 2: 352 case 2:
358 address += FPU_info->___ebp + FPU_info->___esi; 353 address += FPU_info->regs->bp + FPU_info->regs->si;
359 if (addr_modes.override.segment == PREFIX_DEFAULT) 354 if (addr_modes.override.segment == PREFIX_DEFAULT)
360 addr_modes.override.segment = PREFIX_SS_; 355 addr_modes.override.segment = PREFIX_SS_;
361 break; 356 break;
362 case 3: 357 case 3:
363 address += FPU_info->___ebp + FPU_info->___edi; 358 address += FPU_info->regs->bp + FPU_info->regs->di;
364 if (addr_modes.override.segment == PREFIX_DEFAULT) 359 if (addr_modes.override.segment == PREFIX_DEFAULT)
365 addr_modes.override.segment = PREFIX_SS_; 360 addr_modes.override.segment = PREFIX_SS_;
366 break; 361 break;
367 case 4: 362 case 4:
368 address += FPU_info->___esi; 363 address += FPU_info->regs->si;
369 break; 364 break;
370 case 5: 365 case 5:
371 address += FPU_info->___edi; 366 address += FPU_info->regs->di;
372 break; 367 break;
373 case 6: 368 case 6:
374 address += FPU_info->___ebp; 369 address += FPU_info->regs->bp;
375 if (addr_modes.override.segment == PREFIX_DEFAULT) 370 if (addr_modes.override.segment == PREFIX_DEFAULT)
376 addr_modes.override.segment = PREFIX_SS_; 371 addr_modes.override.segment = PREFIX_SS_;
377 break; 372 break;
378 case 7: 373 case 7:
379 address += FPU_info->___ebx; 374 address += FPU_info->regs->bx;
380 break; 375 break;
381 } 376 }
382 377