ia64/xen-unstable

changeset 22:c89b11899064

bitkeeper revision 1.7.3.3 (3df135bbxixm9CkVsgxqH8Sfa-8fIA)

traps.c:
Clean up 'INT <n>' virtualisation. Fix bug in bounds (int 5) handling.
author kaf24@labyrinth.cl.cam.ac.uk
date Fri Dec 06 23:41:47 2002 +0000 (2002-12-06)
parents 5029d4402aeb
children 6b1edd19b627 ab5d1c9a9c89 5e3054a6afc0 1a2ffbadafc6
files xen-2.4.16/arch/i386/traps.c
line diff
     1.1 --- a/xen-2.4.16/arch/i386/traps.c	Fri Dec 06 18:50:27 2002 +0000
     1.2 +++ b/xen-2.4.16/arch/i386/traps.c	Fri Dec 06 23:41:47 2002 +0000
     1.3 @@ -273,7 +273,26 @@ asmlinkage void do_general_protection(st
     1.4      if (!(regs->xcs & 3) || (error_code & 1))
     1.5          goto gp_in_kernel;
     1.6  
     1.7 -    if ( (error_code & 2) )
     1.8 +    /*
     1.9 +     * Cunning trick to allow arbitrary "INT n" handling.
    1.10 +     * 
    1.11 +     * We set DPL == 0 on all vectors in the IDT. This prevents any INT <n>
    1.12 +     * instruction from trapping to the appropriate vector, when that might not 
    1.13 +     * be expected by Xen or the guest OS. For example, that entry might be for
    1.14 +     * a fault handler (unlike traps, faults don't increment EIP), or might
    1.15 +     * expect an error code on the stack (which a software trap never
    1.16 +     * provides), or might be a hardware interrupt handler that doesn't like
    1.17 +     * being called spuriously.  
    1.18 +     * 
    1.19 +     * Instead, a GPF occurs with the faulting IDT vector in the error code.
    1.20 +     * Bit 1 is set to indicate that an IDT entry caused the fault.
    1.21 +     * Bit 0 is clear to indicate that it's a software fault, not hardware.
    1.22 +     * 
    1.23 +     * NOTE: Vectors 3 and 4 are dealt with from their own handler. This is okay
    1.24 +     * because they can only be triggered by an explicit DPL-checked instruction.
    1.25 +     * The DPL specified by the guest OS for these vectors is NOT CHECKED!!
    1.26 +     */
    1.27 +    if ( (error_code & 3) == 2 )
    1.28      {
    1.29          /* This fault must be due to <INT n> instruction. */
    1.30          ti = current->thread.traps + (error_code>>3);
    1.31 @@ -505,9 +524,9 @@ void __init trap_init(void)
    1.32      set_trap_gate(0,&divide_error);
    1.33      set_trap_gate(1,&debug);
    1.34      set_intr_gate(2,&nmi);
    1.35 -    set_system_gate(3,&int3);	/* int3-5 can be called from all */
    1.36 -    set_system_gate(4,&overflow);
    1.37 -    set_system_gate(5,&bounds);
    1.38 +    set_system_gate(3,&int3);     /* usable from all privilege levels */
    1.39 +    set_system_gate(4,&overflow); /* usable from all privilege levels */
    1.40 +    set_trap_gate(5,&bounds);
    1.41      set_trap_gate(6,&invalid_op);
    1.42      set_trap_gate(7,&device_not_available);
    1.43      set_trap_gate(8,&double_fault);
    1.44 @@ -523,15 +542,6 @@ void __init trap_init(void)
    1.45      set_trap_gate(18,&machine_check);
    1.46      set_trap_gate(19,&simd_coprocessor_error);
    1.47  
    1.48 -    /*
    1.49 -     * Cunning trick to allow arbitrary "INT n" handling.
    1.50 -     * 
    1.51 -     * 1. 3 <= N <= 5 is trivial, as these are intended to be explicit.
    1.52 -     * 
    1.53 -     * 2. All others, we set gate DPL == 0. Any use of "INT n" will thus
    1.54 -     *    cause a GPF with CS:EIP pointing at the faulting instruction.
    1.55 -     */
    1.56 -
    1.57      /* Only ring 1 can access monitor services. */
    1.58      _set_gate(idt_table+HYPERVISOR_CALL_VECTOR,15,1,&hypervisor_call);
    1.59