[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [XEN] Early page fault handler to deal with spurious page faults.
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Node ID 4ce643274b67c3aaea83ecd3f2f7133c0d599b88 # Parent 27294bab3d624d570fe3dadeb9988b7759bd774b [XEN] Early page fault handler to deal with spurious page faults. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> --- xen/arch/x86/crash.c | 12 ++---------- xen/arch/x86/setup.c | 11 ++++++----- xen/arch/x86/traps.c | 31 +++++++++++++++++++++++++++++++ xen/arch/x86/x86_32/domain_page.c | 26 -------------------------- xen/arch/x86/x86_32/entry.S | 8 ++++++++ xen/arch/x86/x86_64/entry.S | 6 ++++++ xen/include/xen/domain_page.h | 9 --------- 7 files changed, 53 insertions(+), 50 deletions(-) diff -r 27294bab3d62 -r 4ce643274b67 xen/arch/x86/crash.c --- a/xen/arch/x86/crash.c Thu Dec 07 13:47:13 2006 +0000 +++ b/xen/arch/x86/crash.c Thu Dec 07 14:03:54 2006 +0000 @@ -27,7 +27,6 @@ #include <public/xen.h> #include <asm/hvm/hvm.h> -#ifdef CONFIG_SMP static atomic_t waiting_for_crash_ipi; static int crash_nmi_callback(struct cpu_user_regs *regs, int cpu) @@ -71,9 +70,7 @@ static void nmi_shootdown_cpus(void) atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1); /* Would it be better to replace the trap vector here? */ set_nmi_callback(crash_nmi_callback); - /* Ensure the new callback function is set before sending - * out the NMI - */ + /* Ensure the new callback function is set before sending out the NMI. */ wmb(); smp_send_nmi_allbutself(); @@ -88,7 +85,6 @@ static void nmi_shootdown_cpus(void) /* Leave the nmi callback set */ disable_local_APIC(); } -#endif static void crash_save_xen_notes(void) { @@ -102,16 +98,12 @@ static void crash_save_xen_notes(void) void machine_crash_shutdown(void) { - printk("machine_crash_shutdown: %d\n", smp_processor_id()); local_irq_disable(); -#ifdef CONFIG_SMP nmi_shootdown_cpus(); -#endif -#ifdef CONFIG_X86_IO_APIC disable_IO_APIC(); -#endif + hvm_disable(); crash_save_xen_notes(); diff -r 27294bab3d62 -r 4ce643274b67 xen/arch/x86/setup.c --- a/xen/arch/x86/setup.c Thu Dec 07 13:47:13 2006 +0000 +++ b/xen/arch/x86/setup.c Thu Dec 07 14:03:54 2006 +0000 @@ -305,6 +305,9 @@ void __init __start_xen(multiboot_info_t .stop_bits = 1 }; + extern void early_page_fault(void); + set_intr_gate(TRAP_page_fault, &early_page_fault); + /* Parse the command-line options. */ if ( (mbi->flags & MBI_CMDLINE) && (mbi->cmdline != 0) ) cmdline = __va(mbi->cmdline); @@ -501,21 +504,19 @@ void __init __start_xen(multiboot_info_t kdump_start >>= PAGE_SHIFT; kdump_size >>= PAGE_SHIFT; - /* allocate pages for Kdump memory area */ + /* Allocate pages for Kdump memory area. */ k = alloc_boot_pages_at(kdump_size, kdump_start); - if ( k != kdump_start ) panic("Unable to reserve Kdump memory\n"); - /* allocate pages for relocated initial images */ + /* Allocate pages for relocated initial images. */ k = ((initial_images_end - initial_images_start) & ~PAGE_MASK) ? 1 : 0; k += (initial_images_end - initial_images_start) >> PAGE_SHIFT; k = alloc_boot_pages(k, 1); - - if ( !k ) + if ( k == 0 ) panic("Unable to allocate initial images memory\n"); move_memory(k << PAGE_SHIFT, initial_images_start, initial_images_end); diff -r 27294bab3d62 -r 4ce643274b67 xen/arch/x86/traps.c --- a/xen/arch/x86/traps.c Thu Dec 07 13:47:13 2006 +0000 +++ b/xen/arch/x86/traps.c Thu Dec 07 14:03:54 2006 +0000 @@ -935,6 +935,37 @@ asmlinkage int do_page_fault(struct cpu_ return 0; } +/* + * Early handler to deal with spurious page faults. For example, consider a + * routine that uses a mapping immediately after installing it (making it + * present). The CPU may speculatively execute the memory access before + * executing the PTE write. The instruction will then be marked to cause a + * page fault when it is retired, despite the fact that the PTE is present and + * correct at that point in time. + */ +asmlinkage int do_early_page_fault(struct cpu_user_regs *regs) +{ + static int stuck; + static unsigned long prev_eip, prev_cr2; + unsigned long cr2 = read_cr2(); + + BUG_ON(smp_processor_id() != 0); + + if ( (regs->eip != prev_eip) || (cr2 != prev_cr2) ) + { + prev_eip = regs->eip; + prev_cr2 = cr2; + stuck = 0; + return EXCRET_not_a_fault; + } + + if ( stuck++ == 1000 ) + panic("Early fatal page fault at %04x:%p (cr2=%p, ec=%04x)\n", + regs->cs, _p(regs->eip), _p(cr2), regs->error_code); + + return EXCRET_not_a_fault; +} + long do_fpu_taskswitch(int set) { struct vcpu *v = current; diff -r 27294bab3d62 -r 4ce643274b67 xen/arch/x86/x86_32/domain_page.c --- a/xen/arch/x86/x86_32/domain_page.c Thu Dec 07 13:47:13 2006 +0000 +++ b/xen/arch/x86/x86_32/domain_page.c Thu Dec 07 14:03:54 2006 +0000 @@ -252,29 +252,3 @@ void unmap_domain_page_global(void *va) idx = (__va - IOREMAP_VIRT_START) >> PAGE_SHIFT; set_bit(idx, garbage); } - -paddr_t maddr_from_mapped_domain_page(void *va) -{ - unsigned long __va = (unsigned long)va; - l2_pgentry_t *pl2e; - l1_pgentry_t *pl1e; - unsigned int idx; - struct mapcache *cache; - unsigned long mfn; - - if ( (__va >= MAPCACHE_VIRT_START) && (__va < MAPCACHE_VIRT_END) ) - { - cache = &mapcache_current_vcpu()->domain->arch.mapcache; - idx = ((unsigned long)va - MAPCACHE_VIRT_START) >> PAGE_SHIFT; - mfn = l1e_get_pfn(cache->l1tab[idx]); - } - else - { - ASSERT(__va >= IOREMAP_VIRT_START); - pl2e = virt_to_xen_l2e(__va); - pl1e = l2e_to_l1e(*pl2e) + l1_table_offset(__va); - mfn = l1e_get_pfn(*pl1e); - } - - return ((paddr_t)mfn << PAGE_SHIFT) | ((unsigned long)va & ~PAGE_MASK); -} diff -r 27294bab3d62 -r 4ce643274b67 xen/arch/x86/x86_32/entry.S --- a/xen/arch/x86/x86_32/entry.S Thu Dec 07 13:47:13 2006 +0000 +++ b/xen/arch/x86/x86_32/entry.S Thu Dec 07 14:03:54 2006 +0000 @@ -536,6 +536,14 @@ ENTRY(spurious_interrupt_bug) pushl $TRAP_spurious_int<<16 jmp handle_exception +ENTRY(early_page_fault) + SAVE_ALL_NOSEGREGS(a) + movl %esp,%edx + pushl %edx + call do_early_page_fault + addl $4,%esp + jmp restore_all_xen + ENTRY(nmi) #ifdef CONFIG_X86_SUPERVISOR_MODE_KERNEL # NMI entry protocol is incompatible with guest kernel in ring 0. diff -r 27294bab3d62 -r 4ce643274b67 xen/arch/x86/x86_64/entry.S --- a/xen/arch/x86/x86_64/entry.S Thu Dec 07 13:47:13 2006 +0000 +++ b/xen/arch/x86/x86_64/entry.S Thu Dec 07 14:03:54 2006 +0000 @@ -478,6 +478,12 @@ ENTRY(double_fault) call do_double_fault ud2 +ENTRY(early_page_fault) + SAVE_ALL + movq %rsp,%rdi + call do_early_page_fault + jmp restore_all_xen + ENTRY(nmi) pushq $0 SAVE_ALL diff -r 27294bab3d62 -r 4ce643274b67 xen/include/xen/domain_page.h --- a/xen/include/xen/domain_page.h Thu Dec 07 13:47:13 2006 +0000 +++ b/xen/include/xen/domain_page.h Thu Dec 07 14:03:54 2006 +0000 @@ -33,13 +33,6 @@ void unmap_domain_page(void *va); */ void *map_domain_page_global(unsigned long mfn); void unmap_domain_page_global(void *va); - -/* - * Convert a VA (within a page previously mapped in the context of the - * currently-executing VCPU via a call to map_domain_page(), or via a - * previous call to map_domain_page_global()) to the mapped machine address. - */ -paddr_t maddr_from_mapped_domain_page(void *va); #define DMCACHE_ENTRY_VALID 1U #define DMCACHE_ENTRY_HELD 2U @@ -109,8 +102,6 @@ domain_mmap_cache_destroy(struct domain_ #define map_domain_page_global(mfn) maddr_to_virt((mfn)<<PAGE_SHIFT) #define unmap_domain_page_global(va) ((void)(va)) -#define maddr_from_mapped_domain_page(va) (virt_to_maddr(va)) - struct domain_mmap_cache { }; _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |