I've been able to get an unmodified Xen guest to OOPS once after a lot of test iterations without this patch. I think this patch fixes the problem. I'm a bit surprised that we don't see much more severe LDT problems on Xen without this fix.
Once the synchronous modify_ldt code causes modify_ldt to more aggressively reallocate the LDT, the OOPSes become much more common without this fix. Cc: sta...@vger.kernel.org Signed-off-by: Andy Lutomirski <l...@kernel.org> --- arch/x86/xen/enlighten.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 0b95c9b8283f..e417d08c56c4 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -32,6 +32,7 @@ #include <linux/gfp.h> #include <linux/memblock.h> #include <linux/edd.h> +#include <linux/vmalloc.h> #include <xen/xen.h> #include <xen/events.h> @@ -512,6 +513,10 @@ static void xen_alloc_ldt(struct desc_struct *ldt, unsigned entries) for(i = 0; i < entries; i += entries_per_page) set_aliased_prot(ldt + i, PAGE_KERNEL_RO); + + /* If there are stray aliases, the LDT won't work. */ + if (is_vmalloc_addr(ldt)) + vm_unmap_aliases(); } static void xen_free_ldt(struct desc_struct *ldt, unsigned entries) @@ -519,6 +524,13 @@ static void xen_free_ldt(struct desc_struct *ldt, unsigned entries) const unsigned entries_per_page = PAGE_SIZE / LDT_ENTRY_SIZE; int i; + /* + * The set_aliased_prot call may OOPS due to a hypercall failure + * if there are any lazy vmap aliases of the page. We don't + * need to call vm_unmap_aliases() here, though, because we + * already eliminated any aliases in xen_alloc_ldt. + */ + for(i = 0; i < entries; i += entries_per_page) set_aliased_prot(ldt + i, PAGE_KERNEL); } -- 2.4.3 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/