From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752358AbbKKSTw (ORCPT ); Wed, 11 Nov 2015 13:19:52 -0500 Received: from mga03.intel.com ([134.134.136.65]:14879 "EHLO mga03.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751971AbbKKSTt (ORCPT ); Wed, 11 Nov 2015 13:19:49 -0500 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,277,1444719600"; d="scan'208";a="834416908" Subject: [PATCH 2/2] x86, mpx: fix 32-bit address space calculation To: linux-kernel@vger.kernel.org Cc: x86@kernel.org, Dave Hansen , dave.hansen@linux.intel.com From: Dave Hansen Date: Wed, 11 Nov 2015 10:19:34 -0800 References: <20151111181930.A06D71BF@viggo.jf.intel.com> In-Reply-To: <20151111181930.A06D71BF@viggo.jf.intel.com> Message-Id: <20151111181934.FA7FAC34@viggo.jf.intel.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Dave Hansen I received a bug report that running 32-bit MPX binaries on 64-bit kernels was broken. I traced it down to this little code snippet. We were switching our "number of bounds directory entries" calculation correctly. But, we didn't switch the other side of the calculation: the virtual space size. This meant that we were calculating an absurd size for bd_entry_virt_space() on 32-bit because we used the 64-bit virt_space. This was _also_ broken for 32-bit kernels running on 64-bit hardware since boot_cpu_data.x86_virt_bits=48 even when running in 32-bit mode. Correct that and properly handle all 3 possible cases: 1. 32-bit binary on 64-bit kernel 2. 64-bit binary on 64-bit kernel 3. 32-bit binary on 32-bit kernel This manifested in having bounds tables not properly unmapped. It "leaked" memory but had no functional impact otherwise. Signed-off-by: Dave Hansen --- b/arch/x86/mm/mpx.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff -puN arch/x86/mm/mpx.c~x86-mpx-fix-32-bit-address-space-calculation arch/x86/mm/mpx.c --- a/arch/x86/mm/mpx.c~x86-mpx-fix-32-bit-address-space-calculation 2015-11-11 10:18:50.030248940 -0800 +++ b/arch/x86/mm/mpx.c 2015-11-11 10:18:50.033249076 -0800 @@ -723,11 +723,23 @@ static unsigned long mpx_get_bt_entry_of */ static inline unsigned long bd_entry_virt_space(struct mm_struct *mm) { - unsigned long long virt_space = (1ULL << boot_cpu_data.x86_virt_bits); - if (is_64bit_mm(mm)) - return virt_space / MPX_BD_NR_ENTRIES_64; - else - return virt_space / MPX_BD_NR_ENTRIES_32; + unsigned long long virt_space; + unsigned long long GB = (1ULL << 30); + + /* + * This covers 32-bit emulation as well as 32-bit kernels + * running on 64-bit harware. + */ + if (!is_64bit_mm(mm)) + return (4ULL * GB) / MPX_BD_NR_ENTRIES_32; + + /* + * 'x86_virt_bits' returns what the hardware is capable + * of, and returns the full >32-bit adddress space when + * running 32-bit kernels on 64-bit hardware. + */ + virt_space = (1ULL << boot_cpu_data.x86_virt_bits); + return virt_space / MPX_BD_NR_ENTRIES_64; } /* _