From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754200AbdJaWfX (ORCPT ); Tue, 31 Oct 2017 18:35:23 -0400 Received: from mga02.intel.com ([134.134.136.20]:30175 "EHLO mga02.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932930AbdJaWcI (ORCPT ); Tue, 31 Oct 2017 18:32:08 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.44,326,1505804400"; d="scan'208";a="170236012" Subject: [PATCH 11/23] x86, kaiser: map GDT into user page tables To: linux-kernel@vger.kernel.org Cc: linux-mm@kvack.org, dave.hansen@linux.intel.com, moritz.lipp@iaik.tugraz.at, daniel.gruss@iaik.tugraz.at, michael.schwarz@iaik.tugraz.at, luto@kernel.org, torvalds@linux-foundation.org, keescook@google.com, hughd@google.com, x86@kernel.org From: Dave Hansen Date: Tue, 31 Oct 2017 15:32:06 -0700 References: <20171031223146.6B47C861@viggo.jf.intel.com> In-Reply-To: <20171031223146.6B47C861@viggo.jf.intel.com> Message-Id: <20171031223206.05E4E932@viggo.jf.intel.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The GDT is used to control the x86 segmentation mechanism. It must be virtually mapped when switching segments or at IRET time when switching between userspace and kernel. The original KAISER patch did not do this. I have no ide how it ever worked. Signed-off-by: Dave Hansen Cc: Moritz Lipp Cc: Daniel Gruss Cc: Michael Schwarz Cc: Andy Lutomirski Cc: Linus Torvalds Cc: Kees Cook Cc: Hugh Dickins Cc: x86@kernel.org --- b/arch/x86/kernel/cpu/common.c | 15 +++++++++++++++ b/arch/x86/mm/kaiser.c | 10 ++++++++++ 2 files changed, 25 insertions(+) diff -puN arch/x86/kernel/cpu/common.c~kaiser-user-map-gdt-pages arch/x86/kernel/cpu/common.c --- a/arch/x86/kernel/cpu/common.c~kaiser-user-map-gdt-pages 2017-10-31 15:03:54.432306321 -0700 +++ b/arch/x86/kernel/cpu/common.c 2017-10-31 15:03:54.441306747 -0700 @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -487,6 +488,20 @@ static inline void setup_fixmap_gdt(int #endif __set_fixmap(get_cpu_gdt_ro_index(cpu), get_cpu_gdt_paddr(cpu), prot); + + /* CPU 0's mapping is done in kaiser_init() */ + if (cpu) { + int ret; + + ret = kaiser_add_mapping((unsigned long) get_cpu_gdt_ro(cpu), + PAGE_SIZE, __PAGE_KERNEL_RO); + /* + * We do not have a good way to fail CPU bringup. + * Just WARN about it and hope we boot far enough + * to get a good log out. + */ + WARN_ON(ret); + } } /* Load the original GDT from the per-cpu structure */ diff -puN arch/x86/mm/kaiser.c~kaiser-user-map-gdt-pages arch/x86/mm/kaiser.c --- a/arch/x86/mm/kaiser.c~kaiser-user-map-gdt-pages 2017-10-31 15:03:54.436306511 -0700 +++ b/arch/x86/mm/kaiser.c 2017-10-31 15:03:54.442306794 -0700 @@ -329,6 +329,16 @@ void __init kaiser_init(void) kaiser_add_user_map_early((void *)idt_descr.address, sizeof(gate_desc) * NR_VECTORS, __PAGE_KERNEL_RO); + + /* + * We could theoretically do this in setup_fixmap_gdt(). + * But, we would need to rewrite the above page table + * allocation code to use the bootmem allocator. The + * buddy allocator is not available at the time that we + * call setup_fixmap_gdt() for CPU 0. + */ + kaiser_add_user_map_early(get_cpu_gdt_ro(0), PAGE_SIZE, + __PAGE_KERNEL_RO); } int kaiser_add_mapping(unsigned long addr, unsigned long size, _