ia64/xen-unstable

changeset 661:98b19b3e05eb

bitkeeper revision 1.376 (3f252286eVnrMT7PgP5t-QqVhRZAwQ)

traps.c, hypervisor-if.h:
Allow virtualisation of interrupt gates as well as task gates. If the appropriate flag is sent to set_trap_table then that exception causes the master event enable bit to be cleared in teh shared_info structure.
author kaf24@scramble.cl.cam.ac.uk
date Mon Jul 28 13:17:58 2003 +0000 (2003-07-28)
parents 816756811961
children 4eedf9e718d3
files xen/arch/i386/traps.c xen/include/hypervisor-ifs/hypervisor-if.h xenolinux-2.4.21-sparse/arch/xeno/kernel/traps.c
line diff
     1.1 --- a/xen/arch/i386/traps.c	Wed Jul 23 13:16:18 2003 +0000
     1.2 +++ b/xen/arch/i386/traps.c	Mon Jul 28 13:17:58 2003 +0000
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - *  linux/arch/i386/traps.c
     1.6 + *  xen/arch/i386/traps.c
     1.7   *
     1.8   *  Copyright (C) 1991, 1992  Linus Torvalds
     1.9   *
    1.10 @@ -189,6 +189,7 @@ static void inline do_trap(int trapnr, c
    1.11  			   struct pt_regs * regs, 
    1.12                             long error_code, int use_error_code)
    1.13  {
    1.14 +    struct task_struct *p = current;
    1.15      struct guest_trap_bounce *gtb = guest_trap_bounce+smp_processor_id();
    1.16      trap_info_t *ti;
    1.17      unsigned long fixup;
    1.18 @@ -201,6 +202,8 @@ static void inline do_trap(int trapnr, c
    1.19      gtb->error_code = error_code;
    1.20      gtb->cs         = ti->cs;
    1.21      gtb->eip        = ti->address;
    1.22 +    if ( TI_GET_IF(ti) )
    1.23 +        clear_bit(EVENTS_MASTER_ENABLE_BIT, &p->shared_info->events_mask);
    1.24      return; 
    1.25  
    1.26   fault_in_hypervisor:
    1.27 @@ -274,6 +277,8 @@ asmlinkage void do_page_fault(struct pt_
    1.28      gtb->error_code = error_code;
    1.29      gtb->cs         = ti->cs;
    1.30      gtb->eip        = ti->address;
    1.31 +    if ( TI_GET_IF(ti) )
    1.32 +        clear_bit(EVENTS_MASTER_ENABLE_BIT, &p->shared_info->events_mask);
    1.33      return; 
    1.34  
    1.35      /*
    1.36 @@ -371,6 +376,7 @@ asmlinkage void do_page_fault(struct pt_
    1.37  
    1.38  asmlinkage void do_general_protection(struct pt_regs *regs, long error_code)
    1.39  {
    1.40 +    struct task_struct *p = current;
    1.41      struct guest_trap_bounce *gtb = guest_trap_bounce+smp_processor_id();
    1.42      trap_info_t *ti;
    1.43      unsigned long fixup;
    1.44 @@ -403,13 +409,11 @@ asmlinkage void do_general_protection(st
    1.45      {
    1.46          /* This fault must be due to <INT n> instruction. */
    1.47          ti = current->thread.traps + (error_code>>3);
    1.48 -        if ( ti->dpl >= (regs->xcs & 3) )
    1.49 +        if ( TI_GET_DPL(ti) >= (regs->xcs & 3) )
    1.50          {
    1.51              gtb->flags = GTBF_TRAP_NOCODE;
    1.52 -            gtb->cs    = ti->cs;
    1.53 -            gtb->eip   = ti->address;
    1.54              regs->eip += 2;
    1.55 -            return;
    1.56 +            goto finish_propagation;
    1.57          }
    1.58      }
    1.59      
    1.60 @@ -417,8 +421,11 @@ asmlinkage void do_general_protection(st
    1.61      ti = current->thread.traps + 13;
    1.62      gtb->flags      = GTBF_TRAP;
    1.63      gtb->error_code = error_code;
    1.64 + finish_propagation:
    1.65      gtb->cs         = ti->cs;
    1.66      gtb->eip        = ti->address;
    1.67 +    if ( TI_GET_IF(ti) )
    1.68 +        clear_bit(EVENTS_MASTER_ENABLE_BIT, &p->shared_info->events_mask);
    1.69      return;
    1.70  
    1.71   gp_in_kernel:
    1.72 @@ -718,16 +725,24 @@ long do_set_fast_trap(int idx)
    1.73       * The former range is used by Windows and MS-DOS.
    1.74       * Vector 0x80 is used by Linux and the BSD variants.
    1.75       */
    1.76 -    if ( (idx != 0x80) && ((idx < 0x20) || (idx > 0x2f)) ) return -1;
    1.77 +    if ( (idx != 0x80) && ((idx < 0x20) || (idx > 0x2f)) ) 
    1.78 +        return -1;
    1.79  
    1.80      ti = current->thread.traps + idx;
    1.81  
    1.82 +    /*
    1.83 +     * We can't virtualise interrupt gates, as there's no way to get
    1.84 +     * the CPU to automatically clear the events_mask variable.
    1.85 +     */
    1.86 +    if ( TI_GET_IF(ti) )
    1.87 +        return -1;
    1.88 +
    1.89      CLEAR_FAST_TRAP(&current->thread);
    1.90  
    1.91      current->thread.fast_trap_idx    = idx;
    1.92      current->thread.fast_trap_desc.a = (ti->cs << 16) | (ti->address & 0xffff);
    1.93      current->thread.fast_trap_desc.b = 
    1.94 -        (ti->address & 0xffff0000) | 0x8f00 | (ti->dpl&3)<<13;
    1.95 +        (ti->address & 0xffff0000) | 0x8f00 | (TI_GET_DPL(ti)&3)<<13;
    1.96  
    1.97      SET_FAST_TRAP(&current->thread);
    1.98  
     2.1 --- a/xen/include/hypervisor-ifs/hypervisor-if.h	Wed Jul 23 13:16:18 2003 +0000
     2.2 +++ b/xen/include/hypervisor-ifs/hypervisor-if.h	Mon Jul 28 13:17:58 2003 +0000
     2.3 @@ -146,12 +146,16 @@
     2.4  /*
     2.5   * Send an array of these to HYPERVISOR_set_trap_table()
     2.6   */
     2.7 +#define TI_GET_DPL(_ti)      ((_ti)->flags & 3)
     2.8 +#define TI_GET_IF(_ti)       ((_ti)->flags & 4)
     2.9 +#define TI_SET_DPL(_ti,_dpl) ((_ti)->flags |= (_dpl))
    2.10 +#define TI_SET_IF(_ti,_if)   ((_ti)->flags |= (_if))
    2.11  typedef struct trap_info_st
    2.12  {
    2.13 -    unsigned char  vector;  /* exception/interrupt vector */
    2.14 -    unsigned char  dpl;	    /* privilege level		  */
    2.15 -    unsigned short cs;	    /* code selector		  */
    2.16 -    unsigned long  address; /* code address		  */
    2.17 +    unsigned char  vector;  /* exception vector                              */
    2.18 +    unsigned char  flags;   /* 0-3: privilege level; 4: clear event enable?  */
    2.19 +    unsigned short cs;	    /* code selector                                 */
    2.20 +    unsigned long  address; /* code address                                  */
    2.21  } trap_info_t;
    2.22  
    2.23  /*
     3.1 --- a/xenolinux-2.4.21-sparse/arch/xeno/kernel/traps.c	Wed Jul 23 13:16:18 2003 +0000
     3.2 +++ b/xenolinux-2.4.21-sparse/arch/xeno/kernel/traps.c	Mon Jul 28 13:17:58 2003 +0000
     3.3 @@ -554,6 +554,7 @@ static void __init set_call_gate(void *a
     3.4  }
     3.5  
     3.6  
     3.7 +/* NB. All these are "trap gates" (i.e. events_mask isn't cleared). */
     3.8  static trap_info_t trap_table[] = {
     3.9      {  0, 0, __KERNEL_CS, (unsigned long)divide_error                },
    3.10      {  1, 0, __KERNEL_CS, (unsigned long)debug                       },