From patchwork Thu Jan 26 16:59:39 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Garnier X-Patchwork-Id: 9539799 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 25520604A0 for ; Thu, 26 Jan 2017 17:06:39 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 18FE62094F for ; Thu, 26 Jan 2017 17:06:39 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0C24C26B39; Thu, 26 Jan 2017 17:06:39 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-3.6 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, RCVD_IN_DNSWL_MED, RCVD_IN_SORBS_SPAM, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 121AE2094F for ; Thu, 26 Jan 2017 17:06:38 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cWnSv-0002GX-8u; Thu, 26 Jan 2017 17:04:05 +0000 Received: from mail6.bemta6.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cWnOo-0001gp-SX for xen-devel@lists.xenproject.org; Thu, 26 Jan 2017 16:59:51 +0000 Received: from [85.158.143.35] by server-10.bemta-6.messagelabs.com id E1/AE-13192-60B2A885; Thu, 26 Jan 2017 16:59:50 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrGIsWRWlGSWpSXmKPExsVyMfTAel1W7a4 Ig8Wr+C2+b5nM5MDocfjDFZYAxijWzLyk/IoE1oz5T14zFnwtr+jZfYGtgfFQWhcjF4eQwAxG iRff1rOCOCwCr1gk1hy/xQjiSAj0s0pcXL4XyOEEcmIkdq5cxQ5hV0h8efKbDcQWElCS2LphK TPEqH+MEv9PzWcGSbAJaEnsaZjPBJIQEdjMK7Fozk2wBLPAH0aJGTvNQWxhAWeJtdMhGlgEVC Vund0MdAcHB6+AhcSNrakQy4wlbvefZgWxOQUsJVouNbJALLaQ+LLlJ+sERoEFjAyrGNWLU4v KUot0TfSSijLTM0pyEzNzdA0NzPRyU4uLE9NTcxKTivWS83M3MQJDiwEIdjB2X/Y/xCjJwaQk ytuo0hUhxJeUn1KZkVicEV9UmpNafIhRhoNDSYLXTAsoJ1iUmp5akZaZAwxymLQEB4+SCO8tT aA0b3FBYm5xZjpE6hSjMUdP1+mXTBx7dl1+ySTEkpeflyolzusCMkkApDSjNA9uECz6LjHKSg nzMgKdJsRTkFqUm1mCKv+KUZyDUUmYdwrIFJ7MvBK4fa+ATmECOuUCczvIKSWJCCmpBsb2xDe RPIbn2PiCrnifrQyesfy3rAxDtrID86baLMErL3oOJ/XHnDT1YNhtuHKK3MvICLfYq+EJPXpN n2eV/7pqqGy31/xPI489R+XbxZ5+JwU/f+riuLdFMTcov//ODOuFrOo7vHiE1c+sOjv5beIPU 8Hot5pzo3bf4/2idbwzX5RbgdmrQYmlOCPRUIu5qDgRAN21ZNy5AgAA X-Env-Sender: thgarnie@google.com X-Msg-Ref: server-16.tower-21.messagelabs.com!1485449987!50185250!1 X-Originating-IP: [209.85.192.175] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 9.1.1; banners=-,-,- X-VirusChecked: Checked Received: (qmail 37744 invoked from network); 26 Jan 2017 16:59:48 -0000 Received: from mail-pf0-f175.google.com (HELO mail-pf0-f175.google.com) (209.85.192.175) by server-16.tower-21.messagelabs.com with AES128-GCM-SHA256 encrypted SMTP; 26 Jan 2017 16:59:48 -0000 Received: by mail-pf0-f175.google.com with SMTP id e4so66348367pfg.1 for ; Thu, 26 Jan 2017 08:59:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=keBjFg3ftCXkxu4Uyc6lFZ7Nr+gQEPH1M314Vsr/q3s=; b=MH1fi7Z00JHrVRxq8cQJ+GC0S7lbB9939NfCP0q25xCzVIxOJ6mfH/zzEXsvqZT4ib 0qrIKtLBWiP7gy/boH3mW3Ilg3zwRIViMkM+r21A/Z8Bqs1aHpEWTiS2dNZNvaL6BfPm Z011XTzyOwNbfjcyUXVZ7coBeP8KXv0/xRUSK//op+Meb6H/CIZJZ/eRrrrmT3Z7Fa6O Zi0GKPX8pZBHcUBm6sPLdAjLyS3Hc41KefWFkrKCvEyzf/nnIdHnL7+kIIgcv08x6w7C 2t9PKHsCQdAwuKLC1q3tq450AjcQ37EOTwlnlbAUfQ+SsQ+9EQ4ebOKp93sivPFZc7gh JM6g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=keBjFg3ftCXkxu4Uyc6lFZ7Nr+gQEPH1M314Vsr/q3s=; b=FRdYha4wThwKvtyOELOJIx/FJO2s2GZD1cVdsOh7sLhTlyy4ZYyC2Cz64ojHyslIFu X/fs2Cba8tUtTNBS7KrJhD9LnpKPYz84RwJhepLJGJIEK/txiYqfWmJCYgKxRg9zV8R2 nkXQoQ9bDor9BCpPEeYhU0GUZF2yqA+RNcOLjsW2R7LkMmxuZWtVdm5ouzT95McZ51dl oU62eAviljaw6M8Tc+eCuch7McAPn1guJ32TbqtpE7oiS3wcoQvkU+hGzgk+3DOCpcMS c2Wbv/4gQq91YIW/d7T/Na4T2Xh8R51arXpvhA5W3NGJ93zEAnMvs2CmAe+xfMGyQG+v u1nA== X-Gm-Message-State: AIkVDXIcAj3VKxuDt7Ejx5RyP4D1b22m6sKxjvhgg7YUHpySafRnPgd0OgRrfIP+hrSaGRsE X-Received: by 10.84.143.203 with SMTP id 69mr5572761plz.68.1485449987112; Thu, 26 Jan 2017 08:59:47 -0800 (PST) Received: from skynet.sea.corp.google.com ([100.100.206.185]) by smtp.gmail.com with ESMTPSA id y6sm4723469pge.16.2017.01.26.08.59.46 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 26 Jan 2017 08:59:46 -0800 (PST) From: Thomas Garnier To: Thomas Gleixner , Ingo Molnar , "H . Peter Anvin" , Andrey Ryabinin , Alexander Potapenko , Dmitry Vyukov , Thomas Garnier , Kees Cook , Andy Lutomirski , Arjan van de Ven , Paul Gortmaker , Borislav Petkov , Andy Lutomirski , "Rafael J . Wysocki" , Len Brown , Pavel Machek , Jiri Kosina , Matt Fleming , Ard Biesheuvel , Boris Ostrovsky , Juergen Gross , Rusty Russell , Christian Borntraeger , Fenghua Yu , He Chen , Brian Gerst , "Luis R . Rodriguez" , Adam Buchbinder , Stanislaw Gruszka , Arnd Bergmann , Dave Hansen , Chen Yucong , Vitaly Kuznetsov , David Vrabel , Josh Poimboeuf , Tim Chen , Rik van Riel , Andi Kleen , Jiri Olsa , Prarit Bhargava , Michael Ellerman , Joerg Roedel , Paolo Bonzini , =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= Date: Thu, 26 Jan 2017 08:59:39 -0800 Message-Id: <20170126165940.30799-2-thgarnie@google.com> X-Mailer: git-send-email 2.11.0.483.g087da7b7c-goog In-Reply-To: <20170126165940.30799-1-thgarnie@google.com> References: <20170126165940.30799-1-thgarnie@google.com> X-Mailman-Approved-At: Thu, 26 Jan 2017 17:04:04 +0000 Cc: linux-efi@vger.kernel.org, kvm@vger.kernel.org, linux-pm@vger.kernel.org, x86@kernel.org, linux-kernel@vger.kernel.org, kasan-dev@googlegroups.com, lguest@lists.ozlabs.org, kernel-hardening@lists.openwall.com, xen-devel@lists.xenproject.org Subject: [Xen-devel] [PATCH v2 2/3] x86: Remap GDT tables in the Fixmap section X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP Each processor holds a GDT in its per-cpu structure. The sgdt instruction gives the base address of the current GDT. This address can be used to bypass KASLR memory randomization. With another bug, an attacker could target other per-cpu structures or deduce the base of the main memory section (PAGE_OFFSET). This patch relocates the GDT table for each processor inside the Fixmap section. The space is reserved based on number of supported processors. For consistency, the remapping is done by default on 32 and 64 bit. Each processor switches to its remapped GDT at the end of initialization. For hibernation, the main processor returns with the original GDT and switches back to the remapping at completion. This patch was tested on both architectures. Hibernation and KVM were both tested specially for their usage of the GDT. Signed-off-by: Thomas Garnier --- Based on next-20170125 --- arch/x86/entry/vdso/vma.c | 2 +- arch/x86/include/asm/desc.h | 23 +++++++++++++++++++---- arch/x86/include/asm/fixmap.h | 4 ++++ arch/x86/include/asm/processor.h | 1 + arch/x86/include/asm/stackprotector.h | 2 +- arch/x86/kernel/acpi/sleep.c | 2 +- arch/x86/kernel/apm_32.c | 6 +++--- arch/x86/kernel/cpu/common.c | 26 ++++++++++++++++++++++++-- arch/x86/kernel/setup_percpu.c | 2 +- arch/x86/kernel/smpboot.c | 2 +- arch/x86/platform/efi/efi_32.c | 4 ++-- arch/x86/power/cpu.c | 7 +++++-- arch/x86/xen/enlighten.c | 2 +- arch/x86/xen/smp.c | 2 +- drivers/lguest/x86/core.c | 6 +++--- drivers/pnp/pnpbios/bioscalls.c | 10 +++++----- 16 files changed, 73 insertions(+), 28 deletions(-) diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c index 10820f6cefbf..acae4ef04cdf 100644 --- a/arch/x86/entry/vdso/vma.c +++ b/arch/x86/entry/vdso/vma.c @@ -353,7 +353,7 @@ static void vgetcpu_cpu_init(void *arg) d.p = 1; /* Present */ d.d = 1; /* 32-bit */ - write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_PER_CPU, &d, DESCTYPE_S); + write_gdt_entry(get_cpu_direct_gdt(cpu), GDT_ENTRY_PER_CPU, &d, DESCTYPE_S); } static int vgetcpu_online(unsigned int cpu) diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h index 12080d87da3b..4cc176f57b78 100644 --- a/arch/x86/include/asm/desc.h +++ b/arch/x86/include/asm/desc.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -45,11 +46,25 @@ struct gdt_page { DECLARE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page); -static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu) +/* Provide the original GDT */ +static inline struct desc_struct *get_cpu_direct_gdt(unsigned int cpu) { return per_cpu(gdt_page, cpu).gdt; } +/* Get the fixmap index for a specific processor */ +static inline unsigned int get_cpu_fixmap_gdt_index(int cpu) +{ + return FIX_GDT_REMAP_BEGIN + cpu; +} + +/* Provide the fixmap address of the remapped GDT */ +static inline struct desc_struct *get_cpu_fixmap_gdt(int cpu) +{ + unsigned int idx = get_cpu_fixmap_gdt_index(cpu); + return (struct desc_struct *)__fix_to_virt(idx); +} + #ifdef CONFIG_X86_64 static inline void pack_gate(gate_desc *gate, unsigned type, unsigned long func, @@ -174,7 +189,7 @@ static inline void set_tssldt_descriptor(void *d, unsigned long addr, unsigned t static inline void __set_tss_desc(unsigned cpu, unsigned int entry, void *addr) { - struct desc_struct *d = get_cpu_gdt_table(cpu); + struct desc_struct *d = get_cpu_direct_gdt(cpu); tss_desc tss; /* @@ -202,7 +217,7 @@ static inline void native_set_ldt(const void *addr, unsigned int entries) set_tssldt_descriptor(&ldt, (unsigned long)addr, DESC_LDT, entries * LDT_ENTRY_SIZE - 1); - write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_LDT, + write_gdt_entry(get_cpu_direct_gdt(cpu), GDT_ENTRY_LDT, &ldt, DESC_LDT); asm volatile("lldt %w0"::"q" (GDT_ENTRY_LDT*8)); } @@ -244,7 +259,7 @@ static inline unsigned long native_store_tr(void) static inline void native_load_tls(struct thread_struct *t, unsigned int cpu) { - struct desc_struct *gdt = get_cpu_gdt_table(cpu); + struct desc_struct *gdt = get_cpu_direct_gdt(cpu); unsigned int i; for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++) diff --git a/arch/x86/include/asm/fixmap.h b/arch/x86/include/asm/fixmap.h index c46289799b02..8b913b5e9383 100644 --- a/arch/x86/include/asm/fixmap.h +++ b/arch/x86/include/asm/fixmap.h @@ -100,6 +100,10 @@ enum fixed_addresses { #ifdef CONFIG_X86_INTEL_MID FIX_LNW_VRTC, #endif + /* Fixmap entries to remap the GDTs, one per processor. */ + FIX_GDT_REMAP_BEGIN, + FIX_GDT_REMAP_END = FIX_GDT_REMAP_BEGIN + NR_CPUS - 1, + __end_of_permanent_fixed_addresses, /* diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 1be64da0384e..22801fd345dc 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -705,6 +705,7 @@ extern struct desc_ptr early_gdt_descr; extern void cpu_set_gdt(int); extern void switch_to_new_gdt(int); +extern void load_fixmap_gdt(int); extern void load_percpu_segment(int); extern void cpu_init(void); diff --git a/arch/x86/include/asm/stackprotector.h b/arch/x86/include/asm/stackprotector.h index 58505f01962f..422426b8aba7 100644 --- a/arch/x86/include/asm/stackprotector.h +++ b/arch/x86/include/asm/stackprotector.h @@ -87,7 +87,7 @@ static inline void setup_stack_canary_segment(int cpu) { #ifdef CONFIG_X86_32 unsigned long canary = (unsigned long)&per_cpu(stack_canary, cpu); - struct desc_struct *gdt_table = get_cpu_gdt_table(cpu); + struct desc_struct *gdt_table = get_cpu_direct_gdt(cpu); struct desc_struct desc; desc = gdt_table[GDT_ENTRY_STACK_CANARY]; diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c index 48587335ede8..d13e6d156c22 100644 --- a/arch/x86/kernel/acpi/sleep.c +++ b/arch/x86/kernel/acpi/sleep.c @@ -101,7 +101,7 @@ int x86_acpi_suspend_lowlevel(void) #ifdef CONFIG_SMP initial_stack = (unsigned long)temp_stack + sizeof(temp_stack); early_gdt_descr.address = - (unsigned long)get_cpu_gdt_table(smp_processor_id()); + (unsigned long)get_cpu_direct_gdt(smp_processor_id()); initial_gs = per_cpu_offset(smp_processor_id()); #endif initial_code = (unsigned long)wakeup_long64; diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c index 45d44c173cf9..458dbe18a860 100644 --- a/arch/x86/kernel/apm_32.c +++ b/arch/x86/kernel/apm_32.c @@ -608,7 +608,7 @@ static long __apm_bios_call(void *_call) cpu = get_cpu(); BUG_ON(cpu != 0); - gdt = get_cpu_gdt_table(cpu); + gdt = get_cpu_direct_gdt(cpu); save_desc_40 = gdt[0x40 / 8]; gdt[0x40 / 8] = bad_bios_desc; @@ -684,7 +684,7 @@ static long __apm_bios_call_simple(void *_call) cpu = get_cpu(); BUG_ON(cpu != 0); - gdt = get_cpu_gdt_table(cpu); + gdt = get_cpu_direct_gdt(cpu); save_desc_40 = gdt[0x40 / 8]; gdt[0x40 / 8] = bad_bios_desc; @@ -2351,7 +2351,7 @@ static int __init apm_init(void) * Note we only set APM segments on CPU zero, since we pin the APM * code to that CPU. */ - gdt = get_cpu_gdt_table(0); + gdt = get_cpu_direct_gdt(0); set_desc_base(&gdt[APM_CS >> 3], (unsigned long)__va((unsigned long)apm_info.bios.cseg << 4)); set_desc_base(&gdt[APM_CS_16 >> 3], diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 5ba74f280448..15f06cf3e3d4 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -444,6 +444,23 @@ void load_percpu_segment(int cpu) load_stack_canary_segment(); } +/* Setup the fixmap mapping only once per-processor */ +static inline void setup_fixmap_gdt(int cpu) +{ + __set_fixmap(get_cpu_fixmap_gdt_index(cpu), + __pa(get_cpu_direct_gdt(cpu)), PAGE_KERNEL); +} + +/* Load a fixmap remapping of the per-cpu GDT */ +void load_fixmap_gdt(int cpu) +{ + struct desc_ptr gdt_descr; + + gdt_descr.address = (long)get_cpu_fixmap_gdt(cpu); + gdt_descr.size = GDT_SIZE - 1; + load_gdt(&gdt_descr); +} + /* * Current gdt points %fs at the "master" per-cpu area: after this, * it's on the real one. @@ -452,11 +469,10 @@ void switch_to_new_gdt(int cpu) { struct desc_ptr gdt_descr; - gdt_descr.address = (long)get_cpu_gdt_table(cpu); + gdt_descr.address = (long)get_cpu_direct_gdt(cpu); gdt_descr.size = GDT_SIZE - 1; load_gdt(&gdt_descr); /* Reload the per-cpu base */ - load_percpu_segment(cpu); } @@ -1511,6 +1527,9 @@ void cpu_init(void) if (is_uv_system()) uv_cpu_init(); + + setup_fixmap_gdt(cpu); + load_fixmap_gdt(cpu); } #else @@ -1566,6 +1585,9 @@ void cpu_init(void) dbg_restore_debug_regs(); fpu__init_cpu(); + + setup_fixmap_gdt(cpu); + load_fixmap_gdt(cpu); } #endif diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c index 9820d6d977c6..e413c7607316 100644 --- a/arch/x86/kernel/setup_percpu.c +++ b/arch/x86/kernel/setup_percpu.c @@ -160,7 +160,7 @@ static inline void setup_percpu_segment(int cpu) pack_descriptor(&gdt, per_cpu_offset(cpu), 0xFFFFF, 0x2 | DESCTYPE_S, 0x8); gdt.s = 1; - write_gdt_entry(get_cpu_gdt_table(cpu), + write_gdt_entry(get_cpu_direct_gdt(cpu), GDT_ENTRY_PERCPU, &gdt, DESCTYPE_S); #endif } diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 46732dc3b73c..0b1096685cda 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -974,7 +974,7 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle) unsigned long timeout; idle->thread.sp = (unsigned long)task_pt_regs(idle); - early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu); + early_gdt_descr.address = (unsigned long)get_cpu_direct_gdt(cpu); initial_code = (unsigned long)start_secondary; initial_stack = idle->thread.sp; diff --git a/arch/x86/platform/efi/efi_32.c b/arch/x86/platform/efi/efi_32.c index cef39b097649..72d41dddbaf5 100644 --- a/arch/x86/platform/efi/efi_32.c +++ b/arch/x86/platform/efi/efi_32.c @@ -68,7 +68,7 @@ pgd_t * __init efi_call_phys_prolog(void) load_cr3(initial_page_table); __flush_tlb_all(); - gdt_descr.address = __pa(get_cpu_gdt_table(0)); + gdt_descr.address = __pa(get_cpu_direct_gdt(0)); gdt_descr.size = GDT_SIZE - 1; load_gdt(&gdt_descr); @@ -79,7 +79,7 @@ void __init efi_call_phys_epilog(pgd_t *save_pgd) { struct desc_ptr gdt_descr; - gdt_descr.address = (unsigned long)get_cpu_gdt_table(0); + gdt_descr.address = (unsigned long)get_cpu_direct_gdt(0); gdt_descr.size = GDT_SIZE - 1; load_gdt(&gdt_descr); diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c index 66ade16c7693..644f80341f12 100644 --- a/arch/x86/power/cpu.c +++ b/arch/x86/power/cpu.c @@ -95,7 +95,7 @@ static void __save_processor_state(struct saved_context *ctxt) * 'pmode_gdt' in wakeup_start. */ ctxt->gdt_desc.size = GDT_SIZE - 1; - ctxt->gdt_desc.address = (unsigned long)get_cpu_gdt_table(smp_processor_id()); + ctxt->gdt_desc.address = (unsigned long)get_cpu_direct_gdt(smp_processor_id()); store_tr(ctxt->tr); @@ -162,7 +162,7 @@ static void fix_processor_context(void) int cpu = smp_processor_id(); struct tss_struct *t = &per_cpu(cpu_tss, cpu); #ifdef CONFIG_X86_64 - struct desc_struct *desc = get_cpu_gdt_table(cpu); + struct desc_struct *desc = get_cpu_direct_gdt(cpu); tss_desc tss; #endif set_tss_desc(cpu, t); /* @@ -183,6 +183,9 @@ static void fix_processor_context(void) load_mm_ldt(current->active_mm); /* This does lldt */ fpu__resume_cpu(); + + /* The processor is back on the direct GDT, load back the fixmap */ + load_fixmap_gdt(cpu); } /** diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 51ef95232725..b1a9baad2f0d 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -695,7 +695,7 @@ static void load_TLS_descriptor(struct thread_struct *t, *shadow = t->tls_array[i]; - gdt = get_cpu_gdt_table(cpu); + gdt = get_cpu_direct_gdt(cpu); maddr = arbitrary_virt_to_machine(&gdt[GDT_ENTRY_TLS_MIN+i]); mc = __xen_mc_entry(0); diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index 311acad7dad2..3de63fb4d833 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c @@ -401,7 +401,7 @@ cpu_initialize_context(unsigned int cpu, struct task_struct *idle) if (ctxt == NULL) return -ENOMEM; - gdt = get_cpu_gdt_table(cpu); + gdt = get_cpu_direct_gdt(cpu); #ifdef CONFIG_X86_32 /* Note: PVH is not yet supported on x86_32. */ diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c index d71f6323ac00..aa9d420913c5 100644 --- a/drivers/lguest/x86/core.c +++ b/drivers/lguest/x86/core.c @@ -504,7 +504,7 @@ void __init lguest_arch_host_init(void) * byte, not the size, hence the "-1"). */ state->host_gdt_desc.size = GDT_SIZE-1; - state->host_gdt_desc.address = (long)get_cpu_gdt_table(i); + state->host_gdt_desc.address = (long)get_cpu_direct_gdt(i); /* * All CPUs on the Host use the same Interrupt Descriptor @@ -554,8 +554,8 @@ void __init lguest_arch_host_init(void) * The Host needs to be able to use the LGUEST segments on this * CPU, too, so put them in the Host GDT. */ - get_cpu_gdt_table(i)[GDT_ENTRY_LGUEST_CS] = FULL_EXEC_SEGMENT; - get_cpu_gdt_table(i)[GDT_ENTRY_LGUEST_DS] = FULL_SEGMENT; + get_cpu_direct_gdt(i)[GDT_ENTRY_LGUEST_CS] = FULL_EXEC_SEGMENT; + get_cpu_direct_gdt(i)[GDT_ENTRY_LGUEST_DS] = FULL_SEGMENT; } /* diff --git a/drivers/pnp/pnpbios/bioscalls.c b/drivers/pnp/pnpbios/bioscalls.c index 438d4c72c7b3..ce7288c5864c 100644 --- a/drivers/pnp/pnpbios/bioscalls.c +++ b/drivers/pnp/pnpbios/bioscalls.c @@ -54,7 +54,7 @@ __asm__(".text \n" #define Q2_SET_SEL(cpu, selname, address, size) \ do { \ - struct desc_struct *gdt = get_cpu_gdt_table((cpu)); \ + struct desc_struct *gdt = get_cpu_direct_gdt((cpu)); \ set_desc_base(&gdt[(selname) >> 3], (u32)(address)); \ set_desc_limit(&gdt[(selname) >> 3], (size) - 1); \ } while(0) @@ -95,8 +95,8 @@ static inline u16 call_pnp_bios(u16 func, u16 arg1, u16 arg2, u16 arg3, return PNP_FUNCTION_NOT_SUPPORTED; cpu = get_cpu(); - save_desc_40 = get_cpu_gdt_table(cpu)[0x40 / 8]; - get_cpu_gdt_table(cpu)[0x40 / 8] = bad_bios_desc; + save_desc_40 = get_cpu_direct_gdt(cpu)[0x40 / 8]; + get_cpu_direct_gdt(cpu)[0x40 / 8] = bad_bios_desc; /* On some boxes IRQ's during PnP BIOS calls are deadly. */ spin_lock_irqsave(&pnp_bios_lock, flags); @@ -134,7 +134,7 @@ static inline u16 call_pnp_bios(u16 func, u16 arg1, u16 arg2, u16 arg3, :"memory"); spin_unlock_irqrestore(&pnp_bios_lock, flags); - get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40; + get_cpu_direct_gdt(cpu)[0x40 / 8] = save_desc_40; put_cpu(); /* If we get here and this is set then the PnP BIOS faulted on us. */ @@ -477,7 +477,7 @@ void pnpbios_calls_init(union pnp_bios_install_struct *header) pnp_bios_callpoint.segment = PNP_CS16; for_each_possible_cpu(i) { - struct desc_struct *gdt = get_cpu_gdt_table(i); + struct desc_struct *gdt = get_cpu_direct_gdt(i); if (!gdt) continue; set_desc_base(&gdt[GDT_ENTRY_PNPBIOS_CS32],