mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 02:30:03 +01:00
bitkeeper revision 1.7.3.3 (3df135bbxixm9CkVsgxqH8Sfa-8fIA)
traps.c: Clean up 'INT <n>' virtualisation. Fix bug in bounds (int 5) handling.
This commit is contained in:
1 parent
0c0e4b0b14
commit
2d79667816
1 file changed
+23
-13
@@ -273,7 +273,26 @@ asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
|
||||
if (!(regs->xcs & 3) || (error_code & 1))
|
||||
goto gp_in_kernel;
|
||||
|
||||
if ( (error_code & 2) )
|
||||
/*
|
||||
* Cunning trick to allow arbitrary "INT n" handling.
|
||||
*
|
||||
* We set DPL == 0 on all vectors in the IDT. This prevents any INT <n>
|
||||
* instruction from trapping to the appropriate vector, when that might not
|
||||
* be expected by Xen or the guest OS. For example, that entry might be for
|
||||
* a fault handler (unlike traps, faults don't increment EIP), or might
|
||||
* expect an error code on the stack (which a software trap never
|
||||
* provides), or might be a hardware interrupt handler that doesn't like
|
||||
* being called spuriously.
|
||||
*
|
||||
* Instead, a GPF occurs with the faulting IDT vector in the error code.
|
||||
* Bit 1 is set to indicate that an IDT entry caused the fault.
|
||||
* Bit 0 is clear to indicate that it's a software fault, not hardware.
|
||||
*
|
||||
* NOTE: Vectors 3 and 4 are dealt with from their own handler. This is okay
|
||||
* because they can only be triggered by an explicit DPL-checked instruction.
|
||||
* The DPL specified by the guest OS for these vectors is NOT CHECKED!!
|
||||
*/
|
||||
if ( (error_code & 3) == 2 )
|
||||
{
|
||||
/* This fault must be due to <INT n> instruction. */
|
||||
ti = current->thread.traps + (error_code>>3);
|
||||
@@ -505,9 +524,9 @@ void __init trap_init(void)
|
||||
set_trap_gate(0,÷_error);
|
||||
set_trap_gate(1,&debug);
|
||||
set_intr_gate(2,&nmi);
|
||||
set_system_gate(3,&int3); /* int3-5 can be called from all */
|
||||
set_system_gate(4,&overflow);
|
||||
set_system_gate(5,&bounds);
|
||||
set_system_gate(3,&int3); /* usable from all privilege levels */
|
||||
set_system_gate(4,&overflow); /* usable from all privilege levels */
|
||||
set_trap_gate(5,&bounds);
|
||||
set_trap_gate(6,&invalid_op);
|
||||
set_trap_gate(7,&device_not_available);
|
||||
set_trap_gate(8,&double_fault);
|
||||
@@ -523,15 +542,6 @@ void __init trap_init(void)
|
||||
set_trap_gate(18,&machine_check);
|
||||
set_trap_gate(19,&simd_coprocessor_error);
|
||||
|
||||
/*
|
||||
* Cunning trick to allow arbitrary "INT n" handling.
|
||||
*
|
||||
* 1. 3 <= N <= 5 is trivial, as these are intended to be explicit.
|
||||
*
|
||||
* 2. All others, we set gate DPL == 0. Any use of "INT n" will thus
|
||||
* cause a GPF with CS:EIP pointing at the faulting instruction.
|
||||
*/
|
||||
|
||||
/* Only ring 1 can access monitor services. */
|
||||
_set_gate(idt_table+HYPERVISOR_CALL_VECTOR,15,1,&hypervisor_call);
|
||||
|
||||
|
||||