On Fri, 2010-04-16 at 11:18 +0200, Jan Kiszka wrote: > Jan Kiszka wrote: > > Ensure that we always call the Linux page fault handler with the correct > > cr2 value set. So far this is not the case if a second fault happens > > while we execute the domain fault handler (which may, e.g., perform a > > sleepy migration before returning). > > > > Instead of re-writing cr2 directly in hardware, make use of the paravirt > > capabilities of Linux and simply overload read/write_cr2 for this > > purpose. > > Already had a chance to look at it? Any concerns? We are about to ship > this patch as it proved to fix the bug we saw.
No concerns, I'll merge this. Thanks. > > BTW: I haven't thought about all details yet, but this should finally > allow us to enter the Linux page fault handler with hardware interrupts > enabled, thus drop the related patches to enable them after reading cr2. > > Jan > > > > > Signed-off-by: Jan Kiszka <[email protected]> > > --- > > arch/x86/include/asm/ipipe.h | 2 ++ > > arch/x86/include/asm/system.h | 5 +++++ > > arch/x86/kernel/ipipe.c | 10 ++++++++++ > > 3 files changed, 17 insertions(+), 0 deletions(-) > > > > diff --git a/arch/x86/include/asm/ipipe.h b/arch/x86/include/asm/ipipe.h > > index 32b2ece..baec016 100644 > > --- a/arch/x86/include/asm/ipipe.h > > +++ b/arch/x86/include/asm/ipipe.h > > @@ -33,6 +33,8 @@ > > > > DECLARE_PER_CPU(struct pt_regs, __ipipe_tick_regs); > > > > +DECLARE_PER_CPU(unsigned long, __ipipe_cr2); > > + > > static inline unsigned __ipipe_get_irq_vector(int irq) > > { > > #ifdef CONFIG_X86_IO_APIC > > diff --git a/arch/x86/include/asm/system.h b/arch/x86/include/asm/system.h > > index 2760033..093687e 100644 > > --- a/arch/x86/include/asm/system.h > > +++ b/arch/x86/include/asm/system.h > > @@ -308,8 +308,13 @@ static inline void native_wbinvd(void) > > #else > > #define read_cr0() (native_read_cr0()) > > #define write_cr0(x) (native_write_cr0(x)) > > +#ifdef CONFIG_IPIPE > > +#define read_cr2() __raw_get_cpu_var(__ipipe_cr2) > > +#define write_cr2(x) __raw_get_cpu_var(__ipipe_cr2) = (x) > > +#else /* !CONFIG_IPIPE */ > > #define read_cr2() (native_read_cr2()) > > #define write_cr2(x) (native_write_cr2(x)) > > +#endif /* !CONFIG_IPIPE */ > > #define read_cr3() (native_read_cr3()) > > #define write_cr3(x) (native_write_cr3(x)) > > #define read_cr4() (native_read_cr4()) > > diff --git a/arch/x86/kernel/ipipe.c b/arch/x86/kernel/ipipe.c > > index b1b6912..9425fbd 100644 > > --- a/arch/x86/kernel/ipipe.c > > +++ b/arch/x86/kernel/ipipe.c > > @@ -53,6 +53,9 @@ int __ipipe_tick_irq = 0; /* Legacy timer */ > > > > DEFINE_PER_CPU(struct pt_regs, __ipipe_tick_regs); > > > > +DEFINE_PER_CPU(unsigned long, __ipipe_cr2); > > +EXPORT_PER_CPU_SYMBOL_GPL(__ipipe_cr2); > > + > > #ifdef CONFIG_SMP > > > > static cpumask_t __ipipe_cpu_sync_map; > > @@ -712,6 +715,7 @@ int __ipipe_handle_exception(struct pt_regs *regs, long > > error_code, int vector) > > { > > bool root_entry = false; > > unsigned long flags = 0; > > + unsigned long cr2 = 0; > > > > if (ipipe_root_domain_p) { > > root_entry = true; > > @@ -734,6 +738,9 @@ int __ipipe_handle_exception(struct pt_regs *regs, long > > error_code, int vector) > > return 1; > > #endif /* CONFIG_KGDB */ > > > > + if (vector == ex_do_page_fault) > > + cr2 = native_read_cr2(); > > + > > if (unlikely(ipipe_trap_notify(vector, regs))) { > > if (root_entry) > > local_irq_restore_nosync(flags); > > @@ -779,6 +786,9 @@ int __ipipe_handle_exception(struct pt_regs *regs, long > > error_code, int vector) > > } > > } > > > > + if (vector == ex_do_page_fault) > > + write_cr2(cr2); > > + > > __ipipe_std_extable[vector](regs, error_code); > > > > /* > > > > > -- Philippe. _______________________________________________ Adeos-main mailing list [email protected] https://mail.gna.org/listinfo/adeos-main
