mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
bitkeeper revision 1.1159.170.31 (419a3a86bSLSt5jRubDsLFc4VXWrkQ)
Sanitise failsafe callback. The safe pf handler stuff was madness. If it turns out to be needed, there must be a better way.
This commit is contained in:
1 parent
df2a636c6f
commit
1b6f005a13
4 files changed
+16
-156
No files matched your search
@@ -369,28 +369,19 @@ critical_fixup_table:
|
||||
|
||||
# Hypervisor uses this for application faults while it executes.
|
||||
ENTRY(failsafe_callback)
|
||||
pushal
|
||||
call SYMBOL_NAME(install_safe_pf_handler)
|
||||
movl 32(%esp),%ebx
|
||||
1: movl %ebx,%ds
|
||||
movl 36(%esp),%ebx
|
||||
2: movl %ebx,%es
|
||||
movl 40(%esp),%ebx
|
||||
3: movl %ebx,%fs
|
||||
movl 44(%esp),%ebx
|
||||
4: movl %ebx,%gs
|
||||
call SYMBOL_NAME(install_normal_pf_handler)
|
||||
popal
|
||||
addl $16,%esp
|
||||
1: popl %ds
|
||||
2: popl %es
|
||||
3: popl %fs
|
||||
4: popl %gs
|
||||
5: iret
|
||||
.section .fixup,"ax"; \
|
||||
6: xorl %ebx,%ebx; \
|
||||
6: movl $0,(%esp); \
|
||||
jmp 1b; \
|
||||
7: xorl %ebx,%ebx; \
|
||||
7: movl $0,(%esp); \
|
||||
jmp 2b; \
|
||||
8: xorl %ebx,%ebx; \
|
||||
8: movl $0,(%esp); \
|
||||
jmp 3b; \
|
||||
9: xorl %ebx,%ebx; \
|
||||
9: movl $0,(%esp); \
|
||||
jmp 4b; \
|
||||
10: pushl %ss; \
|
||||
popl %ds; \
|
||||
@@ -511,7 +502,6 @@ ENTRY(_name1) \
|
||||
addl $12,%esp ; \
|
||||
jmp ret_from_exception ;
|
||||
PAGE_FAULT_STUB(page_fault, do_page_fault)
|
||||
PAGE_FAULT_STUB(safe_page_fault, do_safe_page_fault)
|
||||
|
||||
ENTRY(machine_check)
|
||||
pushl $0
|
||||
|
||||
@@ -59,7 +59,6 @@ asmlinkage void segment_not_present(void);
|
||||
asmlinkage void stack_segment(void);
|
||||
asmlinkage void general_protection(void);
|
||||
asmlinkage void page_fault(void);
|
||||
asmlinkage void safe_page_fault(void);
|
||||
asmlinkage void coprocessor_error(void);
|
||||
asmlinkage void simd_coprocessor_error(void);
|
||||
asmlinkage void alignment_check(void);
|
||||
@@ -627,65 +626,3 @@ void __init trap_init(void)
|
||||
|
||||
cpu_init();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* install_safe_pf_handler / install_normal_pf_handler:
|
||||
*
|
||||
* These are used within the failsafe_callback handler in entry.S to avoid
|
||||
* taking a full page fault when reloading FS and GS. This is because FS and
|
||||
* GS could be invalid at pretty much any point while Xenolinux executes (we
|
||||
* don't set them to safe values on entry to the kernel). At *any* point Xen
|
||||
* may be entered due to a hardware interrupt --- on exit from Xen an invalid
|
||||
* FS/GS will cause our failsafe_callback to be executed. This could occur,
|
||||
* for example, while the mmu_update_queue is in an inconsistent state. This
|
||||
* is disastrous because the normal page-fault handler touches the update
|
||||
* queue!
|
||||
*
|
||||
* Fortunately, within the failsafe handler it is safe to force DS/ES/FS/GS
|
||||
* to zero if they cannot be reloaded -- at this point executing a normal
|
||||
* page fault would not change this effect. The safe page-fault handler
|
||||
* ensures this end result (blow away the selector value) without the dangers
|
||||
* of the normal page-fault handler.
|
||||
*
|
||||
* NB. Perhaps this can all go away after we have implemented writable
|
||||
* page tables. :-)
|
||||
*/
|
||||
|
||||
asmlinkage void do_safe_page_fault(struct pt_regs *regs,
|
||||
unsigned long error_code,
|
||||
unsigned long address)
|
||||
{
|
||||
unsigned long fixup;
|
||||
|
||||
if ( (fixup = search_exception_table(regs->eip)) != 0 )
|
||||
{
|
||||
regs->eip = fixup;
|
||||
return;
|
||||
}
|
||||
|
||||
die("Unhandleable 'safe' page fault!", regs, error_code);
|
||||
}
|
||||
|
||||
unsigned long install_safe_pf_handler(void)
|
||||
{
|
||||
static trap_info_t safe_pf[] = {
|
||||
{ 14, 0, __KERNEL_CS, (unsigned long)safe_page_fault },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
unsigned long flags;
|
||||
local_irq_save(flags);
|
||||
HYPERVISOR_set_trap_table(safe_pf);
|
||||
return flags; /* This is returned in %%eax */
|
||||
}
|
||||
|
||||
__attribute__((regparm(3))) /* This function take its arg in %%eax */
|
||||
void install_normal_pf_handler(unsigned long flags)
|
||||
{
|
||||
static trap_info_t normal_pf[] = {
|
||||
{ 14, 0, __KERNEL_CS, (unsigned long)page_fault },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
HYPERVISOR_set_trap_table(normal_pf);
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
@@ -510,28 +510,19 @@ critical_fixup_table:
|
||||
|
||||
# Hypervisor uses this for application faults while it executes.
|
||||
ENTRY(failsafe_callback)
|
||||
pushal
|
||||
call install_safe_pf_handler
|
||||
movl 32(%esp),%ebx
|
||||
1: movl %ebx,%ds
|
||||
movl 36(%esp),%ebx
|
||||
2: movl %ebx,%es
|
||||
movl 40(%esp),%ebx
|
||||
3: movl %ebx,%fs
|
||||
movl 44(%esp),%ebx
|
||||
4: movl %ebx,%gs
|
||||
call install_normal_pf_handler
|
||||
popal
|
||||
addl $16,%esp
|
||||
1: popl %ds
|
||||
2: popl %es
|
||||
3: popl %fs
|
||||
4: popl %gs
|
||||
5: iret
|
||||
.section .fixup,"ax"; \
|
||||
6: xorl %ebx,%ebx; \
|
||||
6: movl $0,(%esp); \
|
||||
jmp 1b; \
|
||||
7: xorl %ebx,%ebx; \
|
||||
7: movl $0,(%esp); \
|
||||
jmp 2b; \
|
||||
8: xorl %ebx,%ebx; \
|
||||
8: movl $0,(%esp); \
|
||||
jmp 3b; \
|
||||
9: xorl %ebx,%ebx; \
|
||||
9: movl $0,(%esp); \
|
||||
jmp 4b; \
|
||||
10: pushl %ss; \
|
||||
popl %ds; \
|
||||
@@ -726,7 +717,6 @@ ENTRY(_name1) \
|
||||
addl $12,%esp ; \
|
||||
jmp ret_from_exception ;
|
||||
PAGE_FAULT_STUB(page_fault, do_page_fault)
|
||||
PAGE_FAULT_STUB(safe_page_fault, do_safe_page_fault)
|
||||
|
||||
#ifdef CONFIG_X86_MCE
|
||||
ENTRY(machine_check)
|
||||
|
||||
@@ -60,8 +60,6 @@ asmlinkage int system_call(void);
|
||||
asmlinkage void lcall7(void);
|
||||
asmlinkage void lcall27(void);
|
||||
|
||||
asmlinkage void safe_page_fault(void);
|
||||
|
||||
/* Do we ignore FPU interrupts ? */
|
||||
char ignore_fpu_irq = 0;
|
||||
|
||||
@@ -1072,58 +1070,3 @@ void __init trap_init(void)
|
||||
*/
|
||||
cpu_init();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* install_safe_pf_handler / install_normal_pf_handler:
|
||||
*
|
||||
* These are used within the failsafe_callback handler in entry.S to avoid
|
||||
* taking a full page fault when reloading FS and GS. This is because FS and
|
||||
* GS could be invalid at pretty much any point while Xen Linux executes (we
|
||||
* don't set them to safe values on entry to the kernel). At *any* point Xen
|
||||
* may be entered due to a hardware interrupt --- on exit from Xen an invalid
|
||||
* FS/GS will cause our failsafe_callback to be executed. This could occur,
|
||||
* for example, while the mmmu_update_queue is in an inconsistent state. This
|
||||
* is disastrous because the normal page-fault handler touches the update
|
||||
* queue!
|
||||
*
|
||||
* Fortunately, within the failsafe handler it is safe to force DS/ES/FS/GS
|
||||
* to zero if they cannot be reloaded -- at this point executing a normal
|
||||
* page fault would not change this effect. The safe page-fault handler
|
||||
* ensures this end result (blow away the selector value) without the dangers
|
||||
* of the normal page-fault handler.
|
||||
*
|
||||
* NB. Perhaps this can all go away after we have implemented writable
|
||||
* page tables. :-)
|
||||
*/
|
||||
|
||||
asmlinkage void do_safe_page_fault(struct pt_regs *regs,
|
||||
unsigned long error_code,
|
||||
unsigned long address)
|
||||
{
|
||||
if (!fixup_exception(regs))
|
||||
die("Unhandleable 'safe' page fault!", regs, error_code);
|
||||
}
|
||||
|
||||
unsigned long install_safe_pf_handler(void)
|
||||
{
|
||||
static trap_info_t safe_pf[] = {
|
||||
{ 14, 0, __KERNEL_CS, (unsigned long)safe_page_fault },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
unsigned long flags;
|
||||
local_irq_save(flags);
|
||||
HYPERVISOR_set_trap_table(safe_pf);
|
||||
return flags; /* This is returned in %%eax */
|
||||
}
|
||||
|
||||
__attribute__((regparm(3))) /* This function take its arg in %%eax */
|
||||
void install_normal_pf_handler(unsigned long flags)
|
||||
{
|
||||
static trap_info_t normal_pf[] = {
|
||||
{ 14, 0, __KERNEL_CS, (unsigned long)page_fault },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
HYPERVISOR_set_trap_table(normal_pf);
|
||||
local_irq_restore(flags);
|
||||
}
|
||||