* [PATCH 2/4] pid: Export find_task_by_vpid for use in external modules
From: Russell King - ARM Linux @ 2018-05-10 19:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CANLsYkwaNmZCUjwJXK0X1ia+RnzumfbpB8EvZJ-HDtOHj8rafQ@mail.gmail.com>
On Thu, May 10, 2018 at 01:39:18PM -0600, Mathieu Poirier wrote:
> Hi Russell,
>
> On 10 May 2018 at 02:40, Russell King - ARM Linux <linux@armlinux.org.uk> wrote:
> > This does not leak information from other namespaces because of the
> > uniqueness of the global PID. However, what it does leak is the value
> > of the global PID which is meaningless in the namespace. So, before
> > the event stream is delivered to userspace, this value needs to be
> > re-written to the namespace's PID value.
>
> Unfortunately that can't be done. The trace stream is compressed and
> needs to be decompressed using an external library. I think the only
> option is to return an error if a user is trying to use this feature
> from a namespace.
That sounds like a sensible approach, and that should get rid of the
vpid stuff too.
Eric, would this solve all your concerns?
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 8.8Mbps down 630kbps up
According to speedtest.net: 8.21Mbps down 510kbps up
^ permalink raw reply
* [PATCH 2/4] pid: Export find_task_by_vpid for use in external modules
From: Mathieu Poirier @ 2018-05-10 19:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180510084057.GT16141@n2100.armlinux.org.uk>
On 10 May 2018 at 02:40, Russell King - ARM Linux <linux@armlinux.org.uk> wrote:
> On Wed, May 09, 2018 at 09:35:07PM -0500, Eric W. Biederman wrote:
>> Mathieu Poirier <mathieu.poirier@linaro.org> writes:
>>
>> > On Tue, May 08, 2018 at 11:59:38PM -0500, Eric W. Biederman wrote:
>> >> Kim Phillips <kim.phillips@arm.com> writes:
>> >>
>> >> > This patch is in the context of allowing the Coresight h/w
>> >> > trace driver suite to be loaded as modules. Coresight uses
>> >> > find_task_by_vpid when running in direct capture mode (via sysfs)
>> >> > when getting/setting the context ID comparator to trigger on
>> >> > (/sys/bus/coresight/devices/<x>.etm/ctxid_pid).
>> >>
>> >> Aside from my objection about how bad an interface a pid in sysfs is.
>> >> The implementation of coresight_vpid_to_pid is horrible.
>> >>
>> >> The code should be just:
>> >>
>> >> static inline pid_t coresight_vpid_to_pid(pid_t vpid)
>> >> {
>> >> rcu_read_lock();
>> >> pid = pid_nr(find_vpid(vpid));
>> >> rcu_read_unlock();
>> >>
>> >> return pid;
>> >> }
>> >> Which takes find_task_by_vpid out of the picture.
>> >
>> > Many thanks for pointing out the right way to do this. When Chunyan added
>> > this feature she broadly published her work and find_task_by_vpid() is the
>> > function she was asked to used.
>>
>> Clearly no one was thinking through the implications of a sysfs file
>> which does not have pid namespace support on namespacing. I am quite
>> upset at this mess of an API. It is not a maintainable way to do things.
>>
>> >> But reading further I am seeing code writing a pid to hardware. That is
>> >> broken. That is a layering violation of the first order. Giving
>> >> implementation details like that to hardware.
>> >
>> > This is how the feature works - as Robin pointed out tracers are designed to
>> > match pid values with the CPU's contextID register. The input value has no
>> > other effect than triggering trace collection, which has absolutely no baring on
>> > the CPU.
>>
>> So please tell me how we make the tracer pid namespace aware. Or is it
>> guaranteed that only the global root user will use this functionality?
>>
>> As you are taking a vpid it looks like users with lesser privileges are
>> able to request this. From the other reply it appears this is the
>> value the tracer returns to put in logs. Perhaps I missed it but I
>> didn't see anything that translated from the global pid to something
>> else. Which would make using this feature in a pid namespace confusing
>> and a problematic information leak if I have understood what has been
>> said so far.
>
Hi Russell,
> Let's look to see what's placed into the context ID register - this is
> done by arch/arm/mm/context.c::contextidr_notifier():
>
> pid = task_pid_nr(thread->task) << ASID_BITS;
>
> This is documented in linux/sched.h as:
>
> * task_xid_nr() : global id, i.e. the id seen from the init namespace;
>
> So, what ends up in the context ID register is the _global_ PID, not a
> namespace specific PID. This means the hardware deals with global PID
> values.
Correct.
>
> It seems quite logical to use the global PID value for the hardware,
> because that is a globally unique value - especially as the hardware
> uses this for filtering events. So asking for a namespace's pid 1
> gets mapped to the global pid value, which won't match some other
> namespace's pid 1.
>
> The problem comes _if_ the event stream delivered to userspace contains
> the global PID values and the event stream is being looked at from
> within a namespace.
Correct.
>
> This does not leak information from other namespaces because of the
> uniqueness of the global PID. However, what it does leak is the value
> of the global PID which is meaningless in the namespace. So, before
> the event stream is delivered to userspace, this value needs to be
> re-written to the namespace's PID value.
Unfortunately that can't be done. The trace stream is compressed and
needs to be decompressed using an external library. I think the only
option is to return an error if a user is trying to use this feature
from a namespace.
>
> Things get more yucky with this when you look at the ctxid_masks stuff
> - which looks to me like it implements a mask on the PID value. Masks
> on the pid value are irrelevant from within a namespace, because the
> mask is applied to the global PID value, not the namespace's PID value.
> You can't really define how a set of namespace PIDs will map to global
> PIDs, so masking the context ID PID value in the presence of namespaces
> is pretty useless - and potentially ends up being an information leak.
Also correct. Since there is no point in trying to use contextID
tracing from a namespace (see above) there is also no point in trying
to apply a mask to the contextIDs. Once again I think it is best to
return an error when using from a namespace.
Thanks,
Mathieu
>
> As for the sysfs file thing, I think the simple solution to that is
> the sysfs file should accept a PID value in the current namespace,
> and translate that to the global namespace - and the global PID value
> should be stored. When reading, the global PID value should be
> translated back to the current namespace, or an error/empty given if
> the PID doesn't exist in that namespace. The current solution to
> store the vpid and simply return it irrespective of the namespace is
> just nonsense.
>
> --
> RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
> FTTC broadband for 0.8mile line in suburbia: sync at 8.8Mbps down 630kbps up
> According to speedtest.net: 8.21Mbps down 510kbps up
^ permalink raw reply
* [PATCH 2/2] i2c: exynos5: remove pointless initializers
From: Peter Rosin @ 2018-05-10 19:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <b69f6656-3831-86ea-5f13-fc805d86b288@samsung.com>
On 2018-05-10 10:44, Andrzej Hajda wrote:
> On 09.05.2018 21:45, Peter Rosin wrote:
>> The variables are always assigned before use anyway.
>>
>> Signed-off-by: Peter Rosin <peda@axentia.se>
>> ---
>> drivers/i2c/busses/i2c-exynos5.c | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/i2c/busses/i2c-exynos5.c b/drivers/i2c/busses/i2c-exynos5.c
>> index a2cbc779c33a..185fba37e830 100644
>> --- a/drivers/i2c/busses/i2c-exynos5.c
>> +++ b/drivers/i2c/busses/i2c-exynos5.c
>> @@ -707,7 +707,7 @@ static int exynos5_i2c_xfer(struct i2c_adapter *adap,
>> struct i2c_msg *msgs, int num)
>> {
>> struct exynos5_i2c *i2c = adap->algo_data;
>> - int i = 0, ret = 0, stop = 0;
>> + int i, ret, stop;
>
> I hope gcc is smart enough to not complain in case of ret.
I think any compiler is smart enough to see that; you must have missed
this line:
ret = clk_enable(i2c->clk);
which is the first to touch ret in the function.
> I think you can merge both patches into one.
I could, but I wanted to make the patches totally obvious and easy to
review. The patches do independent things, so I prefer not to squash.
Cheers,
Peter
>
> Regards
> Andrzej
>
>>
>> if (i2c->suspended) {
>> dev_err(i2c->dev, "HS-I2C is not initialized.\n");
>
>
^ permalink raw reply
* [PATCH 1/2] i2c: exynos5: remove some dead code
From: Peter Rosin @ 2018-05-10 19:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <b3915e40-895f-2a72-27a2-dcffe504456d@samsung.com>
On 2018-05-10 10:36, Andrzej Hajda wrote:
> On 09.05.2018 21:45, Peter Rosin wrote:
>> The else branch cannot be taken as i will always equal num.
>> Get rid of the whole construct.
>>
>> Signed-off-by: Peter Rosin <peda@axentia.se>
>> ---
>> drivers/i2c/busses/i2c-exynos5.c | 12 +-----------
>> 1 file changed, 1 insertion(+), 11 deletions(-)
>>
>> diff --git a/drivers/i2c/busses/i2c-exynos5.c b/drivers/i2c/busses/i2c-exynos5.c
>> index 12ec8484e653..a2cbc779c33a 100644
>> --- a/drivers/i2c/busses/i2c-exynos5.c
>> +++ b/drivers/i2c/busses/i2c-exynos5.c
>> @@ -727,17 +727,7 @@ static int exynos5_i2c_xfer(struct i2c_adapter *adap,
>> goto out;
>> }
>>
>> - if (i == num) {
>> - ret = num;
>> - } else {
>> - /* Only one message, cannot access the device */
>> - if (i == 1)
>> - ret = -EREMOTEIO;
>> - else
>> - ret = i;
>> -
>> - dev_warn(i2c->dev, "xfer message failed\n");
>> - }
>> + ret = num;
>>
>> out:
>> clk_disable(i2c->clk);
>
> You can go further and remove "out:" label, use break instead, and at
> the end use "return (i == num) ? num : ret;" or sth similar.
>
> With this change you can add:
>
> Reviewed-by: Andrzej Hajda <a.hajda@samsung.com>
But then the patch wouldn't be so obviously safe. If I would write
a function equivalent to the original function, I think I'd write
something like:
static int exynos5_i2c_xfer(struct i2c_adapter *adap,
struct i2c_msg *msgs, int num)
{
struct exynos5_i2c *i2c = adap->algo_data;
int i, ret;
if (i2c->suspended) {
dev_err(i2c->dev, "HS-I2C is not initialized.\n");
return -EIO;
}
ret = clk_enable(i2c->clk);
if (ret)
return ret;
for (i = 0; !ret && i < num; i++)
ret = exynos5_i2c_xfer_msg(i2c, msgs + i, i == num - 1);
clk_disable(i2c->clk);
return ret ?: num;
}
And I think that is safe because I don't see any possibility for
exynos_i2c_xfer_msg to return anything but zero success or negative
errors. Since I can only compile-test, so I do not feel all that
good about going further than I did.
But if you or anyone can test the above function, feel free to make
a patch out of it. I don't care enough to make a bunch of iterations
on these trivialities. I just spotted dead code and dumb initializers
while looking for other things. So, take it or leave it. I.e. it was
just a couple of drive-by patches.
Cheers,
Peter
^ permalink raw reply
* [PATCH 2/2] arm64: dts: renesas: initial V3HSK board device tree
From: Sergei Shtylyov @ 2018-05-10 18:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <3923fc5f-103c-94c9-57ba-cb29e8c55d05@cogentembedded.com>
Add the initial device tree for the V3H Starter Kit board.
The board has 1 debug serial port (SCIF0); include support for it,
so that the serial console can work.
Based on the original (and large) patch by Vladimir Barinov.
Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
---
arch/arm64/boot/dts/renesas/Makefile | 2
arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts | 60 +++++++++++++++++++++++++
2 files changed, 61 insertions(+), 1 deletion(-)
Index: renesas/arch/arm64/boot/dts/renesas/Makefile
===================================================================
--- renesas.orig/arch/arm64/boot/dts/renesas/Makefile
+++ renesas/arch/arm64/boot/dts/renesas/Makefile
@@ -9,6 +9,6 @@ dtb-$(CONFIG_ARCH_R8A7796) += r8a7796-m3
dtb-$(CONFIG_ARCH_R8A7796) += r8a7796-salvator-xs.dtb
dtb-$(CONFIG_ARCH_R8A77965) += r8a77965-salvator-x.dtb r8a77965-salvator-xs.dtb
dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-eagle.dtb r8a77970-v3msk.dtb
-dtb-$(CONFIG_ARCH_R8A77980) += r8a77980-condor.dtb
+dtb-$(CONFIG_ARCH_R8A77980) += r8a77980-condor.dtb r8a77980-v3hsk.dtb
dtb-$(CONFIG_ARCH_R8A77990) += r8a77990-ebisu.dtb
dtb-$(CONFIG_ARCH_R8A77995) += r8a77995-draak.dtb
Index: renesas/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
===================================================================
--- /dev/null
+++ renesas/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for the V3H Starter Kit board
+ *
+ * Copyright (C) 2018 Renesas Electronics Corp.
+ * Copyright (C) 2018 Cogent Embedded, Inc.
+ */
+
+/dts-v1/;
+#include "r8a77980.dtsi"
+
+/ {
+ model = "Renesas V3H Starter Kit board";
+ compatible = "renesas,v3hsk", "renesas,r8a77980";
+
+ aliases {
+ serial0 = &scif0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory at 48000000 {
+ device_type = "memory";
+ /* first 128MB is reserved for secure area. */
+ reg = <0 0x48000000 0 0x78000000>;
+ };
+};
+
+&extal_clk {
+ clock-frequency = <16666666>;
+};
+
+&extalr_clk {
+ clock-frequency = <32768>;
+};
+
+&pfc {
+ scif0_pins: scif0 {
+ groups = "scif0_data";
+ function = "scif0";
+ };
+
+ scif_clk_pins: scif_clk {
+ groups = "scif_clk_b";
+ function = "scif_clk";
+ };
+};
+
+&scif0 {
+ pinctrl-0 = <&scif0_pins>, <&scif_clk_pins>;
+ pinctrl-names = "default";
+
+ status = "okay";
+};
+
+&scif_clk {
+ clock-frequency = <14745600>;
+};
^ permalink raw reply
* [PATCH 0/2] Add V3H Starter Kit board support
From: Sergei Shtylyov @ 2018-05-10 18:07 UTC (permalink / raw)
To: linux-arm-kernel
Hello!
Here's the set of 2 patches against Simon Horman's 'renesas.git' repo's
'renesas-devel-20180509-v4.17-rc4' tag. I'm adding the device tree support
for the R8A77980-based V3H Starter Kit board; only serial console is supported
for now, NFS support will require more work (it won't use EtherAVB but GEther)
and will be posted later...
[1/2] dt-bindings: arm: document Renesas V3HSK board bindings
[2/2] arm64: dts: renesas: initial V3HSK board device tree
WBR, Sergei
^ permalink raw reply
* [PATCH] ARM: keystone: fix platform_domain_notifier array overrun
From: Santosh Shilimkar @ 2018-05-10 17:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <E1fGlYS-0001CN-Sd@rmk-PC.armlinux.org.uk>
On 5/10/2018 6:24 AM, Russell King wrote:
> platform_domain_notifier contains a variable sized array, which the
> pm_clk_notify() notifier treats as a NULL terminated array:
>
> for (con_id = clknb->con_ids; *con_id; con_id++)
> pm_clk_add(dev, *con_id);
>
> Omitting the initialiser for con_ids means that the array is zero
> sized, and there is no NULL terminator. This leads to pm_clk_notify()
> overrunning into what ever structure follows, which may not be NULL.
> This leads to an oops:
>
> Unable to handle kernel NULL pointer dereference at virtual address 0000008c
> pgd = c0003000
> [0000008c] *pgd=80000800004003c, *pmd=00000000c
> Internal error: Oops: 206 [#1] PREEMPT SMP ARM
> Modules linked in:c
> CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.16.0+ #9
> Hardware name: Keystone
> PC is at strlen+0x0/0x34
> LR is at kstrdup+0x18/0x54
> pc : [<c0623340>] lr : [<c0111d6c>] psr: 20000013
> sp : eec73dc0 ip : eed780c0 fp : 00000001
> r10: 00000000 r9 : 00000000 r8 : eed71e10
> r7 : 0000008c r6 : 0000008c r5 : 014000c0 r4 : c03a6ff4
> r3 : c09445d0 r2 : 00000000 r1 : 014000c0 r0 : 0000008c
> Flags: nzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user
> Control: 30c5387d Table: 00003000 DAC: fffffffd
> Process swapper/0 (pid: 1, stack limit = 0xeec72210)
> Stack: (0xeec73dc0 to 0xeec74000)
> ...
> [<c0623340>] (strlen) from [<c0111d6c>] (kstrdup+0x18/0x54)
> [<c0111d6c>] (kstrdup) from [<c03a6ff4>] (__pm_clk_add+0x58/0x120)
> [<c03a6ff4>] (__pm_clk_add) from [<c03a731c>] (pm_clk_notify+0x64/0xa8)
> [<c03a731c>] (pm_clk_notify) from [<c004614c>] (notifier_call_chain+0x44/0x84)
> [<c004614c>] (notifier_call_chain) from [<c0046320>] (__blocking_notifier_call_chain+0x48/0x60)
> [<c0046320>] (__blocking_notifier_call_chain) from [<c0046350>] (blocking_notifier_call_chain+0x18/0x20)
> [<c0046350>] (blocking_notifier_call_chain) from [<c0390234>] (device_add+0x36c/0x534)
> [<c0390234>] (device_add) from [<c047fc00>] (of_platform_device_create_pdata+0x70/0xa4)
> [<c047fc00>] (of_platform_device_create_pdata) from [<c047fea0>] (of_platform_bus_create+0xf0/0x1ec)
> [<c047fea0>] (of_platform_bus_create) from [<c047fff8>] (of_platform_populate+0x5c/0xac)
> [<c047fff8>] (of_platform_populate) from [<c08b1f04>] (of_platform_default_populate_init+0x8c/0xa8)
> [<c08b1f04>] (of_platform_default_populate_init) from [<c000a78c>] (do_one_initcall+0x3c/0x164)
> [<c000a78c>] (do_one_initcall) from [<c087bd9c>] (kernel_init_freeable+0x10c/0x1d0)
> [<c087bd9c>] (kernel_init_freeable) from [<c0628db0>] (kernel_init+0x8/0xf0)
> [<c0628db0>] (kernel_init) from [<c00090d8>] (ret_from_fork+0x14/0x3c)
> Exception stack(0xeec73fb0 to 0xeec73ff8)
> 3fa0: 00000000 00000000 00000000 00000000
> 3fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> 3fe0: 00000000 00000000 00000000 00000000 00000013 00000000
> Code: e3520000 1afffff7 e12fff1e c0801730 (e5d02000)
> ---[ end trace cafa8f148e262e80 ]---
>
> Fix this by adding the necessary initialiser.
>
> Fixes: fc20ffe1213b ("ARM: keystone: add PM domain support for clock management")
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
> ---
Looks good. Thanks Russell !!
Acked-by: Santosh Shilimkar <ssantosh@kernel.org>
Arnd, olof,
Could you please pick this up for the fixes branch ?
^ permalink raw reply
* [RFC][PATCH] arm64: update iomem_resource.end
From: Robin Murphy @ 2018-05-10 17:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1525906703-28481-1-git-send-email-nicoleotsuka@gmail.com>
On 09/05/18 23:58, Nicolin Chen wrote:
> The iomem_resource.end is -1 by default and should be updated in
> arch-level code.
>
> ARM64 so far hasn't updated it while core kernel code (mm/hmm.c)
> started to use iomem_resource.end for boundary check. So it'd be
> better to assign iomem_resource.end using a valid value, the end
> of physical address space for example because iomem_resource.end
> in theory should reflect that.
>
> However, VA_BITS might be smaller than PA_BITS in ARM64. So using
> the end of physical address space doesn't make a lot of sense in
> this case, or could be even harmful since virtual address cannot
> reach that memory region.
Why? There's plenty of stuff in the physical address space that will
only ever be accessed via ioremap/memremap. There's no reason you
shouldn't be able to run a VA_BITS < 48 kernel on a Cavium ThunderX
where *all* the I/O is in the top half of the PA space. We already
constrain RAM in this very function to those regions which fit into the
linear map, and if you're accessing anything other than RAM through the
linear map you're probably doing something wrong.
Furthermore, the physical region covered by the linear map doesn't
necessarily start@physical address 0 anyway - see PHYS_OFFSET.
Robin.
> Furthermore, the linear region size of
> ARM64 only has the half of Virtual Memory size -- "VA_BITS - 1".
>
> So this patch updates the iomem_resource.end by using the end of
> physical address space or the end of linear mapping region when
> (VA_BITS - 1) is smaller than PA_BITS.
>
> Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
> ---
> arch/arm64/mm/init.c | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index f48b194..22015af 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -377,6 +377,12 @@ void __init arm64_memblock_init(void)
> BUILD_BUG_ON(linear_region_size != BIT(VA_BITS - 1));
>
> /*
> + * Update iomem_resource.end based on size of physical address space,
> + * or linear region size when (VA_BITS - 1) is smaller than PA_BITS.
> + */
> + iomem_resource.end = BIT(min(PHYS_MASK_SHIFT, VA_BITS - 1)) - 1;
> +
> + /*
> * Select a suitable value for the base of physical memory.
> */
> memstart_addr = round_down(memblock_start_of_DRAM(),
>
^ permalink raw reply
* [patch v19 4/4] Documentation: jtag: Add ABI documentation
From: Randy Dunlap @ 2018-05-10 17:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1525967064-10760-5-git-send-email-oleksandrs@mellanox.com>
On 05/10/2018 08:44 AM, Oleksandr Shamray wrote:
> Added document that describe the ABI for JTAG class drivrer
>
> Signed-off-by: Oleksandr Shamray <oleksandrs@mellanox.com>
> Acked-by: Arnd Bergmann <arnd@arndb.de>
> ---
> v18-v19
> Pavel Machek <pavel@ucw.cz>
> - Added JTAG doccumentation to Documentation/jtag
>
> v17->v18
> v16->v17
> v15->v16
> v14->v15
> v13->v14
> v12->v13
> v11->v12
> Tobias Klauser <tklauser@distanz.ch>
> - rename /Documentation/ABI/testing/jatg-dev -> jtag-dev
> - Typo: s/interfase/interface
> v10->v11
> v9->v10
> Fixes added by Oleksandr:
> - change jtag-cdev to jtag-dev in documentation
> - update Kernel Version and Date in jtag-dev documentation;
> v8->v9
> v7->v8
> v6->v7
> Comments pointed by Pavel Machek <pavel@ucw.cz>
> - Added jtag-cdev documentation to Documentation/ABI/testing folder
> ---
> Documentation/ABI/testing/jtag-dev | 27 +++++++++
> Documentation/jtag/overview | 31 ++++++++++
> Documentation/jtag/transactions | 108 ++++++++++++++++++++++++++++++++++++
> 3 files changed, 166 insertions(+), 0 deletions(-)
> create mode 100644 Documentation/ABI/testing/jtag-dev
> create mode 100644 Documentation/jtag/overview
> create mode 100644 Documentation/jtag/transactions
> diff --git a/Documentation/jtag/overview b/Documentation/jtag/overview
> new file mode 100644
> index 0000000..e35afc0
> --- /dev/null
> +++ b/Documentation/jtag/overview
> @@ -0,0 +1,31 @@
> +Linux kernel JTAG support
> +=========================
> +
> +The JTAG (Joint Test Action Group) is an industry standard for hardware
just: JTAG
drop the "The"
maybe: for verifying
hardware designs
(although that's not quite what wikipedia says)
> +verifying designs and testing printed circuit boards after manufacture.
> +JTAG provides access to many logic signals of a complex integrated circuit,
> +including the device pins
pins.
Oh. Just drop the 2 lines above since they are repeated below.
> +
> +JTAG provides access to many logic signals of a complex integrated circuit,
> +including the device pins.
> +
> +A JTAG interface is a special interface added to a chip.
> +Depending on the version of JTAG, two, four, or five pins are added.
> +
> +The connector pins are:
> + TDI (Test Data In)
> + TDO (Test Data Out)
> + TCK (Test Clock)
> + TMS (Test Mode Select)
> + TRST (Test Reset) optional.
> +
> +JTAG interface is supposed to have two parts - basic core driver and
is designed
> +hardware specific driver.
> +The basic driver introduces general interface which is not dependent of specific
introduces a general interface
> +hardware. It provides communication between user space and hardware specific
and a hardware specific
> +driver.
> +Each JTAG device is represented as char device from (jtag0, jtag1, ...).
as a char device
> +Access to JTAG device is performed through IOCTL call.
Access to a JTAG device is performed through IOCTL calls.
> +
> +Call flow example:
User: open /dev/jtagX
> +User (IOCTL) -> /dev/jtagX -> JTAG core driver -> JTAG hw specific driver
User: close /dev/jtagX
> diff --git a/Documentation/jtag/transactions b/Documentation/jtag/transactions
> new file mode 100644
> index 0000000..91f7f92
> --- /dev/null
> +++ b/Documentation/jtag/transactions
> @@ -0,0 +1,108 @@
> +The JTAG API
> +=============
> +
> +JTAG master devices can be accessed through a character misc-device.
> +Each JTAG master interface can be accessed by using /dev/jtagN
> +
> +JTAG system calls set:
> +- SIR (Scan Instruction Register, IEEE 1149.1 Data Register scan);
Why is SIR for Data Register?
> +- SDR (Scan Data Register, IEEE 1149.1 Instruction Register scan);
Why is SDR for Instruction Register?
> +- RUNTEST (Forces the IEEE 1149.1 bus to a run state for a specified
> +number of clocks.
> +
> +open(), close()
> +-------
> +open() opens JTAG device. Only one open operation per JTAG device
> +can be performed. Twice and more open for one device will return error
Two or more opens for one device will return errors.
> +
> +Open/Close device:
> +- open('/dev/jtag0', O_RDWR);
open("/dev/jtag0", O_RDWR);
> +- close(jtag_fd');
close(jtag_fd);
> +
> +ioctl()
> +-------
> +All access operations to JTAG device performed trougth ioctl interface.
devices are performed through the ioctl interface.
> +It support another requests:
The IOCTL interface supports these requests:
> + JTAG_IOCRUNTEST - Force JTAG state machine to RUN_TEST/IDLE state
> + JTAG_SIOCFREQ - Set JTAG TCK frequency
> + JTAG_GIOCFREQ - GET JTAG TCK frequency
> + JTAG_IOCXFER - send JTAG data Xfer
> + JTAG_GIOCSTATUS - get current JTAG TAP status
> + JTAG_SIOCMODE - set JTAG mode flags.
> +
> +JTAG_SIOCFREQ, JTAG_GIOCFREQ
> +------
> +Set/Get JTAG clock speed:
> +
unsigned int frq;
> + ioctl(jtag_fd, JTAG_SIOCFREQ, &frq);
> + ioctl(jtag_fd, JTAG_GIOCFREQ, &frq);
> +
> +JTAG_IOCRUNTEST
> +------
> +Force JTAG state machine to RUN_TEST/IDLE state
> +
> +struct jtag_run_test_idle {
> + __u8 reset;
> + __u8 endstate;
> + __u8 tck;
> +};
> +
> +reset: 0 - run IDLE/PAUSE from current state
> + 1 - go through TEST_LOGIC/RESET state before IDLE/PAUSE
> +end: completion flag
endstate:
> +tck: clock counter
> +
> +Example:
> + struct jtag_run_test_idle runtest;
> +
> + runtest.endstate = JTAG_STATE_IDLE;
> + runtest.reset = 0;
> + runtest.tck = data_p->tck;
> + usleep(25 * 1000);
> + ioctl(jtag_fd, JTAG_IOCRUNTEST, &runtest);
> +
> +JTAG_IOCXFER
> +------
> +Send SDR/SIR transaction
> +
> +struct jtag_xfer {
> + __u8 type;
> + __u8 direction;
> + __u8 endstate;
> + __u8 padding;
> + __u32 length;
> + __u64 tdio;
> +};
> +
> +type: transfer type - JTAG_SIR_XFER/JTAG_SDR_XFER
> +direction: xfer direction - JTAG_SIR_XFER/JTAG_SDR_XFER,
> +length: xfer data len in bits
> +tdio : xfer data array
> +endir: xfer end state after transaction finish
endstate:
> + can be: JTAG_STATE_IDLE/JTAG_STATE_PAUSEIR/JTAG_STATE_PAUSEDR
> +
> +Example:
> + struct jtag_xfer xfer;
> + static char buf[64];
> + static unsigned int buf_len = 0;
> + [...]
> + xfer.type = JTAG_SDR_XFER;
> + xfer.tdio = (__u64)buf;
> + xfer.length = buf_len;
> + xfer.endstate = JTAG_STATE_IDLE;
> +
> + if (is_read)
> + xfer.direction = JTAG_READ_XFER;
> + else
> + xfer.direction = JTAG_WRITE_XFER;
> +
> + ioctl(jtag_fd, JTAG_IOCXFER, &xfer);
> +
> +JTAG_SIOCMODE
> +------
> +If hw driver can support different running modes you can change it.
> +
> +Example:
> + int mode;
+#define JTAG_SIOCMODE _IOW(__JTAG_IOCTL_MAGIC, 5, unsigned int)
so:
unsigned int mode;
> + mode = JTAG_XFER_HW_MODE;
> + ioctl(jtag_fd, JTAG_SIOCMODE, &mode);
>
--
~Randy
^ permalink raw reply
* [PATCH v3 1/8] arm/arm64: KVM: Formalise end of direct linear map
From: Marc Zyngier @ 2018-05-10 17:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180510162347.3858-2-steve.capper@arm.com>
[+Christoffer]
Hi Steve,
On 10/05/18 17:23, Steve Capper wrote:
> 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 ed8fd0d19a3e..45c211fd50da 100644
> --- a/arch/arm/include/asm/memory.h
> +++ b/arch/arm/include/asm/memory.h
> @@ -24,6 +24,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 49d99214f43c..c5617cbbf1ff 100644
> --- a/arch/arm64/include/asm/memory.h
> +++ b/arch/arm64/include/asm/memory.h
> @@ -61,6 +61,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 7f6a944db23d..22af347d65f1 100644
> --- a/virt/kvm/arm/mmu.c
> +++ b/virt/kvm/arm/mmu.c
> @@ -1927,10 +1927,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) &&
This doesn't feel right to me now that we have the HYP randomization
code merged. The way kern_hyp_va works now is only valid for addresses
between VA(memblock_start_of_DRAM()) and high_memory.
I fear that you could trigger the failing condition below as you
evaluate the idmap address against something that is now not a HYP VA.
> hyp_idmap_start != (unsigned long)__hyp_idmap_text_start) {
> /*
> * The idmap page is intersecting with the VA space,
>
I'd appreciate if you could keep me cc'd on this series.
Thanks,
M.
--
Jazz is not dead. It just smells funny...
^ permalink raw reply
* [xlnx:xlnx_rebase_v4.14 308/918] drivers/usb/dwc3/host.c:24:6: error: redefinition of 'dwc3_host_wakeup_capable'
From: kbuild test robot @ 2018-05-10 17:10 UTC (permalink / raw)
To: linux-arm-kernel
tree: https://github.com/Xilinx/linux-xlnx xlnx_rebase_v4.14
head: 944a760cdb1098e23096c923aef70488fdbd501b
commit: c46d066e5633e178b138742850c37ed262a9af6d [308/918] dwc3: Add support for clock disabling during suspend
config: ia64-allmodconfig (attached as .config)
compiler: ia64-linux-gcc (GCC) 7.2.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
git checkout c46d066e5633e178b138742850c37ed262a9af6d
# save the attached .config to linux build tree
make.cross ARCH=ia64
All errors (new ones prefixed by >>):
>> drivers/usb/dwc3/host.c:24:6: error: redefinition of 'dwc3_host_wakeup_capable'
void dwc3_host_wakeup_capable(struct device *dev, bool wakeup)
^~~~~~~~~~~~~~~~~~~~~~~~
In file included from drivers/usb/dwc3/host.c:20:0:
include/linux/usb/xhci_pdriver.h:25:6: note: previous definition of 'dwc3_host_wakeup_capable' was here
void dwc3_host_wakeup_capable(struct device *dev, bool wakeup)
^~~~~~~~~~~~~~~~~~~~~~~~
vim +/dwc3_host_wakeup_capable +24 drivers/usb/dwc3/host.c
23
> 24 void dwc3_host_wakeup_capable(struct device *dev, bool wakeup)
25 {
26 dwc3_simple_wakeup_capable(dev, wakeup);
27 }
28
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 49013 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180511/4a0c175f/attachment-0001.gz>
^ permalink raw reply
* [PATCH v2] tty: pl011: Avoid spuriously stuck-off interrupts
From: Dave Martin @ 2018-05-10 17:08 UTC (permalink / raw)
To: linux-arm-kernel
Commit 9b96fbacda34 ("serial: PL011: clear pending interrupts")
clears the RX and receive timeout interrupts on pl011 startup, to
avoid a screaming-interrupt scenario that can occur when the
firmware or bootloader leaves these interrupts asserted.
This has been noted as an issue when running Linux on qemu [1].
Unfortunately, the above fix seems to lead to potential
misbehaviour if the RX FIFO interrupt is asserted _non_ spuriously
on driver startup, if the RX FIFO is also already full to the
trigger level.
Clearing the RX FIFO interrupt does not change the FIFO fill level.
In this scenario, because the interrupt is now clear and because
the FIFO is already full to the trigger level, no new assertion of
the RX FIFO interrupt can occur unless the FIFO is drained back
below the trigger level. This never occurs because the pl011
driver is waiting for an RX FIFO interrupt to tell it that there is
something to read, and does not read the FIFO at all until that
interrupt occurs.
Thus, simply clearing "spurious" interrupts on startup may be
misguided, since there is no way to be sure that the interrupts are
truly spurious, and things can go wrong if they are not.
This patch instead clears the interrupt condition by draining the
RX FIFO during UART startup, after clearing any potentially
spurious interrupt. This should ensure that an interrupt will
definitely be asserted if the RX FIFO subsequently becomes
sufficiently full.
The drain is done at the point of enabling interrupts only. This
means that it will occur any time the UART is newly opened through
the tty layer. It will not apply to polled-mode use of the UART by
kgdboc: since that scenario cannot use interrupts by design, this
should not matter. kgdboc will interact badly with "normal" use of
the UART in any case: this patch makes no attempt to paper over
such issues.
This patch does not attempt to address the case where the RX FIFO
fills faster than it can be drained: that is a pathological
hardware design problem that is beyond the scope of the driver to
work around. As a failsafe, the number of poll iterations for
draining the FIFO is limited to twice the FIFO size. This will
ensure that the kernel at least boots even if it is impossible to
drain the FIFO for some reason.
[1] [Qemu-devel] [Qemu-arm] [PATCH] pl011: do not put into fifo
before enabled the interruption
https://lists.gnu.org/archive/html/qemu-devel/2018-01/msg06446.html
Reported-by: Wei Xu <xuwei5@hisilicon.com>
Cc: Russell King <linux@armlinux.org.uk>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Peter Maydell <peter.maydell@linaro.org>
Fixes: 9b96fbacda34 ("serial: PL011: clear pending interrupts")
Signed-off-by: Dave Martin <Dave.Martin@arm.com>
---
Changes since v1 [1]
* Deleted Andrew Jones' Reviewed/Tested-bys due to the following
change.
If you can please retest that the updated patch fixes your
issue that would be appreciated.
Suggested by Russell King:
* Only drain 2 * FIFO size, to avoid going into an infinite spin
if something does wrong. If the FIFO still couldn't be drained
sufficiently then pl011 RX won't work properly, but the kernel
will at least boot.
[1] [PATCH] tty: pl011: Avoid spuriously stuck-off interrupts
http://lists.infradead.org/pipermail/linux-arm-kernel/2018-April/574362.html
---
drivers/tty/serial/amba-pl011.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index 4b40a5b..ebd33c0 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -1727,10 +1727,26 @@ static int pl011_allocate_irq(struct uart_amba_port *uap)
*/
static void pl011_enable_interrupts(struct uart_amba_port *uap)
{
+ unsigned int i;
+
spin_lock_irq(&uap->port.lock);
/* Clear out any spuriously appearing RX interrupts */
pl011_write(UART011_RTIS | UART011_RXIS, uap, REG_ICR);
+
+ /*
+ * RXIS is asserted only when the RX FIFO transitions from below
+ * to above the trigger threshold. If the RX FIFO is already
+ * full to the threshold this can't happen and RXIS will now be
+ * stuck off. Drain the RX FIFO explicitly to fix this:
+ */
+ for (i = 0; i < uap->fifosize * 2; ++i) {
+ if (pl011_read(uap, REG_FR) & UART01x_FR_RXFE)
+ break;
+
+ pl011_read(uap, REG_DR);
+ }
+
uap->im = UART011_RTIM;
if (!pl011_dma_rx_running(uap))
uap->im |= UART011_RXIM;
--
2.1.4
^ permalink raw reply related
* [xlnx:xlnx_rebase_v4.14 132/918] drivers/misc/jesd204b/xilinx_jesd204b.c:29:17: error: field 'hw' has incomplete type
From: kbuild test robot @ 2018-05-10 16:56 UTC (permalink / raw)
To: linux-arm-kernel
tree: https://github.com/Xilinx/linux-xlnx xlnx_rebase_v4.14
head: 944a760cdb1098e23096c923aef70488fdbd501b
commit: 5d774267f2dcee0cd5158b9ebe3bb58a0fd984e1 [132/918] jesd204b: move the current driver to a folder
config: ia64-allmodconfig (attached as .config)
compiler: ia64-linux-gcc (GCC) 7.2.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
git checkout 5d774267f2dcee0cd5158b9ebe3bb58a0fd984e1
# save the attached .config to linux build tree
make.cross ARCH=ia64
All errors (new ones prefixed by >>):
>> drivers/misc/jesd204b/xilinx_jesd204b.c:29:17: error: field 'hw' has incomplete type
struct clk_hw hw;
^~
In file included from include/linux/err.h:5:0,
from include/linux/clk.h:15,
from drivers/misc/jesd204b/xilinx_jesd204b.c:11:
drivers/misc/jesd204b/xilinx_jesd204b.c: In function 'jesd204b_clk_enable':
>> include/linux/kernel.h:929:32: error: dereferencing pointer to incomplete type 'struct clk_hw'
BUILD_BUG_ON_MSG(!__same_type(*(ptr), ((type *)0)->member) && \
^~~~~~
include/linux/compiler.h:554:19: note: in definition of macro '__compiletime_assert'
bool __cond = !(condition); \
^~~~~~~~~
include/linux/compiler.h:577:2: note: in expansion of macro '_compiletime_assert'
_compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
^~~~~~~~~~~~~~~~~~~
include/linux/build_bug.h:47:37: note: in expansion of macro 'compiletime_assert'
#define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
^~~~~~~~~~~~~~~~~~
include/linux/kernel.h:929:2: note: in expansion of macro 'BUILD_BUG_ON_MSG'
BUILD_BUG_ON_MSG(!__same_type(*(ptr), ((type *)0)->member) && \
^~~~~~~~~~~~~~~~
include/linux/kernel.h:929:20: note: in expansion of macro '__same_type'
BUILD_BUG_ON_MSG(!__same_type(*(ptr), ((type *)0)->member) && \
^~~~~~~~~~~
drivers/misc/jesd204b/xilinx_jesd204b.c:35:26: note: in expansion of macro 'container_of'
#define to_clk_priv(_hw) container_of(_hw, struct child_clk, hw)
^~~~~~~~~~~~
drivers/misc/jesd204b/xilinx_jesd204b.c:215:2: note: in expansion of macro 'to_clk_priv'
to_clk_priv(hw)->enabled = true;
^~~~~~~~~~~
drivers/misc/jesd204b/xilinx_jesd204b.c: At top level:
>> drivers/misc/jesd204b/xilinx_jesd204b.c:230:21: error: variable 'clkout_ops' has initializer but incomplete type
static const struct clk_ops clkout_ops = {
^~~~~~~
>> drivers/misc/jesd204b/xilinx_jesd204b.c:231:3: error: 'const struct clk_ops' has no member named 'recalc_rate'
.recalc_rate = jesd204b_clk_recalc_rate,
^~~~~~~~~~~
drivers/misc/jesd204b/xilinx_jesd204b.c:231:17: warning: excess elements in struct initializer
.recalc_rate = jesd204b_clk_recalc_rate,
^~~~~~~~~~~~~~~~~~~~~~~~
drivers/misc/jesd204b/xilinx_jesd204b.c:231:17: note: (near initialization for 'clkout_ops')
>> drivers/misc/jesd204b/xilinx_jesd204b.c:232:3: error: 'const struct clk_ops' has no member named 'enable'
.enable = jesd204b_clk_enable,
^~~~~~
drivers/misc/jesd204b/xilinx_jesd204b.c:232:12: warning: excess elements in struct initializer
.enable = jesd204b_clk_enable,
^~~~~~~~~~~~~~~~~~~
drivers/misc/jesd204b/xilinx_jesd204b.c:232:12: note: (near initialization for 'clkout_ops')
>> drivers/misc/jesd204b/xilinx_jesd204b.c:233:3: error: 'const struct clk_ops' has no member named 'disable'
.disable = jesd204b_clk_disable,
^~~~~~~
drivers/misc/jesd204b/xilinx_jesd204b.c:233:13: warning: excess elements in struct initializer
.disable = jesd204b_clk_disable,
^~~~~~~~~~~~~~~~~~~~
drivers/misc/jesd204b/xilinx_jesd204b.c:233:13: note: (near initialization for 'clkout_ops')
>> drivers/misc/jesd204b/xilinx_jesd204b.c:234:3: error: 'const struct clk_ops' has no member named 'is_enabled'
.is_enabled = jesd204b_clk_is_enabled,
^~~~~~~~~~
drivers/misc/jesd204b/xilinx_jesd204b.c:234:16: warning: excess elements in struct initializer
.is_enabled = jesd204b_clk_is_enabled,
^~~~~~~~~~~~~~~~~~~~~~~
drivers/misc/jesd204b/xilinx_jesd204b.c:234:16: note: (near initialization for 'clkout_ops')
drivers/misc/jesd204b/xilinx_jesd204b.c: In function 'jesd204b_probe':
>> drivers/misc/jesd204b/xilinx_jesd204b.c:252:23: error: storage size of 'init' isn't known
struct clk_init_data init;
^~~~
drivers/misc/jesd204b/xilinx_jesd204b.c:252:23: warning: unused variable 'init' [-Wunused-variable]
drivers/misc/jesd204b/xilinx_jesd204b.c: At top level:
>> drivers/misc/jesd204b/xilinx_jesd204b.c:230:29: error: storage size of 'clkout_ops' isn't known
static const struct clk_ops clkout_ops = {
^~~~~~~~~~
vim +/hw +29 drivers/misc/jesd204b/xilinx_jesd204b.c
26
27
28 struct child_clk {
> 29 struct clk_hw hw;
30 struct jesd204b_state *st;
31 unsigned long rate;
32 bool enabled;
33 };
34
> 35 #define to_clk_priv(_hw) container_of(_hw, struct child_clk, hw)
36
37 static inline void jesd204b_write(struct jesd204b_state *st,
38 unsigned reg, unsigned val)
39 {
40 iowrite32(val, st->regs + reg);
41 }
42
43 static inline unsigned int jesd204b_read(struct jesd204b_state *st,
44 unsigned reg)
45 {
46 return ioread32(st->regs + reg);
47 }
48
49 static ssize_t jesd204b_laneinfo_read(struct device *dev,
50 struct device_attribute *attr,
51 char *buf, unsigned lane)
52 {
53 struct jesd204b_state *st = dev_get_drvdata(dev);
54 int ret;
55 unsigned val1, val2, val3;
56
57 val1 = jesd204b_read(st, XLNX_JESD204_REG_ID_L(lane));
58 val2 = jesd204b_read(st, XLNX_JESD204_REG_LANE_F(lane));
59 val3 = jesd204b_read(st, XLNX_JESD204_REG_SCR_S_HD_CF(lane));
60 ret = sprintf(buf,
61 "DID: %d, BID: %d, LID: %d, L: %d, SCR: %d, F: %d\n",
62 XLNX_JESD204_LANE_DID(val1),
63 XLNX_JESD204_LANE_BID(val1),
64 XLNX_JESD204_LANE_LID(val1),
65 XLNX_JESD204_LANE_L(val1),
66 XLNX_JESD204_LANE_SCR(val3),
67 XLNX_JESD204_LANE_F(val2));
68
69 val1 = jesd204b_read(st, XLNX_JESD204_REG_LANE_K(lane));
70 val2 = jesd204b_read(st, XLNX_JESD204_REG_M_N_ND_CS(lane));
71
72 ret += sprintf(buf + ret,
73 "K: %d, M: %d, N: %d, CS: %d, S: %d, N': %d, HD: %d\n",
74 XLNX_JESD204_LANE_K(val1),
75 XLNX_JESD204_LANE_M(val2),
76 XLNX_JESD204_LANE_N(val2),
77 XLNX_JESD204_LANE_CS(val2),
78 XLNX_JESD204_LANE_S(val3),
79 XLNX_JESD204_LANE_ND(val2),
80 XLNX_JESD204_LANE_HD(val3));
81
82 val1 = jesd204b_read(st, XLNX_JESD204_REG_FCHK(lane));
83 ret += sprintf(buf + ret, "FCHK: 0x%X, CF: %d\n",
84 XLNX_JESD204_LANE_FCHK(val1),
85 XLNX_JESD204_LANE_CF(val3));
86
87 val1 = jesd204b_read(st, XLNX_JESD204_REG_SC2_ADJ_CTRL(lane));
88 val2 = jesd204b_read(st, XLNX_JESD204_REG_LANE_VERSION(lane));
89 ret += sprintf(buf + ret,
90 "ADJCNT: %d, PHYADJ: %d, ADJDIR: %d, JESDV: %d, SUBCLASS: %d\n",
91 XLNX_JESD204_LANE_ADJ_CNT(val1),
92 XLNX_JESD204_LANE_PHASE_ADJ_REQ(val1),
93 XLNX_JESD204_LANE_ADJ_CNT_DIR(val1),
94 XLNX_JESD204_LANE_JESDV(val2),
95 XLNX_JESD204_LANE_SUBCLASS(val2));
96
97 ret += sprintf(buf + ret, "MFCNT : 0x%X\n",
98 jesd204b_read(st, XLNX_JESD204_REG_TM_MFC_CNT(lane)));
99 ret += sprintf(buf + ret, "ILACNT: 0x%X\n",
100 jesd204b_read(st, XLNX_JESD204_REG_TM_ILA_CNT(lane)));
101 ret += sprintf(buf + ret, "ERRCNT: 0x%X\n",
102 jesd204b_read(st, XLNX_JESD204_REG_TM_ERR_CNT(lane)));
103 ret += sprintf(buf + ret, "BUFCNT: 0x%X\n",
104 jesd204b_read(st, XLNX_JESD204_REG_TM_BUF_ADJ(lane)));
105 ret += sprintf(buf + ret, "LECNT: 0x%X\n",
106 jesd204b_read(st,
107 XLNX_JESD204_REG_TM_LINK_ERR_CNT(lane)));
108
109 ret += sprintf(buf + ret, "FC: %lu\n", st->rate);
110
111 return ret;
112 }
113
114 #define JESD_LANE(_x) \
115 static ssize_t jesd204b_lane##_x##_info_read(struct device *dev, \
116 struct device_attribute *attr, \
117 char *buf) \
118 { \
119 return jesd204b_laneinfo_read(dev, attr, buf, _x); \
120 } \
121 static DEVICE_ATTR(lane##_x##_info, S_IRUSR, jesd204b_lane##_x##_info_read, \
122 NULL)
123
124 JESD_LANE(0);
125 JESD_LANE(1);
126 JESD_LANE(2);
127 JESD_LANE(3);
128 JESD_LANE(4);
129 JESD_LANE(5);
130 JESD_LANE(6);
131 JESD_LANE(7);
132
133 static ssize_t jesd204b_lane_syscstat_read(struct device *dev,
134 struct device_attribute *attr,
135 char *buf, unsigned lane)
136 {
137 struct jesd204b_state *st = dev_get_drvdata(dev);
138 unsigned stat;
139
140 stat = jesd204b_read(st, XLNX_JESD204_REG_SYNC_ERR_STAT);
141
142 return sprintf(buf,
143 "NOT_IN_TAB: %d, DISPARITY: %d, UNEXPECTED_K: %d\n",
144 stat & XLNX_JESD204_SYNC_ERR_NOT_IN_TAB(lane),
145 stat & XLNX_JESD204_SYNC_ERR_DISPARITY(lane),
146 stat & XLNX_JESD204_SYNC_ERR_UNEXPECTED_K(lane));
147 }
148
149 #define JESD_SYNCSTAT_LANE(_x) \
150 static ssize_t jesd204b_lane##_x##_syncstat_read(struct device *dev, \
151 struct device_attribute *attr,\
152 char *buf) \
153 { \
154 return jesd204b_lane_syscstat_read(dev, attr, buf, _x); \
155 } \
156 static DEVICE_ATTR(lane##_x##_syncstat, S_IRUSR, \
157 jesd204b_lane##_x##_syncstat_read, NULL)
158
159 JESD_SYNCSTAT_LANE(0);
160 JESD_SYNCSTAT_LANE(1);
161 JESD_SYNCSTAT_LANE(2);
162 JESD_SYNCSTAT_LANE(3);
163 JESD_SYNCSTAT_LANE(4);
164 JESD_SYNCSTAT_LANE(5);
165 JESD_SYNCSTAT_LANE(6);
166 JESD_SYNCSTAT_LANE(7);
167
168 static ssize_t jesd204b_reg_write(struct device *dev,
169 struct device_attribute *attr,
170 const char *buf, size_t count)
171 {
172 struct jesd204b_state *st = dev_get_drvdata(dev);
173 unsigned val;
174 int ret;
175
176 ret = sscanf(buf, "%i %i", &st->addr, &val);
177 if (ret == 2)
178 jesd204b_write(st, st->addr, val);
179
180 return count;
181 }
182
183 static ssize_t jesd204b_reg_read(struct device *dev,
184 struct device_attribute *attr,
185 char *buf)
186 {
187 struct jesd204b_state *st = dev_get_drvdata(dev);
188
189 return sprintf(buf, "0x%X\n", jesd204b_read(st, st->addr));
190 }
191
192 static DEVICE_ATTR(reg_access, S_IWUSR | S_IRUSR, jesd204b_reg_read,
193 jesd204b_reg_write);
194
195 static ssize_t jesd204b_syncreg_read(struct device *dev,
196 struct device_attribute *attr,
197 char *buf)
198 {
199 struct jesd204b_state *st = dev_get_drvdata(dev);
200
201 return sprintf(buf, "0x%X\n", jesd204b_read(st,
202 XLNX_JESD204_REG_SYNC_STATUS));
203 }
204
205 static DEVICE_ATTR(sync_status, S_IRUSR, jesd204b_syncreg_read, NULL);
206
207 static unsigned long jesd204b_clk_recalc_rate(struct clk_hw *hw,
208 unsigned long parent_rate)
209 {
210 return parent_rate;
211 }
212
213 static int jesd204b_clk_enable(struct clk_hw *hw)
214 {
> 215 to_clk_priv(hw)->enabled = true;
216
217 return 0;
218 }
219
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 48869 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180511/a7bfeef0/attachment-0001.gz>
^ permalink raw reply
* [PATCH v7 13/16] KVM: arm64: Remove eager host SVE state saving
From: Catalin Marinas @ 2018-05-10 16:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1525882385-29181-14-git-send-email-Dave.Martin@arm.com>
On Wed, May 09, 2018 at 05:13:02PM +0100, Dave P Martin wrote:
> Now that the host SVE context can be saved on demand from Hyp,
> there is no longer any need to save this state in advance before
> entering the guest.
>
> This patch removes the relevant call to
> kvm_fpsimd_flush_cpu_state().
>
> Since the problem that function was intended to solve now no longer
> exists, the function and its dependencies are also deleted.
>
> Signed-off-by: Dave Martin <Dave.Martin@arm.com>
> Acked-by: Christoffer Dall <christoffer.dall@arm.com>
> Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
^ permalink raw reply
* [PATCH v7 12/16] KVM: arm64: Save host SVE context as appropriate
From: Catalin Marinas @ 2018-05-10 16:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1525882385-29181-13-git-send-email-Dave.Martin@arm.com>
On Wed, May 09, 2018 at 05:13:01PM +0100, Dave P Martin wrote:
> This patch adds SVE context saving to the hyp FPSIMD context switch
> path. This means that it is no longer necessary to save the host
> SVE state in advance of entering the guest, when in use.
>
> In order to avoid adding pointless complexity to the code, VHE is
> assumed if SVE is in use. VHE is an architectural prerequisite for
> SVE, so there is no good reason to turn CONFIG_ARM64_VHE off in
> kernels that support both SVE and KVM.
>
> Historically, software models exist that can expose the
> architecturally invalid configuration of SVE without VHE, so if
> this situation is detected at kvm_init() time then KVM will be
> disabled.
>
> Signed-off-by: Dave Martin <Dave.Martin@arm.com>
> Reviewed-by: Christoffer Dall <christoffer.dall@arm.com>
> Acked-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
> arch/arm64/Kconfig | 7 +++++++
> arch/arm64/kvm/fpsimd.c | 1 -
> arch/arm64/kvm/hyp/switch.c | 20 +++++++++++++++++++-
> virt/kvm/arm/arm.c | 18 ++++++++++++++++++
> 4 files changed, 44 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index eb2cf49..b0d3820 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -1130,6 +1130,7 @@ endmenu
> config ARM64_SVE
> bool "ARM Scalable Vector Extension support"
> default y
> + depends on !KVM || ARM64_VHE
> help
> The Scalable Vector Extension (SVE) is an extension to the AArch64
> execution state which complements and extends the SIMD functionality
> @@ -1155,6 +1156,12 @@ config ARM64_SVE
> booting the kernel. If unsure and you are not observing these
> symptoms, you should assume that it is safe to say Y.
>
> + CPUs that support SVE are architecturally required to support the
> + Virtualization Host Extensions (VHE), so the kernel makes no
> + provision for supporting SVE alongside KVM without VHE enabled.
> + Thus, you will need to enable CONFIG_ARM64_VHE if you want to support
> + KVM in the same kernel image.
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
^ permalink raw reply
* [PATCH v7 08/16] KVM: arm64: Optimise FPSIMD handling to reduce guest/host thrashing
From: Catalin Marinas @ 2018-05-10 16:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1525882385-29181-9-git-send-email-Dave.Martin@arm.com>
On Wed, May 09, 2018 at 05:12:57PM +0100, Dave P Martin wrote:
> This patch refactors KVM to align the host and guest FPSIMD
> save/restore logic with each other for arm64. This reduces the
> number of redundant save/restore operations that must occur, and
> reduces the common-case IRQ blackout time during guest exit storms
> by saving the host state lazily and optimising away the need to
> restore the host state before returning to the run loop.
>
> Four hooks are defined in order to enable this:
>
> * kvm_arch_vcpu_run_map_fp():
> Called on PID change to map necessary bits of current to Hyp.
>
> * kvm_arch_vcpu_load_fp():
> Set up FP/SIMD for entering the KVM run loop (parse as
> "vcpu_load fp").
>
> * kvm_arch_vcpu_ctxsync_fp():
> Get FP/SIMD into a safe state for re-enabling interrupts after a
> guest exit back to the run loop.
>
> For arm64 specifically, this involves updating the host kernel's
> FPSIMD context tracking metadata so that kernel-mode NEON use
> will cause the vcpu's FPSIMD state to be saved back correctly
> into the vcpu struct. This must be done before re-enabling
> interrupts because kernel-mode NEON may be used by softirqs.
>
> * kvm_arch_vcpu_put_fp():
> Save guest FP/SIMD state back to memory and dissociate from the
> CPU ("vcpu_put fp").
>
> Also, the arm64 FPSIMD context switch code is updated to enable it
> to save back FPSIMD state for a vcpu, not just current. A few
> helpers drive this:
>
> * fpsimd_bind_state_to_cpu(struct user_fpsimd_state *fp):
> mark this CPU as having context fp (which may belong to a vcpu)
> currently loaded in its registers. This is the non-task
> equivalent of the static function fpsimd_bind_to_cpu() in
> fpsimd.c.
>
> * task_fpsimd_save():
> exported to allow KVM to save the guest's FPSIMD state back to
> memory on exit from the run loop.
>
> * fpsimd_flush_state():
> invalidate any context's FPSIMD state that is currently loaded.
> Used to disassociate the vcpu from the CPU regs on run loop exit.
>
> These changes allow the run loop to enable interrupts (and thus
> softirqs that may use kernel-mode NEON) without having to save the
> guest's FPSIMD state eagerly.
>
> Some new vcpu_arch fields are added to make all this work. Because
> host FPSIMD state can now be saved back directly into current's
> thread_struct as appropriate, host_cpu_context is no longer used
> for preserving the FPSIMD state. However, it is still needed for
> preserving other things such as the host's system registers. To
> avoid ABI churn, the redundant storage space in host_cpu_context is
> not removed for now.
>
> arch/arm is not addressed by this patch and continues to use its
> current save/restore logic. It could provide implementations of
> the helpers later if desired.
>
> Signed-off-by: Dave Martin <Dave.Martin@arm.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
^ permalink raw reply
* [PATCH] arm64: dts: renesas: r8a77970: add SMP support
From: Sergei Shtylyov @ 2018-05-10 16:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180509190517.ho5og3grbuzf4wz4@verge.net.au>
Hello!
On 05/09/2018 10:05 PM, Simon Horman wrote:
>>>> Add the device node for the second Cortex-A53 CPU core.
>>>>
>>>> Based on the original (and large) patch by Daisuke Matsushita
>>>> <daisuke.matsushita.ns@hitachi.com>.
>>>>
>>>> Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
>>>> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
>>>
>>> Dupe of https://patchwork.kernel.org/patch/10032875/
>>
>> Sorry!
>> Not an exact dupe, though -- mine has clock/power #define's used,
>> yours -- only bare #s. :-)
>>
>>> From series "[PATCH 0/2] arm64: dts: renesas: r8a77970: Add SMP Support"
>>> (https://www.spinics.net/lists/linux-renesas-soc/msg19681.html)
>>
>> Hmm... what's the fate of this series?
>
> There is now a v2 of Geert's series which incorporates your enhancements.
I suggested to respin it. :-)
> I will apply that.
Thank you.
For the record, I had better luck than Geert testing SMP on Eagle: only CPU0
couldn't be offlined (and I was unable to find a workaround), others could be on/
offlined w/o issues. As for suspend/resume -- it did work but I could only test
s2idle (/sys/power/mem_sleep had no other variants)...
MBR, Sergei
^ permalink raw reply
* [PATCH] kvm: Change return type to vm_fault_t
From: Paolo Bonzini @ 2018-05-10 16:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180418191958.GA25806@jordon-HP-15-Notebook-PC>
On 18/04/2018 21:19, Souptick Joarder wrote:
> Use new return type vm_fault_t for fault handler. For
> now, this is just documenting that the function returns
> a VM_FAULT value rather than an errno. Once all instances
> are converted, vm_fault_t will become a distinct type.
>
> commit 1c8f422059ae ("mm: change return type to vm_fault_t")
>
> Signed-off-by: Souptick Joarder <jrdr.linux@gmail.com>
> Reviewed-by: Matthew Wilcox <mawilcox@microsoft.com>
> ---
> arch/mips/kvm/mips.c | 2 +-
> arch/powerpc/kvm/powerpc.c | 2 +-
> arch/s390/kvm/kvm-s390.c | 2 +-
> arch/x86/kvm/x86.c | 2 +-
> include/linux/kvm_host.h | 2 +-
> virt/kvm/arm/arm.c | 2 +-
> virt/kvm/kvm_main.c | 2 +-
> 7 files changed, 7 insertions(+), 7 deletions(-)
>
> diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
> index 2549fdd..03e0e0f 100644
> --- a/arch/mips/kvm/mips.c
> +++ b/arch/mips/kvm/mips.c
> @@ -1076,7 +1076,7 @@ int kvm_arch_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
> return -ENOIOCTLCMD;
> }
>
> -int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
> +vm_fault_t kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
> {
> return VM_FAULT_SIGBUS;
> }
> diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
> index 403e642..3099dee 100644
> --- a/arch/powerpc/kvm/powerpc.c
> +++ b/arch/powerpc/kvm/powerpc.c
> @@ -1825,7 +1825,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
> return r;
> }
>
> -int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
> +vm_fault_t kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
> {
> return VM_FAULT_SIGBUS;
> }
> diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
> index ba4c709..24af487 100644
> --- a/arch/s390/kvm/kvm-s390.c
> +++ b/arch/s390/kvm/kvm-s390.c
> @@ -3941,7 +3941,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
> return r;
> }
>
> -int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
> +vm_fault_t kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
> {
> #ifdef CONFIG_KVM_S390_UCONTROL
> if ((vmf->pgoff == KVM_S390_SIE_PAGE_OFFSET)
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index c8a0b54..95d8102 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -3827,7 +3827,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
> return r;
> }
>
> -int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
> +vm_fault_t kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
> {
> return VM_FAULT_SIGBUS;
> }
> diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
> index ac0062b..8eeb062 100644
> --- a/include/linux/kvm_host.h
> +++ b/include/linux/kvm_host.h
> @@ -736,7 +736,7 @@ long kvm_arch_dev_ioctl(struct file *filp,
> unsigned int ioctl, unsigned long arg);
> long kvm_arch_vcpu_ioctl(struct file *filp,
> unsigned int ioctl, unsigned long arg);
> -int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf);
> +vm_fault_t kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf);
>
> int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext);
>
> diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
> index 86941f6..6c8cc31 100644
> --- a/virt/kvm/arm/arm.c
> +++ b/virt/kvm/arm/arm.c
> @@ -163,7 +163,7 @@ int kvm_arch_create_vcpu_debugfs(struct kvm_vcpu *vcpu)
> return 0;
> }
>
> -int kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
> +vm_fault_t kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
> {
> return VM_FAULT_SIGBUS;
> }
> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> index 4501e65..45eb54b 100644
> --- a/virt/kvm/kvm_main.c
> +++ b/virt/kvm/kvm_main.c
> @@ -2341,7 +2341,7 @@ void kvm_vcpu_on_spin(struct kvm_vcpu *me, bool yield_to_kernel_mode)
> }
> EXPORT_SYMBOL_GPL(kvm_vcpu_on_spin);
>
> -static int kvm_vcpu_fault(struct vm_fault *vmf)
> +static vm_fault_t kvm_vcpu_fault(struct vm_fault *vmf)
> {
> struct kvm_vcpu *vcpu = vmf->vma->vm_file->private_data;
> struct page *page;
> --
> 1.9.1
>
Applied, thanks.
Paolo
^ permalink raw reply
* [PATCH v7 06/16] arm64/sve: Refactor user SVE trap maintenance for external use
From: Catalin Marinas @ 2018-05-10 16:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1525882385-29181-7-git-send-email-Dave.Martin@arm.com>
On Wed, May 09, 2018 at 05:12:55PM +0100, Dave P Martin wrote:
> In preparation for optimising the way KVM manages switching the
> guest and host FPSIMD state, it is necessary to provide a means for
> code outside arch/arm64/kernel/fpsimd.c to restore the user trap
> configuration for SVE correctly for the current task.
>
> Rather than requiring external code to duplicate the maintenance
> explicitly, this patch wraps moves the trap maintenenace to
> fpsimd_bind_to_cpu(), since it is logically part of the work of
> associating the current task with the cpu.
>
> Because fpsimd_bind_to_cpu() is rather a cryptic name to publish
> alongside fpsimd_bind_state_to_cpu(), the former function is
> renamed to fpsimd_bind_task_to_cpu() to make its purpose more
> explicit.
>
> This patch makes appropriate changes to ensure that
> fpsimd_bind_task_to_cpu() is always called alongside
> task_fpsimd_load(), so that the trap maintenance continues to be
> done in every situation where it was done prior to this patch.
>
> As a side-effect, the metadata updates done by
> fpsimd_bind_task_to_cpu() now change from conditional to
> unconditional in the "already bound" case of sigreturn. This is
> harmless, and a couple of extra stores on this slow path will not
> impact performance. I consider this a reasonable price to pay for
> a slightly cleaner interface.
>
> Signed-off-by: Dave Martin <Dave.Martin@arm.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
^ permalink raw reply
* [PATCH v3 8/8] arm64: mm: Add 48/52-bit kernel VA support
From: Steve Capper @ 2018-05-10 16:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180510162347.3858-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 | 10 +++++++++-
arch/arm64/mm/proc.S | 13 +++++++++++++
2 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index f68eeab08904..6fe0c2976f0d 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -266,6 +266,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_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
@@ -282,6 +283,7 @@ config MULTI_IRQ_HANDLER
config KASAN_SHADOW_OFFSET
hex
depends on KASAN
+ default 0xdfffa00000000000 if ARM64_VA_BITS_52
default 0xdfffa00000000000 if ARM64_VA_BITS_48
default 0xdfffd00000000000 if ARM64_VA_BITS_47
default 0xdffffe8000000000 if ARM64_VA_BITS_42
@@ -670,6 +672,10 @@ config ARM64_VA_BITS_47
config ARM64_VA_BITS_48
bool "48-bit"
+config ARM64_VA_BITS_52
+ bool "52-bit (ARMv8.2) (48 if not in hardware)"
+ depends on ARM64_64K_PAGES
+
endchoice
config ARM64_VA_BITS
@@ -679,10 +685,12 @@ 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 52 if ARM64_VA_BITS_52
config ARM64_VA_BITS_MIN
int
- default ARM64_VA_BITS
+ default ARM64_VA_BITS if !ARM64_VA_BITS_52
+ default 48 if ARM64_VA_BITS_52
choice
prompt "Physical address space size"
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 5f8d9e452190..031604502776 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -472,9 +472,22 @@ ENTRY(__cpu_setup)
ENDPROC(__cpu_setup)
ENTRY(__setup_va_constants)
+#ifdef CONFIG_ARM64_VA_BITS_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
+ mov x1, TCR_T0SZ(VA_BITS)
+ mov x2, #1 << (VA_BITS - 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 v3 7/8] arm64: mm: Make VA space size variable
From: Steve Capper @ 2018-05-10 16:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180510162347.3858-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 space size. This patch introduces
vabits_actual, a variable which is defined at very early boot.
The meaning of a few variables changes, however, to facilitate this
change.
VA_BITS - The maximum size of the VA space (compile time constant),
VA_BITS_MIN - The minimum size of the VA space (compile time constant),
VA_BITS_ACTUAL - The actual size of the VA space (determined at boot).
Signed-off-by: Steve Capper <steve.capper@arm.com>
---
Changed in V3, I have been asked to try keep VA_BITS itself constant,
and this is my attempt at doing this.
I am happy to extend this patch or go back to forcing VA_BITS variable
depending upon feedback.
---
arch/arm64/Kconfig | 4 ++++
arch/arm64/include/asm/efi.h | 4 ++--
arch/arm64/include/asm/kasan.h | 2 +-
arch/arm64/include/asm/memory.h | 22 ++++++++++++++--------
arch/arm64/include/asm/mmu_context.h | 2 +-
arch/arm64/include/asm/pgtable-hwdef.h | 1 +
arch/arm64/include/asm/pgtable.h | 2 +-
arch/arm64/include/asm/processor.h | 2 +-
arch/arm64/kernel/head.S | 6 ++++--
arch/arm64/kernel/kaslr.c | 6 +++---
arch/arm64/kernel/machine_kexec.c | 2 +-
arch/arm64/kvm/va_layout.c | 14 +++++++-------
arch/arm64/mm/fault.c | 4 ++--
arch/arm64/mm/init.c | 7 ++++++-
arch/arm64/mm/kasan_init.c | 3 ++-
arch/arm64/mm/mmu.c | 7 +++++--
arch/arm64/mm/proc.S | 28 ++++++++++++++++++++++++++++
17 files changed, 83 insertions(+), 33 deletions(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 4d2bc91d4017..f68eeab08904 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -680,6 +680,10 @@ config ARM64_VA_BITS
default 47 if ARM64_VA_BITS_47
default 48 if ARM64_VA_BITS_48
+config ARM64_VA_BITS_MIN
+ int
+ default ARM64_VA_BITS
+
choice
prompt "Physical address space size"
default ARM64_PA_BITS_48
diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h
index 192d791f1103..dc2e47c53dff 100644
--- a/arch/arm64/include/asm/efi.h
+++ b/arch/arm64/include/asm/efi.h
@@ -68,7 +68,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
@@ -79,7 +79,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/kasan.h b/arch/arm64/include/asm/kasan.h
index ea397897ae4a..59ff3ba9bb90 100644
--- a/arch/arm64/include/asm/kasan.h
+++ b/arch/arm64/include/asm/kasan.h
@@ -27,7 +27,7 @@
* (1ULL << (64 - KASAN_SHADOW_SCALE_SHIFT))
*/
#define _KASAN_SHADOW_START(va) (KASAN_SHADOW_END - (1UL << ((va) - KASAN_SHADOW_SCALE_SHIFT)))
-#define KASAN_SHADOW_START _KASAN_SHADOW_START(VA_BITS)
+#define KASAN_SHADOW_START _KASAN_SHADOW_START(VA_BITS_ACTUAL)
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 aa26958e5034..2d96501b8712 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -57,10 +57,6 @@
* 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)
@@ -70,6 +66,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_MIN)
+#define _VA_START(va) (UL(0xffffffffffffffff) - \
+ (UL(1) << ((va) - 1)) + 1)
#define KERNEL_START _text
#define KERNEL_END _end
@@ -88,7 +87,7 @@
+ 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)
@@ -174,10 +173,17 @@
#endif
#ifndef __ASSEMBLY__
+extern u64 vabits_actual;
+#define VA_BITS_ACTUAL ({vabits_actual;})
+#define VA_START (_VA_START(VA_BITS_ACTUAL))
+#define PAGE_OFFSET (UL(0xffffffffffffffff) - \
+ (UL(1) << VA_BITS_ACTUAL) + 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; })
@@ -221,9 +227,9 @@ 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_ACTUAL - 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) ({ \
@@ -242,7 +248,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 39ec0b8a689e..75d8d7a48a3c 100644
--- a/arch/arm64/include/asm/mmu_context.h
+++ b/arch/arm64/include/asm/mmu_context.h
@@ -101,7 +101,7 @@ static inline void __cpu_set_tcr_t0sz(unsigned long t0sz)
isb();
}
-#define cpu_set_default_tcr_t0sz() __cpu_set_tcr_t0sz(TCR_T0SZ(VA_BITS))
+#define cpu_set_default_tcr_t0sz() __cpu_set_tcr_t0sz(TCR_T0SZ(VA_BITS_ACTUAL))
#define cpu_set_idmap_tcr_t0sz() __cpu_set_tcr_t0sz(idmap_t0sz)
/*
diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
index fd208eac9f2a..20f8740c505a 100644
--- a/arch/arm64/include/asm/pgtable-hwdef.h
+++ b/arch/arm64/include/asm/pgtable-hwdef.h
@@ -81,6 +81,7 @@
#define PGDIR_SIZE (_AC(1, UL) << PGDIR_SHIFT)
#define PGDIR_MASK (~(PGDIR_SIZE-1))
#define PTRS_PER_PGD (1 << (VA_BITS - PGDIR_SHIFT))
+#define PTRS_PER_PGD_ACTUAL (1 << (VA_BITS_ACTUAL - PGDIR_SHIFT))
/*
* Section address mask and size definitions.
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 31e26f3ab078..337ea50f2440 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -583,7 +583,7 @@ static inline phys_addr_t pgd_page_paddr(pgd_t pgd)
#define pgd_ERROR(pgd) __pgd_error(__FILE__, __LINE__, pgd_val(pgd))
/* to find an entry in a page-table-directory */
-#define pgd_index(addr) (((addr) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
+#define pgd_index(addr) (((addr) >> PGDIR_SHIFT) & (PTRS_PER_PGD_ACTUAL - 1))
#define pgd_offset_raw(pgd, addr) ((pgd) + pgd_index(addr))
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 767598932549..244d23d1d911 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)
#define KERNEL_DS UL(-1)
#define USER_DS (TASK_SIZE_64 - 1)
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index b0853069702f..50abb6617a8a 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
@@ -253,6 +254,7 @@ ENDPROC(preserve_boot_args)
add \rtbl, \tbl, #PAGE_SIZE
mov \sv, \rtbl
mov \count, #0
+
compute_indices \vstart, \vend, #PGDIR_SHIFT, \pgds, \istart, \iend, \count
populate_entries \tbl, \rtbl, \istart, \iend, #PMD_TYPE_TABLE, #PAGE_SIZE, \tmp
mov \tbl, \sv
@@ -338,7 +340,7 @@ __create_page_tables:
dmb sy
dc ivac, x6 // Invalidate potentially stale cache line
-#if (VA_BITS < 48)
+#if (VA_BITS_MIN < 48)
#define EXTRA_SHIFT (PGDIR_SHIFT + PAGE_SHIFT - 3)
#define EXTRA_PTRS (1 << (PHYS_MASK_SHIFT - EXTRA_SHIFT))
@@ -376,7 +378,7 @@ __create_page_tables:
adrp x0, swapper_pg_dir
mov_q x5, KIMAGE_VADDR + TEXT_OFFSET // compile time __va(_text)
add x5, x5, x23 // add KASLR displacement
- mov x4, PTRS_PER_PGD
+ ldr_l x4, ptrs_per_pgd
adrp x6, _end // runtime __pa(_end)
adrp x3, _text // runtime __pa(_text)
sub x6, x6, x3 // _end - _text
diff --git a/arch/arm64/kernel/kaslr.c b/arch/arm64/kernel/kaslr.c
index f0e6ab8abe9c..bb6ab342f80b 100644
--- a/arch/arm64/kernel/kaslr.c
+++ b/arch/arm64/kernel/kaslr.c
@@ -117,15 +117,15 @@ 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
- * middle half of the VMALLOC area (VA_BITS - 2), and stay clear of
+ * middle half of the VMALLOC area (VA_BITS_MIN - 2), and stay clear of
* the lower and upper quarters to avoid colliding with other
* allocations.
* 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);
- offset = BIT(VA_BITS - 3) + (seed & mask);
+ mask = ((1UL << (VA_BITS_MIN - 2)) - 1) & ~(SZ_2M - 1);
+ offset = BIT(VA_BITS_MIN - 3) + (seed & mask);
/* use the top 16 bits to randomize the linear region */
memstart_offset_seed = seed >> 48;
diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
index f76ea92dff91..732ef5dd1e4c 100644
--- a/arch/arm64/kernel/machine_kexec.c
+++ b/arch/arm64/kernel/machine_kexec.c
@@ -355,7 +355,7 @@ void crash_free_reserved_phys_range(unsigned long begin, unsigned long end)
void arch_crash_save_vmcoreinfo(void)
{
- VMCOREINFO_NUMBER(VA_BITS);
+ VMCOREINFO_NUMBER(VA_BITS_ACTUAL);
/* Please note VMCOREINFO_NUMBER() uses "%d", not "%x" */
vmcoreinfo_append_str("NUMBER(kimage_voffset)=0x%llx\n",
kimage_voffset);
diff --git a/arch/arm64/kvm/va_layout.c b/arch/arm64/kvm/va_layout.c
index c712a7376bc1..c9a1debb45bd 100644
--- a/arch/arm64/kvm/va_layout.c
+++ b/arch/arm64/kvm/va_layout.c
@@ -40,25 +40,25 @@ static void compute_layout(void)
int kva_msb;
/* Where is my RAM region? */
- hyp_va_msb = idmap_addr & BIT(VA_BITS - 1);
- hyp_va_msb ^= BIT(VA_BITS - 1);
+ hyp_va_msb = idmap_addr & BIT(VA_BITS_ACTUAL - 1);
+ hyp_va_msb ^= BIT(VA_BITS_ACTUAL - 1);
kva_msb = fls64((u64)phys_to_virt(memblock_start_of_DRAM()) ^
(u64)(high_memory - 1));
- if (kva_msb == (VA_BITS - 1)) {
+ if (kva_msb == (VA_BITS_ACTUAL - 1)) {
/*
* No space in the address, let's compute the mask so
- * that it covers (VA_BITS - 1) bits, and the region
+ * that it covers (VA_BITS_ACTUAL - 1) bits, and the region
* bit. The tag stays set to zero.
*/
- va_mask = BIT(VA_BITS - 1) - 1;
+ va_mask = BIT(VA_BITS_ACTUAL - 1) - 1;
va_mask |= hyp_va_msb;
} else {
/*
* We do have some free bits to insert a random tag.
* Hyp VAs are now created from kernel linear map VAs
- * using the following formula (with V == VA_BITS):
+ * using the following formula (with V == VA_BITS_ACTUAL):
*
* 63 ... V | V-1 | V-2 .. tag_lsb | tag_lsb - 1 .. 0
* ---------------------------------------------------------
@@ -66,7 +66,7 @@ static void compute_layout(void)
*/
tag_lsb = kva_msb;
va_mask = GENMASK_ULL(tag_lsb - 1, 0);
- tag_val = get_random_long() & GENMASK_ULL(VA_BITS - 2, tag_lsb);
+ tag_val = get_random_long() & GENMASK_ULL(VA_BITS_ACTUAL - 2, tag_lsb);
tag_val |= hyp_va_msb;
tag_val >>= tag_lsb;
}
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 4165485e8b6e..7990f25d2031 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -151,9 +151,9 @@ void show_pte(unsigned long addr)
return;
}
- pr_alert("%s pgtable: %luk pages, %u-bit VAs, pgdp = %p\n",
+ pr_alert("%s pgtable: %luk pages, %llu-bit VAs, pgdp = %p\n",
mm == &init_mm ? "swapper" : "user", PAGE_SIZE / SZ_1K,
- VA_BITS, mm->pgd);
+ VA_BITS_ACTUAL, mm->pgd);
pgdp = pgd_offset(mm, addr);
pgd = READ_ONCE(*pgdp);
pr_alert("[%016lx] pgd=%016llx", addr, pgd_val(pgd));
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index efb7e860f99f..ff005ea5c8e8 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)
{
@@ -361,7 +364,7 @@ static void __init fdt_enforce_memory_region(void)
void __init arm64_memblock_init(void)
{
- const s64 linear_region_size = BIT(VA_BITS - 1);
+ const s64 linear_region_size = BIT(VA_BITS_ACTUAL - 1);
/* Handle linux,usable-memory-range property */
fdt_enforce_memory_region();
@@ -375,6 +378,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 221ddead81ac..452b36fbf2b0 100644
--- a/arch/arm64/mm/kasan_init.c
+++ b/arch/arm64/mm/kasan_init.c
@@ -135,7 +135,8 @@ 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));
+ BUILD_BUG_ON(!IS_ALIGNED(_KASAN_SHADOW_START(VA_BITS), PGDIR_SIZE));
+ 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);
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 197f4110ae2c..e5834492dbcc 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -49,8 +49,11 @@
#define NO_BLOCK_MAPPINGS BIT(0)
#define NO_CONT_MAPPINGS BIT(1)
-u64 idmap_t0sz = TCR_T0SZ(VA_BITS);
u64 idmap_ptrs_per_pgd = PTRS_PER_PGD;
+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);
@@ -668,7 +671,7 @@ int kern_addr_valid(unsigned long addr)
pmd_t *pmdp, pmd;
pte_t *ptep, pte;
- if ((((long)addr) >> VA_BITS) != -1UL)
+ if ((((long)addr) >> VA_BITS_ACTUAL) != -1UL)
return 0;
pgdp = pgd_offset_k(addr);
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 5f9a73a4452c..5f8d9e452190 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -437,9 +437,18 @@ 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_MIN) | TCR_CACHE_FLAGS | TCR_SMP_FLAGS | \
+ TCR_TG_FLAGS | TCR_KASLR_FLAGS | TCR_ASID16 | \
+ TCR_TBI0 | TCR_A1
+#if (CONFIG_ARM64_VA_BITS != CONFIG_ARM64_VA_BITS_MIN)
+ ldr_l x9, vabits_actual
+ cmp x9, #VA_BITS
+ b.ne 1f
ldr x10, =TCR_TxSZ(VA_BITS) | TCR_CACHE_FLAGS | TCR_SMP_FLAGS | \
TCR_TG_FLAGS | TCR_KASLR_FLAGS | TCR_ASID16 | \
TCR_TBI0 | TCR_A1
+1:
+#endif
tcr_set_idmap_t0sz x10, x9
/*
@@ -461,3 +470,22 @@ ENTRY(__cpu_setup)
msr tcr_el1, x10
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)
--
2.11.0
^ permalink raw reply related
* [PATCH v3 6/8] arm64: module-plts: Extend veneer to address 52-bit VAs
From: Steve Capper @ 2018-05-10 16:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180510162347.3858-1-steve.capper@arm.com>
From: Ard Bieusheuval <ard.biesheuvel@linaro.org>
In preparation for 52-bit VA support in the Linux kernel, we extend the
plts veneer to support 52-bit addresses via an extra movk instruction.
[Steve: code from Ard off-list, changed the #ifdef logic to inequality]
Signed-off-by: Steve Capper <steve.capper@arm.com>
---
New in V3 of the series.
I'm not sure if this is strictly necessary as the VAs of the module
space will fit within 48-bits of addressing even when a 52-bit VA space
is enabled. However, this may act to future-proof the 52-bit VA support
should any future adjustments be made to the VA space.
---
arch/arm64/include/asm/module.h | 13 ++++++++++++-
arch/arm64/kernel/module-plts.c | 12 ++++++++++++
2 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/include/asm/module.h b/arch/arm64/include/asm/module.h
index 97d0ef12e2ff..30b8ca95d19a 100644
--- a/arch/arm64/include/asm/module.h
+++ b/arch/arm64/include/asm/module.h
@@ -59,6 +59,9 @@ struct plt_entry {
__le32 mov0; /* movn x16, #0x.... */
__le32 mov1; /* movk x16, #0x...., lsl #16 */
__le32 mov2; /* movk x16, #0x...., lsl #32 */
+#if CONFIG_ARM64_VA_BITS > 48
+ __le32 mov3; /* movk x16, #0x...., lsl #48 */
+#endif
__le32 br; /* br x16 */
};
@@ -71,7 +74,8 @@ static inline struct plt_entry get_plt_entry(u64 val)
* +--------+------------+--------+-----------+-------------+---------+
*
* Rd := 0x10 (x16)
- * hw := 0b00 (no shift), 0b01 (lsl #16), 0b10 (lsl #32)
+ * hw := 0b00 (no shift), 0b01 (lsl #16), 0b10 (lsl #32),
+ * 0b11 (lsl #48)
* opc := 0b11 (MOVK), 0b00 (MOVN), 0b10 (MOVZ)
* sf := 1 (64-bit variant)
*/
@@ -79,6 +83,9 @@ static inline struct plt_entry get_plt_entry(u64 val)
cpu_to_le32(0x92800010 | (((~val ) & 0xffff)) << 5),
cpu_to_le32(0xf2a00010 | ((( val >> 16) & 0xffff)) << 5),
cpu_to_le32(0xf2c00010 | ((( val >> 32) & 0xffff)) << 5),
+#if CONFIG_ARM64_VA_BITS > 48
+ cpu_to_le32(0xf2e00010 | ((( val >> 48) & 0xffff)) << 5),
+#endif
cpu_to_le32(0xd61f0200)
};
}
@@ -86,6 +93,10 @@ static inline struct plt_entry get_plt_entry(u64 val)
static inline bool plt_entries_equal(const struct plt_entry *a,
const struct plt_entry *b)
{
+#if CONFIG_ARM64_VA_BITS > 48
+ if (a->mov3 != b->mov3)
+ return false;
+#endif
return a->mov0 == b->mov0 &&
a->mov1 == b->mov1 &&
a->mov2 == b->mov2;
diff --git a/arch/arm64/kernel/module-plts.c b/arch/arm64/kernel/module-plts.c
index f0690c2ca3e0..4d5617e09943 100644
--- a/arch/arm64/kernel/module-plts.c
+++ b/arch/arm64/kernel/module-plts.c
@@ -50,6 +50,9 @@ u64 module_emit_veneer_for_adrp(struct module *mod, void *loc, u64 val)
struct plt_entry *plt = (struct plt_entry *)pltsec->plt->sh_addr;
int i = pltsec->plt_num_entries++;
u32 mov0, mov1, mov2, br;
+#if CONFIG_ARM64_VA_BITS > 48
+ u32 mov3;
+#endif
int rd;
if (WARN_ON(pltsec->plt_num_entries > pltsec->plt_max_entries))
@@ -69,6 +72,12 @@ u64 module_emit_veneer_for_adrp(struct module *mod, void *loc, u64 val)
mov2 = aarch64_insn_gen_movewide(rd, (u16)(val >> 32), 32,
AARCH64_INSN_VARIANT_64BIT,
AARCH64_INSN_MOVEWIDE_KEEP);
+#if CONFIG_ARM64_VA_BITS > 48
+ mov3 = aarch64_insn_gen_movewide(rd, (u16)(val >> 48), 48,
+ AARCH64_INSN_VARIANT_64BIT,
+ AARCH64_INSN_MOVEWIDE_KEEP);
+#endif
+
br = aarch64_insn_gen_branch_imm((u64)&plt[i].br, (u64)loc + 4,
AARCH64_INSN_BRANCH_NOLINK);
@@ -76,6 +85,9 @@ u64 module_emit_veneer_for_adrp(struct module *mod, void *loc, u64 val)
cpu_to_le32(mov0),
cpu_to_le32(mov1),
cpu_to_le32(mov2),
+#if CONFIG_ARM64_VA_BITS > 48
+ cpu_to_le32(mov3),
+#endif
cpu_to_le32(br)
};
--
2.11.0
^ permalink raw reply related
* [PATCH v3 5/8] arm64: dump: Make kernel page table dumper dynamic again
From: Steve Capper @ 2018-05-10 16:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180510162347.3858-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 76e8857b2baf..c1030b3ca3c7 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 },
};
@@ -381,7 +403,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)
@@ -407,6 +428,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 v3 4/8] arm64: mm: Replace fixed map BUILD_BUG_ON's with BUG_ON's
From: Steve Capper @ 2018-05-10 16:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180510162347.3858-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 12ce780fcef4..197f4110ae2c 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -811,7 +811,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 ((pmdp != fixmap_pmd(fix_to_virt(FIX_BTMAP_BEGIN)))
@@ -879,9 +879,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 v3 3/8] arm64: kasan: Switch to using KASAN_SHADOW_OFFSET
From: Steve Capper @ 2018-05-10 16:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180510162347.3858-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 >> KASAN_SHADOW_SCALE_SHIFT + KASAN_SHADOW_OFFSET)
if (somethingWrong(shadowValue))
flagAnError();
This code sequence is inserted into many places, thus
KASAN_SHADOW_OFFSET is essentially baked into many places in the kernel
text.
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 >> KASAN_SHADOW_SCALE_SHIFT + KASAN_SHADOW_OFFSET
This means that if we increase the size of the VA space, the start of
the KASAN region expands into lower addresses whilst the end of the
KASAN region is fixed.
Currently the arm64 code computes KASAN_SHADOW_OFFSET at build time via
build scripts with the VA size used as a parameter. (There are build
time checks in the C code too to ensure that expected values are being
derived). It is sufficient, and indeed is a simplification, to remove
the build scripts (and build time checks) entirely and instead provide
KASAN_SHADOW_OFFSET values.
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>
---
Changed in V3, rebase to include KASAN_SHADOW_SCALE_SHIFT, wording
tidied up.
---
Documentation/arm64/kasan-offsets.sh | 20 ++++++++++++++++++++
arch/arm64/Kconfig | 10 ++++++++++
arch/arm64/Makefile | 9 ---------
arch/arm64/include/asm/kasan.h | 11 ++++-------
arch/arm64/include/asm/memory.h | 7 +++++--
arch/arm64/mm/kasan_init.c | 2 --
6 files changed, 39 insertions(+), 20 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..329353f8489d
--- /dev/null
+++ b/Documentation/arm64/kasan-offsets.sh
@@ -0,0 +1,20 @@
+#!/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
+
+KASAN_SHADOW_SCALE_SHIFT=3
+
+print_kasan_offset () {
+ printf "%02d\t" $1
+ printf "0x%08x00000000\n" $(( (0xffffffff & (-1 << ($1 - 1 - 32))) \
+ + (1 << ($1 - 32 - KASAN_SHADOW_SCALE_SHIFT)) \
+ - (1 << (64 - 32 - KASAN_SHADOW_SCALE_SHIFT)) ))
+}
+
+echo KASAN_SHADOW_SCALE_SHIFT = $KASAN_SHADOW_SCALE_SHIFT
+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 eb2cf4938f6d..4d2bc91d4017 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -279,6 +279,16 @@ config ARCH_PROC_KCORE_TEXT
config MULTI_IRQ_HANDLER
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 2785f34aa790..08ccbfaec3c5 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -96,15 +96,6 @@ else
TEXT_OFFSET := 0x00080000
endif
-# KASAN_SHADOW_OFFSET = VA_START + (1 << (VA_BITS - KASAN_SHADOW_SCALE_SHIFT))
-# - (1 << (64 - KASAN_SHADOW_SCALE_SHIFT))
-# in 32-bit arithmetic
-KASAN_SHADOW_SCALE_SHIFT := 3
-KASAN_SHADOW_OFFSET := $(shell printf "0x%08x00000000\n" $$(( \
- (0xffffffff & (-1 << ($(CONFIG_ARM64_VA_BITS) - 1 - 32))) \
- + (1 << ($(CONFIG_ARM64_VA_BITS) - 32 - $(KASAN_SHADOW_SCALE_SHIFT))) \
- - (1 << (64 - 32 - $(KASAN_SHADOW_SCALE_SHIFT))) )) )
-
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 8758bb008436..ea397897ae4a 100644
--- a/arch/arm64/include/asm/kasan.h
+++ b/arch/arm64/include/asm/kasan.h
@@ -14,11 +14,8 @@
* KASAN_SHADOW_START: beginning of the kernel virtual addresses.
* KASAN_SHADOW_END: KASAN_SHADOW_START + 1/N of kernel virtual addresses,
* where N = (1 << KASAN_SHADOW_SCALE_SHIFT).
- */
-#define KASAN_SHADOW_START (VA_START)
-#define KASAN_SHADOW_END (KASAN_SHADOW_START + KASAN_SHADOW_SIZE)
-
-/*
+ *
+ * KASAN_SHADOW_OFFSET:
* This value is used to map an address to the corresponding shadow
* address by the following formula:
* shadow_addr = (address >> KASAN_SHADOW_SCALE_SHIFT) + KASAN_SHADOW_OFFSET
@@ -29,8 +26,8 @@
* KASAN_SHADOW_OFFSET = KASAN_SHADOW_END -
* (1ULL << (64 - KASAN_SHADOW_SCALE_SHIFT))
*/
-#define KASAN_SHADOW_OFFSET (KASAN_SHADOW_END - (1ULL << \
- (64 - KASAN_SHADOW_SCALE_SHIFT)))
+#define _KASAN_SHADOW_START(va) (KASAN_SHADOW_END - (1UL << ((va) - KASAN_SHADOW_SCALE_SHIFT)))
+#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 f0478617db32..aa26958e5034 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -64,7 +64,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)
@@ -83,9 +83,12 @@
#define KASAN_SHADOW_SCALE_SHIFT 3
#define KASAN_SHADOW_SIZE (UL(1) << (VA_BITS - KASAN_SHADOW_SCALE_SHIFT))
#define KASAN_THREAD_SHIFT 1
+#define KASAN_SHADOW_OFFSET _AC(CONFIG_KASAN_SHADOW_OFFSET, UL)
+#define KASAN_SHADOW_END ((UL(1) << (64 - KASAN_SHADOW_SCALE_SHIFT)) \
+ + 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 7571e3e6e0f0..221ddead81ac 100644
--- a/arch/arm64/mm/kasan_init.c
+++ b/arch/arm64/mm/kasan_init.c
@@ -135,8 +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 << (64 - KASAN_SHADOW_SCALE_SHIFT)));
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
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