From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755259AbcAHPsV (ORCPT ); Fri, 8 Jan 2016 10:48:21 -0500 Received: from foss.arm.com ([217.140.101.70]:46166 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752033AbcAHPsU (ORCPT ); Fri, 8 Jan 2016 10:48:20 -0500 Date: Fri, 8 Jan 2016 15:48:15 +0000 From: Catalin Marinas To: Mark Rutland Cc: keescook@chromium.org, arnd@arndb.de, kernel-hardening@lists.openwall.com, bhupesh.sharma@freescale.com, Ard Biesheuvel , will.deacon@arm.com, linux-kernel@vger.kernel.org, leif.lindholm@linaro.org, stuart.yoder@freescale.com, marc.zyngier@arm.com, christoffer.dall@linaro.org, linux-arm-kernel@lists.infradead.org Subject: Re: [PATCH v2 11/13] arm64: allow kernel Image to be loaded anywhere in physical memory Message-ID: <20160108154814.GI16432@e104818-lin.cambridge.arm.com> References: <1451489172-17420-1-git-send-email-ard.biesheuvel@linaro.org> <1451489172-17420-12-git-send-email-ard.biesheuvel@linaro.org> <20160108152738.GG16432@e104818-lin.cambridge.arm.com> <20160108153653.GB32692@leverpostej> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20160108153653.GB32692@leverpostej> User-Agent: Mutt/1.5.23 (2014-03-12) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, Jan 08, 2016 at 03:36:54PM +0000, Mark Rutland wrote: > On Fri, Jan 08, 2016 at 03:27:38PM +0000, Catalin Marinas wrote: > > On Wed, Dec 30, 2015 at 04:26:10PM +0100, Ard Biesheuvel wrote: > > > +static void __init enforce_memory_limit(void) > > > +{ > > > + const phys_addr_t kbase = round_down(__pa(_text), MIN_KIMG_ALIGN); > > > + u64 to_remove = memblock_phys_mem_size() - memory_limit; > > > + phys_addr_t max_addr = 0; > > > + struct memblock_region *r; > > > + > > > + if (memory_limit == (phys_addr_t)ULLONG_MAX) > > > + return; > > > + > > > + /* > > > + * The kernel may be high up in physical memory, so try to apply the > > > + * limit below the kernel first, and only let the generic handling > > > + * take over if it turns out we haven't clipped enough memory yet. > > > + */ > > > + for_each_memblock(memory, r) { > > > + if (r->base + r->size > kbase) { > > > + u64 rem = min(to_remove, kbase - r->base); > > > + > > > + max_addr = r->base + rem; > > > + to_remove -= rem; > > > + break; > > > + } > > > + if (to_remove <= r->size) { > > > + max_addr = r->base + to_remove; > > > + to_remove = 0; > > > + break; > > > + } > > > + to_remove -= r->size; > > > + } > > > + > > > + memblock_remove(0, max_addr); > > > + > > > + if (to_remove) > > > + memblock_enforce_memory_limit(memory_limit); > > > +} > > > > IIUC, this is changing the user expectations a bit. There are people > > using the mem= limit to hijack some top of the RAM for other needs > > (though they could do it in a saner way like changing the DT memory > > nodes). > > Which will be hopelessly broken in the presence of KASLR, the kernel > being loaded at a different address, pages betting reserved differently > due to page size, etc. With KASLR disabled, I think we should aim for the existing behaviour as much as possible. The original aim of these patches was to relax the kernel image placement rules, to make it easier for boot loaders rather than completely randomising it. With KASLR enabled, I agree it's hard to make any assumptions about what memory is available. But removing memory only from the top would also help with the point you already raised - keeping lower memory for devices with narrower DMA mask. -- Catalin From mboxrd@z Thu Jan 1 00:00:00 1970 From: catalin.marinas@arm.com (Catalin Marinas) Date: Fri, 8 Jan 2016 15:48:15 +0000 Subject: [PATCH v2 11/13] arm64: allow kernel Image to be loaded anywhere in physical memory In-Reply-To: <20160108153653.GB32692@leverpostej> References: <1451489172-17420-1-git-send-email-ard.biesheuvel@linaro.org> <1451489172-17420-12-git-send-email-ard.biesheuvel@linaro.org> <20160108152738.GG16432@e104818-lin.cambridge.arm.com> <20160108153653.GB32692@leverpostej> Message-ID: <20160108154814.GI16432@e104818-lin.cambridge.arm.com> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org On Fri, Jan 08, 2016 at 03:36:54PM +0000, Mark Rutland wrote: > On Fri, Jan 08, 2016 at 03:27:38PM +0000, Catalin Marinas wrote: > > On Wed, Dec 30, 2015 at 04:26:10PM +0100, Ard Biesheuvel wrote: > > > +static void __init enforce_memory_limit(void) > > > +{ > > > + const phys_addr_t kbase = round_down(__pa(_text), MIN_KIMG_ALIGN); > > > + u64 to_remove = memblock_phys_mem_size() - memory_limit; > > > + phys_addr_t max_addr = 0; > > > + struct memblock_region *r; > > > + > > > + if (memory_limit == (phys_addr_t)ULLONG_MAX) > > > + return; > > > + > > > + /* > > > + * The kernel may be high up in physical memory, so try to apply the > > > + * limit below the kernel first, and only let the generic handling > > > + * take over if it turns out we haven't clipped enough memory yet. > > > + */ > > > + for_each_memblock(memory, r) { > > > + if (r->base + r->size > kbase) { > > > + u64 rem = min(to_remove, kbase - r->base); > > > + > > > + max_addr = r->base + rem; > > > + to_remove -= rem; > > > + break; > > > + } > > > + if (to_remove <= r->size) { > > > + max_addr = r->base + to_remove; > > > + to_remove = 0; > > > + break; > > > + } > > > + to_remove -= r->size; > > > + } > > > + > > > + memblock_remove(0, max_addr); > > > + > > > + if (to_remove) > > > + memblock_enforce_memory_limit(memory_limit); > > > +} > > > > IIUC, this is changing the user expectations a bit. There are people > > using the mem= limit to hijack some top of the RAM for other needs > > (though they could do it in a saner way like changing the DT memory > > nodes). > > Which will be hopelessly broken in the presence of KASLR, the kernel > being loaded at a different address, pages betting reserved differently > due to page size, etc. With KASLR disabled, I think we should aim for the existing behaviour as much as possible. The original aim of these patches was to relax the kernel image placement rules, to make it easier for boot loaders rather than completely randomising it. With KASLR enabled, I agree it's hard to make any assumptions about what memory is available. But removing memory only from the top would also help with the point you already raised - keeping lower memory for devices with narrower DMA mask. -- Catalin From mboxrd@z Thu Jan 1 00:00:00 1970 Reply-To: kernel-hardening@lists.openwall.com Date: Fri, 8 Jan 2016 15:48:15 +0000 From: Catalin Marinas Message-ID: <20160108154814.GI16432@e104818-lin.cambridge.arm.com> References: <1451489172-17420-1-git-send-email-ard.biesheuvel@linaro.org> <1451489172-17420-12-git-send-email-ard.biesheuvel@linaro.org> <20160108152738.GG16432@e104818-lin.cambridge.arm.com> <20160108153653.GB32692@leverpostej> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20160108153653.GB32692@leverpostej> Subject: [kernel-hardening] Re: [PATCH v2 11/13] arm64: allow kernel Image to be loaded anywhere in physical memory To: Mark Rutland Cc: keescook@chromium.org, arnd@arndb.de, kernel-hardening@lists.openwall.com, bhupesh.sharma@freescale.com, Ard Biesheuvel , will.deacon@arm.com, linux-kernel@vger.kernel.org, leif.lindholm@linaro.org, stuart.yoder@freescale.com, marc.zyngier@arm.com, christoffer.dall@linaro.org, linux-arm-kernel@lists.infradead.org List-ID: On Fri, Jan 08, 2016 at 03:36:54PM +0000, Mark Rutland wrote: > On Fri, Jan 08, 2016 at 03:27:38PM +0000, Catalin Marinas wrote: > > On Wed, Dec 30, 2015 at 04:26:10PM +0100, Ard Biesheuvel wrote: > > > +static void __init enforce_memory_limit(void) > > > +{ > > > + const phys_addr_t kbase = round_down(__pa(_text), MIN_KIMG_ALIGN); > > > + u64 to_remove = memblock_phys_mem_size() - memory_limit; > > > + phys_addr_t max_addr = 0; > > > + struct memblock_region *r; > > > + > > > + if (memory_limit == (phys_addr_t)ULLONG_MAX) > > > + return; > > > + > > > + /* > > > + * The kernel may be high up in physical memory, so try to apply the > > > + * limit below the kernel first, and only let the generic handling > > > + * take over if it turns out we haven't clipped enough memory yet. > > > + */ > > > + for_each_memblock(memory, r) { > > > + if (r->base + r->size > kbase) { > > > + u64 rem = min(to_remove, kbase - r->base); > > > + > > > + max_addr = r->base + rem; > > > + to_remove -= rem; > > > + break; > > > + } > > > + if (to_remove <= r->size) { > > > + max_addr = r->base + to_remove; > > > + to_remove = 0; > > > + break; > > > + } > > > + to_remove -= r->size; > > > + } > > > + > > > + memblock_remove(0, max_addr); > > > + > > > + if (to_remove) > > > + memblock_enforce_memory_limit(memory_limit); > > > +} > > > > IIUC, this is changing the user expectations a bit. There are people > > using the mem= limit to hijack some top of the RAM for other needs > > (though they could do it in a saner way like changing the DT memory > > nodes). > > Which will be hopelessly broken in the presence of KASLR, the kernel > being loaded at a different address, pages betting reserved differently > due to page size, etc. With KASLR disabled, I think we should aim for the existing behaviour as much as possible. The original aim of these patches was to relax the kernel image placement rules, to make it easier for boot loaders rather than completely randomising it. With KASLR enabled, I agree it's hard to make any assumptions about what memory is available. But removing memory only from the top would also help with the point you already raised - keeping lower memory for devices with narrower DMA mask. -- Catalin