From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755247AbbG1F3r (ORCPT ); Tue, 28 Jul 2015 01:29:47 -0400 Received: from mail.kernel.org ([198.145.29.136]:38679 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754656AbbG1F3p (ORCPT ); Tue, 28 Jul 2015 01:29:45 -0400 From: Andy Lutomirski To: Peter Zijlstra , Steven Rostedt Cc: "security@kernel.org" , X86 ML , Borislav Petkov , Sasha Levin , linux-kernel@vger.kernel.org, Konrad Rzeszutek Wilk , Boris Ostrovsky , Andrew Cooper , Jan Beulich , xen-devel , Andy Lutomirski , stable@vger.kernel.org Subject: [PATCH v5 1/4] x86/xen: Unmap aliases in xen_alloc_ldt and xen_free_ldt Date: Mon, 27 Jul 2015 22:29:38 -0700 Message-Id: X-Mailer: git-send-email 2.4.3 In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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: stable@vger.kernel.org Signed-off-by: Andy Lutomirski --- 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 #include #include +#include #include #include @@ -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