From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754068AbdKXRZ0 (ORCPT ); Fri, 24 Nov 2017 12:25:26 -0500 Received: from mail-wr0-f194.google.com ([209.85.128.194]:36222 "EHLO mail-wr0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754050AbdKXRZV (ORCPT ); Fri, 24 Nov 2017 12:25:21 -0500 X-Google-Smtp-Source: AGs4zMYu+fcTj9I3LOqBFBhlq017rQb/Vz13qEW0sR9dORvCCrHhWrkA5ZnHu4LDQv95kEKWX8o+Kg== From: Ingo Molnar To: linux-kernel@vger.kernel.org Cc: Dave Hansen , Andy Lutomirski , Thomas Gleixner , "H . Peter Anvin" , Peter Zijlstra , Borislav Petkov , Linus Torvalds Subject: [PATCH 29/43] x86/mm/kaiser: Map dynamically-allocated LDTs Date: Fri, 24 Nov 2017 18:23:57 +0100 Message-Id: <20171124172411.19476-30-mingo@kernel.org> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20171124172411.19476-1-mingo@kernel.org> References: <20171124172411.19476-1-mingo@kernel.org> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Dave Hansen Normally, a process has a NULL mm->context.ldt. But, there is a syscall for a process to set a new one. If a process does that, the LDT be mapped into the user page tables, just like the default copy. The original KAISER patch missed this case. Signed-off-by: Dave Hansen Signed-off-by: Thomas Gleixner Cc: Linus Torvalds Cc: Peter Zijlstra Cc: daniel.gruss@iaik.tugraz.at Cc: hughd@google.com Cc: keescook@google.com Cc: linux-mm@kvack.org Cc: luto@kernel.org Cc: michael.schwarz@iaik.tugraz.at Cc: moritz.lipp@iaik.tugraz.at Cc: richard.fellner@student.tugraz.at Link: https://lkml.kernel.org/r/20171123003455.275397F7@viggo.jf.intel.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/ldt.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c index 1c1eae961340..d6ab1144fdbf 100644 --- a/arch/x86/kernel/ldt.c +++ b/arch/x86/kernel/ldt.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -57,11 +58,21 @@ static void flush_ldt(void *__mm) refresh_ldt_segments(); } +static void __free_ldt_struct(struct ldt_struct *ldt) +{ + if (ldt->nr_entries * LDT_ENTRY_SIZE > PAGE_SIZE) + vfree_atomic(ldt->entries); + else + free_page((unsigned long)ldt->entries); + kfree(ldt); +} + /* The caller must call finalize_ldt_struct on the result. LDT starts zeroed. */ static struct ldt_struct *alloc_ldt_struct(unsigned int num_entries) { struct ldt_struct *new_ldt; unsigned int alloc_size; + int ret; if (num_entries > LDT_ENTRIES) return NULL; @@ -89,6 +100,12 @@ static struct ldt_struct *alloc_ldt_struct(unsigned int num_entries) return NULL; } + ret = kaiser_add_mapping((unsigned long)new_ldt->entries, alloc_size, + __PAGE_KERNEL | _PAGE_GLOBAL); + if (ret) { + __free_ldt_struct(new_ldt); + return NULL; + } new_ldt->nr_entries = num_entries; return new_ldt; } @@ -115,12 +132,10 @@ static void free_ldt_struct(struct ldt_struct *ldt) if (likely(!ldt)) return; + kaiser_remove_mapping((unsigned long)ldt->entries, + ldt->nr_entries * LDT_ENTRY_SIZE); paravirt_free_ldt(ldt->entries, ldt->nr_entries); - if (ldt->nr_entries * LDT_ENTRY_SIZE > PAGE_SIZE) - vfree_atomic(ldt->entries); - else - free_page((unsigned long)ldt->entries); - kfree(ldt); + __free_ldt_struct(ldt); } /* -- 2.14.1