ia64/xen-unstable

changeset 4862:013d5aa0f1e8

bitkeeper revision 1.1389.19.1 (42832192JUW7jFIgG2nBVTpvJUUvKA)

Fix page-faulting error path in privileged-instruction emulator.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Thu May 12 09:27:46 2005 +0000 (2005-05-12)
parents b633f24b48be
children cabc09d5f3b8
files xen/arch/x86/traps.c
line diff
     1.1 --- a/xen/arch/x86/traps.c	Wed May 11 23:27:00 2005 +0000
     1.2 +++ b/xen/arch/x86/traps.c	Thu May 12 09:27:46 2005 +0000
     1.3 @@ -433,10 +433,19 @@ static inline int admin_io_okay(
     1.4  #define outl_user(_v, _p, _d, _r) \
     1.5      (admin_io_okay(_p, 4, _d, _r) ? outl(_v, _p) : ((void)0))
     1.6  
     1.7 +/* Propagate a fault back to the guest kernel. */
     1.8 +#define USER_READ_FAULT  4 /* user mode, read fault */
     1.9 +#define USER_WRITE_FAULT 6 /* user mode, write fault */
    1.10 +#define PAGE_FAULT(_faultaddr, _errcode)        \
    1.11 +({  propagate_page_fault(_faultaddr, _errcode); \
    1.12 +    return EXCRET_fault_fixed;                  \
    1.13 +})
    1.14 +
    1.15 +/* Isntruction fetch with error handling. */
    1.16  #define insn_fetch(_type, _size, _ptr)          \
    1.17  ({  unsigned long _x;                           \
    1.18      if ( get_user(_x, (_type *)eip) )           \
    1.19 -        goto read_fault;                        \
    1.20 +        PAGE_FAULT(eip, USER_READ_FAULT);       \
    1.21      eip += _size; (_type)_x; })
    1.22  
    1.23  static int emulate_privileged_op(struct cpu_user_regs *regs)
    1.24 @@ -502,17 +511,17 @@ static int emulate_privileged_op(struct 
    1.25              case 1:
    1.26                  data = (u8)inb_user((u16)regs->edx, ed, regs);
    1.27                  if ( put_user((u8)data, (u8 *)regs->edi) )
    1.28 -                    goto write_fault;
    1.29 +                    PAGE_FAULT(regs->edi, USER_WRITE_FAULT);
    1.30                  break;
    1.31              case 2:
    1.32                  data = (u16)inw_user((u16)regs->edx, ed, regs);
    1.33                  if ( put_user((u16)data, (u16 *)regs->edi) )
    1.34 -                    goto write_fault;
    1.35 +                    PAGE_FAULT(regs->edi, USER_WRITE_FAULT);
    1.36                  break;
    1.37              case 4:
    1.38                  data = (u32)inl_user((u16)regs->edx, ed, regs);
    1.39                  if ( put_user((u32)data, (u32 *)regs->edi) )
    1.40 -                    goto write_fault;
    1.41 +                    PAGE_FAULT(regs->edi, USER_WRITE_FAULT);
    1.42                  break;
    1.43              }
    1.44              regs->edi += (regs->eflags & EF_DF) ? -op_bytes : op_bytes;
    1.45 @@ -527,17 +536,17 @@ static int emulate_privileged_op(struct 
    1.46              {
    1.47              case 1:
    1.48                  if ( get_user(data, (u8 *)regs->esi) )
    1.49 -                    goto read_fault;
    1.50 +                    PAGE_FAULT(regs->esi, USER_READ_FAULT);
    1.51                  outb_user((u8)data, (u16)regs->edx, ed, regs);
    1.52                  break;
    1.53              case 2:
    1.54                  if ( get_user(data, (u16 *)regs->esi) )
    1.55 -                    goto read_fault;
    1.56 +                    PAGE_FAULT(regs->esi, USER_READ_FAULT);
    1.57                  outw_user((u16)data, (u16)regs->edx, ed, regs);
    1.58                  break;
    1.59              case 4:
    1.60                  if ( get_user(data, (u32 *)regs->esi) )
    1.61 -                    goto read_fault;
    1.62 +                    PAGE_FAULT(regs->esi, USER_READ_FAULT);
    1.63                  outl_user((u32)data, (u16)regs->edx, ed, regs);
    1.64                  break;
    1.65              }
    1.66 @@ -736,14 +745,6 @@ static int emulate_privileged_op(struct 
    1.67  
    1.68   fail:
    1.69      return 0;
    1.70 -
    1.71 - read_fault:
    1.72 -    propagate_page_fault(eip, 4); /* user mode, read fault */
    1.73 -    return EXCRET_fault_fixed;
    1.74 -
    1.75 - write_fault:
    1.76 -    propagate_page_fault(eip, 6); /* user mode, write fault */
    1.77 -    return EXCRET_fault_fixed;
    1.78  }
    1.79  
    1.80  asmlinkage int do_general_protection(struct cpu_user_regs *regs)