diff options
| author | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-07 11:59:11 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-07 11:59:11 -0500 |
| commit | 4522d58275f124105819723e24e912c8e5bf3cdd (patch) | |
| tree | b92c29014fadffe049c1925676037f0092b8d112 /arch/i386/kernel/vm86.c | |
| parent | 6cf24f031bc97cb5a7c9df3b6e73c45b628b2b28 (diff) | |
| parent | 64a26a731235b59c9d73bbe82c1f896d57400d37 (diff) | |
Merge branch 'for-linus' of git://one.firstfloor.org/home/andi/git/linux-2.6
* 'for-linus' of git://one.firstfloor.org/home/andi/git/linux-2.6: (156 commits)
[PATCH] x86-64: Export smp_call_function_single
[PATCH] i386: Clean up smp_tune_scheduling()
[PATCH] unwinder: move .eh_frame to RODATA
[PATCH] unwinder: fully support linker generated .eh_frame_hdr section
[PATCH] x86-64: don't use set_irq_regs()
[PATCH] x86-64: check vector in setup_ioapic_dest to verify if need setup_IO_APIC_irq
[PATCH] x86-64: Make ix86 default to HIGHMEM4G instead of NOHIGHMEM
[PATCH] i386: replace kmalloc+memset with kzalloc
[PATCH] x86-64: remove remaining pc98 code
[PATCH] x86-64: remove unused variable
[PATCH] x86-64: Fix constraints in atomic_add_return()
[PATCH] x86-64: fix asm constraints in i386 atomic_add_return
[PATCH] x86-64: Correct documentation for bzImage protocol v2.05
[PATCH] x86-64: replace kmalloc+memset with kzalloc in MTRR code
[PATCH] x86-64: Fix numaq build error
[PATCH] x86-64: include/asm-x86_64/cpufeature.h isn't a userspace header
[PATCH] unwinder: Add debugging output to the Dwarf2 unwinder
[PATCH] x86-64: Clarify error message in GART code
[PATCH] x86-64: Fix interrupt race in idle callback (3rd try)
[PATCH] x86-64: Remove unwind stack pointer alignment forcing again
...
Fixed conflict in include/linux/uaccess.h manually
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/i386/kernel/vm86.c')
| -rw-r--r-- | arch/i386/kernel/vm86.c | 121 |
1 files changed, 74 insertions, 47 deletions
diff --git a/arch/i386/kernel/vm86.c b/arch/i386/kernel/vm86.c index cbcd61d6120b..be2f96e67f78 100644 --- a/arch/i386/kernel/vm86.c +++ b/arch/i386/kernel/vm86.c | |||
| @@ -43,6 +43,7 @@ | |||
| 43 | #include <linux/highmem.h> | 43 | #include <linux/highmem.h> |
| 44 | #include <linux/ptrace.h> | 44 | #include <linux/ptrace.h> |
| 45 | #include <linux/audit.h> | 45 | #include <linux/audit.h> |
| 46 | #include <linux/stddef.h> | ||
| 46 | 47 | ||
| 47 | #include <asm/uaccess.h> | 48 | #include <asm/uaccess.h> |
| 48 | #include <asm/io.h> | 49 | #include <asm/io.h> |
| @@ -72,10 +73,10 @@ | |||
| 72 | /* | 73 | /* |
| 73 | * 8- and 16-bit register defines.. | 74 | * 8- and 16-bit register defines.. |
| 74 | */ | 75 | */ |
| 75 | #define AL(regs) (((unsigned char *)&((regs)->eax))[0]) | 76 | #define AL(regs) (((unsigned char *)&((regs)->pt.eax))[0]) |
| 76 | #define AH(regs) (((unsigned char *)&((regs)->eax))[1]) | 77 | #define AH(regs) (((unsigned char *)&((regs)->pt.eax))[1]) |
| 77 | #define IP(regs) (*(unsigned short *)&((regs)->eip)) | 78 | #define IP(regs) (*(unsigned short *)&((regs)->pt.eip)) |
| 78 | #define SP(regs) (*(unsigned short *)&((regs)->esp)) | 79 | #define SP(regs) (*(unsigned short *)&((regs)->pt.esp)) |
| 79 | 80 | ||
| 80 | /* | 81 | /* |
| 81 | * virtual flags (16 and 32-bit versions) | 82 | * virtual flags (16 and 32-bit versions) |
| @@ -89,10 +90,37 @@ | |||
| 89 | #define SAFE_MASK (0xDD5) | 90 | #define SAFE_MASK (0xDD5) |
| 90 | #define RETURN_MASK (0xDFF) | 91 | #define RETURN_MASK (0xDFF) |
| 91 | 92 | ||
| 92 | #define VM86_REGS_PART2 orig_eax | 93 | /* convert kernel_vm86_regs to vm86_regs */ |
| 93 | #define VM86_REGS_SIZE1 \ | 94 | static int copy_vm86_regs_to_user(struct vm86_regs __user *user, |
| 94 | ( (unsigned)( & (((struct kernel_vm86_regs *)0)->VM86_REGS_PART2) ) ) | 95 | const struct kernel_vm86_regs *regs) |
| 95 | #define VM86_REGS_SIZE2 (sizeof(struct kernel_vm86_regs) - VM86_REGS_SIZE1) | 96 | { |
| 97 | int ret = 0; | ||
| 98 | |||
| 99 | /* kernel_vm86_regs is missing xfs, so copy everything up to | ||
| 100 | (but not including) xgs, and then rest after xgs. */ | ||
| 101 | ret += copy_to_user(user, regs, offsetof(struct kernel_vm86_regs, pt.xgs)); | ||
| 102 | ret += copy_to_user(&user->__null_gs, ®s->pt.xgs, | ||
| 103 | sizeof(struct kernel_vm86_regs) - | ||
| 104 | offsetof(struct kernel_vm86_regs, pt.xgs)); | ||
| 105 | |||
| 106 | return ret; | ||
| 107 | } | ||
| 108 | |||
| 109 | /* convert vm86_regs to kernel_vm86_regs */ | ||
| 110 | static int copy_vm86_regs_from_user(struct kernel_vm86_regs *regs, | ||
| 111 | const struct vm86_regs __user *user, | ||
| 112 | unsigned extra) | ||
| 113 | { | ||
| 114 | int ret = 0; | ||
| 115 | |||
| 116 | ret += copy_from_user(regs, user, offsetof(struct kernel_vm86_regs, pt.xgs)); | ||
| 117 | ret += copy_from_user(®s->pt.xgs, &user->__null_gs, | ||
| 118 | sizeof(struct kernel_vm86_regs) - | ||
| 119 | offsetof(struct kernel_vm86_regs, pt.xgs) + | ||
| 120 | extra); | ||
| 121 | |||
| 122 | return ret; | ||
| 123 | } | ||
| 96 | 124 | ||
| 97 | struct pt_regs * FASTCALL(save_v86_state(struct kernel_vm86_regs * regs)); | 125 | struct pt_regs * FASTCALL(save_v86_state(struct kernel_vm86_regs * regs)); |
| 98 | struct pt_regs * fastcall save_v86_state(struct kernel_vm86_regs * regs) | 126 | struct pt_regs * fastcall save_v86_state(struct kernel_vm86_regs * regs) |
| @@ -112,10 +140,8 @@ struct pt_regs * fastcall save_v86_state(struct kernel_vm86_regs * regs) | |||
| 112 | printk("no vm86_info: BAD\n"); | 140 | printk("no vm86_info: BAD\n"); |
| 113 | do_exit(SIGSEGV); | 141 | do_exit(SIGSEGV); |
| 114 | } | 142 | } |
| 115 | set_flags(regs->eflags, VEFLAGS, VIF_MASK | current->thread.v86mask); | 143 | set_flags(regs->pt.eflags, VEFLAGS, VIF_MASK | current->thread.v86mask); |
| 116 | tmp = copy_to_user(¤t->thread.vm86_info->regs,regs, VM86_REGS_SIZE1); | 144 | tmp = copy_vm86_regs_to_user(¤t->thread.vm86_info->regs,regs); |
| 117 | tmp += copy_to_user(¤t->thread.vm86_info->regs.VM86_REGS_PART2, | ||
| 118 | ®s->VM86_REGS_PART2, VM86_REGS_SIZE2); | ||
| 119 | tmp += put_user(current->thread.screen_bitmap,¤t->thread.vm86_info->screen_bitmap); | 145 | tmp += put_user(current->thread.screen_bitmap,¤t->thread.vm86_info->screen_bitmap); |
| 120 | if (tmp) { | 146 | if (tmp) { |
| 121 | printk("vm86: could not access userspace vm86_info\n"); | 147 | printk("vm86: could not access userspace vm86_info\n"); |
| @@ -129,9 +155,11 @@ struct pt_regs * fastcall save_v86_state(struct kernel_vm86_regs * regs) | |||
| 129 | current->thread.saved_esp0 = 0; | 155 | current->thread.saved_esp0 = 0; |
| 130 | put_cpu(); | 156 | put_cpu(); |
| 131 | 157 | ||
| 132 | loadsegment(fs, current->thread.saved_fs); | ||
| 133 | loadsegment(gs, current->thread.saved_gs); | ||
| 134 | ret = KVM86->regs32; | 158 | ret = KVM86->regs32; |
| 159 | |||
| 160 | loadsegment(fs, current->thread.saved_fs); | ||
| 161 | ret->xgs = current->thread.saved_gs; | ||
| 162 | |||
| 135 | return ret; | 163 | return ret; |
| 136 | } | 164 | } |
| 137 | 165 | ||
| @@ -183,9 +211,9 @@ asmlinkage int sys_vm86old(struct pt_regs regs) | |||
| 183 | tsk = current; | 211 | tsk = current; |
| 184 | if (tsk->thread.saved_esp0) | 212 | if (tsk->thread.saved_esp0) |
| 185 | goto out; | 213 | goto out; |
| 186 | tmp = copy_from_user(&info, v86, VM86_REGS_SIZE1); | 214 | tmp = copy_vm86_regs_from_user(&info.regs, &v86->regs, |
| 187 | tmp += copy_from_user(&info.regs.VM86_REGS_PART2, &v86->regs.VM86_REGS_PART2, | 215 | offsetof(struct kernel_vm86_struct, vm86plus) - |
| 188 | (long)&info.vm86plus - (long)&info.regs.VM86_REGS_PART2); | 216 | sizeof(info.regs)); |
| 189 | ret = -EFAULT; | 217 | ret = -EFAULT; |
| 190 | if (tmp) | 218 | if (tmp) |
| 191 | goto out; | 219 | goto out; |
| @@ -233,9 +261,9 @@ asmlinkage int sys_vm86(struct pt_regs regs) | |||
| 233 | if (tsk->thread.saved_esp0) | 261 | if (tsk->thread.saved_esp0) |
| 234 | goto out; | 262 | goto out; |
| 235 | v86 = (struct vm86plus_struct __user *)regs.ecx; | 263 | v86 = (struct vm86plus_struct __user *)regs.ecx; |
| 236 | tmp = copy_from_user(&info, v86, VM86_REGS_SIZE1); | 264 | tmp = copy_vm86_regs_from_user(&info.regs, &v86->regs, |
| 237 | tmp += copy_from_user(&info.regs.VM86_REGS_PART2, &v86->regs.VM86_REGS_PART2, | 265 | offsetof(struct kernel_vm86_struct, regs32) - |
| 238 | (long)&info.regs32 - (long)&info.regs.VM86_REGS_PART2); | 266 | sizeof(info.regs)); |
| 239 | ret = -EFAULT; | 267 | ret = -EFAULT; |
| 240 | if (tmp) | 268 | if (tmp) |
| 241 | goto out; | 269 | goto out; |
| @@ -252,15 +280,15 @@ out: | |||
| 252 | static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk) | 280 | static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk) |
| 253 | { | 281 | { |
| 254 | struct tss_struct *tss; | 282 | struct tss_struct *tss; |
| 255 | long eax; | ||
| 256 | /* | 283 | /* |
| 257 | * make sure the vm86() system call doesn't try to do anything silly | 284 | * make sure the vm86() system call doesn't try to do anything silly |
| 258 | */ | 285 | */ |
| 259 | info->regs.__null_ds = 0; | 286 | info->regs.pt.xds = 0; |
| 260 | info->regs.__null_es = 0; | 287 | info->regs.pt.xes = 0; |
| 288 | info->regs.pt.xgs = 0; | ||
| 261 | 289 | ||
| 262 | /* we are clearing fs,gs later just before "jmp resume_userspace", | 290 | /* we are clearing fs later just before "jmp resume_userspace", |
| 263 | * because starting with Linux 2.1.x they aren't no longer saved/restored | 291 | * because it is not saved/restored. |
| 264 | */ | 292 | */ |
| 265 | 293 | ||
| 266 | /* | 294 | /* |
| @@ -268,10 +296,10 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk | |||
| 268 | * has set it up safely, so this makes sure interrupt etc flags are | 296 | * has set it up safely, so this makes sure interrupt etc flags are |
| 269 | * inherited from protected mode. | 297 | * inherited from protected mode. |
| 270 | */ | 298 | */ |
| 271 | VEFLAGS = info->regs.eflags; | 299 | VEFLAGS = info->regs.pt.eflags; |
| 272 | info->regs.eflags &= SAFE_MASK; | 300 | info->regs.pt.eflags &= SAFE_MASK; |
| 273 | info->regs.eflags |= info->regs32->eflags & ~SAFE_MASK; | 301 | info->regs.pt.eflags |= info->regs32->eflags & ~SAFE_MASK; |
| 274 | info->regs.eflags |= VM_MASK; | 302 | info->regs.pt.eflags |= VM_MASK; |
| 275 | 303 | ||
| 276 | switch (info->cpu_type) { | 304 | switch (info->cpu_type) { |
| 277 | case CPU_286: | 305 | case CPU_286: |
| @@ -294,7 +322,7 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk | |||
| 294 | info->regs32->eax = 0; | 322 | info->regs32->eax = 0; |
| 295 | tsk->thread.saved_esp0 = tsk->thread.esp0; | 323 | tsk->thread.saved_esp0 = tsk->thread.esp0; |
| 296 | savesegment(fs, tsk->thread.saved_fs); | 324 | savesegment(fs, tsk->thread.saved_fs); |
| 297 | savesegment(gs, tsk->thread.saved_gs); | 325 | tsk->thread.saved_gs = info->regs32->xgs; |
| 298 | 326 | ||
| 299 | tss = &per_cpu(init_tss, get_cpu()); | 327 | tss = &per_cpu(init_tss, get_cpu()); |
| 300 | tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0; | 328 | tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0; |
| @@ -306,19 +334,18 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk | |||
| 306 | tsk->thread.screen_bitmap = info->screen_bitmap; | 334 | tsk->thread.screen_bitmap = info->screen_bitmap; |
| 307 | if (info->flags & VM86_SCREEN_BITMAP) | 335 | if (info->flags & VM86_SCREEN_BITMAP) |
| 308 | mark_screen_rdonly(tsk->mm); | 336 | mark_screen_rdonly(tsk->mm); |
| 309 | __asm__ __volatile__("xorl %eax,%eax; movl %eax,%fs; movl %eax,%gs\n\t"); | ||
| 310 | __asm__ __volatile__("movl %%eax, %0\n" :"=r"(eax)); | ||
| 311 | 337 | ||
| 312 | /*call audit_syscall_exit since we do not exit via the normal paths */ | 338 | /*call audit_syscall_exit since we do not exit via the normal paths */ |
| 313 | if (unlikely(current->audit_context)) | 339 | if (unlikely(current->audit_context)) |
| 314 | audit_syscall_exit(AUDITSC_RESULT(eax), eax); | 340 | audit_syscall_exit(AUDITSC_RESULT(0), 0); |
| 315 | 341 | ||
| 316 | __asm__ __volatile__( | 342 | __asm__ __volatile__( |
| 317 | "movl %0,%%esp\n\t" | 343 | "movl %0,%%esp\n\t" |
| 318 | "movl %1,%%ebp\n\t" | 344 | "movl %1,%%ebp\n\t" |
| 345 | "mov %2, %%fs\n\t" | ||
| 319 | "jmp resume_userspace" | 346 | "jmp resume_userspace" |
| 320 | : /* no outputs */ | 347 | : /* no outputs */ |
| 321 | :"r" (&info->regs), "r" (task_thread_info(tsk))); | 348 | :"r" (&info->regs), "r" (task_thread_info(tsk)), "r" (0)); |
| 322 | /* we never return here */ | 349 | /* we never return here */ |
| 323 | } | 350 | } |
| 324 | 351 | ||
| @@ -348,12 +375,12 @@ static inline void clear_IF(struct kernel_vm86_regs * regs) | |||
| 348 | 375 | ||
| 349 | static inline void clear_TF(struct kernel_vm86_regs * regs) | 376 | static inline void clear_TF(struct kernel_vm86_regs * regs) |
| 350 | { | 377 | { |
| 351 | regs->eflags &= ~TF_MASK; | 378 | regs->pt.eflags &= ~TF_MASK; |
| 352 | } | 379 | } |
| 353 | 380 | ||
| 354 | static inline void clear_AC(struct kernel_vm86_regs * regs) | 381 | static inline void clear_AC(struct kernel_vm86_regs * regs) |
| 355 | { | 382 | { |
| 356 | regs->eflags &= ~AC_MASK; | 383 | regs->pt.eflags &= ~AC_MASK; |
| 357 | } | 384 | } |
| 358 | 385 | ||
| 359 | /* It is correct to call set_IF(regs) from the set_vflags_* | 386 | /* It is correct to call set_IF(regs) from the set_vflags_* |
| @@ -370,7 +397,7 @@ static inline void clear_AC(struct kernel_vm86_regs * regs) | |||
| 370 | static inline void set_vflags_long(unsigned long eflags, struct kernel_vm86_regs * regs) | 397 | static inline void set_vflags_long(unsigned long eflags, struct kernel_vm86_regs * regs) |
| 371 | { | 398 | { |
| 372 | set_flags(VEFLAGS, eflags, current->thread.v86mask); | 399 | set_flags(VEFLAGS, eflags, current->thread.v86mask); |
| 373 | set_flags(regs->eflags, eflags, SAFE_MASK); | 400 | set_flags(regs->pt.eflags, eflags, SAFE_MASK); |
| 374 | if (eflags & IF_MASK) | 401 | if (eflags & IF_MASK) |
| 375 | set_IF(regs); | 402 | set_IF(regs); |
| 376 | else | 403 | else |
| @@ -380,7 +407,7 @@ static inline void set_vflags_long(unsigned long eflags, struct kernel_vm86_regs | |||
| 380 | static inline void set_vflags_short(unsigned short flags, struct kernel_vm86_regs * regs) | 407 | static inline void set_vflags_short(unsigned short flags, struct kernel_vm86_regs * regs) |
| 381 | { | 408 | { |
| 382 | set_flags(VFLAGS, flags, current->thread.v86mask); | 409 | set_flags(VFLAGS, flags, current->thread.v86mask); |
| 383 | set_flags(regs->eflags, flags, SAFE_MASK); | 410 | set_flags(regs->pt.eflags, flags, SAFE_MASK); |
| 384 | if (flags & IF_MASK) | 411 | if (flags & IF_MASK) |
| 385 | set_IF(regs); | 412 | set_IF(regs); |
| 386 | else | 413 | else |
| @@ -389,7 +416,7 @@ static inline void set_vflags_short(unsigned short flags, struct kernel_vm86_reg | |||
| 389 | 416 | ||
| 390 | static inline unsigned long get_vflags(struct kernel_vm86_regs * regs) | 417 | static inline unsigned long get_vflags(struct kernel_vm86_regs * regs) |
| 391 | { | 418 | { |
| 392 | unsigned long flags = regs->eflags & RETURN_MASK; | 419 | unsigned long flags = regs->pt.eflags & RETURN_MASK; |
| 393 | 420 | ||
| 394 | if (VEFLAGS & VIF_MASK) | 421 | if (VEFLAGS & VIF_MASK) |
| 395 | flags |= IF_MASK; | 422 | flags |= IF_MASK; |
| @@ -493,7 +520,7 @@ static void do_int(struct kernel_vm86_regs *regs, int i, | |||
| 493 | unsigned long __user *intr_ptr; | 520 | unsigned long __user *intr_ptr; |
| 494 | unsigned long segoffs; | 521 | unsigned long segoffs; |
| 495 | 522 | ||
| 496 | if (regs->cs == BIOSSEG) | 523 | if (regs->pt.xcs == BIOSSEG) |
| 497 | goto cannot_handle; | 524 | goto cannot_handle; |
| 498 | if (is_revectored(i, &KVM86->int_revectored)) | 525 | if (is_revectored(i, &KVM86->int_revectored)) |
| 499 | goto cannot_handle; | 526 | goto cannot_handle; |
| @@ -505,9 +532,9 @@ static void do_int(struct kernel_vm86_regs *regs, int i, | |||
| 505 | if ((segoffs >> 16) == BIOSSEG) | 532 | if ((segoffs >> 16) == BIOSSEG) |
| 506 | goto cannot_handle; | 533 | goto cannot_handle; |
| 507 | pushw(ssp, sp, get_vflags(regs), cannot_handle); | 534 | pushw(ssp, sp, get_vflags(regs), cannot_handle); |
| 508 | pushw(ssp, sp, regs->cs, cannot_handle); | 535 | pushw(ssp, sp, regs->pt.xcs, cannot_handle); |
| 509 | pushw(ssp, sp, IP(regs), cannot_handle); | 536 | pushw(ssp, sp, IP(regs), cannot_handle); |
| 510 | regs->cs = segoffs >> 16; | 537 | regs->pt.xcs = segoffs >> 16; |
| 511 | SP(regs) -= 6; | 538 | SP(regs) -= 6; |
| 512 | IP(regs) = segoffs & 0xffff; | 539 | IP(regs) = segoffs & 0xffff; |
| 513 | clear_TF(regs); | 540 | clear_TF(regs); |
| @@ -524,7 +551,7 @@ int handle_vm86_trap(struct kernel_vm86_regs * regs, long error_code, int trapno | |||
| 524 | if (VMPI.is_vm86pus) { | 551 | if (VMPI.is_vm86pus) { |
| 525 | if ( (trapno==3) || (trapno==1) ) | 552 | if ( (trapno==3) || (trapno==1) ) |
| 526 | return_to_32bit(regs, VM86_TRAP + (trapno << 8)); | 553 | return_to_32bit(regs, VM86_TRAP + (trapno << 8)); |
| 527 | do_int(regs, trapno, (unsigned char __user *) (regs->ss << 4), SP(regs)); | 554 | do_int(regs, trapno, (unsigned char __user *) (regs->pt.xss << 4), SP(regs)); |
| 528 | return 0; | 555 | return 0; |
| 529 | } | 556 | } |
| 530 | if (trapno !=1) | 557 | if (trapno !=1) |
| @@ -560,10 +587,10 @@ void handle_vm86_fault(struct kernel_vm86_regs * regs, long error_code) | |||
| 560 | handle_vm86_trap(regs, 0, 1); \ | 587 | handle_vm86_trap(regs, 0, 1); \ |
| 561 | return; } while (0) | 588 | return; } while (0) |
| 562 | 589 | ||
| 563 | orig_flags = *(unsigned short *)®s->eflags; | 590 | orig_flags = *(unsigned short *)®s->pt.eflags; |
| 564 | 591 | ||
| 565 | csp = (unsigned char __user *) (regs->cs << 4); | 592 | csp = (unsigned char __user *) (regs->pt.xcs << 4); |
| 566 | ssp = (unsigned char __user *) (regs->ss << 4); | 593 | ssp = (unsigned char __user *) (regs->pt.xss << 4); |
| 567 | sp = SP(regs); | 594 | sp = SP(regs); |
| 568 | ip = IP(regs); | 595 | ip = IP(regs); |
| 569 | 596 | ||
| @@ -650,7 +677,7 @@ void handle_vm86_fault(struct kernel_vm86_regs * regs, long error_code) | |||
| 650 | SP(regs) += 6; | 677 | SP(regs) += 6; |
| 651 | } | 678 | } |
| 652 | IP(regs) = newip; | 679 | IP(regs) = newip; |
| 653 | regs->cs = newcs; | 680 | regs->pt.xcs = newcs; |
| 654 | CHECK_IF_IN_TRAP; | 681 | CHECK_IF_IN_TRAP; |
| 655 | if (data32) { | 682 | if (data32) { |
| 656 | set_vflags_long(newflags, regs); | 683 | set_vflags_long(newflags, regs); |
