ia64/xen-unstable

changeset 3424:91b80105fc04

bitkeeper revision 1.1159.170.90 (41e53190NTwQxrBNj2UypCRVNj7fyQ)

More seg-fixup cleanups and safety fixes.
author kaf24@scramble.cl.cam.ac.uk
date Wed Jan 12 14:17:52 2005 +0000 (2005-01-12)
parents 3552b3979933
children 1c8e5bc858f0 983a02b6959a
files xen/arch/x86/traps.c xen/arch/x86/x86_32/seg_fixup.c xen/include/asm-x86/mm.h
line diff
     1.1 --- a/xen/arch/x86/traps.c	Wed Jan 12 09:36:10 2005 +0000
     1.2 +++ b/xen/arch/x86/traps.c	Wed Jan 12 14:17:52 2005 +0000
     1.3 @@ -382,13 +382,27 @@ asmlinkage void do_machine_check(struct 
     1.4      fatal_trap(TRAP_machine_check, regs);
     1.5  }
     1.6  
     1.7 +void propagate_page_fault(unsigned long addr, u16 error_code)
     1.8 +{
     1.9 +    trap_info_t *ti;
    1.10 +    struct domain *d = current;
    1.11 +    struct trap_bounce *tb = &d->thread.trap_bounce;
    1.12 +
    1.13 +    ti = d->thread.traps + 14;
    1.14 +    tb->flags = TBF_EXCEPTION | TBF_EXCEPTION_ERRCODE | TBF_EXCEPTION_CR2;
    1.15 +    tb->cr2        = addr;
    1.16 +    tb->error_code = error_code;
    1.17 +    tb->cs         = ti->cs;
    1.18 +    tb->eip        = ti->address;
    1.19 +    if ( TI_GET_IF(ti) )
    1.20 +        d->shared_info->vcpu_data[0].evtchn_upcall_mask = 1;
    1.21 +}
    1.22 +
    1.23  asmlinkage int do_page_fault(struct xen_regs *regs)
    1.24  {
    1.25 -    trap_info_t *ti;
    1.26      unsigned long off, addr, fixup;
    1.27      struct domain *d = current;
    1.28      extern int map_ldt_shadow_page(unsigned int);
    1.29 -    struct trap_bounce *tb = &d->thread.trap_bounce;
    1.30      int cpu = d->processor;
    1.31  
    1.32      __asm__ __volatile__ ("movl %%cr2,%0" : "=r" (addr) : );
    1.33 @@ -437,14 +451,7 @@ asmlinkage int do_page_fault(struct xen_
    1.34      if ( !GUEST_FAULT(regs) )
    1.35          goto xen_fault;
    1.36  
    1.37 -    ti = d->thread.traps + 14;
    1.38 -    tb->flags = TBF_EXCEPTION | TBF_EXCEPTION_ERRCODE | TBF_EXCEPTION_CR2;
    1.39 -    tb->cr2        = addr;
    1.40 -    tb->error_code = regs->error_code;
    1.41 -    tb->cs         = ti->cs;
    1.42 -    tb->eip        = ti->address;
    1.43 -    if ( TI_GET_IF(ti) )
    1.44 -        d->shared_info->vcpu_data[0].evtchn_upcall_mask = 1;
    1.45 +    propagate_page_fault(addr, regs->error_code);
    1.46      return 0; 
    1.47  
    1.48   xen_fault:
     2.1 --- a/xen/arch/x86/x86_32/seg_fixup.c	Wed Jan 12 09:36:10 2005 +0000
     2.2 +++ b/xen/arch/x86/x86_32/seg_fixup.c	Wed Jan 12 14:17:52 2005 +0000
     2.3 @@ -278,9 +278,7 @@ void *decode_reg(struct xen_regs *regs, 
     2.4  
     2.5  /*
     2.6   * Called from the general-protection fault handler to attempt to decode
     2.7 - * and emulate an instruction that depends on 4GB segments. At this point
     2.8 - * we assume that the instruction itself is paged into memory (the CPU
     2.9 - * must have triggered this in order to decode the instruction itself).
    2.10 + * and emulate an instruction that depends on 4GB segments.
    2.11   */
    2.12  int gpf_emulate_4gb(struct xen_regs *regs)
    2.13  {
    2.14 @@ -315,7 +313,7 @@ int gpf_emulate_4gb(struct xen_regs *reg
    2.15          if ( get_user(b, pb) )
    2.16          {
    2.17              DPRINTK("Fault while accessing byte %d of instruction\n", pb-eip);
    2.18 -            goto fail;
    2.19 +            goto page_fault;
    2.20          }
    2.21  
    2.22          if ( (pb - eip) >= 15 )
    2.23 @@ -371,10 +369,21 @@ int gpf_emulate_4gb(struct xen_regs *reg
    2.24          switch ( decode & 7 )
    2.25          {
    2.26          case 1:
    2.27 -            offset = (long)(*(char *)pb);
    2.28 +            if ( get_user(b, pb) )
    2.29 +            {
    2.30 +                DPRINTK("Fault while extracting <moffs8>.\n");
    2.31 +                goto page_fault;
    2.32 +            }
    2.33 +            pb++;
    2.34 +            offset = (signed long)(signed char)b;
    2.35              goto skip_modrm;
    2.36          case 4:
    2.37 -            offset = *(long *)pb;
    2.38 +            if ( get_user(offset, (u32 *)pb) )
    2.39 +            {
    2.40 +                DPRINTK("Fault while extracting <disp8>.\n");
    2.41 +                goto page_fault;
    2.42 +            }
    2.43 +            pb += 4;
    2.44              goto skip_modrm;
    2.45          default:
    2.46              goto fail;
    2.47 @@ -388,7 +397,7 @@ int gpf_emulate_4gb(struct xen_regs *reg
    2.48      if ( get_user(modrm, pb) )
    2.49      {
    2.50          DPRINTK("Fault while extracting modrm byte\n");
    2.51 -        goto fail;
    2.52 +        goto page_fault;
    2.53      }
    2.54  
    2.55      pb++;
    2.56 @@ -420,7 +429,7 @@ int gpf_emulate_4gb(struct xen_regs *reg
    2.57              if ( get_user(disp32, (u32 *)pb) )
    2.58              {
    2.59                  DPRINTK("Fault while extracting <disp8>.\n");
    2.60 -                goto fail;
    2.61 +                goto page_fault;
    2.62              }
    2.63              pb += 4;
    2.64          }
    2.65 @@ -432,7 +441,7 @@ int gpf_emulate_4gb(struct xen_regs *reg
    2.66          if ( get_user(disp8, pb) )
    2.67          {
    2.68              DPRINTK("Fault while extracting <disp8>.\n");
    2.69 -            goto fail;
    2.70 +            goto page_fault;
    2.71          }
    2.72          pb++;
    2.73          disp32 = (disp8 & 0x80) ? (disp8 | ~0xff) : disp8;;
    2.74 @@ -444,7 +453,7 @@ int gpf_emulate_4gb(struct xen_regs *reg
    2.75          if ( get_user(disp32, (u32 *)pb) )
    2.76          {
    2.77              DPRINTK("Fault while extracting <disp8>.\n");
    2.78 -            goto fail;
    2.79 +            goto page_fault;
    2.80          }
    2.81          pb += 4;
    2.82          break;
    2.83 @@ -478,7 +487,7 @@ int gpf_emulate_4gb(struct xen_regs *reg
    2.84              d->shared_info->vcpu_data[0].evtchn_upcall_mask = 1;
    2.85      }
    2.86  
    2.87 -    return 1;
    2.88 +    return EXCRET_fault_fixed;
    2.89  
    2.90   fixme:
    2.91      DPRINTK("Undecodable instruction %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x "
    2.92 @@ -488,4 +497,8 @@ int gpf_emulate_4gb(struct xen_regs *reg
    2.93              regs->cs, regs->eip);
    2.94   fail:
    2.95      return 0;
    2.96 +
    2.97 + page_fault:
    2.98 +    propagate_page_fault((unsigned long)pb, 4);
    2.99 +    return EXCRET_fault_fixed;
   2.100  }
     3.1 --- a/xen/include/asm-x86/mm.h	Wed Jan 12 09:36:10 2005 +0000
     3.2 +++ b/xen/include/asm-x86/mm.h	Wed Jan 12 14:17:52 2005 +0000
     3.3 @@ -296,4 +296,6 @@ void audit_domains(void);
     3.4  #define audit_domains()  ((void)0)
     3.5  #endif
     3.6  
     3.7 +void propagate_page_fault(unsigned long addr, u16 error_code);
     3.8 +
     3.9  #endif /* __ASM_X86_MM_H__ */