Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753839AbdC2Qs7 (ORCPT ); Wed, 29 Mar 2017 12:48:59 -0400 Received: from mail.kernel.org ([198.145.29.136]:34784 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753650AbdC2Qs5 (ORCPT ); Wed, 29 Mar 2017 12:48:57 -0400 From: Andy Lutomirski To: x86@kernel.org Cc: linux-kernel@vger.kernel.org, Borislav Petkov , Boris Ostrovsky , Juergen Gross , Thomas Garnier , Andy Lutomirski Subject: [PATCH v2 2/2] x86/boot/32: Rewrite test_wp_bit() Date: Wed, 29 Mar 2017 09:48:42 -0700 Message-Id: X-Mailer: git-send-email 2.9.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 Content-Length: 2401 Lines: 85 This code seems to be very old and has gotten only minor updates. It's overcomplicated and has a bunch of comments that are, at best, of purely historical interest. Nowadays we have a shiny function probe_kernel_write() that does more or less exactly what we need. Use it. I switched the page that we test from swapper_pg_dir to empty_zero_page because writing zero to empty_zero_page is more obviously safe than writing to the paging structures. (It's extremely unlikely that any of this would cause problems in practice because the write will fail on any supported CPU.) Signed-off-by: Andy Lutomirski --- arch/x86/mm/init_32.c | 35 ++++++----------------------------- 1 file changed, 6 insertions(+), 29 deletions(-) diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c index b30f20951e9e..097089a5e4d5 100644 --- a/arch/x86/mm/init_32.c +++ b/arch/x86/mm/init_32.c @@ -56,8 +56,6 @@ unsigned long highstart_pfn, highend_pfn; -static noinline int do_test_wp_bit(void); - bool __read_mostly __vmalloc_start_set = false; /* @@ -726,15 +724,18 @@ void __init paging_init(void) */ static void __init test_wp_bit(void) { + char z = 0; + printk(KERN_INFO "Checking if this processor honours the WP bit even in supervisor mode..."); - /* Any page-aligned address will do, the test is non-destructive */ - __set_fixmap(FIX_WP_TEST, __pa(&swapper_pg_dir), PAGE_KERNEL_RO); - if (!do_test_wp_bit()) { + __set_fixmap(FIX_WP_TEST, __pa_symbol(empty_zero_page), PAGE_KERNEL_RO); + + if (probe_kernel_write((char *)fix_to_virt(FIX_WP_TEST), &z, 1) == 0) { printk(KERN_CONT "No.\n"); panic("Linux doesn't support CPUs with broken WP."); } + clear_fixmap(FIX_WP_TEST); printk(KERN_CONT "Ok.\n"); @@ -847,30 +848,6 @@ int arch_remove_memory(u64 start, u64 size) #endif #endif -/* - * This function cannot be __init, since exceptions don't work in that - * section. Put this after the callers, so that it cannot be inlined. - */ -static noinline int do_test_wp_bit(void) -{ - char tmp_reg; - int flag; - - __asm__ __volatile__( - " movb %0, %1 \n" - "1: movb %1, %0 \n" - " xorl %2, %2 \n" - "2: \n" - _ASM_EXTABLE(1b,2b) - :"=m" (*(char *)fix_to_virt(FIX_WP_TEST)), - "=q" (tmp_reg), - "=r" (flag) - :"2" (1) - :"memory"); - - return flag; -} - int kernel_set_to_readonly __read_mostly; void set_kernel_text_rw(void) -- 2.9.3