* [PATCH v6] atmel_flexcom: Support resuming after a chip reset
From: Alexandre Belloni @ 2017-12-18 20:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171212162119.32138-1-romain.izard.pro@gmail.com>
On 12/12/2017 at 17:21:19 +0100, Romain Izard wrote:
> The controller used by a flexcom module is configured at boot, and left
> alone after this. In the suspend mode called "backup with self-refresh"
> available on SAMA5D2, the chip will resume with most of its registers
> reset. In this case, we need to restore the state of the flexcom driver
> on resume.
>
> Signed-off-by: Romain Izard <romain.izard.pro@gmail.com>
Seems good to me
Acked-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
> ---
> Changes in v5:
> * extract from the patch series, and send as a standalone patch
>
> Changes in v6:
> * Reword the patch title and description
> * Rename the internal structure to ddata
>
> drivers/mfd/atmel-flexcom.c | 63 ++++++++++++++++++++++++++++++++++-----------
> 1 file changed, 48 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/mfd/atmel-flexcom.c b/drivers/mfd/atmel-flexcom.c
> index 064bde9cff5a..f684a93a3340 100644
> --- a/drivers/mfd/atmel-flexcom.c
> +++ b/drivers/mfd/atmel-flexcom.c
> @@ -39,34 +39,43 @@
> #define FLEX_MR_OPMODE(opmode) (((opmode) << FLEX_MR_OPMODE_OFFSET) & \
> FLEX_MR_OPMODE_MASK)
>
> +struct atmel_flexcom {
> + void __iomem *base;
> + u32 opmode;
> + struct clk *clk;
> +};
>
> static int atmel_flexcom_probe(struct platform_device *pdev)
> {
> struct device_node *np = pdev->dev.of_node;
> - struct clk *clk;
> struct resource *res;
> - void __iomem *base;
> - u32 opmode;
> + struct atmel_flexcom *ddata;
> int err;
>
> - err = of_property_read_u32(np, "atmel,flexcom-mode", &opmode);
> + ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
> + if (!ddata)
> + return -ENOMEM;
> +
> + platform_set_drvdata(pdev, ddata);
> +
> + err = of_property_read_u32(np, "atmel,flexcom-mode", &ddata->opmode);
> if (err)
> return err;
>
> - if (opmode < ATMEL_FLEXCOM_MODE_USART ||
> - opmode > ATMEL_FLEXCOM_MODE_TWI)
> + if (ddata->opmode < ATMEL_FLEXCOM_MODE_USART ||
> + ddata->opmode > ATMEL_FLEXCOM_MODE_TWI)
> return -EINVAL;
>
> res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> - base = devm_ioremap_resource(&pdev->dev, res);
> - if (IS_ERR(base))
> - return PTR_ERR(base);
> + ddata->base = devm_ioremap_resource(&pdev->dev, res);
> + if (IS_ERR(ddata->base))
> + return PTR_ERR(ddata->base);
>
> - clk = devm_clk_get(&pdev->dev, NULL);
> - if (IS_ERR(clk))
> - return PTR_ERR(clk);
> + ddata->clk = devm_clk_get(&pdev->dev, NULL);
> + if (IS_ERR(ddata->clk))
> + return PTR_ERR(ddata->clk);
>
> - err = clk_prepare_enable(clk);
> + err = clk_prepare_enable(ddata->clk);
> if (err)
> return err;
>
> @@ -76,9 +85,9 @@ static int atmel_flexcom_probe(struct platform_device *pdev)
> * inaccessible and are read as zero. Also the external I/O lines of the
> * Flexcom are muxed to reach the selected device.
> */
> - writel(FLEX_MR_OPMODE(opmode), base + FLEX_MR);
> + writel(FLEX_MR_OPMODE(ddata->opmode), ddata->base + FLEX_MR);
>
> - clk_disable_unprepare(clk);
> + clk_disable_unprepare(ddata->clk);
>
> return devm_of_platform_populate(&pdev->dev);
> }
> @@ -89,10 +98,34 @@ static const struct of_device_id atmel_flexcom_of_match[] = {
> };
> MODULE_DEVICE_TABLE(of, atmel_flexcom_of_match);
>
> +#ifdef CONFIG_PM_SLEEP
> +static int atmel_flexcom_resume(struct device *dev)
> +{
> + struct atmel_flexcom *ddata = dev_get_drvdata(dev);
> + int err;
> + u32 val;
> +
> + err = clk_prepare_enable(ddata->clk);
> + if (err)
> + return err;
> +
> + val = FLEX_MR_OPMODE(ddata->opmode),
> + writel(val, ddata->base + FLEX_MR);
> +
> + clk_disable_unprepare(ddata->clk);
> +
> + return 0;
> +}
> +#endif
> +
> +static SIMPLE_DEV_PM_OPS(atmel_flexcom_pm_ops, NULL,
> + atmel_flexcom_resume);
> +
> static struct platform_driver atmel_flexcom_driver = {
> .probe = atmel_flexcom_probe,
> .driver = {
> .name = "atmel_flexcom",
> + .pm = &atmel_flexcom_pm_ops,
> .of_match_table = atmel_flexcom_of_match,
> },
> };
> --
> 2.14.1
>
--
Alexandre Belloni, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
^ permalink raw reply
* [PATCH V2 9/9] ARM: dts: stm32: add initial support of stm32mp157c eval board
From: Arnd Bergmann @ 2017-12-18 20:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1513610272-7824-10-git-send-email-ludovic.Barre@st.com>
On Mon, Dec 18, 2017 at 4:17 PM, Ludovic Barre <ludovic.Barre@st.com> wrote:
=
> +
> +/ {
> + model = "STMicroelectronics STM32MP157C eval daughter";
> + compatible = "st,stm32mp157c-ed1", "st,stm32mp157";
> +
> + chosen {
> + bootargs = "earlyprintk console=ttySTM3,115200 root=/dev/ram";
> + stdout-path = "serial3:115200n8";
> + };
I'd remove the bootargs here and let the boot loader take care of
that, in particular
since all three arguments are rather old-school: earlycon is preferred over
earlyprintk, console= should not be needed if you set stdout-path, and
/dev/ram is obsoleted by initramfs.
Arnd
^ permalink raw reply
* [PATCH V2 3/9] ARM: stm32: prepare stm32 family to welcome armv7 architecture
From: Arnd Bergmann @ 2017-12-18 20:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1513610272-7824-4-git-send-email-ludovic.Barre@st.com>
On Mon, Dec 18, 2017 at 4:17 PM, Ludovic Barre <ludovic.Barre@st.com> wrote:
> From: Ludovic Barre <ludovic.barre@st.com>
>
> This patch prepares the STM32 machine for the integration of Cortex-A
> based microprocessor (MPU), on top of the existing Cortex-M
> microcontroller family (MCU). Since both MCUs and MPUs are sharing
> common hardware blocks we can keep using ARCH_STM32 flag for most of
> them. If a hardware block is specific to one family we can use either
> ARM_SINGLE_ARMV7M or ARCH_MULTI_V7 flag.
>
> Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
Looks good overall. Two more small comments:
>
> +if ARCH_STM32
> +
> config MACH_STM32F429
> - bool "STMicrolectronics STM32F429"
> - depends on ARCH_STM32
> + bool "STMicroelectronics STM32F429"
> + depends on ARM_SINGLE_ARMV7M
> default y
Instead of the explicit dependency for each board, I'd leave the surrounding
'if ARM_SINGLE_ARMV7M'. I think you had in v1.
> diff --git a/arch/arm/mach-stm32/Makefile b/arch/arm/mach-stm32/Makefile
> index bd0b7b5..5940af1 100644
> --- a/arch/arm/mach-stm32/Makefile
> +++ b/arch/arm/mach-stm32/Makefile
> @@ -1 +1 @@
> -obj-y += board-dt.o
> +obj-$(CONFIG_ARM_SINGLE_ARMV7M) += board-mcu-dt.o
> diff --git a/arch/arm/mach-stm32/board-dt.c b/arch/arm/mach-stm32/board-mcu-dt.c
> similarity index 100%
> rename from arch/arm/mach-stm32/board-dt.c
> rename to arch/arm/mach-stm32/board-mcu-dt.c
Why the rename? I don't expect the new machines to have any notable
contents in a board file, if any at all, so just use one file for both.
I see the board-dt.c file refers to armv7m_restart, we can either put
that in an #ifdef, or find a way to make it the default for all armv7-m
platforms that don't provide any other restart method.
Arnd
^ permalink raw reply
* [PATCH v4 01/12] dt-bindings: thermal: Describe Armada AP806 and CP110
From: Baruch Siach @ 2017-12-18 20:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171218143643.7714-2-miquel.raynal@free-electrons.com>
Hi Miqu?l,
On Mon, Dec 18, 2017 at 03:36:32PM +0100, Miquel Raynal wrote:
> From: Baruch Siach <baruch@tkos.co.il>
>
> Add compatible strings for AP806 and CP110 that are part of the Armada
> 8k/7k line of SoCs.
>
> Add a note on the differences in the size of the control area in
> different bindings. This is an existing difference between the Armada
> 375 binding and the other boards already supported. The new AP806 and
> CP110 bindings are similar to the existing Armada 375 in this regard.
>
> Signed-off-by: Baruch Siach <baruch@tkos.co.il>
> [<miquel.raynal@free-electrons.com>: reword, additional details]
> Signed-off-by: Miquel Raynal <miquel.raynal@free-electrons.com>
> ---
> .../devicetree/bindings/thermal/armada-thermal.txt | 24 +++++++++++++++++-----
> 1 file changed, 19 insertions(+), 5 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/thermal/armada-thermal.txt b/Documentation/devicetree/bindings/thermal/armada-thermal.txt
> index 24aacf8948c5..9b7b2c03cc6f 100644
> --- a/Documentation/devicetree/bindings/thermal/armada-thermal.txt
> +++ b/Documentation/devicetree/bindings/thermal/armada-thermal.txt
> @@ -7,17 +7,31 @@ Required properties:
> marvell,armada375-thermal
> marvell,armada380-thermal
> marvell,armadaxp-thermal
> + marvell,armada-ap806-thermal
> + marvell,armada-cp110-thermal
>
> - reg: Device's register space.
> Two entries are expected, see the examples below.
> - The first one is required for the sensor register;
> - the second one is required for the control register
> - to be used for sensor initialization (a.k.a. calibration).
> + The first one points to the status register (4B).
> + The second one points to the control registers (8B).
> + Note: with legacy bindings, the second entry pointed
> + only to the so called "control MSB" ("control 1"), was
> + 4B wide and did not let the possibility to reach the
> + "control LSB" ("control 0") register. This is only
> + allowed for compatibility reasons in Armada
> + 370/375/38x/XP DT nodes.
"allowed" is not the right term, IMO. Legacy compatibles MUST point to the MSB
control register to preserve compatibility with existing DTs.
The original patch had a list of legacy and non-legacy compatibles. I think we
need to keep them.
baruch
> -Example:
> +Examples:
>
> + /* Legacy bindings */
> thermal at d0018300 {
> compatible = "marvell,armada370-thermal";
> - reg = <0xd0018300 0x4
> + reg = <0xd0018300 0x4
> 0xd0018304 0x4>;
> };
> +
> + ap_thermal: thermal at 6f8084 {
> + compatible = "marvell,armada-ap806-thermal";
> + reg = <0x6f808C 0x4>,
> + <0x6f8084 0x8>;
> + };
--
http://baruch.siach.name/blog/ ~. .~ Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
- baruch at tkos.co.il - tel: +972.52.368.4656, http://www.tkos.co.il -
^ permalink raw reply
* [PATCH v4 04/12] thermal: armada: Clarify control registers accesses
From: Baruch Siach @ 2017-12-18 20:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171218143643.7714-5-miquel.raynal@free-electrons.com>
Hi Miqu?l,
On Mon, Dec 18, 2017 at 03:36:35PM +0100, Miquel Raynal wrote:
> Bindings were incomplete for a long time by only exposing one of the two
> available control registers. To ease the migration to the full bindings
> (already in use for the Armada 375 SoC), rename the pointers for
> clarification. This way, it will only be needed to add another pointer
> to access the other control register when the time comes.
>
> This avoids dangerous situations where the offset 0 of the control
> area can be either one register or the other depending on the bindings
> used. After this change, device trees of other SoCs could be migrated to
> the "full" bindings if they may benefit from features from the
> unaccessible register, without any change in the driver.
>
> Signed-off-by: Miquel Raynal <miquel.raynal@free-electrons.com>
> Reviewed-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
> ---
[...]
> + /*
> + * Legacy DT bindings only described "control1" register (also referred
> + * as "control MSB" on old documentation). New bindings cover
> + * "control0/control LSB" and "control1/control MSB" registers within
> + * the same resource, which is then of size 8 instead of 4.
> + */
> + if (resource_size(res) == LEGACY_CONTROL_MEM_LEN) {
> + /* ->control0 unavailable in this configuration */
> + priv->control1 = control + LEGACY_CONTROL1_OFFSET;
> + } else {
> + priv->control0 = control + CONTROL0_OFFSET;
> + priv->control1 = control + CONTROL1_OFFSET;
> + }
The needs_control0 field that you mentioned in the cover page is missing here.
baruch
--
http://baruch.siach.name/blog/ ~. .~ Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
- baruch at tkos.co.il - tel: +972.52.368.4656, http://www.tkos.co.il -
^ permalink raw reply
* [PATCH net-next 2/2 v9] net: ethernet: Add a driver for Gemini gigabit ethernet
From: Linus Walleij @ 2017-12-18 20:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171218145403.GE10595@n2100.armlinux.org.uk>
On Mon, Dec 18, 2017 at 3:54 PM, Russell King - ARM Linux
<linux@armlinux.org.uk> wrote:
> On Mon, Dec 18, 2017 at 03:48:17PM +0100, Micha? Miros?aw wrote:
>> On Mon, Dec 18, 2017 at 02:57:37PM +0100, Linus Walleij wrote:
>> > On Sat, Dec 16, 2017 at 8:39 PM, Linus Walleij <linus.walleij@linaro.org> wrote:
>> >
>> > > The Gemini ethernet has been around for years as an out-of-tree
>> > > patch used with the NAS boxen and routers built on StorLink
>> > > SL3512 and SL3516, later Storm Semiconductor, later Cortina
>> > > Systems. These ASICs are still being deployed and brand new
>> > > off-the-shelf systems using it can easily be acquired.
>> [...]
>> > > ---
>> > > Changes from v8:
>> > > - Remove dependency guards in Kconfig to get a wider compile
>> > > coverage for the driver to detect broken APIs etc.
>> >
>> > I guess we need to hold this off for a while, the code does
>> > some weird stuff using the ARM-internal page DMA mapping
>> > API.
>> >
>> > I *think* what happens is that the driver allocates a global queue
>> > used for RX and TX on both interfaces, then initializes that with
>> > page pointers and gives that to the hardware to play with.
>> >
>> > When an RX packet comes in, the RX routine needs to figure
>> > out from the DMA (physical) address which remapped
>> > page/address this random physical address pointer
>> > corresponds to.
>> >
>> > The Linux DMA API assumption is that the driver keeps track
>> > of this mapping, not the hardware. So we need to figure out
>> > a way to reverse-map this. Preferably quickly, and without
>> > using any ARM-internal mapping APIs.
>>
>> IIRC, the hardware copies descriptors from free queue (FREEQ)
>> to RX queues. FREEQ is shared among the two ethernet ports.
Seems like that to me too. I will try to refactor and break it
apart a bit.
The way freeq works is undocumented, even in the official
datasheet for CS3516 (the memory area is just "reserved"),
so the code is the only documentation of it.
>> This platform is CPU bound, so every additional lookup will
>> hit performance here. In my version I had an #ifdef for
>> COMPILE_TEST that replaced ARM-specific calls with stubs.
>> Since the driver is not expected to work on other platforms,
>> this seemed like the best workaround to make it compile
>> on other arches.
>
> Really. No. Stop going beneath the covers and using ARM private
> implementation APIs in drivers.
>
> Take that as a big NAK to that.
Don't worry, it won't happen. I am already thinking about better
approaches that stay with the public DMA-API.
> (I don't seem have the patch in question here to look at though.)
I'll put you on CC in future postings.
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH] clk: sunxi: sun9i-mmc: Implement reset callback for reset controls
From: Stephen Boyd @ 2017-12-18 21:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171218035751.20661-1-wens@csie.org>
On 12/18, Chen-Yu Tsai wrote:
> Our MMC host driver now issues a reset, instead of just deasserting
> the reset control, since commit c34eda69ad4c ("mmc: sunxi: Reset the
> device at probe time"). The sun9i-mmc clock driver does not support
> this, and will fail, which results in MMC not probing.
>
> This patch implements the reset callback by asserting the reset control,
> then deasserting it after a small delay.
>
> Fixes: 7a6fca879f59 ("clk: sunxi: Add driver for A80 MMC config clocks/resets")
> Cc: <stable@vger.kernel.org> # 4.14.x
> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
> ---
Did you want us to pick this up into clk-fixes? It seems to be
causing MMC to not work for some time? That sounds annoying
enough.
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
* arm64 crashkernel fails to boot on acpi-only machines due to ACPI regions being no longer mapped as NOMAP
From: Bhupesh Sharma @ 2017-12-18 21:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171218051657.GA5998@dhcp-128-65.nay.redhat.com>
Hi Dave,
On Mon, Dec 18, 2017 at 10:46 AM, Dave Young <dyoung@redhat.com> wrote:
> kexec at fedoraproject... is for Fedora kexec scripts discussion, changed it
> to kexec at lists.infradead.org
>
> Also add linux-acpi list
> On 12/18/17 at 02:31am, Bhupesh Sharma wrote:
>> On Fri, Dec 15, 2017 at 3:05 PM, Ard Biesheuvel
>> <ard.biesheuvel@linaro.org> wrote:
>> > On 15 December 2017 at 09:59, AKASHI Takahiro
>> > <takahiro.akashi@linaro.org> wrote:
>> >> On Wed, Dec 13, 2017 at 12:17:22PM +0000, Ard Biesheuvel wrote:
>> >>> On 13 December 2017 at 12:16, AKASHI Takahiro
>> >>> <takahiro.akashi@linaro.org> wrote:
>> >>> > On Wed, Dec 13, 2017 at 10:49:27AM +0000, Ard Biesheuvel wrote:
>> >>> >> On 13 December 2017 at 10:26, AKASHI Takahiro
>> >>> >> <takahiro.akashi@linaro.org> wrote:
>> >>> >> > Bhupesh, Ard,
>> >>> >> >
>> >>> >> > On Wed, Dec 13, 2017 at 03:21:59AM +0530, Bhupesh Sharma wrote:
>> >>> >> >> Hi Ard, Akashi
>> >>> >> >>
>> >>> >> > (snip)
>> >>> >> >
>> >>> >> >> Looking deeper into the issue, since the arm64 kexec-tools uses the
>> >>> >> >> 'linux,usable-memory-range' dt property to allow crash dump kernel to
>> >>> >> >> identify its own usable memory and exclude, at its boot time, any
>> >>> >> >> other memory areas that are part of the panicked kernel's memory.
>> >>> >> >> (see https://www.kernel.org/doc/Documentation/devicetree/bindings/chosen.txt
>> >>> >> >> , for details)
>> >>> >> >
>> >>> >> > Right.
>> >>> >> >
>> >>> >> >> 1). Now when 'kexec -p' is executed, this node is patched up only
>> >>> >> >> with the crashkernel memory range:
>> >>> >> >>
>> >>> >> >> /* add linux,usable-memory-range */
>> >>> >> >> nodeoffset = fdt_path_offset(new_buf, "/chosen");
>> >>> >> >> result = fdt_setprop_range(new_buf, nodeoffset,
>> >>> >> >> PROP_USABLE_MEM_RANGE, &crash_reserved_mem,
>> >>> >> >> address_cells, size_cells);
>> >>> >> >>
>> >>> >> >> (see https://git.kernel.org/pub/scm/utils/kernel/kexec/kexec-tools.git/tree/kexec/arch/arm64/kexec-arm64.c#n465
>> >>> >> >> , for details)
>> >>> >> >>
>> >>> >> >> 2). This excludes the ACPI reclaim regions irrespective of whether
>> >>> >> >> they are marked as System RAM or as RESERVED. As,
>> >>> >> >> 'linux,usable-memory-range' dt node is patched up only with
>> >>> >> >> 'crash_reserved_mem' and not 'system_memory_ranges'
>> >>> >> >>
>> >>> >> >> 3). As a result when the crashkernel boots up it doesn't find this
>> >>> >> >> ACPI memory and crashes while trying to access the same:
>> >>> >> >>
>> >>> >> >> # kexec -p /boot/vmlinuz-`uname -r` --initrd=/boot/initramfs-`uname
>> >>> >> >> -r`.img --reuse-cmdline -d
>> >>> >> >>
>> >>> >> >> [snip..]
>> >>> >> >>
>> >>> >> >> Reserved memory range
>> >>> >> >> 000000000e800000-000000002e7fffff (0)
>> >>> >> >>
>> >>> >> >> Coredump memory ranges
>> >>> >> >> 0000000000000000-000000000e7fffff (0)
>> >>> >> >> 000000002e800000-000000003961ffff (0)
>> >>> >> >> 0000000039d40000-000000003ed2ffff (0)
>> >>> >> >> 000000003ed60000-000000003fbfffff (0)
>> >>> >> >> 0000001040000000-0000001ffbffffff (0)
>> >>> >> >> 0000002000000000-0000002ffbffffff (0)
>> >>> >> >> 0000009000000000-0000009ffbffffff (0)
>> >>> >> >> 000000a000000000-000000affbffffff (0)
>> >>> >> >>
>> >>> >> >> 4). So if we revert Ard's patch or just comment the fixing up of the
>> >>> >> >> memory cap'ing passed to the crash kernel inside
>> >>> >> >> 'arch/arm64/mm/init.c' (see below):
>> >>> >> >>
>> >>> >> >> static void __init fdt_enforce_memory_region(void)
>> >>> >> >> {
>> >>> >> >> struct memblock_region reg = {
>> >>> >> >> .size = 0,
>> >>> >> >> };
>> >>> >> >>
>> >>> >> >> of_scan_flat_dt(early_init_dt_scan_usablemem, ®);
>> >>> >> >>
>> >>> >> >> if (reg.size)
>> >>> >> >> //memblock_cap_memory_range(reg.base, reg.size); /*
>> >>> >> >> comment this out */
>> >>> >> >> }
>> >>> >> >
>> >>> >> > Please just don't do that. It can cause a fatal damage on
>> >>> >> > memory contents of the *crashed* kernel.
>> >>> >> >
>> >>> >> >> 5). Both the above temporary solutions fix the problem.
>> >>> >> >>
>> >>> >> >> 6). However exposing all System RAM regions to the crashkernel is not
>> >>> >> >> advisable and may cause the crashkernel or some crashkernel drivers to
>> >>> >> >> fail.
>> >>> >> >>
>> >>> >> >> 6a). I am trying an approach now, where the ACPI reclaim regions are
>> >>> >> >> added to '/proc/iomem' separately as ACPI reclaim regions by the
>> >>> >> >> kernel code and on the other hand the user-space 'kexec-tools' will
>> >>> >> >> pick up the ACPI reclaim regions from '/proc/iomem' and add it to the
>> >>> >> >> dt node 'linux,usable-memory-range'
>> >>> >> >
>> >>> >> > I still don't understand why we need to carry over the information
>> >>> >> > about "ACPI Reclaim memory" to crash dump kernel. In my understandings,
>> >>> >> > such regions are free to be reused by the kernel after some point of
>> >>> >> > initialization. Why does crash dump kernel need to know about them?
>> >>> >> >
>> >>> >>
>> >>> >> Not really. According to the UEFI spec, they can be reclaimed after
>> >>> >> the OS has initialized, i.e., when it has consumed the ACPI tables and
>> >>> >> no longer needs them. Of course, in order to be able to boot a kexec
>> >>> >> kernel, those regions needs to be preserved, which is why they are
>> >>> >> memblock_reserve()'d now.
>> >>> >
>> >>> > For my better understandings, who is actually accessing such regions
>> >>> > during boot time, uefi itself or efistub?
>> >>> >
>> >>>
>> >>> No, only the kernel. This is where the ACPI tables are stored. For
>> >>> instance, on QEMU we have
>> >>>
>> >>> ACPI: RSDP 0x0000000078980000 000024 (v02 BOCHS )
>> >>> ACPI: XSDT 0x0000000078970000 000054 (v01 BOCHS BXPCFACP 00000001
>> >>> 01000013)
>> >>> ACPI: FACP 0x0000000078930000 00010C (v05 BOCHS BXPCFACP 00000001
>> >>> BXPC 00000001)
>> >>> ACPI: DSDT 0x0000000078940000 0011DA (v02 BOCHS BXPCDSDT 00000001
>> >>> BXPC 00000001)
>> >>> ACPI: APIC 0x0000000078920000 000140 (v03 BOCHS BXPCAPIC 00000001
>> >>> BXPC 00000001)
>> >>> ACPI: GTDT 0x0000000078910000 000060 (v02 BOCHS BXPCGTDT 00000001
>> >>> BXPC 00000001)
>> >>> ACPI: MCFG 0x0000000078900000 00003C (v01 BOCHS BXPCMCFG 00000001
>> >>> BXPC 00000001)
>> >>> ACPI: SPCR 0x00000000788F0000 000050 (v02 BOCHS BXPCSPCR 00000001
>> >>> BXPC 00000001)
>> >>> ACPI: IORT 0x00000000788E0000 00007C (v00 BOCHS BXPCIORT 00000001
>> >>> BXPC 00000001)
>> >>>
>> >>> covered by
>> >>>
>> >>> efi: 0x0000788e0000-0x00007894ffff [ACPI Reclaim Memory ...]
>> >>> ...
>> >>> efi: 0x000078970000-0x00007898ffff [ACPI Reclaim Memory ...]
>> >>
>> >> OK. I mistakenly understood those regions could be freed after exiting
>> >> UEFI boot services.
>> >>
>> >>>
>> >>> >> So it seems that kexec does not honour the memblock_reserve() table
>> >>> >> when booting the next kernel.
>> >>> >
>> >>> > not really.
>> >>> >
>> >>> >> > (In other words, can or should we skip some part of ACPI-related init code
>> >>> >> > on crash dump kernel?)
>> >>> >> >
>> >>> >>
>> >>> >> I don't think so. And the change to the handling of ACPI reclaim
>> >>> >> regions only revealed the bug, not created it (given that other
>> >>> >> memblock_reserve regions may be affected as well)
>> >>> >
>> >>> > As whether we should honor such reserved regions over kexec'ing
>> >>> > depends on each one's specific nature, we will have to take care one-by-one.
>> >>> > As a matter of fact, no information about "reserved" memblocks is
>> >>> > exposed to user space (via proc/iomem).
>> >>> >
>> >>>
>> >>> That is why I suggested (somewhere in this thread?) to not expose them
>> >>> as 'System RAM'. Do you think that could solve this?
>> >>
>> >> Memblock-reserv'ing them is necessary to prevent their corruption and
>> >> marking them under another name in /proc/iomem would also be good in order
>> >> not to allocate them as part of crash kernel's memory.
>> >>
>> >
>> > I agree. However, this may not be entirely trivial, since iterating
>> > over the memblock_reserved table and creating iomem entries may result
>> > in collisions.
>>
>> I found a method (using the patch I shared earlier in this thread) to mark these
>> entries as 'ACPI reclaim memory' ranges rather than System RAM or
>> reserved regions.
>>
>> >> But I'm not still convinced that we should export them in useable-
>> >> memory-range to crash dump kernel. They will be accessed through
>> >> acpi_os_map_memory() and so won't be required to be part of system ram
>> >> (or memblocks), I guess.
>> >
>> > Agreed. They will be covered by the linear mapping in the boot kernel,
>> > and be mapped explicitly via ioremap_cache() in the kexec kernel,
>> > which is exactly what we want in this case.
>>
>> Now this is what is confusing me. I don't see the above happening.
>>
>> I see that the primary kernel boots up and adds the ACPI regions via:
>> acpi_os_ioremap
>> -> ioremap_cache
>>
>> But during the crashkernel boot, ''acpi_os_ioremap' calls
>> 'ioremap' for the ACPI Reclaim Memory regions and not the _cache
>> variant.
>>
>> And it fails while accessing the ACPI tables:
>>
>> [ 0.039205] ACPI: Core revision 20170728
>> pud=000000002e7d0003, *pmd=000000002e7c0003, *pte=00e8000039710707
>> [ 0.095098] Internal error: Oops: 96000021 [#1] SMP
>> [ 0.100022] Modules linked in:
>> [ 0.103102] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.14.0-rc6 #1
>> [ 0.109432] task: ffff000008d05180 task.stack: ffff000008cc0000
>> [ 0.115414] PC is at acpi_ns_lookup+0x25c/0x3c0
>> [ 0.119987] LR is at acpi_ds_load1_begin_op+0xa4/0x294
>> [ 0.125175] pc : [<ffff0000084a6764>] lr : [<ffff00000849b4f8>]
>> pstate: 60000045
>> [ 0.132647] sp : ffff000008ccfb40
>> [ 0.135989] x29: ffff000008ccfb40 x28: ffff000008a9f2a4
>> [ 0.141354] x27: ffff0000088be820 x26: 0000000000000000
>> [ 0.146718] x25: 000000000000001b x24: 0000000000000001
>> [ 0.152083] x23: 0000000000000001 x22: ffff000009710027
>> [ 0.157447] x21: ffff000008ccfc50 x20: 0000000000000001
>> [ 0.162812] x19: 000000000000001b x18: 0000000000000005
>> [ 0.168176] x17: 0000000000000000 x16: 0000000000000000
>> [ 0.173541] x15: 0000000000000000 x14: 000000000000038e
>> [ 0.178905] x13: ffffffff00000000 x12: ffffffffffffffff
>> [ 0.184270] x11: 0000000000000006 x10: 00000000ffffff76
>> [ 0.189634] x9 : 000000000000005f x8 : ffff8000126d0140
>> [ 0.194998] x7 : 0000000000000000 x6 : ffff000008ccfc50
>> [ 0.200362] x5 : ffff80000fe62c00 x4 : 0000000000000001
>> [ 0.205727] x3 : ffff000008ccfbe0 x2 : ffff0000095e3980
>> [ 0.211091] x1 : ffff000009710027 x0 : 0000000000000000
>> [ 0.216456] Process swapper/0 (pid: 0, stack limit = 0xffff000008cc0000)
>> [ 0.223224] Call trace:
>> [ 0.225688] Exception stack(0xffff000008ccfa00 to 0xffff000008ccfb40)
>> [ 0.232194] fa00: 0000000000000000 ffff000009710027
>> ffff0000095e3980 ffff000008ccfbe0
>> [ 0.240106] fa20: 0000000000000001 ffff80000fe62c00
>> ffff000008ccfc50 0000000000000000
>> [ 0.248018] fa40: ffff8000126d0140 000000000000005f
>> 00000000ffffff76 0000000000000006
>> [ 0.255931] fa60: ffffffffffffffff ffffffff00000000
>> 000000000000038e 0000000000000000
>> [ 0.263843] fa80: 0000000000000000 0000000000000000
>> 0000000000000005 000000000000001b
>> [ 0.271754] faa0: 0000000000000001 ffff000008ccfc50
>> ffff000009710027 0000000000000001
>> [ 0.279667] fac0: 0000000000000001 000000000000001b
>> 0000000000000000 ffff0000088be820
>> [ 0.287579] fae0: ffff000008a9f2a4 ffff000008ccfb40
>> ffff00000849b4f8 ffff000008ccfb40
>> [ 0.295491] fb00: ffff0000084a6764 0000000060000045
>> ffff000008ccfb40 ffff000008260a18
>> [ 0.303403] fb20: ffffffffffffffff ffff0000087f3fb0
>> ffff000008ccfb40 ffff0000084a6764
>> [ 0.311316] [<ffff0000084a6764>] acpi_ns_lookup+0x25c/0x3c0
>> [ 0.316943] [<ffff00000849b4f8>] acpi_ds_load1_begin_op+0xa4/0x294
>> [ 0.323186] [<ffff0000084ad4ac>] acpi_ps_build_named_op+0xc4/0x198
>> [ 0.329428] [<ffff0000084ad6cc>] acpi_ps_create_op+0x14c/0x270
>> [ 0.335319] [<ffff0000084acfa8>] acpi_ps_parse_loop+0x188/0x5c8
>> [ 0.341298] [<ffff0000084ae048>] acpi_ps_parse_aml+0xb0/0x2b8
>> [ 0.347101] [<ffff0000084a8e10>] acpi_ns_one_complete_parse+0x144/0x184
>> [ 0.353783] [<ffff0000084a8e98>] acpi_ns_parse_table+0x48/0x68
>> [ 0.359675] [<ffff0000084a82cc>] acpi_ns_load_table+0x4c/0xdc
>> [ 0.365479] [<ffff0000084b32f8>] acpi_tb_load_namespace+0xe4/0x264
>> [ 0.371723] [<ffff000008baf9b4>] acpi_load_tables+0x48/0xc0
>> [ 0.377350] [<ffff000008badc20>] acpi_early_init+0x9c/0xd0
>> [ 0.382891] [<ffff000008b70d50>] start_kernel+0x3b4/0x43c
>> [ 0.388343] Code: b9008fb9 2a000318 36380054 32190318 (b94002c0)
>> [ 0.394500] ---[ end trace c46ed37f9651c58e ]---
>> [ 0.399160] Kernel panic - not syncing: Fatal exception
>> [ 0.404437] Rebooting in 10 seconds.
>>
>> So, I think the linear mapping done by the primary kernel does not
>> make these accessible in the crash kernel directly.
>>
>> Any pointers?
>
> Can you get the code line number for acpi_ns_lookup+0x25c?
gdb points to the following code line number:
(gdb) list *(acpi_ns_lookup+0x25c)
0xffff0000084aa250 is in acpi_ns_lookup (drivers/acpi/acpica/nsaccess.c:577).
572 }
573 }
574
575 /* Extract one ACPI name from the front of the pathname */
576
577 ACPI_MOVE_32_TO_32(&simple_name, path);
578
579 /* Try to find the single (4 character) ACPI name */
580
581 status =
(gdb)
i.e. ACPI_MOVE_32_TO_32(&simple_name, path);
addr2line also confirms the same:
# addr2line -e vmlinux ffff0000084aa250
/root/git/kernel-alt/drivers/acpi/acpica/nsaccess.c:577
Regards,
Bhupesh
>>
>> Regards,
>> Bhupesh
>>
>> >> Just FYI, on x86, ACPI tables seems to be exposed to crash dump kernel
>> >> via a kernel command line parameter, "memmap=".
>> >>
>> _______________________________________________
>> kexec mailing list -- kexec at lists.fedoraproject.org
>> To unsubscribe send an email to kexec-leave at lists.fedoraproject.org
^ permalink raw reply
* [PATCH 0/2] ARM: dts: r8a7792: Timer node nodes out of bus
From: Simon Horman @ 2017-12-18 21:32 UTC (permalink / raw)
To: linux-arm-kernel
Move the timer node, which have no reg property, out of the root node.
The nodes that have been moved do not have any register properties and thus
shouldn't be placed on the bus.
In preparation for the above sort nodes in the root node alphabetically.
Based on renesas-devel-20171218-v4.15-rc4
Simon Horman (2):
ARM: dts: r8a7792: sort root sub-nodes alphabetically
ARM: dts: r8a7792: move timer node out of bus
arch/arm/boot/dts/r8a7792.dtsi | 64 ++++++++++++++++++++----------------------
1 file changed, 30 insertions(+), 34 deletions(-)
--
2.11.0
^ permalink raw reply
* [PATCH 1/2] ARM: dts: r8a7792: sort root sub-nodes alphabetically
From: Simon Horman @ 2017-12-18 21:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171218213233.3373-1-horms+renesas@verge.net.au>
Sort root sub-nodes alphabetically for allow for easier maintenance
of this file.
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
arch/arm/boot/dts/r8a7792.dtsi | 48 +++++++++++++++++++++---------------------
1 file changed, 24 insertions(+), 24 deletions(-)
diff --git a/arch/arm/boot/dts/r8a7792.dtsi b/arch/arm/boot/dts/r8a7792.dtsi
index ac05fdb91798..d31258958c36 100644
--- a/arch/arm/boot/dts/r8a7792.dtsi
+++ b/arch/arm/boot/dts/r8a7792.dtsi
@@ -36,6 +36,22 @@
vin5 = &vin5;
};
+ /* External root clock */
+ extal_clk: extal {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ /* This value must be overridden by the board. */
+ clock-frequency = <0>;
+ };
+
+ /* External CAN clock */
+ can_clk: can {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ /* This value must be overridden by the board. */
+ clock-frequency = <0>;
+ };
+
cpus {
#address-cells = <1>;
#size-cells = <0>;
@@ -69,6 +85,14 @@
};
};
+ /* External SCIF clock */
+ scif_clk: scif {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ /* This value must be overridden by the board. */
+ clock-frequency = <0>;
+ };
+
soc {
compatible = "simple-bus";
interrupt-parent = <&gic>;
@@ -833,28 +857,4 @@
#reset-cells = <1>;
};
};
-
- /* External root clock */
- extal_clk: extal {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- /* This value must be overridden by the board. */
- clock-frequency = <0>;
- };
-
- /* External SCIF clock */
- scif_clk: scif {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- /* This value must be overridden by the board. */
- clock-frequency = <0>;
- };
-
- /* External CAN clock */
- can_clk: can {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- /* This value must be overridden by the board. */
- clock-frequency = <0>;
- };
};
--
2.11.0
^ permalink raw reply related
* [PATCH 2/2] ARM: dts: r8a7792: move timer node out of bus
From: Simon Horman @ 2017-12-18 21:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171218213233.3373-1-horms+renesas@verge.net.au>
The timer node does not have any register properties and thus shouldn't be
placed on the bus.
This problem is flagged by the compiler as follows:
$ make dtbs W=1
...
DTC arch/arm/boot/dts/r8a7792-wheat.dtb
arch/arm/boot/dts/r8a7792-blanche.dtb: Warning (simple_bus_reg): Node /soc/timer missing or empty reg/ranges property
arch/arm/boot/dts/r8a7792-wheat.dtb: Warning (simple_bus_reg): Node /soc/timer missing or empty reg/ranges property
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
arch/arm/boot/dts/r8a7792.dtsi | 20 ++++++++------------
1 file changed, 8 insertions(+), 12 deletions(-)
diff --git a/arch/arm/boot/dts/r8a7792.dtsi b/arch/arm/boot/dts/r8a7792.dtsi
index d31258958c36..5317e353569f 100644
--- a/arch/arm/boot/dts/r8a7792.dtsi
+++ b/arch/arm/boot/dts/r8a7792.dtsi
@@ -137,18 +137,6 @@
resets = <&cpg 407>;
};
- timer {
- compatible = "arm,armv7-timer";
- interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) |
- IRQ_TYPE_LEVEL_LOW)>,
- <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) |
- IRQ_TYPE_LEVEL_LOW)>,
- <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) |
- IRQ_TYPE_LEVEL_LOW)>,
- <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) |
- IRQ_TYPE_LEVEL_LOW)>;
- };
-
rst: reset-controller at e6160000 {
compatible = "renesas,r8a7792-rst";
reg = <0 0xe6160000 0 0x0100>;
@@ -857,4 +845,12 @@
#reset-cells = <1>;
};
};
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+ };
};
--
2.11.0
^ permalink raw reply related
* [PATCH v2 0/2] ARM: dts: r8a7743: move timer nodes nodes out of bus
From: Simon Horman @ 2017-12-18 21:40 UTC (permalink / raw)
To: linux-arm-kernel
Move the timer node, which have no reg property, out of the root node.
The nodes that have been moved do not have any register properties and thus
shouldn't be placed on the bus.
In preparation for the above sort nodes in the root node alphabetically.
Based renesas-devel-20171218-v4.15-rc4
Changes since v1:
* Rebase
* Avoid line-wrapping nodes
Simon Horman (2):
ARM: dts: r8a7743: sort root sub-nodes alphabetically
ARM: dts: r8a7743: move timer node out of bus
arch/arm/boot/dts/r8a7743.dtsi | 116 +++++++++++++++++++++--------------------
1 file changed, 60 insertions(+), 56 deletions(-)
--
2.11.0
^ permalink raw reply
* [PATCH v2 1/2] ARM: dts: r8a7743: sort root sub-nodes alphabetically
From: Simon Horman @ 2017-12-18 21:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171218214043.10796-1-horms+renesas@verge.net.au>
Sort root sub-nodes alphabetically for allow for easier maintenance
of this file.
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
v2
* Rebase
---
arch/arm/boot/dts/r8a7743.dtsi | 100 ++++++++++++++++++++++-------------------
1 file changed, 54 insertions(+), 46 deletions(-)
diff --git a/arch/arm/boot/dts/r8a7743.dtsi b/arch/arm/boot/dts/r8a7743.dtsi
index 59860c8ef362..d333a545956d 100644
--- a/arch/arm/boot/dts/r8a7743.dtsi
+++ b/arch/arm/boot/dts/r8a7743.dtsi
@@ -37,6 +37,29 @@
vin2 = &vin2;
};
+ /*
+ * The external audio clocks are configured as 0 Hz fixed frequency
+ * clocks by default.
+ * Boards that provide audio clocks should override them.
+ */
+ audio_clk_a: audio_clk_a {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
+ audio_clk_b: audio_clk_b {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
+ audio_clk_c: audio_clk_c {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
cpus {
#address-cells = <1>;
#size-cells = <0>;
@@ -79,6 +102,37 @@
};
};
+ /* External CAN clock */
+ can_clk: can {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ /* This value must be overridden by the board. */
+ clock-frequency = <0>;
+ };
+
+ /* External root clock */
+ extal_clk: extal {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ /* This value must be overridden by the board. */
+ clock-frequency = <0>;
+ };
+
+ /* External PCIe clock - can be overridden by the board */
+ pcie_bus_clk: pcie_bus {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
+ /* External SCIF clock */
+ scif_clk: scif {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ /* This value must be overridden by the board. */
+ clock-frequency = <0>;
+ };
+
soc {
compatible = "simple-bus";
interrupt-parent = <&gic>;
@@ -1485,56 +1539,10 @@
clock-frequency = <0>;
};
- /*
- * The external audio clocks are configured as 0 Hz fixed frequency
- * clocks by default.
- * Boards that provide audio clocks should override them.
- */
- audio_clk_a: audio_clk_a {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <0>;
- };
-
- audio_clk_b: audio_clk_b {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <0>;
- };
-
- audio_clk_c: audio_clk_c {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <0>;
- };
-
/* External USB clock - can be overridden by the board */
usb_extal_clk: usb_extal {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <48000000>;
};
-
- /* External CAN clock */
- can_clk: can {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- /* This value must be overridden by the board. */
- clock-frequency = <0>;
- };
-
- /* External PCIe clock - can be overridden by the board */
- pcie_bus_clk: pcie_bus {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <0>;
- };
-
- /* External SCIF clock */
- scif_clk: scif {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- /* This value must be overridden by the board. */
- clock-frequency = <0>;
- };
};
--
2.11.0
^ permalink raw reply related
* [PATCH v2 2/2] ARM: dts: r8a7743: move timer node out of bus
From: Simon Horman @ 2017-12-18 21:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171218214043.10796-1-horms+renesas@verge.net.au>
The timer node does not have any register properties and thus shouldn't be
placed on the bus.
This problem is flagged by the compiler as follows:
$ make
DTC arch/arm/boot/dts/r8a7743-iwg20d-q7-dbcm-ca.dtb
arch/arm/boot/dts/r8a7743-iwg20d-q7.dtb: Warning (simple_bus_reg): Node /soc/timer missing or empty reg/ranges property
arch/arm/boot/dts/r8a7743-iwg20d-q7-dbcm-ca.dtb: Warning (simple_bus_reg): Node /soc/timer missing or empty reg/ranges property
DTC arch/arm/boot/dts/r8a7743-sk-rzg1m.dtb
arch/arm/boot/dts/r8a7743-sk-rzg1m.dtb: Warning (simple_bus_reg): Node /soc/timer missing or empty reg/ranges property
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
v2
* Avoid line-wrapping properties
---
arch/arm/boot/dts/r8a7743.dtsi | 20 ++++++++------------
1 file changed, 8 insertions(+), 12 deletions(-)
diff --git a/arch/arm/boot/dts/r8a7743.dtsi b/arch/arm/boot/dts/r8a7743.dtsi
index d333a545956d..5ba0af76b29c 100644
--- a/arch/arm/boot/dts/r8a7743.dtsi
+++ b/arch/arm/boot/dts/r8a7743.dtsi
@@ -304,18 +304,6 @@
resets = <&cpg 407>;
};
- timer {
- compatible = "arm,armv7-timer";
- interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) |
- IRQ_TYPE_LEVEL_LOW)>,
- <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) |
- IRQ_TYPE_LEVEL_LOW)>,
- <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) |
- IRQ_TYPE_LEVEL_LOW)>,
- <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) |
- IRQ_TYPE_LEVEL_LOW)>;
- };
-
cpg: clock-controller at e6150000 {
compatible = "renesas,r8a7743-cpg-mssr";
reg = <0 0xe6150000 0 0x1000>;
@@ -1539,6 +1527,14 @@
clock-frequency = <0>;
};
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+ };
+
/* External USB clock - can be overridden by the board */
usb_extal_clk: usb_extal {
compatible = "fixed-clock";
--
2.11.0
^ permalink raw reply related
* [PATCH V2 0/7] 52-bit kernel VAs for arm64
From: Steve Capper @ 2017-12-18 21:47 UTC (permalink / raw)
To: linux-arm-kernel
This patch series brings 52-bit kernel VA support to arm64; if supported
at boot time. A new kernel option CONFIG_ARM64_VA_BITS_48_52 is available
when configured with a 64KB PAGE_SIZE (as on ARMv8.2-LPA, 52-bit VAs are
only allowed when running with a 64KB granule).
Switching between 48 and 52-bit does not involve any changes to the number
of page table levels. The number of PGDIR entries increases when running
with a 52 bit kernel VA.
In order to allow the kernel to switch between VA spaces at boot time, we
need to re-arrange the current kernel VA space. In particular, the KASAN
end address needs to be valid for both 48-bit and 52-bit VA spaces, meaning
we need to flip the kernel VA space s.t. the KASAN end address is high and
the direct linear mapping is low.
In V1 of this patch set the kernel position was also changed, this reduced
the possible variation in KASLR; so in V2 of this series the changes to the
kernel VA space are restricted to just swapping the halves of the kernel
VA space. In a future patch it would be possible to further expand the KASLR
offset space by adding a negative offset when running with a 52-bit VA.
In the series, the KASAN_SHADOW_OFFSET logic is altered to match the system
used for x86; namely that KASAN_SHADOW_OFFSET is a Kconfig constant rather
than a derived quantity. In order to simplify future VA work, the code to
compute the KASAN shadow offset is supplied as a script in the documentation
folder. It may be possible in a future patch to put the KASAN end address
at the end of the kernel VA space. This would allow one to use the same
KASAN shadow offset for all VA spaces.
If KASAN is not enabled, we use the same address layout for modules and
kernel for both 48-bit and 52-bit address spaces. The VMEMMAP region is
placed dynamically (it is larger for 52-bit VAs) which affects the positon
of the fixed map and PCI IO region.
This patch series modifies VA_BITS from a constant pre-processor macro, to
a runtime variable and this requires changes to other parts of the arm64
code such the page table dumper. Some parts of the code require pre-processing
constants derived from VA_BITS, so two new pre-processor constants have
been introduced:
VA_BITS_MIN the minimum number of VA_BITS used, this can be used to bound
addresses conservatively s.t. mappings work for both address
space sizes. An example use case being the EFI stub code
efi_get_max_initrd_addr(). Another example being to determine
whether or not we need an extra page table level for the
identity mapping (on 64KB PAGE_SIZE we already have 3-levels
for both 48-bit and 52-bit VA space).
VA_BITS_ALT if running with a higher kernel VA space, this is the number
of bits available. VA_BITS_MIN and VA_BITS_ALT can be used
together to generate constants (or test compile time asserts)
which are then chosen at runtime.
This patch series applies to 4.15-rc4, with the early pagetable patches I
posted earlier:
http://lists.infradead.org/pipermail/linux-arm-kernel/2017-November/543494.html
and in V2 this is based on Marc Zyngier's HASLR series at:
http://lists.infradead.org/pipermail/linux-arm-kernel/2017-December/547456.html
Basing this series on HASLR means that we no longer need the HYP mapping
logic fixes and adjustments to HYP mapping logic for variable VA spaces;
thus reduces the number of patches needed in V2 of this series.
Changes to V2:
* Kernel VA space only flipped, the order of modules, kImage etc are now
retained,
* 4.15-rc4 is used as a base as it includes a fix from V1 that has been
merged already,
* HASLR patch series is used as a base meaning HYP VA fixes are no
longer required.
Steve Capper (7):
arm/arm64: KVM: Formalise end of direct linear map
arm64: mm: Flip kernel VA space
arm64: kasan: Switch to using KASAN_SHADOW_OFFSET
arm64: mm: Replace fixed map BUILD_BUG_ON's with BUG_ON's
arm64: dump: Make kernel page table dumper dynamic again
arm64: mm: Make VA_BITS variable, introduce VA_BITS_MIN
arm64: mm: Add 48/52-bit kernel VA support
Documentation/arm64/kasan-offsets.sh | 17 +++++++++++
arch/arm/include/asm/memory.h | 1 +
arch/arm64/Kconfig | 22 ++++++++++++++
arch/arm64/Makefile | 7 -----
arch/arm64/include/asm/assembler.h | 2 +-
arch/arm64/include/asm/efi.h | 4 +--
arch/arm64/include/asm/kasan.h | 21 +++++--------
arch/arm64/include/asm/memory.h | 35 ++++++++++++++--------
arch/arm64/include/asm/mmu_context.h | 2 +-
arch/arm64/include/asm/pgtable.h | 6 ++--
arch/arm64/include/asm/processor.h | 2 +-
arch/arm64/kernel/head.S | 13 ++++----
arch/arm64/kernel/kaslr.c | 4 +--
arch/arm64/kvm/hyp-init.S | 2 +-
arch/arm64/mm/dump.c | 58 +++++++++++++++++++++++++++++-------
arch/arm64/mm/fault.c | 2 +-
arch/arm64/mm/init.c | 14 ++++-----
arch/arm64/mm/kasan_init.c | 14 +++++----
arch/arm64/mm/mmu.c | 15 ++++++----
arch/arm64/mm/proc.S | 42 +++++++++++++++++++++++++-
virt/kvm/arm/mmu.c | 4 +--
21 files changed, 204 insertions(+), 83 deletions(-)
create mode 100644 Documentation/arm64/kasan-offsets.sh
--
2.11.0
^ permalink raw reply
* [PATCH V2 1/7] arm/arm64: KVM: Formalise end of direct linear map
From: Steve Capper @ 2017-12-18 21:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171218214736.13761-1-steve.capper@arm.com>
We assume that the direct linear map ends at ~0 in the KVM HYP map
intersection checking code. This assumption will become invalid later on
for arm64 when the address space of the kernel is re-arranged.
This patch introduces a new constant PAGE_OFFSET_END for both arm and
arm64 and defines it to be ~0UL
Signed-off-by: Steve Capper <steve.capper@arm.com>
---
arch/arm/include/asm/memory.h | 1 +
arch/arm64/include/asm/memory.h | 1 +
virt/kvm/arm/mmu.c | 4 ++--
3 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
index 1f54e4e98c1e..e223a945c361 100644
--- a/arch/arm/include/asm/memory.h
+++ b/arch/arm/include/asm/memory.h
@@ -30,6 +30,7 @@
/* PAGE_OFFSET - the virtual address of the start of the kernel image */
#define PAGE_OFFSET UL(CONFIG_PAGE_OFFSET)
+#define PAGE_OFFSET_END (~0UL)
#ifdef CONFIG_MMU
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index d4bae7d6e0d8..2dedc775d151 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -67,6 +67,7 @@
(UL(1) << VA_BITS) + 1)
#define PAGE_OFFSET (UL(0xffffffffffffffff) - \
(UL(1) << (VA_BITS - 1)) + 1)
+#define PAGE_OFFSET_END (~0UL)
#define KIMAGE_VADDR (MODULES_END)
#define MODULES_END (MODULES_VADDR + MODULES_VSIZE)
#define MODULES_VADDR (VA_START + KASAN_SHADOW_SIZE)
diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
index 6633f5f07200..d1f79383fca5 100644
--- a/virt/kvm/arm/mmu.c
+++ b/virt/kvm/arm/mmu.c
@@ -1794,10 +1794,10 @@ int kvm_mmu_init(void)
kvm_debug("IDMAP page: %lx\n", hyp_idmap_start);
kvm_debug("HYP VA range: %lx:%lx\n",
kern_hyp_va(PAGE_OFFSET),
- kern_hyp_va((unsigned long)high_memory - 1));
+ kern_hyp_va(PAGE_OFFSET_END));
if (hyp_idmap_start >= kern_hyp_va(PAGE_OFFSET) &&
- hyp_idmap_start < kern_hyp_va((unsigned long)high_memory - 1) &&
+ hyp_idmap_start < kern_hyp_va(PAGE_OFFSET_END) &&
hyp_idmap_start != (unsigned long)__hyp_idmap_text_start) {
/*
* The idmap page is intersecting with the VA space,
--
2.11.0
^ permalink raw reply related
* [PATCH V2 2/7] arm64: mm: Flip kernel VA space
From: Steve Capper @ 2017-12-18 21:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171218214736.13761-1-steve.capper@arm.com>
Put the direct linear map in the lower addresses of the kernel VA range
and everything else in the higher ranges.
This allows us to make room for an inline KASAN shadow that operates
under both 48 and 52 bit kernel VA sizes. For example with a 52-bit VA,
if KASAN_SHADOW_END < 0xFFF8000000000000 (it is in the lower addresses
of the kernel VA range), this will be below the start of the minimum
48-bit kernel VA address of 0xFFFF000000000000.
We need to adjust:
*) KASAN shadow region placement logic,
*) KASAN_SHADOW_OFFSET computation logic,
*) virt_to_phys, phys_to_virt checks,
*) page table dumper.
These are all small changes, that need to take place atomically, so they
are bundled into this commit.
Signed-off-by: Steve Capper <steve.capper@arm.com>
---
arch/arm64/Makefile | 2 +-
arch/arm64/include/asm/memory.h | 10 +++++-----
arch/arm64/include/asm/pgtable.h | 2 +-
arch/arm64/mm/dump.c | 8 ++++----
arch/arm64/mm/init.c | 9 +--------
arch/arm64/mm/kasan_init.c | 4 ++--
arch/arm64/mm/mmu.c | 4 ++--
7 files changed, 16 insertions(+), 23 deletions(-)
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index b481b4a7c011..7eaff48d2a39 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -100,7 +100,7 @@ endif
# KASAN_SHADOW_OFFSET = VA_START + (1 << (VA_BITS - 3)) - (1 << 61)
# in 32-bit arithmetic
KASAN_SHADOW_OFFSET := $(shell printf "0x%08x00000000\n" $$(( \
- (0xffffffff & (-1 << ($(CONFIG_ARM64_VA_BITS) - 32))) \
+ (0xffffffff & (-1 << ($(CONFIG_ARM64_VA_BITS) - 1 - 32))) \
+ (1 << ($(CONFIG_ARM64_VA_BITS) - 32 - 3)) \
- (1 << (64 - 32 - 3)) )) )
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index 2dedc775d151..0a912eb3d74f 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -64,15 +64,15 @@
*/
#define VA_BITS (CONFIG_ARM64_VA_BITS)
#define VA_START (UL(0xffffffffffffffff) - \
- (UL(1) << VA_BITS) + 1)
-#define PAGE_OFFSET (UL(0xffffffffffffffff) - \
(UL(1) << (VA_BITS - 1)) + 1)
-#define PAGE_OFFSET_END (~0UL)
+#define PAGE_OFFSET (UL(0xffffffffffffffff) - \
+ (UL(1) << VA_BITS) + 1)
+#define PAGE_OFFSET_END (VA_START)
#define KIMAGE_VADDR (MODULES_END)
#define MODULES_END (MODULES_VADDR + MODULES_VSIZE)
#define MODULES_VADDR (VA_START + KASAN_SHADOW_SIZE)
#define MODULES_VSIZE (SZ_128M)
-#define VMEMMAP_START (PAGE_OFFSET - VMEMMAP_SIZE)
+#define VMEMMAP_START (-VMEMMAP_SIZE)
#define PCI_IO_END (VMEMMAP_START - SZ_2M)
#define PCI_IO_START (PCI_IO_END - PCI_IO_SIZE)
#define FIXADDR_TOP (PCI_IO_START - SZ_2M)
@@ -223,7 +223,7 @@ static inline unsigned long kaslr_offset(void)
* space. Testing the top bit for the start of the region is a
* sufficient check.
*/
-#define __is_lm_address(addr) (!!((addr) & BIT(VA_BITS - 1)))
+#define __is_lm_address(addr) (!((addr) & BIT(VA_BITS - 1)))
#define __lm_to_phys(addr) (((addr) & ~PAGE_OFFSET) + PHYS_OFFSET)
#define __kimg_to_phys(addr) ((addr) - kimage_voffset)
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 6d611f8b7c5b..63ea76cc8357 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -31,7 +31,7 @@
* and fixed mappings
*/
#define VMALLOC_START (MODULES_END)
-#define VMALLOC_END (PAGE_OFFSET - PUD_SIZE - VMEMMAP_SIZE - SZ_64K)
+#define VMALLOC_END (- PUD_SIZE - VMEMMAP_SIZE - SZ_64K)
#define vmemmap ((struct page *)VMEMMAP_START - (memstart_addr >> PAGE_SHIFT))
diff --git a/arch/arm64/mm/dump.c b/arch/arm64/mm/dump.c
index 7b60d62ac593..d1814b247d4b 100644
--- a/arch/arm64/mm/dump.c
+++ b/arch/arm64/mm/dump.c
@@ -30,6 +30,8 @@
#include <asm/ptdump.h>
static const struct addr_marker address_markers[] = {
+ { PAGE_OFFSET, "Linear Mapping start" },
+ { VA_START, "Linear Mapping end" },
#ifdef CONFIG_KASAN
{ KASAN_SHADOW_START, "Kasan shadow start" },
{ KASAN_SHADOW_END, "Kasan shadow end" },
@@ -43,10 +45,8 @@ static const struct addr_marker address_markers[] = {
{ PCI_IO_START, "PCI I/O start" },
{ PCI_IO_END, "PCI I/O end" },
#ifdef CONFIG_SPARSEMEM_VMEMMAP
- { VMEMMAP_START, "vmemmap start" },
- { VMEMMAP_START + VMEMMAP_SIZE, "vmemmap end" },
+ { VMEMMAP_START, "vmemmap" },
#endif
- { PAGE_OFFSET, "Linear Mapping" },
{ -1, NULL },
};
@@ -375,7 +375,7 @@ static void ptdump_initialize(void)
static struct ptdump_info kernel_ptdump_info = {
.mm = &init_mm,
.markers = address_markers,
- .base_addr = VA_START,
+ .base_addr = PAGE_OFFSET,
};
void ptdump_check_wx(void)
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index d84c77125b3a..0a5da98f92fa 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -361,19 +361,12 @@ static void __init fdt_enforce_memory_region(void)
void __init arm64_memblock_init(void)
{
- const s64 linear_region_size = -(s64)PAGE_OFFSET;
+ const s64 linear_region_size = BIT(VA_BITS - 1);
/* Handle linux,usable-memory-range property */
fdt_enforce_memory_region();
/*
- * Ensure that the linear region takes up exactly half of the kernel
- * virtual address space. This way, we can distinguish a linear address
- * from a kernel/module/vmalloc address by testing a single bit.
- */
- BUILD_BUG_ON(linear_region_size != BIT(VA_BITS - 1));
-
- /*
* Select a suitable value for the base of physical memory.
*/
memstart_addr = round_down(memblock_start_of_DRAM(),
diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c
index acba49fb5aac..5aef679e61c6 100644
--- a/arch/arm64/mm/kasan_init.c
+++ b/arch/arm64/mm/kasan_init.c
@@ -205,10 +205,10 @@ void __init kasan_init(void)
kasan_map_populate(kimg_shadow_start, kimg_shadow_end,
pfn_to_nid(virt_to_pfn(lm_alias(_text))));
- kasan_populate_zero_shadow((void *)KASAN_SHADOW_START,
+ kasan_populate_zero_shadow(kasan_mem_to_shadow((void *) VA_START),
(void *)mod_shadow_start);
kasan_populate_zero_shadow((void *)kimg_shadow_end,
- kasan_mem_to_shadow((void *)PAGE_OFFSET));
+ (void *)KASAN_SHADOW_END);
if (kimg_shadow_start > mod_shadow_end)
kasan_populate_zero_shadow((void *)mod_shadow_end,
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 58b1ed6fd7ec..5a16e2b9b1a2 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -356,7 +356,7 @@ static phys_addr_t pgd_pgtable_alloc(void)
static void __init create_mapping_noalloc(phys_addr_t phys, unsigned long virt,
phys_addr_t size, pgprot_t prot)
{
- if (virt < VMALLOC_START) {
+ if ((virt >= VA_START) && (virt < VMALLOC_START)) {
pr_warn("BUG: not creating mapping for %pa@0x%016lx - outside kernel range\n",
&phys, virt);
return;
@@ -383,7 +383,7 @@ void __init create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys,
static void update_mapping_prot(phys_addr_t phys, unsigned long virt,
phys_addr_t size, pgprot_t prot)
{
- if (virt < VMALLOC_START) {
+ if ((virt >= VA_START) && (virt < VMALLOC_START)) {
pr_warn("BUG: not updating mapping for %pa@0x%016lx - outside kernel range\n",
&phys, virt);
return;
--
2.11.0
^ permalink raw reply related
* [PATCH V2 3/7] arm64: kasan: Switch to using KASAN_SHADOW_OFFSET
From: Steve Capper @ 2017-12-18 21:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171218214736.13761-1-steve.capper@arm.com>
KASAN_SHADOW_OFFSET is a constant that is supplied to gcc as a command
line argument and affects the codegen of the inline address sanetiser.
Essentially, for an example memory access:
*ptr1 = val;
The compiler will insert logic similar to the below:
shadowValue = *(ptr1 >> 3 + KASAN_SHADOW_OFFSET)
if (somethingWrong(shadowValue))
flagAnError();
As this code sequence is inserted into many places, and
KASAN_SHADOW_OFFSET is essentially baked into many places in the kernel
.text, the only sane thing we can do at compile time is to check that
the KASAN_SHADOW_OFFSET gives us a memory region that is valid,
otherwise BUILD_BUG on a discrepancy.
i.e. If we want to run a single kernel binary with multiple address
spaces, then we need to do this with KASAN_SHADOW_OFFSET fixed.
Thankfully, due to the way the KASAN_SHADOW_OFFSET is used to provide
shadow addresses we know that the end of the shadow region is constant
w.r.t. VA space size:
KASAN_SHADOW_END = ~0 >> 3 + KASAN_SHADOW_OFFSET
This means that if we increase the size of the VA space, the KASAN
region expands upwards into the new space that is provided.
This patch removes the logic to compute the KASAN_SHADOW_OFFSET in the
arm64 Makefile, and instead we adopt the approach used by x86 to supply
offset values in kConfig. To help debug/develop future VA space changes,
the Makefile logic has been preserved in a script file in the arm64
Documentation folder.
Signed-off-by: Steve Capper <steve.capper@arm.com>
---
Documentation/arm64/kasan-offsets.sh | 17 +++++++++++++++++
arch/arm64/Kconfig | 10 ++++++++++
arch/arm64/Makefile | 7 -------
arch/arm64/include/asm/kasan.h | 21 ++++++++-------------
arch/arm64/include/asm/memory.h | 7 ++++---
arch/arm64/mm/kasan_init.c | 1 -
6 files changed, 39 insertions(+), 24 deletions(-)
create mode 100644 Documentation/arm64/kasan-offsets.sh
diff --git a/Documentation/arm64/kasan-offsets.sh b/Documentation/arm64/kasan-offsets.sh
new file mode 100644
index 000000000000..d07a95518770
--- /dev/null
+++ b/Documentation/arm64/kasan-offsets.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+# Print out the KASAN_SHADOW_OFFSETS required to place the KASAN SHADOW
+# start address at the mid-point of the kernel VA space
+
+print_kasan_offset () {
+ printf "%02d\t" $1
+ printf "0x%08x00000000\n" $(( (0xffffffff & (-1 << ($1 - 1 - 32))) \
+ + (1 << ($1 - 32 - 3)) \
+ - (1 << (64 - 32 - 3)) ))
+}
+
+printf "VABITS\tKASAN_SHADOW_OFFSET\n"
+print_kasan_offset 48
+print_kasan_offset 42
+print_kasan_offset 39
+print_kasan_offset 36
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index c9a7e9e1414f..dc7e54522fa1 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -272,6 +272,16 @@ config ARCH_SUPPORTS_UPROBES
config ARCH_PROC_KCORE_TEXT
def_bool y
+config KASAN_SHADOW_OFFSET
+ hex
+ depends on KASAN
+ default 0xdfffa00000000000 if ARM64_VA_BITS_48
+ default 0xdfffd00000000000 if ARM64_VA_BITS_47
+ default 0xdffffe8000000000 if ARM64_VA_BITS_42
+ default 0xdfffffd000000000 if ARM64_VA_BITS_39
+ default 0xdffffffa00000000 if ARM64_VA_BITS_36
+ default 0xffffffffffffffff
+
source "init/Kconfig"
source "kernel/Kconfig.freezer"
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index 7eaff48d2a39..13cc9311ef7d 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -97,13 +97,6 @@ else
TEXT_OFFSET := 0x00080000
endif
-# KASAN_SHADOW_OFFSET = VA_START + (1 << (VA_BITS - 3)) - (1 << 61)
-# in 32-bit arithmetic
-KASAN_SHADOW_OFFSET := $(shell printf "0x%08x00000000\n" $$(( \
- (0xffffffff & (-1 << ($(CONFIG_ARM64_VA_BITS) - 1 - 32))) \
- + (1 << ($(CONFIG_ARM64_VA_BITS) - 32 - 3)) \
- - (1 << (64 - 32 - 3)) )) )
-
export TEXT_OFFSET GZFLAGS
core-y += arch/arm64/kernel/ arch/arm64/mm/
diff --git a/arch/arm64/include/asm/kasan.h b/arch/arm64/include/asm/kasan.h
index e266f80e45b7..5f0d6130e53f 100644
--- a/arch/arm64/include/asm/kasan.h
+++ b/arch/arm64/include/asm/kasan.h
@@ -13,21 +13,16 @@
/*
* KASAN_SHADOW_START: beginning of the kernel virtual addresses.
* KASAN_SHADOW_END: KASAN_SHADOW_START + 1/8 of kernel virtual addresses.
- */
-#define KASAN_SHADOW_START (VA_START)
-#define KASAN_SHADOW_END (KASAN_SHADOW_START + KASAN_SHADOW_SIZE)
-
-/*
- * This value is used to map an address to the corresponding shadow
- * address by the following formula:
- * shadow_addr = (address >> 3) + KASAN_SHADOW_OFFSET;
*
- * (1 << 61) shadow addresses - [KASAN_SHADOW_OFFSET,KASAN_SHADOW_END]
- * cover all 64-bits of virtual addresses. So KASAN_SHADOW_OFFSET
- * should satisfy the following equation:
- * KASAN_SHADOW_OFFSET = KASAN_SHADOW_END - (1ULL << 61)
+ * We derive these values from KASAN_SHADOW_OFFSET and the size of the VA
+ * space.
+ *
+ * KASAN shadow addresses are derived from the following formula:
+ * shadow_addr = (address >> 3) + KASAN_SHADOW_OFFSET;
+ *
*/
-#define KASAN_SHADOW_OFFSET (KASAN_SHADOW_END - (1ULL << (64 - 3)))
+#define _KASAN_SHADOW_START(va) (KASAN_SHADOW_END - (1UL << ((va) - 3)))
+#define KASAN_SHADOW_START _KASAN_SHADOW_START(VA_BITS)
void kasan_init(void);
void kasan_copy_shadow(pgd_t *pgdir);
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index 0a912eb3d74f..c52b90cdc583 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -70,7 +70,7 @@
#define PAGE_OFFSET_END (VA_START)
#define KIMAGE_VADDR (MODULES_END)
#define MODULES_END (MODULES_VADDR + MODULES_VSIZE)
-#define MODULES_VADDR (VA_START + KASAN_SHADOW_SIZE)
+#define MODULES_VADDR (KASAN_SHADOW_END)
#define MODULES_VSIZE (SZ_128M)
#define VMEMMAP_START (-VMEMMAP_SIZE)
#define PCI_IO_END (VMEMMAP_START - SZ_2M)
@@ -86,11 +86,12 @@
* stack size when KASAN is in use.
*/
#ifdef CONFIG_KASAN
-#define KASAN_SHADOW_SIZE (UL(1) << (VA_BITS - 3))
#define KASAN_THREAD_SHIFT 1
+#define KASAN_SHADOW_OFFSET _AC(CONFIG_KASAN_SHADOW_OFFSET, UL)
+#define KASAN_SHADOW_END ((UL(1) << 61) + KASAN_SHADOW_OFFSET)
#else
-#define KASAN_SHADOW_SIZE (0)
#define KASAN_THREAD_SHIFT 0
+#define KASAN_SHADOW_END (VA_START)
#endif
#define MIN_THREAD_SHIFT (14 + KASAN_THREAD_SHIFT)
diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c
index 5aef679e61c6..968535789d13 100644
--- a/arch/arm64/mm/kasan_init.c
+++ b/arch/arm64/mm/kasan_init.c
@@ -135,7 +135,6 @@ static void __init kasan_pgd_populate(unsigned long addr, unsigned long end,
/* The early shadow maps everything to a single page of zeroes */
asmlinkage void __init kasan_early_init(void)
{
- BUILD_BUG_ON(KASAN_SHADOW_OFFSET != KASAN_SHADOW_END - (1UL << 61));
BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_START, PGDIR_SIZE));
BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_END, PGDIR_SIZE));
kasan_pgd_populate(KASAN_SHADOW_START, KASAN_SHADOW_END, NUMA_NO_NODE,
--
2.11.0
^ permalink raw reply related
* [PATCH V2 4/7] arm64: mm: Replace fixed map BUILD_BUG_ON's with BUG_ON's
From: Steve Capper @ 2017-12-18 21:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171218214736.13761-1-steve.capper@arm.com>
In order to prepare for a variable VA_BITS we need to account for a
variable size VMEMMAP which in turn means the position of the fixed map
is variable at compile time.
Thus, we need to replace the BUILD_BUG_ON's that check the fixed map
position with BUG_ON's.
Signed-off-by: Steve Capper <steve.capper@arm.com>
---
arch/arm64/mm/mmu.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 5a16e2b9b1a2..7c04479a809a 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -760,7 +760,7 @@ void __init early_fixmap_init(void)
* The boot-ioremap range spans multiple pmds, for which
* we are not prepared:
*/
- BUILD_BUG_ON((__fix_to_virt(FIX_BTMAP_BEGIN) >> PMD_SHIFT)
+ BUG_ON((__fix_to_virt(FIX_BTMAP_BEGIN) >> PMD_SHIFT)
!= (__fix_to_virt(FIX_BTMAP_END) >> PMD_SHIFT));
if ((pmd != fixmap_pmd(fix_to_virt(FIX_BTMAP_BEGIN)))
@@ -828,9 +828,9 @@ void *__init __fixmap_remap_fdt(phys_addr_t dt_phys, int *size, pgprot_t prot)
* On 4k pages, we'll use section mappings for the FDT so we only
* have to be in the same PUD.
*/
- BUILD_BUG_ON(dt_virt_base % SZ_2M);
+ BUG_ON(dt_virt_base % SZ_2M);
- BUILD_BUG_ON(__fix_to_virt(FIX_FDT_END) >> SWAPPER_TABLE_SHIFT !=
+ BUG_ON(__fix_to_virt(FIX_FDT_END) >> SWAPPER_TABLE_SHIFT !=
__fix_to_virt(FIX_BTMAP_BEGIN) >> SWAPPER_TABLE_SHIFT);
offset = dt_phys % SWAPPER_BLOCK_SIZE;
--
2.11.0
^ permalink raw reply related
* [PATCH V2 5/7] arm64: dump: Make kernel page table dumper dynamic again
From: Steve Capper @ 2017-12-18 21:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171218214736.13761-1-steve.capper@arm.com>
The kernel page table dumper assumes that the placement of VA regions is
constant and determined at compile time. As we are about to introduce
variable VA logic, we need to be able to determine certain regions at
boot time.
This patch adds logic to the kernel page table dumper s.t. these regions
can be computed at boot time.
Signed-off-by: Steve Capper <steve.capper@arm.com>
---
arch/arm64/mm/dump.c | 58 ++++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 47 insertions(+), 11 deletions(-)
diff --git a/arch/arm64/mm/dump.c b/arch/arm64/mm/dump.c
index d1814b247d4b..4a3e71046cb2 100644
--- a/arch/arm64/mm/dump.c
+++ b/arch/arm64/mm/dump.c
@@ -29,23 +29,45 @@
#include <asm/pgtable-hwdef.h>
#include <asm/ptdump.h>
-static const struct addr_marker address_markers[] = {
- { PAGE_OFFSET, "Linear Mapping start" },
- { VA_START, "Linear Mapping end" },
+
+enum address_markers_idx {
+ PAGE_OFFSET_NR = 0,
+ VA_START_NR,
+#ifdef CONFIG_KASAN
+ KASAN_START_NR,
+ KASAN_END_NR,
+#endif
+ MODULES_START_NR,
+ MODULES_END_NR,
+ VMALLOC_START_NR,
+ VMALLOC_END_NR,
+ FIXADDR_START_NR,
+ FIXADDR_END_NR,
+ PCI_START_NR,
+ PCI_END_NR,
+#ifdef CONFIG_SPARSEMEM_VMEMMAP
+ VMEMMAP_START_NR,
+#endif
+ END_NR
+};
+
+static struct addr_marker address_markers[] = {
+ { 0 /* PAGE_OFFSET */, "Linear Mapping start" },
+ { 0 /* VA_START */, "Linear Mapping end" },
#ifdef CONFIG_KASAN
- { KASAN_SHADOW_START, "Kasan shadow start" },
+ { 0 /* KASAN_SHADOW_START */, "Kasan shadow start" },
{ KASAN_SHADOW_END, "Kasan shadow end" },
#endif
{ MODULES_VADDR, "Modules start" },
{ MODULES_END, "Modules end" },
{ VMALLOC_START, "vmalloc() Area" },
- { VMALLOC_END, "vmalloc() End" },
- { FIXADDR_START, "Fixmap start" },
- { FIXADDR_TOP, "Fixmap end" },
- { PCI_IO_START, "PCI I/O start" },
- { PCI_IO_END, "PCI I/O end" },
+ { 0 /* VMALLOC_END */, "vmalloc() End" },
+ { 0 /* FIXADDR_START */, "Fixmap start" },
+ { 0 /* FIXADDR_TOP */, "Fixmap end" },
+ { 0 /* PCI_IO_START */, "PCI I/O start" },
+ { 0 /* PCI_IO_END */, "PCI I/O end" },
#ifdef CONFIG_SPARSEMEM_VMEMMAP
- { VMEMMAP_START, "vmemmap" },
+ { 0 /* VMEMMAP_START */, "vmemmap" },
#endif
{ -1, NULL },
};
@@ -375,7 +397,6 @@ static void ptdump_initialize(void)
static struct ptdump_info kernel_ptdump_info = {
.mm = &init_mm,
.markers = address_markers,
- .base_addr = PAGE_OFFSET,
};
void ptdump_check_wx(void)
@@ -401,6 +422,21 @@ void ptdump_check_wx(void)
static int ptdump_init(void)
{
ptdump_initialize();
+ kernel_ptdump_info.base_addr = PAGE_OFFSET;
+ address_markers[PAGE_OFFSET_NR].start_address = PAGE_OFFSET;
+ address_markers[VA_START_NR].start_address = VA_START;
+#ifdef CONFIG_KASAN
+ address_markers[KASAN_START_NR].start_address = KASAN_SHADOW_START;
+#endif
+ address_markers[VMALLOC_END_NR].start_address = VMALLOC_END;
+ address_markers[FIXADDR_START_NR].start_address = FIXADDR_START;
+ address_markers[FIXADDR_END_NR].start_address = FIXADDR_TOP;
+ address_markers[PCI_START_NR].start_address = PCI_IO_START;
+ address_markers[PCI_END_NR].start_address = PCI_IO_END;
+#ifdef CONFIG_SPARSEMEM_VMEMMAP
+ address_markers[VMEMMAP_START_NR].start_address = VMEMMAP_START;
+#endif
+
return ptdump_debugfs_register(&kernel_ptdump_info,
"kernel_page_tables");
}
--
2.11.0
^ permalink raw reply related
* [PATCH V2 6/7] arm64: mm: Make VA_BITS variable, introduce VA_BITS_MIN
From: Steve Capper @ 2017-12-18 21:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171218214736.13761-1-steve.capper@arm.com>
In order to allow the kernel to select different virtual address sizes
on boot we need to "de-constify" VA_BITS. This patch introduces
vabits_actual, a variable which is defined at very early boot, and
VA_BITS is then re-defined to reference this variable.
Having VA_BITS variable can potentially break a lot of code that makes
compile time deductions from it. To prevent future code changes being
made that break variable VA, this patch enforces VA_BITS to be variable
always (i.e. no CONFIG options will change this).
A new constant, VA_BITS_MIN is defined, that gives the minimum address
space size the kernel is compiled for. This is used for example in the
EFI stub code to choose the furthest addressable distance for the
initrd to be placed. Increasing the VA space size on bootup does not
invalidate this logic.
Also, VA_BITS_MIN is now used to detect whether or not additional page
table levels are required for the idmap. We used to check for
#ifdef CONFIG_ARM64_VA_BITS_48
which does not work when moving up to 52-bits.
Signed-off-by: Steve Capper <steve.capper@arm.com>
---
arch/arm64/Kconfig | 4 ++++
arch/arm64/include/asm/assembler.h | 2 +-
arch/arm64/include/asm/efi.h | 4 ++--
arch/arm64/include/asm/memory.h | 21 +++++++++++++--------
arch/arm64/include/asm/mmu_context.h | 2 +-
arch/arm64/include/asm/pgtable.h | 4 ++--
arch/arm64/include/asm/processor.h | 2 +-
arch/arm64/kernel/head.S | 13 ++++++++-----
arch/arm64/kernel/kaslr.c | 4 ++--
arch/arm64/kvm/hyp-init.S | 2 +-
arch/arm64/mm/fault.c | 2 +-
arch/arm64/mm/init.c | 5 +++++
arch/arm64/mm/kasan_init.c | 9 ++++++---
arch/arm64/mm/mmu.c | 5 ++++-
arch/arm64/mm/proc.S | 29 ++++++++++++++++++++++++++++-
15 files changed, 79 insertions(+), 29 deletions(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index dc7e54522fa1..5a42edc18718 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -666,6 +666,10 @@ config ARM64_VA_BITS
default 47 if ARM64_VA_BITS_47
default 48 if ARM64_VA_BITS_48
+config ARM64_VA_BITS_ALT
+ bool
+ default n
+
config CPU_BIG_ENDIAN
bool "Build big-endian kernel"
help
diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index 8b168280976f..4128664df6ab 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -344,7 +344,7 @@ alternative_endif
* tcr_set_idmap_t0sz - update TCR.T0SZ so that we can load the ID map
*/
.macro tcr_set_idmap_t0sz, valreg, tmpreg
-#ifndef CONFIG_ARM64_VA_BITS_48
+#if VA_BITS_MIN < 48
ldr_l \tmpreg, idmap_t0sz
bfi \valreg, \tmpreg, #TCR_T0SZ_OFFSET, #TCR_TxSZ_WIDTH
#endif
diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h
index c4cd5081d78b..ea5a0a5f521b 100644
--- a/arch/arm64/include/asm/efi.h
+++ b/arch/arm64/include/asm/efi.h
@@ -66,7 +66,7 @@ static inline unsigned long efi_get_max_fdt_addr(unsigned long dram_base)
/*
* On arm64, we have to ensure that the initrd ends up in the linear region,
- * which is a 1 GB aligned region of size '1UL << (VA_BITS - 1)' that is
+ * which is a 1 GB aligned region of size '1UL << (VA_BITS_MIN - 1)' that is
* guaranteed to cover the kernel Image.
*
* Since the EFI stub is part of the kernel Image, we can relax the
@@ -77,7 +77,7 @@ static inline unsigned long efi_get_max_fdt_addr(unsigned long dram_base)
static inline unsigned long efi_get_max_initrd_addr(unsigned long dram_base,
unsigned long image_addr)
{
- return (image_addr & ~(SZ_1G - 1UL)) + (1UL << (VA_BITS - 1));
+ return (image_addr & ~(SZ_1G - 1UL)) + (1UL << (VA_BITS_MIN - 1));
}
#define efi_call_early(f, ...) sys_table_arg->boottime->f(__VA_ARGS__)
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index c52b90cdc583..2c11df336109 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -62,11 +62,6 @@
* VA_BITS - the maximum number of bits for virtual addresses.
* VA_START - the first kernel virtual address.
*/
-#define VA_BITS (CONFIG_ARM64_VA_BITS)
-#define VA_START (UL(0xffffffffffffffff) - \
- (UL(1) << (VA_BITS - 1)) + 1)
-#define PAGE_OFFSET (UL(0xffffffffffffffff) - \
- (UL(1) << VA_BITS) + 1)
#define PAGE_OFFSET_END (VA_START)
#define KIMAGE_VADDR (MODULES_END)
#define MODULES_END (MODULES_VADDR + MODULES_VSIZE)
@@ -76,6 +71,9 @@
#define PCI_IO_END (VMEMMAP_START - SZ_2M)
#define PCI_IO_START (PCI_IO_END - PCI_IO_SIZE)
#define FIXADDR_TOP (PCI_IO_START - SZ_2M)
+#define VA_BITS_MIN (CONFIG_ARM64_VA_BITS)
+#define _VA_START(va) (UL(0xffffffffffffffff) - \
+ (UL(1) << ((va) - 1)) + 1)
#define KERNEL_START _text
#define KERNEL_END _end
@@ -91,7 +89,7 @@
#define KASAN_SHADOW_END ((UL(1) << 61) + KASAN_SHADOW_OFFSET)
#else
#define KASAN_THREAD_SHIFT 0
-#define KASAN_SHADOW_END (VA_START)
+#define KASAN_SHADOW_END (_VA_START(VA_BITS_MIN))
#endif
#define MIN_THREAD_SHIFT (14 + KASAN_THREAD_SHIFT)
@@ -177,10 +175,17 @@
#endif
#ifndef __ASSEMBLY__
+extern u64 vabits_actual;
+#define VA_BITS ({vabits_actual;})
+#define VA_START (_VA_START(VA_BITS))
+#define PAGE_OFFSET (UL(0xffffffffffffffff) - \
+ (UL(1) << VA_BITS) + 1)
+#define PAGE_OFFSET_END (VA_START)
#include <linux/bitops.h>
#include <linux/mmdebug.h>
+extern s64 physvirt_offset;
extern s64 memstart_addr;
/* PHYS_OFFSET - the physical address of the start of memory. */
#define PHYS_OFFSET ({ VM_BUG_ON(memstart_addr & 1); memstart_addr; })
@@ -226,7 +231,7 @@ static inline unsigned long kaslr_offset(void)
*/
#define __is_lm_address(addr) (!((addr) & BIT(VA_BITS - 1)))
-#define __lm_to_phys(addr) (((addr) & ~PAGE_OFFSET) + PHYS_OFFSET)
+#define __lm_to_phys(addr) (((addr) + physvirt_offset))
#define __kimg_to_phys(addr) ((addr) - kimage_voffset)
#define __virt_to_phys_nodebug(x) ({ \
@@ -245,7 +250,7 @@ extern phys_addr_t __phys_addr_symbol(unsigned long x);
#define __phys_addr_symbol(x) __pa_symbol_nodebug(x)
#endif
-#define __phys_to_virt(x) ((unsigned long)((x) - PHYS_OFFSET) | PAGE_OFFSET)
+#define __phys_to_virt(x) ((unsigned long)((x) - physvirt_offset))
#define __phys_to_kimg(x) ((unsigned long)((x) + kimage_voffset))
/*
diff --git a/arch/arm64/include/asm/mmu_context.h b/arch/arm64/include/asm/mmu_context.h
index 9d155fa9a507..c2faa8895a78 100644
--- a/arch/arm64/include/asm/mmu_context.h
+++ b/arch/arm64/include/asm/mmu_context.h
@@ -66,7 +66,7 @@ extern u64 idmap_t0sz;
static inline bool __cpu_uses_extended_idmap(void)
{
- return (!IS_ENABLED(CONFIG_ARM64_VA_BITS_48) &&
+ return ((VA_BITS_MIN < 48) &&
unlikely(idmap_t0sz != TCR_T0SZ(VA_BITS)));
}
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 63ea76cc8357..3c5a10e1954f 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -681,8 +681,8 @@ static inline void pmdp_set_wrprotect(struct mm_struct *mm,
}
#endif
-extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
-extern pgd_t idmap_pg_dir[PTRS_PER_PGD];
+extern pgd_t swapper_pg_dir[];
+extern pgd_t idmap_pg_dir[];
extern pgd_t swapper_pg_end[];
/*
* Encode and decode a swap entry:
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 023cacb946c3..aa294d1ddea8 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -19,7 +19,7 @@
#ifndef __ASM_PROCESSOR_H
#define __ASM_PROCESSOR_H
-#define TASK_SIZE_64 (UL(1) << VA_BITS)
+#define TASK_SIZE_64 (UL(1) << VA_BITS_MIN)
#ifndef __ASSEMBLY__
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 7039c8a8b239..83e73bd59a76 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -119,6 +119,7 @@ ENTRY(stext)
adrp x23, __PHYS_OFFSET
and x23, x23, MIN_KIMG_ALIGN - 1 // KASLR offset, defaults to 0
bl set_cpu_boot_mode_flag
+ bl __setup_va_constants
bl __create_page_tables
/*
* The following calls CPU setup code, see arch/arm64/mm/proc.S for
@@ -250,7 +251,9 @@ ENDPROC(preserve_boot_args)
add \rtbl, \tbl, #PAGE_SIZE
mov \sv, \rtbl
mov \count, #1
- compute_indices \vstart, \vend, #PGDIR_SHIFT, #PTRS_PER_PGD, \istart, \iend, \count
+
+ ldr_l \tmp, ptrs_per_pgd
+ compute_indices \vstart, \vend, #PGDIR_SHIFT, \tmp, \istart, \iend, \count
populate_entries \tbl, \rtbl, \istart, \iend, #PMD_TYPE_TABLE, #PAGE_SIZE, \tmp
mov \tbl, \sv
mov \sv, \rtbl
@@ -314,7 +317,7 @@ __create_page_tables:
adrp x3, __idmap_text_start // __pa(__idmap_text_start)
adrp x4, __idmap_text_end // __pa(__idmap_text_end)
-#ifndef CONFIG_ARM64_VA_BITS_48
+#if (VA_BITS_MIN < 48)
#define EXTRA_SHIFT (PGDIR_SHIFT + PAGE_SHIFT - 3)
#define EXTRA_PTRS (1 << (48 - EXTRA_SHIFT))
@@ -329,7 +332,7 @@ __create_page_tables:
* utilised, and that lowering T0SZ will always result in an additional
* translation level to be configured.
*/
-#if VA_BITS != EXTRA_SHIFT
+#if VA_BITS_MIN != EXTRA_SHIFT
#error "Mismatch between VA_BITS and page size/number of translation levels"
#endif
@@ -340,8 +343,8 @@ __create_page_tables:
* the physical address of __idmap_text_end.
*/
clz x5, x4
- cmp x5, TCR_T0SZ(VA_BITS) // default T0SZ small enough?
- b.ge 1f // .. then skip additional level
+ cmp x5, TCR_T0SZ(VA_BITS_MIN) // default T0SZ small enough?
+ b.ge 1f // .. then skip additional level
adr_l x6, idmap_t0sz
str x5, [x6]
diff --git a/arch/arm64/kernel/kaslr.c b/arch/arm64/kernel/kaslr.c
index 47080c49cc7e..b6a9bd2f4bfb 100644
--- a/arch/arm64/kernel/kaslr.c
+++ b/arch/arm64/kernel/kaslr.c
@@ -117,12 +117,12 @@ u64 __init kaslr_early_init(u64 dt_phys)
/*
* OK, so we are proceeding with KASLR enabled. Calculate a suitable
* kernel image offset from the seed. Let's place the kernel in the
- * lower half of the VMALLOC area (VA_BITS - 2).
+ * lower half of the VMALLOC area (VA_BITS_MIN - 2).
* Even if we could randomize@page granularity for 16k and 64k pages,
* let's always round to 2 MB so we don't interfere with the ability to
* map using contiguous PTEs
*/
- mask = ((1UL << (VA_BITS - 2)) - 1) & ~(SZ_2M - 1);
+ mask = ((1UL << (VA_BITS_MIN - 2)) - 1) & ~(SZ_2M - 1);
offset = seed & mask;
/* use the top 16 bits to randomize the linear region */
diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S
index 870828c364c5..68f84da225b5 100644
--- a/arch/arm64/kvm/hyp-init.S
+++ b/arch/arm64/kvm/hyp-init.S
@@ -71,7 +71,7 @@ __do_hyp_init:
mov x5, #TCR_EL2_RES1
orr x4, x4, x5
-#ifndef CONFIG_ARM64_VA_BITS_48
+#if VA_BITS_MIN < 48
/*
* If we are running with VA_BITS < 48, we may be running with an extra
* level of translation in the ID map. This is only the case if system
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 9b7f89df49db..1f6cfa37b2d2 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -149,7 +149,7 @@ void show_pte(unsigned long addr)
return;
}
- pr_alert("%s pgtable: %luk pages, %u-bit VAs, pgd = %p\n",
+ pr_alert("%s pgtable: %luk pages, %llu-bit VAs, pgd = %p\n",
mm == &init_mm ? "swapper" : "user", PAGE_SIZE / SZ_1K,
VA_BITS, mm->pgd);
pgd = pgd_offset(mm, addr);
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 0a5da98f92fa..105ceedf7d52 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -62,6 +62,9 @@
s64 memstart_addr __ro_after_init = -1;
phys_addr_t arm64_dma_phys_limit __ro_after_init;
+s64 physvirt_offset __ro_after_init = -1;
+EXPORT_SYMBOL(physvirt_offset);
+
#ifdef CONFIG_BLK_DEV_INITRD
static int __init early_initrd(char *p)
{
@@ -372,6 +375,8 @@ void __init arm64_memblock_init(void)
memstart_addr = round_down(memblock_start_of_DRAM(),
ARM64_MEMSTART_ALIGN);
+ physvirt_offset = PHYS_OFFSET - PAGE_OFFSET;
+
/*
* Remove the memory that we will not be able to cover with the
* linear mapping. Take care not to clip the kernel which may be
diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c
index 968535789d13..38c933c17f82 100644
--- a/arch/arm64/mm/kasan_init.c
+++ b/arch/arm64/mm/kasan_init.c
@@ -27,7 +27,7 @@
#include <asm/sections.h>
#include <asm/tlbflush.h>
-static pgd_t tmp_pg_dir[PTRS_PER_PGD] __initdata __aligned(PGD_SIZE);
+static pgd_t tmp_pg_dir[PAGE_SIZE] __initdata __aligned(PAGE_SIZE);
/*
* The p*d_populate functions call virt_to_phys implicitly so they can't be used
@@ -135,7 +135,10 @@ static void __init kasan_pgd_populate(unsigned long addr, unsigned long end,
/* The early shadow maps everything to a single page of zeroes */
asmlinkage void __init kasan_early_init(void)
{
- BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_START, PGDIR_SIZE));
+#ifdef CONFIG_ARM64_VA_BITS_ALT
+ BUILD_BUG_ON(!IS_ALIGNED(_KASAN_SHADOW_START(VA_BITS_ALT), PGDIR_SIZE));
+#endif
+ BUILD_BUG_ON(!IS_ALIGNED(_KASAN_SHADOW_START(VA_BITS_MIN), PGDIR_SIZE));
BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_END, PGDIR_SIZE));
kasan_pgd_populate(KASAN_SHADOW_START, KASAN_SHADOW_END, NUMA_NO_NODE,
true);
@@ -195,7 +198,7 @@ void __init kasan_init(void)
* tmp_pg_dir used to keep early shadow mapped until full shadow
* setup will be finished.
*/
- memcpy(tmp_pg_dir, swapper_pg_dir, sizeof(tmp_pg_dir));
+ memcpy(tmp_pg_dir, swapper_pg_dir, PTRS_PER_PGD * sizeof(pgd_t));
dsb(ishst);
cpu_replace_ttbr1(lm_alias(tmp_pg_dir));
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 7c04479a809a..9aa261aa7968 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -49,7 +49,10 @@
#define NO_BLOCK_MAPPINGS BIT(0)
#define NO_CONT_MAPPINGS BIT(1)
-u64 idmap_t0sz = TCR_T0SZ(VA_BITS);
+u64 idmap_t0sz __ro_after_init;
+u64 ptrs_per_pgd __ro_after_init;
+u64 vabits_actual __ro_after_init;
+EXPORT_SYMBOL(vabits_actual);
u64 kimage_voffset __ro_after_init;
EXPORT_SYMBOL(kimage_voffset);
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 95233dfc4c39..16564324c957 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -223,8 +223,16 @@ ENTRY(__cpu_setup)
* Set/prepare TCR and TTBR. We use 512GB (39-bit) address range for
* both user and kernel.
*/
- ldr x10, =TCR_TxSZ(VA_BITS) | TCR_CACHE_FLAGS | TCR_SMP_FLAGS | \
+ ldr x10, =TCR_TxSZ(VA_BITS_MIN) | TCR_CACHE_FLAGS | TCR_SMP_FLAGS | \
TCR_TG_FLAGS | TCR_ASID16 | TCR_TBI0
+#ifdef CONFIG_ARM64_VA_BITS_ALT
+ ldr_l x9, vabits_actual
+ cmp x9, #VA_BITS_ALT
+ b.ne 1f
+ ldr x10, =TCR_TxSZ(VA_BITS_ALT) | TCR_CACHE_FLAGS | TCR_SMP_FLAGS | \
+ TCR_TG_FLAGS | TCR_ASID16 | TCR_TBI0
+1:
+#endif
tcr_set_idmap_t0sz x10, x9
/*
@@ -250,6 +258,25 @@ ENTRY(__cpu_setup)
ret // return to head.S
ENDPROC(__cpu_setup)
+ENTRY(__setup_va_constants)
+ mov x0, #VA_BITS_MIN
+ mov x1, TCR_T0SZ(VA_BITS_MIN)
+ mov x2, #1 << (VA_BITS_MIN - PGDIR_SHIFT)
+ str_l x0, vabits_actual, x5
+ str_l x1, idmap_t0sz, x5
+ str_l x2, ptrs_per_pgd, x5
+
+ adr_l x0, vabits_actual
+ adr_l x1, idmap_t0sz
+ adr_l x2, ptrs_per_pgd
+ dmb sy
+ dc ivac, x0 // Invalidate potentially stale cache
+ dc ivac, x1
+ dc ivac, x2
+
+ ret
+ENDPROC(__setup_va_constants)
+
/*
* We set the desired value explicitly, including those of the
* reserved bits. The values of bits EE & E0E were set early in
--
2.11.0
^ permalink raw reply related
* [PATCH V2 7/7] arm64: mm: Add 48/52-bit kernel VA support
From: Steve Capper @ 2017-12-18 21:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171218214736.13761-1-steve.capper@arm.com>
Add the option to use 52-bit VA support upon availability at boot. We
use the same KASAN_SHADOW_OFFSET for both 48 and 52 bit VA spaces as in
both cases the start and end of the KASAN shadow region are PGD aligned.
>From ID_AA64MMFR2, we check the LVA field on very early boot and set the
VA size, PGDIR_SHIFT and TCR.T[01]SZ values which then influence how the
rest of the memory system behaves.
Note that userspace addresses will still be capped out at 48-bit. More
patches are needed to deal with scenarios where the user provides
MMAP_FIXED hint and a high address to mmap.
Signed-off-by: Steve Capper <steve.capper@arm.com>
---
arch/arm64/Kconfig | 8 ++++++++
arch/arm64/include/asm/memory.h | 4 ++++
arch/arm64/mm/proc.S | 13 +++++++++++++
3 files changed, 25 insertions(+)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 5a42edc18718..3fa5342849dc 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -262,6 +262,7 @@ config PGTABLE_LEVELS
default 2 if ARM64_16K_PAGES && ARM64_VA_BITS_36
default 2 if ARM64_64K_PAGES && ARM64_VA_BITS_42
default 3 if ARM64_64K_PAGES && ARM64_VA_BITS_48
+ default 3 if ARM64_64K_PAGES && ARM64_VA_BITS_48_52
default 3 if ARM64_4K_PAGES && ARM64_VA_BITS_39
default 3 if ARM64_16K_PAGES && ARM64_VA_BITS_47
default 4 if !ARM64_64K_PAGES && ARM64_VA_BITS_48
@@ -275,6 +276,7 @@ config ARCH_PROC_KCORE_TEXT
config KASAN_SHADOW_OFFSET
hex
depends on KASAN
+ default 0xdfffa00000000000 if ARM64_VA_BITS_48_52
default 0xdfffa00000000000 if ARM64_VA_BITS_48
default 0xdfffd00000000000 if ARM64_VA_BITS_47
default 0xdffffe8000000000 if ARM64_VA_BITS_42
@@ -656,6 +658,10 @@ config ARM64_VA_BITS_47
config ARM64_VA_BITS_48
bool "48-bit"
+config ARM64_VA_BITS_48_52
+ bool "48 or 52-bit (decided at boot time)"
+ depends on ARM64_64K_PAGES
+
endchoice
config ARM64_VA_BITS
@@ -665,9 +671,11 @@ config ARM64_VA_BITS
default 42 if ARM64_VA_BITS_42
default 47 if ARM64_VA_BITS_47
default 48 if ARM64_VA_BITS_48
+ default 48 if ARM64_VA_BITS_48_52
config ARM64_VA_BITS_ALT
bool
+ default y if ARM64_VA_BITS_48_52
default n
config CPU_BIG_ENDIAN
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index 2c11df336109..417b70bb50be 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -75,6 +75,10 @@
#define _VA_START(va) (UL(0xffffffffffffffff) - \
(UL(1) << ((va) - 1)) + 1)
+#ifdef CONFIG_ARM64_VA_BITS_48_52
+#define VA_BITS_ALT (52)
+#endif
+
#define KERNEL_START _text
#define KERNEL_END _end
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 16564324c957..42a91a4a1126 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -259,9 +259,22 @@ ENTRY(__cpu_setup)
ENDPROC(__cpu_setup)
ENTRY(__setup_va_constants)
+#ifdef CONFIG_ARM64_VA_BITS_48_52
+ mrs_s x5, SYS_ID_AA64MMFR2_EL1
+ and x5, x5, #0xf << ID_AA64MMFR2_LVA_SHIFT
+ cmp x5, #1 << ID_AA64MMFR2_LVA_SHIFT
+ b.ne 1f
+ mov x0, #VA_BITS_ALT
+ mov x1, TCR_T0SZ(VA_BITS_ALT)
+ mov x2, #1 << (VA_BITS_ALT - PGDIR_SHIFT)
+ b 2f
+#endif
+
+1:
mov x0, #VA_BITS_MIN
mov x1, TCR_T0SZ(VA_BITS_MIN)
mov x2, #1 << (VA_BITS_MIN - PGDIR_SHIFT)
+2:
str_l x0, vabits_actual, x5
str_l x1, idmap_t0sz, x5
str_l x2, ptrs_per_pgd, x5
--
2.11.0
^ permalink raw reply related
* [PATCH 0/2] ARM: dts: r8a7745: move timer node nodes out of bus
From: Simon Horman @ 2017-12-18 21:50 UTC (permalink / raw)
To: linux-arm-kernel
Move the timer node, which have no reg property, out of the root node.
The nodes that have been moved do not have any register properties and thus
shouldn't be placed on the bus.
In preparation for the above sort nodes in the root node alphabetically.
Based on renesas-devel-20171218-v4.15-rc4
Simon Horman (2):
ARM: dts: r8a7745: sort root sub-nodes alphabetically
ARM: dts: r8a7745: move timer node out of bus
arch/arm/boot/dts/r8a7745.dtsi | 64 ++++++++++++++++++++----------------------
1 file changed, 30 insertions(+), 34 deletions(-)
--
2.11.0
^ permalink raw reply
* [PATCH 1/2] ARM: dts: r8a7745: sort root sub-nodes alphabetically
From: Simon Horman @ 2017-12-18 21:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171218215044.13088-1-horms+renesas@verge.net.au>
Sort root sub-nodes alphabetically for allow for easier maintenance
of this file.
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
arch/arm/boot/dts/r8a7745.dtsi | 48 +++++++++++++++++++++---------------------
1 file changed, 24 insertions(+), 24 deletions(-)
diff --git a/arch/arm/boot/dts/r8a7745.dtsi b/arch/arm/boot/dts/r8a7745.dtsi
index 0fa78612746f..65d92076bdde 100644
--- a/arch/arm/boot/dts/r8a7745.dtsi
+++ b/arch/arm/boot/dts/r8a7745.dtsi
@@ -35,6 +35,14 @@
vin1 = &vin1;
};
+ /* External CAN clock */
+ can_clk: can {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ /* This value must be overridden by the board. */
+ clock-frequency = <0>;
+ };
+
cpus {
#address-cells = <1>;
#size-cells = <0>;
@@ -67,6 +75,22 @@
};
};
+ /* External root clock */
+ extal_clk: extal {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ /* This value must be overridden by the board. */
+ clock-frequency = <0>;
+ };
+
+ /* External SCIF clock */
+ scif_clk: scif {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ /* This value must be overridden by the board. */
+ clock-frequency = <0>;
+ };
+
soc {
compatible = "simple-bus";
interrupt-parent = <&gic>;
@@ -1119,34 +1143,10 @@
};
};
- /* External root clock */
- extal_clk: extal {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- /* This value must be overridden by the board. */
- clock-frequency = <0>;
- };
-
/* External USB clock - can be overridden by the board */
usb_extal_clk: usb_extal {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <48000000>;
};
-
- /* External CAN clock */
- can_clk: can {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- /* This value must be overridden by the board. */
- clock-frequency = <0>;
- };
-
- /* External SCIF clock */
- scif_clk: scif {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- /* This value must be overridden by the board. */
- clock-frequency = <0>;
- };
};
--
2.11.0
^ permalink raw reply related
* [PATCH 2/2] ARM: dts: r8a7745: move timer node out of bus
From: Simon Horman @ 2017-12-18 21:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171218215044.13088-1-horms+renesas@verge.net.au>
The timer node does not have any register properties and thus shouldn't be
placed on the bus.
This problem is flagged by the compiler as follows:
$ make dtbs W=1
...
arch/arm/boot/dts/r8a7745-iwg22d-sodimm.dtb: Warning (simple_bus_reg): Node /soc/timer missing or empty reg/ranges property
arch/arm/boot/dts/r8a7745-iwg22d-sodimm-dbhd-ca.dtb: Warning (simple_bus_reg): Node /soc/timer missing or empty reg/ranges property
DTC arch/arm/boot/dts/r8a7745-sk-rzg1e.dtb
arch/arm/boot/dts/r8a7745-sk-rzg1e.dtb: Warning (simple_bus_reg): Node /soc/timer missing or empty reg/ranges property
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
arch/arm/boot/dts/r8a7745.dtsi | 20 ++++++++------------
1 file changed, 8 insertions(+), 12 deletions(-)
diff --git a/arch/arm/boot/dts/r8a7745.dtsi b/arch/arm/boot/dts/r8a7745.dtsi
index 65d92076bdde..612de9eeb7e2 100644
--- a/arch/arm/boot/dts/r8a7745.dtsi
+++ b/arch/arm/boot/dts/r8a7745.dtsi
@@ -247,18 +247,6 @@
resets = <&cpg 407>;
};
- timer {
- compatible = "arm,armv7-timer";
- interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) |
- IRQ_TYPE_LEVEL_LOW)>,
- <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) |
- IRQ_TYPE_LEVEL_LOW)>,
- <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) |
- IRQ_TYPE_LEVEL_LOW)>,
- <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) |
- IRQ_TYPE_LEVEL_LOW)>;
- };
-
cpg: clock-controller at e6150000 {
compatible = "renesas,r8a7745-cpg-mssr";
reg = <0 0xe6150000 0 0x1000>;
@@ -1143,6 +1131,14 @@
};
};
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupts-extended = <&gic GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <&gic GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <&gic GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <&gic GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+ };
+
/* External USB clock - can be overridden by the board */
usb_extal_clk: usb_extal {
compatible = "fixed-clock";
--
2.11.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox