* Re: [PATCH 2/9] crypto: Add Allwinner sun8i-ce Crypto Engine
From: Corentin Labbe @ 2019-09-09 13:19 UTC (permalink / raw)
To: Maxime Ripard
Cc: mark.rutland, devicetree, herbert, linux-sunxi, linux,
linux-kernel, wens, robh+dt, linux-crypto, davem,
linux-arm-kernel
In-Reply-To: <20190909113837.vrnqdfgzhsiymfpm@flea>
On Mon, Sep 09, 2019 at 01:38:37PM +0200, Maxime Ripard wrote:
> On Sat, Sep 07, 2019 at 09:04:08PM +0200, Corentin Labbe wrote:
> > > Also, I'm not sure what is the point of having the clocks names be
> > > parameters there as well. It's constant across all the compatibles,
> > > the only thing that isn't is the number of clocks and the module clock
> > > rate. It's what you should have in there.
> >
> > Since the datasheet give some max frequency, I think I will add a
> > max_freq and add a check to verify if the clock is in the right
> > range
>
> It's a bit pointless. What are you going to do if it's not correct?
> What are you trying to fix / report with this?
I thinked to print a warning.
If someone want to play with overclocking for example, the driver should said that probably some result could be invalid.
>
> > > > + }
> > > > +};
> > > > +
> > > > +static const struct ce_variant ce_h5_variant = {
> > > > + .alg_cipher = { CE_ID_NOTSUPP, CE_ALG_AES, CE_ALG_DES, CE_ALG_3DES,
> > > > + CE_ID_NOTSUPP,
> > > > + },
> > > > + .op_mode = { CE_ID_NOTSUPP, CE_OP_ECB, CE_OP_CBC
> > > > + },
> > > > + .intreg = CE_ISR,
> > > > + .maxflow = 4,
> > > > + .ce_clks = {
> > > > + { "ahb", 200000000 },
> > > > + { "mod", 300000000 },
> > > > + }
> > > > +};
> > > > +
> > > > +static const struct ce_variant ce_h6_variant = {
> > > > + .alg_cipher = { CE_ID_NOTSUPP, CE_ALG_AES, CE_ALG_DES, CE_ALG_3DES,
> > > > + CE_ALG_RAES,
> > > > + },
> > > > + .op_mode = { CE_ID_NOTSUPP, CE_OP_ECB, CE_OP_CBC
> > > > + },
> > > > + .model = CE_v2,
> > >
> > > Can't that be derived from the version register and / or the
> > > compatible? This seems to be redundant with each.
> >
> > I could use the compatible, but I want to avoid a string comparison
> > on each request.
>
> Well, this is specifically what this structure is for then, right? So
> instead of having the model, just add the information that you want
> there.
>
ok, I will change to a "bool all_size_in_bytes"
> > > > +int sun8i_ce_get_engine_number(struct sun8i_ce_dev *ce)
> > > > +{
> > > > + return atomic_inc_return(&ce->flow) % ce->variant->maxflow;
> > > > +}
> > >
> > > I'm not sure what this is supposed to be doing, but that mod there
> > > seems pretty dangerous.
> > >
> > > ...
> >
> > This mod do a round robin on each channel.
> > I dont see why it is dangerous.
>
> Well, you're using the atomic API here which is most commonly used for
> refcounting, while you're using a mod.
>
> Plus, while the increment is atomic, the modulo isn't, so you can end
> up in a case where you would be preempted between the
> atomic_inc_return and the mod, which is dangerous.
>
> Again, I'm not sure what this function is doing (which is also a
> problem in itself). I guess you should just make it clearer what it
> does, and then we can discuss it properly.
Each request need to be assigned to a channel.
Each channel are identified by a number from 1 to 4.
So this function return the channel to use, 1 then 2 then 3 then 4 then 1...
Note that this is uncritical. If, due to anything, two request are assigned to the same channel, nothing will break.
>
> > > > + err = clk_set_rate(ce->ceclks[i], ce->variant->ce_clks[i].freq);
> > > > + if (err)
> > > > + dev_err(&pdev->dev, "Fail to set %s clk speed to %lu\n",
> > > > + ce->variant->ce_clks[i].name,
> > > > + ce->variant->ce_clks[i].freq);
> > > > + } else {
> > > > + dev_info(&pdev->dev, "%s run at %lu\n",
> > > > + ce->variant->ce_clks[i].name, cr);
> > >
> > > Ditto.
> > >
> > > > + }
> > > > + err = clk_prepare_enable(ce->ceclks[i]);
> > >
> > > Do you really need this right now though?
> >
> > Not sure to understand, why I shouldnt do it now ?
> > Does it is related to your pm_runtime remark below ?
> >
> > My feeling was to submit the driver without PM and convert it after.
>
> runtime_pm would be pretty cheap to add though judging by what you're
> doing there.
>
I will try to add runtime_pm
> > > > + if (err) {
> > > > + dev_err(&pdev->dev, "Cannot prepare_enable %s\n",
> > > > + ce->variant->ce_clks[i].name);
> > > > + return err;
> > > > + }
> > > > + }
> > > > +
> > > > + /* Get Non Secure IRQ */
> > > > + irq = platform_get_irq(pdev, 0);
> > > > + if (irq < 0) {
> > > > + dev_err(ce->dev, "Cannot get NS IRQ\n");
> > > > + return irq;
> > > > + }
> > > > +
> > > > + err = devm_request_irq(&pdev->dev, irq, ce_irq_handler, 0,
> > > > + "sun8i-ce-ns", ce);
> > > > + if (err < 0) {
> > > > + dev_err(ce->dev, "Cannot request NS IRQ\n");
> > > > + return err;
> > > > + }
> > > > +
> > > > + ce->reset = devm_reset_control_get_optional(&pdev->dev, "ahb");
> > > > + if (IS_ERR(ce->reset)) {
> > > > + if (PTR_ERR(ce->reset) == -EPROBE_DEFER)
> > > > + return PTR_ERR(ce->reset);
> > > > + dev_info(&pdev->dev, "No reset control found\n");
> > >
> > > It's not optional though.
> >
> > I dont understand why.
>
> On all the SoCs, you need that reset line to be deasserted, otherwise
> the IP (and therefore the driver) will be non-functional. It's not an
> option to run without it.
Currently all the SoC have a reset, but nothing prevent a new SoC with CE without reset.
Anyway, I will made the reset mandatory for the moment.
>
> > > > + ce->reset = NULL;
> > > > + }
> > > > +
> > > > + err = reset_control_deassert(ce->reset);
> > > > + if (err) {
> > > > + dev_err(&pdev->dev, "Cannot deassert reset control\n");
> > > > + goto error_clk;
> > > > + }
> > >
> > > Again, you don't really need this at this moment. Using runtime_pm
> > > would make more sense.
> > >
> > > > + v = readl(ce->base + CE_CTR);
> > > > + v >>= 16;
> > > > + v &= 0x07;
> > >
> > > This should be in a define
> > >
> >
> > Will fix.
> >
> > > > + dev_info(&pdev->dev, "CE_NS Die ID %x\n", v);
> > >
> > > And if that really makes sense to print it, the error message should
> > > be made less cryptic.
> > >
> >
> > Will fix.
> >
> > > > +
> > > > + ce->dev = &pdev->dev;
> > > > + platform_set_drvdata(pdev, ce);
> > > > +
> > > > + mutex_init(&ce->mlock);
> > > > +
> > > > + ce->chanlist = devm_kcalloc(ce->dev, ce->variant->maxflow,
> > > > + sizeof(struct sun8i_ce_flow), GFP_KERNEL);
> > > > + if (!ce->chanlist) {
> > > > + err = -ENOMEM;
> > > > + goto error_flow;
> > > > + }
> > > > +
> > > > + for (i = 0; i < ce->variant->maxflow; i++) {
> > > > + init_completion(&ce->chanlist[i].complete);
> > > > + mutex_init(&ce->chanlist[i].lock);
> > > > +
> > > > + ce->chanlist[i].engine = crypto_engine_alloc_init(ce->dev, true);
> > > > + if (!ce->chanlist[i].engine) {
> > > > + dev_err(ce->dev, "Cannot allocate engine\n");
> > > > + i--;
> > > > + goto error_engine;
> > > > + }
> > > > + err = crypto_engine_start(ce->chanlist[i].engine);
> > > > + if (err) {
> > > > + dev_err(ce->dev, "Cannot start engine\n");
> > > > + goto error_engine;
> > > > + }
> > > > + ce->chanlist[i].tl = dma_alloc_coherent(ce->dev,
> > > > + sizeof(struct ce_task),
> > > > + &ce->chanlist[i].t_phy,
> > > > + GFP_KERNEL);
> > > > + if (!ce->chanlist[i].tl) {
> > > > + dev_err(ce->dev, "Cannot get DMA memory for task %d\n",
> > > > + i);
> > > > + err = -ENOMEM;
> > > > + goto error_engine;
> > > > + }
> > > > + }
> > >
> > > All this initialization should be done before calling
> > > request_irq. You're using some of those fields in your handler.
> >
> > No interrupt could fire, since algorithms are still not registred.
>
> That's not true. Spurious interrupts are a thing, the engine could
> have been left in a weird state by the bootloader / kexec / reboot
> with some pending interrupts, etc.
>
> You have registered that handler already, you should expect it to be
> called at any point in time.
>
Ok will fix.
Thanks for your review.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v2 0/2] mm/kasan: dump alloc/free stack for page allocator
From: Vlastimil Babka @ 2019-09-09 13:07 UTC (permalink / raw)
To: walter-zh.wu, Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov,
Matthias Brugger, Andrew Morton, Martin Schwidefsky, Will Deacon,
Andrey Konovalov, Arnd Bergmann, Thomas Gleixner, Michal Hocko,
Qian Cai
Cc: wsd_upstream, linux-kernel, kasan-dev, linux-mm, linux-mediatek,
linux-arm-kernel
In-Reply-To: <20190909082412.24356-1-walter-zh.wu@mediatek.com>
On 9/9/19 10:24 AM, walter-zh.wu@mediatek.com wrote:
> From: Walter Wu <walter-zh.wu@mediatek.com>
>
> This patch is KASAN report adds the alloc/free stacks for page allocator
> in order to help programmer to see memory corruption caused by page.
>
> By default, KASAN doesn't record alloc and free stack for page allocator.
> It is difficult to fix up page use-after-free or dobule-free issue.
>
> Our patchsets will record the last stack of pages.
> It is very helpful for solving the page use-after-free or double-free.
>
> KASAN report will show the last stack of page, it may be:
> a) If page is in-use state, then it prints alloc stack.
> It is useful to fix up page out-of-bound issue.
I still disagree with duplicating most of page_owner functionality for
the sake of using a single stack handle for both alloc and free (while
page_owner + debug_pagealloc with patches in mmotm uses two handles). It
reduces the amount of potentially important debugging information, and I
really doubt the u32-per-page savings are significant, given the rest of
KASAN overhead.
> BUG: KASAN: slab-out-of-bounds in kmalloc_pagealloc_oob_right+0x88/0x90
> Write of size 1 at addr ffffffc0d64ea00a by task cat/115
> ...
> Allocation stack of page:
> set_page_stack.constprop.1+0x30/0xc8
> kasan_alloc_pages+0x18/0x38
> prep_new_page+0x5c/0x150
> get_page_from_freelist+0xb8c/0x17c8
> __alloc_pages_nodemask+0x1a0/0x11b0
> kmalloc_order+0x28/0x58
> kmalloc_order_trace+0x28/0xe0
> kmalloc_pagealloc_oob_right+0x2c/0x68
>
> b) If page is freed state, then it prints free stack.
> It is useful to fix up page use-after-free or double-free issue.
>
> BUG: KASAN: use-after-free in kmalloc_pagealloc_uaf+0x70/0x80
> Write of size 1 at addr ffffffc0d651c000 by task cat/115
> ...
> Free stack of page:
> kasan_free_pages+0x68/0x70
> __free_pages_ok+0x3c0/0x1328
> __free_pages+0x50/0x78
> kfree+0x1c4/0x250
> kmalloc_pagealloc_uaf+0x38/0x80
>
> This has been discussed, please refer below link.
> https://bugzilla.kernel.org/show_bug.cgi?id=203967
That's not a discussion, but a single comment from Dmitry, which btw
contains "provide alloc *and* free stacks for it" ("it" refers to page,
emphasis mine). It would be nice if he or other KASAN guys could clarify.
> Changes since v1:
> - slim page_owner and move it into kasan
> - enable the feature by default
>
> Signed-off-by: Walter Wu <walter-zh.wu@mediatek.com>
> ---
> include/linux/kasan.h | 1 +
> lib/Kconfig.kasan | 2 ++
> mm/kasan/common.c | 32 ++++++++++++++++++++++++++++++++
> mm/kasan/kasan.h | 5 +++++
> mm/kasan/report.c | 27 +++++++++++++++++++++++++++
> 5 files changed, 67 insertions(+)
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: Status of led-backlight driver
From: Daniel Thompson @ 2019-09-09 13:04 UTC (permalink / raw)
To: Jean-Jacques Hiblot
Cc: mpartap, tony, merlijn, kernel list, sre, nekit1000,
tomi.valkeinen, Pavel Machek, linux-omap, linux-arm-kernel
In-Reply-To: <e40fcd10-85ef-9e04-0960-210736075f1f@ti.com>
On Mon, Sep 09, 2019 at 01:46:39PM +0200, Jean-Jacques Hiblot wrote:
> Hi Daniel,
>
> On 09/09/2019 13:14, Daniel Thompson wrote:
> > On Sat, Sep 07, 2019 at 12:07:27PM +0200, Pavel Machek wrote:
> > > Hi!
> > >
> > > I don't see the LED-backlight driver in -next. Could it be pushed? It
> > > is one of last pieces to get working backlight on Motorola Droid 4...
> > Sorry, I dropped the ball on this and was therefore rather late
> > reviewing this patchset.
> >
> > Assuming I have read the code correctly I think there are some
> > problems with the max_brightness handling in the backlight code.
>
> Can you comment this? I'll be happy to fix the problem.
I did that before replying to the nudges. See:
https://lore.kernel.org/linux-leds/20190909095304.67ehnpg6gckwpno4@holly.lan/
> Reading the v4 again, I noticed that that I still had not removed the
> brightness scaling. Is that the problem ?
Yes (plus a couple of nits).
Daniel.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v2 02/14] soc: ti: k3: add navss ringacc driver
From: Peter Ujfalusi @ 2019-09-09 13:00 UTC (permalink / raw)
To: Tero Kristo, vkoul, robh+dt, nm, ssantosh
Cc: devicetree, grygorii.strashko, lokeshvutla, j-keerthy,
linux-kernel, tony, dmaengine, dan.j.williams, linux-arm-kernel
In-Reply-To: <13e5c02f-7060-3a30-56cb-a9caca9fc85b@ti.com>
Hi,
Grygorii, can you take a look?
On 09/09/2019 9.09, Tero Kristo wrote:
> Hi,
>
> Mostly some cosmetic comments below, other than that seems fine to me.
>
> On 30/07/2019 12:34, Peter Ujfalusi wrote:
>> From: Grygorii Strashko <grygorii.strashko@ti.com>
>>
>> The Ring Accelerator (RINGACC or RA) provides hardware acceleration to
>> enable straightforward passing of work between a producer and a consumer.
>> There is one RINGACC module per NAVSS on TI AM65x SoCs.
>>
>> The RINGACC converts constant-address read and write accesses to
>> equivalent
>> read or write accesses to a circular data structure in memory. The
>> RINGACC
>> eliminates the need for each DMA controller which needs to access ring
>> elements from having to know the current state of the ring (base address,
>> current offset). The DMA controller performs a read or write access to a
>> specific address range (which maps to the source interface on the
>> RINGACC)
>> and the RINGACC replaces the address for the transaction with a new
>> address
>> which corresponds to the head or tail element of the ring (head for
>> reads,
>> tail for writes). Since the RINGACC maintains the state, multiple DMA
>> controllers or channels are allowed to coherently share the same rings as
>> applicable. The RINGACC is able to place data which is destined towards
>> software into cached memory directly.
>>
>> Supported ring modes:
>> - Ring Mode
>> - Messaging Mode
>> - Credentials Mode
>> - Queue Manager Mode
>>
>> TI-SCI integration:
>>
>> Texas Instrument's System Control Interface (TI-SCI) Message Protocol now
>> has control over Ringacc module resources management (RM) and Rings
>> configuration.
>>
>> The corresponding support of TI-SCI Ringacc module RM protocol
>> introduced as option through DT parameters:
>> - ti,sci: phandle on TI-SCI firmware controller DT node
>> - ti,sci-dev-id: TI-SCI device identifier as per TI-SCI firmware spec
>>
>> if both parameters present - Ringacc driver will configure/free/reset
>> Rings
>> using TI-SCI Message Ringacc RM Protocol.
>>
>> The Ringacc driver manages Rings allocation by itself now and requests
>> TI-SCI firmware to allocate and configure specific Rings only. It's done
>> this way because, Linux driver implements two stage Rings allocation and
>> configuration (allocate ring and configure ring) while I-SCI Message
>
> I-SCI should be TI-SCI I believe.
Yes, it supposed to be.
>
>> Protocol supports only one combined operation (allocate+configure).
>>
>> Grygorii Strashko <grygorii.strashko@ti.com>
>
> Above seems to be missing SoB?
Oh, it is really missing.
>
>> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
>> ---
>> drivers/soc/ti/Kconfig | 17 +
>> drivers/soc/ti/Makefile | 1 +
>> drivers/soc/ti/k3-ringacc.c | 1191 +++++++++++++++++++++++++++++
>> include/linux/soc/ti/k3-ringacc.h | 262 +++++++
>> 4 files changed, 1471 insertions(+)
>> create mode 100644 drivers/soc/ti/k3-ringacc.c
>> create mode 100644 include/linux/soc/ti/k3-ringacc.h
>>
>> diff --git a/drivers/soc/ti/Kconfig b/drivers/soc/ti/Kconfig
>> index cf545f428d03..10c76faa503e 100644
>> --- a/drivers/soc/ti/Kconfig
>> +++ b/drivers/soc/ti/Kconfig
>> @@ -80,6 +80,23 @@ config TI_SCI_PM_DOMAINS
>> called ti_sci_pm_domains. Note this is needed early in boot
>> before
>> rootfs may be available.
>> +config TI_K3_RINGACC
>> + tristate "K3 Ring accelerator Sub System"
>> + depends on ARCH_K3 || COMPILE_TEST
>> + depends on TI_SCI_INTA_IRQCHIP
>> + default y
>> + help
>> + Say y here to support the K3 Ring accelerator module.
>> + The Ring Accelerator (RINGACC or RA) provides hardware
>> acceleration
>> + to enable straightforward passing of work between a producer
>> + and a consumer. There is one RINGACC module per NAVSS on TI
>> AM65x SoCs
>> + If unsure, say N.
>> +
>> +config TI_K3_RINGACC_DEBUG
>> + tristate "K3 Ring accelerator Sub System tests and debug"
>> + depends on TI_K3_RINGACC
>> + default n
>> +
>> endif # SOC_TI
>> config TI_SCI_INTA_MSI_DOMAIN
>> diff --git a/drivers/soc/ti/Makefile b/drivers/soc/ti/Makefile
>> index b3868d392d4f..cc4bc8b08bf5 100644
>> --- a/drivers/soc/ti/Makefile
>> +++ b/drivers/soc/ti/Makefile
>> @@ -9,3 +9,4 @@ obj-$(CONFIG_AMX3_PM) += pm33xx.o
>> obj-$(CONFIG_WKUP_M3_IPC) += wkup_m3_ipc.o
>> obj-$(CONFIG_TI_SCI_PM_DOMAINS) += ti_sci_pm_domains.o
>> obj-$(CONFIG_TI_SCI_INTA_MSI_DOMAIN) += ti_sci_inta_msi.o
>> +obj-$(CONFIG_TI_K3_RINGACC) += k3-ringacc.o
>> diff --git a/drivers/soc/ti/k3-ringacc.c b/drivers/soc/ti/k3-ringacc.c
>> new file mode 100644
>> index 000000000000..401dfc963319
>> --- /dev/null
>> +++ b/drivers/soc/ti/k3-ringacc.c
>> @@ -0,0 +1,1191 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * TI K3 NAVSS Ring Accelerator subsystem driver
>> + *
>> + * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com
>> + */
>> +
>> +#include <linux/dma-mapping.h>
>> +#include <linux/io.h>
>> +#include <linux/module.h>
>> +#include <linux/of.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/pm_runtime.h>
>> +#include <linux/soc/ti/k3-ringacc.h>
>> +#include <linux/soc/ti/ti_sci_protocol.h>
>> +#include <linux/soc/ti/ti_sci_inta_msi.h>
>> +#include <linux/of_irq.h>
>> +#include <linux/irqdomain.h>
>> +
>> +static LIST_HEAD(k3_ringacc_list);
>> +static DEFINE_MUTEX(k3_ringacc_list_lock);
>> +
>> +#ifdef CONFIG_TI_K3_RINGACC_DEBUG
>> +#define k3_nav_dbg(dev, arg...) dev_err(dev, arg)
>
> dev_err seems exaggeration for debug purposes, maybe just dev_info.
>
>> +static void dbg_writel(u32 v, void __iomem *reg)
>> +{
>> + pr_err("WRITEL(32): v(%08X)-->reg(%p)\n", v, reg);
>
> Again, maybe just pr_info.
I think I'll just drop CONFIG_TI_K3_RINGACC_DEBUG altogether along with
dbg_writel/dbg_readl/k3_nav_dbg and use dev_dbg() when appropriate.
>
>> + writel(v, reg);
>> +}
>> +
>> +static u32 dbg_readl(void __iomem *reg)
>> +{
>> + u32 v;
>> +
>> + v = readl(reg);
>> + pr_err("READL(32): v(%08X)<--reg(%p)\n", v, reg);
>> + return v;
>> +}
>> +#else
>> +#define k3_nav_dbg(dev, arg...) dev_dbg(dev, arg)
>> +#define dbg_writel(v, reg) writel(v, reg)
>
> Do you need to use hard writel, writel_relaxed is not enough?
not sure if we really need the barriers, but __raw_writel() should be
fine here imho
>> +
>> +#define dbg_readl(reg) readl(reg)
>
> Same as above but for read?
__raw_readl() could be fine in also.
...
>> +/**
>> + * struct k3_ringacc - Rings accelerator descriptor
>> + *
>> + * @dev - pointer on RA device
>> + * @proxy_gcfg - RA proxy global config registers
>> + * @proxy_target_base - RA proxy datapath region
>> + * @num_rings - number of ring in RA
>> + * @rm_gp_range - general purpose rings range from tisci
>> + * @dma_ring_reset_quirk - DMA reset w/a enable
>> + * @num_proxies - number of RA proxies
>> + * @rings - array of rings descriptors (struct @k3_ring)
>> + * @list - list of RAs in the system
>> + * @tisci - pointer ti-sci handle
>> + * @tisci_ring_ops - ti-sci rings ops
>> + * @tisci_dev_id - ti-sci device id
>> + */
>> +struct k3_ringacc {
>> + struct device *dev;
>> + struct k3_ringacc_proxy_gcfg_regs __iomem *proxy_gcfg;
>> + void __iomem *proxy_target_base;
>> + u32 num_rings; /* number of rings in Ringacc module */
>> + unsigned long *rings_inuse;
>> + struct ti_sci_resource *rm_gp_range;
>> +
>> + bool dma_ring_reset_quirk;
>> + u32 num_proxies;
>> + unsigned long *proxy_inuse;
>
> proxy_inuse is not documented above.
I see, I'll update the documentation.
>> +
>> + struct k3_ring *rings;
>> + struct list_head list;
>> + struct mutex req_lock; /* protect rings allocation */
>> +
>> + const struct ti_sci_handle *tisci;
>> + const struct ti_sci_rm_ringacc_ops *tisci_ring_ops;
>> + u32 tisci_dev_id;
>> +};
>> +
>> +static long k3_ringacc_ring_get_fifo_pos(struct k3_ring *ring)
>> +{
>> + return K3_RINGACC_FIFO_WINDOW_SIZE_BYTES -
>> + (4 << ring->elm_size);
>> +}
>> +
>> +static void *k3_ringacc_get_elm_addr(struct k3_ring *ring, u32 idx)
>> +{
>> + return (idx * (4 << ring->elm_size) + ring->ring_mem_virt);
>
> The arithmetic here seems backwards compared to most other code I've
> seen. It would be more readable if you have it like:
>
> ring->ring_mem_virt + idx * (4 << ring->elm_size);
Yes, I'll update.
>
>> +}
>> +
>> +static int k3_ringacc_ring_push_mem(struct k3_ring *ring, void *elem);
>> +static int k3_ringacc_ring_pop_mem(struct k3_ring *ring, void *elem);
>> +
>> +static struct k3_ring_ops k3_ring_mode_ring_ops = {
>> + .push_tail = k3_ringacc_ring_push_mem,
>> + .pop_head = k3_ringacc_ring_pop_mem,
>> +};
>> +
>> +static int k3_ringacc_ring_push_io(struct k3_ring *ring, void *elem);
>> +static int k3_ringacc_ring_pop_io(struct k3_ring *ring, void *elem);
>> +static int k3_ringacc_ring_push_head_io(struct k3_ring *ring, void
>> *elem);
>> +static int k3_ringacc_ring_pop_tail_io(struct k3_ring *ring, void
>> *elem);
>> +
>> +static struct k3_ring_ops k3_ring_mode_msg_ops = {
>> + .push_tail = k3_ringacc_ring_push_io,
>> + .push_head = k3_ringacc_ring_push_head_io,
>> + .pop_tail = k3_ringacc_ring_pop_tail_io,
>> + .pop_head = k3_ringacc_ring_pop_io,
>> +};
>> +
>> +static int k3_ringacc_ring_push_head_proxy(struct k3_ring *ring, void
>> *elem);
>> +static int k3_ringacc_ring_push_tail_proxy(struct k3_ring *ring, void
>> *elem);
>> +static int k3_ringacc_ring_pop_head_proxy(struct k3_ring *ring, void
>> *elem);
>> +static int k3_ringacc_ring_pop_tail_proxy(struct k3_ring *ring, void
>> *elem);
>> +
>> +static struct k3_ring_ops k3_ring_mode_proxy_ops = {
>> + .push_tail = k3_ringacc_ring_push_tail_proxy,
>> + .push_head = k3_ringacc_ring_push_head_proxy,
>> + .pop_tail = k3_ringacc_ring_pop_tail_proxy,
>> + .pop_head = k3_ringacc_ring_pop_head_proxy,
>> +};
>> +
>> +#ifdef CONFIG_TI_K3_RINGACC_DEBUG
>> +void k3_ringacc_ring_dump(struct k3_ring *ring)
>> +{
>> + struct device *dev = ring->parent->dev;
>> +
>> + k3_nav_dbg(dev, "dump ring: %d\n", ring->ring_id);
>> + k3_nav_dbg(dev, "dump mem virt %p, dma %pad\n",
>> + ring->ring_mem_virt, &ring->ring_mem_dma);
>> + k3_nav_dbg(dev, "dump elmsize %d, size %d, mode %d, proxy_id %d\n",
>> + ring->elm_size, ring->size, ring->mode, ring->proxy_id);
>> +
>> + k3_nav_dbg(dev, "dump ring_rt_regs: db%08x\n",
>> + readl(&ring->rt->db));
>
> Why not use readl_relaxed in this func?
__raw_readl() might be enough?
>
>> + k3_nav_dbg(dev, "dump occ%08x\n",
>> + readl(&ring->rt->occ));
>> + k3_nav_dbg(dev, "dump indx%08x\n",
>> + readl(&ring->rt->indx));
>> + k3_nav_dbg(dev, "dump hwocc%08x\n",
>> + readl(&ring->rt->hwocc));
>> + k3_nav_dbg(dev, "dump hwindx%08x\n",
>> + readl(&ring->rt->hwindx));
>> +
>> + if (ring->ring_mem_virt)
>> + print_hex_dump(KERN_ERR, "dump ring_mem_virt ",
>> + DUMP_PREFIX_NONE, 16, 1,
>> + ring->ring_mem_virt, 16 * 8, false);
>> +}
>> +EXPORT_SYMBOL_GPL(k3_ringacc_ring_dump);
>
> Do you really need to export a debug function?
It might come helpful for clients to dump the ring status runtime, but
since we don't have users, I'll move it to static.
>> +#endif
>> +
>> +struct k3_ring *k3_ringacc_request_ring(struct k3_ringacc *ringacc,
>> + int id, u32 flags)
>> +{
>> + int proxy_id = K3_RINGACC_PROXY_NOT_USED;
>> +
>> + mutex_lock(&ringacc->req_lock);
>> +
>> + if (id == K3_RINGACC_RING_ID_ANY) {
>> + /* Request for any general purpose ring */
>> + struct ti_sci_resource_desc *gp_rings =
>> + &ringacc->rm_gp_range->desc[0];
>> + unsigned long size;
>> +
>> + size = gp_rings->start + gp_rings->num;
>> + id = find_next_zero_bit(ringacc->rings_inuse, size,
>> + gp_rings->start);
>> + if (id == size)
>> + goto error;
>> + } else if (id < 0) {
>> + goto error;
>> + }
>> +
>> + if (test_bit(id, ringacc->rings_inuse) &&
>> + !(ringacc->rings[id].flags & K3_RING_FLAG_SHARED))
>> + goto error;
>> + else if (ringacc->rings[id].flags & K3_RING_FLAG_SHARED)
>> + goto out;
>> +
>> + if (flags & K3_RINGACC_RING_USE_PROXY) {
>> + proxy_id = find_next_zero_bit(ringacc->proxy_inuse,
>> + ringacc->num_proxies, 0);
>> + if (proxy_id == ringacc->num_proxies)
>> + goto error;
>> + }
>> +
>> + if (!try_module_get(ringacc->dev->driver->owner))
>> + goto error;
>> +
>> + if (proxy_id != K3_RINGACC_PROXY_NOT_USED) {
>> + set_bit(proxy_id, ringacc->proxy_inuse);
>> + ringacc->rings[id].proxy_id = proxy_id;
>> + k3_nav_dbg(ringacc->dev, "Giving ring#%d proxy#%d\n",
>> + id, proxy_id);
>> + } else {
>> + k3_nav_dbg(ringacc->dev, "Giving ring#%d\n", id);
>> + }
>> +
>> + set_bit(id, ringacc->rings_inuse);
>> +out:
>> + ringacc->rings[id].use_count++;
>> + mutex_unlock(&ringacc->req_lock);
>> + return &ringacc->rings[id];
>> +
>> +error:
>> + mutex_unlock(&ringacc->req_lock);
>> + return NULL;
>> +}
>> +EXPORT_SYMBOL_GPL(k3_ringacc_request_ring);
>> +
>> +static void k3_ringacc_ring_reset_sci(struct k3_ring *ring)
>> +{
>> + struct k3_ringacc *ringacc = ring->parent;
>> + int ret;
>> +
>> + ret = ringacc->tisci_ring_ops->config(
>> + ringacc->tisci,
>> + TI_SCI_MSG_VALUE_RM_RING_COUNT_VALID,
>> + ringacc->tisci_dev_id,
>> + ring->ring_id,
>> + 0,
>> + 0,
>> + ring->size,
>> + 0,
>> + 0,
>> + 0);
>> + if (ret)
>> + dev_err(ringacc->dev, "TISCI reset ring fail (%d) ring_idx
>> %d\n",
>> + ret, ring->ring_id);
>
> Return value of sci ops is masked, why not return it and let the caller
> handle it properly?
>
> Same comment for anything similar that follows.
Hrm, there is not much a caller can do other than PANIC in case the ring
configuration fails.
I can probagate the error, but not sure what action can be taken, if any.
>> +}
>> +
>> +void k3_ringacc_ring_reset(struct k3_ring *ring)
>> +{
>> + if (!ring || !(ring->flags & K3_RING_FLAG_BUSY))
>> + return;
>> +
>> + ring->occ = 0;
>> + ring->free = 0;
>> + ring->rindex = 0;
>> + ring->windex = 0;
>> +
>> + k3_ringacc_ring_reset_sci(ring);
>> +}
>> +EXPORT_SYMBOL_GPL(k3_ringacc_ring_reset);
>> +
>> +static void k3_ringacc_ring_reconfig_qmode_sci(struct k3_ring *ring,
>> + enum k3_ring_mode mode)
>> +{
>> + struct k3_ringacc *ringacc = ring->parent;
>> + int ret;
>> +
>> + ret = ringacc->tisci_ring_ops->config(
>> + ringacc->tisci,
>> + TI_SCI_MSG_VALUE_RM_RING_MODE_VALID,
>> + ringacc->tisci_dev_id,
>> + ring->ring_id,
>> + 0,
>> + 0,
>> + 0,
>> + mode,
>> + 0,
>> + 0);
>> + if (ret)
>> + dev_err(ringacc->dev, "TISCI reconf qmode fail (%d) ring_idx
>> %d\n",
>> + ret, ring->ring_id);
>> +}
>> +
>> +void k3_ringacc_ring_reset_dma(struct k3_ring *ring, u32 occ)
>> +{
>> + if (!ring || !(ring->flags & K3_RING_FLAG_BUSY))
>> + return;
>> +
>> + if (!ring->parent->dma_ring_reset_quirk)
>> + return;
>> +
>> + if (!occ)
>> + occ = dbg_readl(&ring->rt->occ);
>> +
>> + if (occ) {
>> + u32 db_ring_cnt, db_ring_cnt_cur;
>> +
>> + k3_nav_dbg(ring->parent->dev, "%s %u occ: %u\n", __func__,
>> + ring->ring_id, occ);
>> + /* 2. Reset the ring */
>
> 2? Where is 1?
Oh, I'll fix the numbering.
>
>> + k3_ringacc_ring_reset_sci(ring);
>> +
>> + /*
>> + * 3. Setup the ring in ring/doorbell mode
>> + * (if not already in this mode)
>> + */
>> + if (ring->mode != K3_RINGACC_RING_MODE_RING)
>> + k3_ringacc_ring_reconfig_qmode_sci(
>> + ring, K3_RINGACC_RING_MODE_RING);
>> + /*
>> + * 4. Ring the doorbell 2**22 – ringOcc times.
>> + * This will wrap the internal UDMAP ring state occupancy
>> + * counter (which is 21-bits wide) to 0.
>> + */
>> + db_ring_cnt = (1U << 22) - occ;
>> +
>> + while (db_ring_cnt != 0) {
>> + /*
>> + * Ring the doorbell with the maximum count each
>> + * iteration if possible to minimize the total
>> + * of writes
>> + */
>> + if (db_ring_cnt > K3_RINGACC_MAX_DB_RING_CNT)
>> + db_ring_cnt_cur = K3_RINGACC_MAX_DB_RING_CNT;
>> + else
>> + db_ring_cnt_cur = db_ring_cnt;
>> +
>> + writel(db_ring_cnt_cur, &ring->rt->db);
>> + db_ring_cnt -= db_ring_cnt_cur;
>> + }
>> +
>> + /* 5. Restore the original ring mode (if not ring mode) */
>> + if (ring->mode != K3_RINGACC_RING_MODE_RING)
>> + k3_ringacc_ring_reconfig_qmode_sci(ring, ring->mode);
>> + }
>> +
>> + /* 2. Reset the ring */
>
> Again 2?
I'll drop the '2.'
>
>> + k3_ringacc_ring_reset(ring);
>> +}
>> +EXPORT_SYMBOL_GPL(k3_ringacc_ring_reset_dma);
>> +
>> +static void k3_ringacc_ring_free_sci(struct k3_ring *ring)
>> +{
>> + struct k3_ringacc *ringacc = ring->parent;
>> + int ret;
>> +
>> + ret = ringacc->tisci_ring_ops->config(
>> + ringacc->tisci,
>> + TI_SCI_MSG_VALUE_RM_ALL_NO_ORDER,
>> + ringacc->tisci_dev_id,
>> + ring->ring_id,
>> + 0,
>> + 0,
>> + 0,
>> + 0,
>> + 0,
>> + 0);
>> + if (ret)
>> + dev_err(ringacc->dev, "TISCI ring free fail (%d) ring_idx %d\n",
>> + ret, ring->ring_id);
>> +}
>> +
>> +int k3_ringacc_ring_free(struct k3_ring *ring)
>> +{
>> + struct k3_ringacc *ringacc;
>> +
>> + if (!ring)
>> + return -EINVAL;
>> +
>> + ringacc = ring->parent;
>> +
>> + k3_nav_dbg(ring->parent->dev, "flags: 0x%08x\n", ring->flags);
>> +
>> + if (!test_bit(ring->ring_id, ringacc->rings_inuse))
>> + return -EINVAL;
>> +
>> + mutex_lock(&ringacc->req_lock);
>> +
>> + if (--ring->use_count)
>> + goto out;
>> +
>> + if (!(ring->flags & K3_RING_FLAG_BUSY))
>> + goto no_init;
>> +
>> + k3_ringacc_ring_free_sci(ring);
>> +
>> + dma_free_coherent(ringacc->dev,
>> + ring->size * (4 << ring->elm_size),
>> + ring->ring_mem_virt, ring->ring_mem_dma);
>> + ring->flags = 0;
>> + ring->ops = NULL;
>> + if (ring->proxy_id != K3_RINGACC_PROXY_NOT_USED) {
>> + clear_bit(ring->proxy_id, ringacc->proxy_inuse);
>> + ring->proxy = NULL;
>> + ring->proxy_id = K3_RINGACC_PROXY_NOT_USED;
>> + }
>> +
>> +no_init:
>> + clear_bit(ring->ring_id, ringacc->rings_inuse);
>> +
>> + module_put(ringacc->dev->driver->owner);
>> +
>> +out:
>> + mutex_unlock(&ringacc->req_lock);
>> + return 0;
>> +}
>> +EXPORT_SYMBOL_GPL(k3_ringacc_ring_free);
>> +
>> +u32 k3_ringacc_get_ring_id(struct k3_ring *ring)
>> +{
>> + if (!ring)
>> + return -EINVAL;
>> +
>> + return ring->ring_id;
>> +}
>> +EXPORT_SYMBOL_GPL(k3_ringacc_get_ring_id);
>> +
>> +u32 k3_ringacc_get_tisci_dev_id(struct k3_ring *ring)
>> +{
>> + if (!ring)
>> + return -EINVAL;
>> +
>
> What if parent is NULL? Can it ever be here?
No, parent can not be NULL as the client would not have the ring in the
first place.
>
>> + return ring->parent->tisci_dev_id;
>> +}
>> +EXPORT_SYMBOL_GPL(k3_ringacc_get_tisci_dev_id);
>> +
>> +int k3_ringacc_get_ring_irq_num(struct k3_ring *ring)
>> +{
>> + int irq_num;
>> +
>> + if (!ring)
>> + return -EINVAL;
>> +
>> + irq_num = ti_sci_inta_msi_get_virq(ring->parent->dev,
>> ring->ring_id);
>> + if (irq_num <= 0)
>> + irq_num = -EINVAL;
>> + return irq_num;
>> +}
>> +EXPORT_SYMBOL_GPL(k3_ringacc_get_ring_irq_num);
>> +
>> +static int k3_ringacc_ring_cfg_sci(struct k3_ring *ring)
>> +{
>> + struct k3_ringacc *ringacc = ring->parent;
>> + u32 ring_idx;
>> + int ret;
>> +
>> + if (!ringacc->tisci)
>> + return -EINVAL;
>> +
>> + ring_idx = ring->ring_id;
>> + ret = ringacc->tisci_ring_ops->config(
>> + ringacc->tisci,
>> + TI_SCI_MSG_VALUE_RM_ALL_NO_ORDER,
>> + ringacc->tisci_dev_id,
>> + ring_idx,
>> + lower_32_bits(ring->ring_mem_dma),
>> + upper_32_bits(ring->ring_mem_dma),
>> + ring->size,
>> + ring->mode,
>> + ring->elm_size,
>> + 0);
>> + if (ret)
>> + dev_err(ringacc->dev, "TISCI config ring fail (%d) ring_idx
>> %d\n",
>> + ret, ring_idx);
>> +
>> + return ret;
>> +}
>> +
>> +int k3_ringacc_ring_cfg(struct k3_ring *ring, struct k3_ring_cfg *cfg)
>> +{
>> + struct k3_ringacc *ringacc = ring->parent;
>> + int ret = 0;
>> +
>> + if (!ring || !cfg)
>> + return -EINVAL;
>> + if (cfg->elm_size > K3_RINGACC_RING_ELSIZE_256 ||
>> + cfg->mode > K3_RINGACC_RING_MODE_QM ||
>> + cfg->size & ~K3_RINGACC_CFG_RING_SIZE_ELCNT_MASK ||
>> + !test_bit(ring->ring_id, ringacc->rings_inuse))
>> + return -EINVAL;
>> +
>> + if (ring->use_count != 1)
>
> Hmm, isn't this a failure actually?
Yes, it is: -EBUSY
>> + return 0;
>> +
>> + ring->size = cfg->size;
>> + ring->elm_size = cfg->elm_size;
>> + ring->mode = cfg->mode;
>> + ring->occ = 0;
>> + ring->free = 0;
>> + ring->rindex = 0;
>> + ring->windex = 0;
>> +
>> + if (ring->proxy_id != K3_RINGACC_PROXY_NOT_USED)
>> + ring->proxy = ringacc->proxy_target_base +
>> + ring->proxy_id * K3_RINGACC_PROXY_TARGET_STEP;
>> +
>> + switch (ring->mode) {
>> + case K3_RINGACC_RING_MODE_RING:
>> + ring->ops = &k3_ring_mode_ring_ops;
>> + break;
>> + case K3_RINGACC_RING_MODE_QM:
>> + /*
>> + * In Queue mode elm_size can be 8 only and each operation
>> + * uses 2 element slots
>> + */
>> + if (cfg->elm_size != K3_RINGACC_RING_ELSIZE_8 ||
>> + cfg->size % 2)
>> + goto err_free_proxy;
>> + /* else, fall through */
>> + case K3_RINGACC_RING_MODE_MESSAGE:
>> + if (ring->proxy)
>> + ring->ops = &k3_ring_mode_proxy_ops;
>> + else
>> + ring->ops = &k3_ring_mode_msg_ops;
>> + break;
>> + default:
>> + ring->ops = NULL;
>> + ret = -EINVAL;
>> + goto err_free_proxy;
>> + };
>> +
>> + ring->ring_mem_virt =
>> + dma_alloc_coherent(ringacc->dev,
>> + ring->size * (4 << ring->elm_size),
>> + &ring->ring_mem_dma, GFP_KERNEL);
>> + if (!ring->ring_mem_virt) {
>> + dev_err(ringacc->dev, "Failed to alloc ring mem\n");
>> + ret = -ENOMEM;
>> + goto err_free_ops;
>> + }
>> +
>> + ret = k3_ringacc_ring_cfg_sci(ring);
>> +
>> + if (ret)
>> + goto err_free_mem;
>> +
>> + ring->flags |= K3_RING_FLAG_BUSY;
>> + ring->flags |= (cfg->flags & K3_RINGACC_RING_SHARED) ?
>> + K3_RING_FLAG_SHARED : 0;
>> +
>> + k3_ringacc_ring_dump(ring);
>> +
>> + return 0;
>> +
>> +err_free_mem:
>> + dma_free_coherent(ringacc->dev,
>> + ring->size * (4 << ring->elm_size),
>> + ring->ring_mem_virt,
>> + ring->ring_mem_dma);
>> +err_free_ops:
>> + ring->ops = NULL;
>> +err_free_proxy:
>> + ring->proxy = NULL;
>> + return ret;
>> +}
>> +EXPORT_SYMBOL_GPL(k3_ringacc_ring_cfg);
>> +
>> +u32 k3_ringacc_ring_get_size(struct k3_ring *ring)
>> +{
>> + if (!ring || !(ring->flags & K3_RING_FLAG_BUSY))
>> + return -EINVAL;
>> +
>> + return ring->size;
>> +}
>> +EXPORT_SYMBOL_GPL(k3_ringacc_ring_get_size);
>> +
>> +u32 k3_ringacc_ring_get_free(struct k3_ring *ring)
>> +{
>> + if (!ring || !(ring->flags & K3_RING_FLAG_BUSY))
>> + return -EINVAL;
>> +
>> + if (!ring->free)
>> + ring->free = ring->size - dbg_readl(&ring->rt->occ);
>> +
>> + return ring->free;
>> +}
>> +EXPORT_SYMBOL_GPL(k3_ringacc_ring_get_free);
>> +
>> +u32 k3_ringacc_ring_get_occ(struct k3_ring *ring)
>> +{
>> + if (!ring || !(ring->flags & K3_RING_FLAG_BUSY))
>> + return -EINVAL;
>> +
>> + return dbg_readl(&ring->rt->occ);
>> +}
>> +EXPORT_SYMBOL_GPL(k3_ringacc_ring_get_occ);
>> +
>> +u32 k3_ringacc_ring_is_full(struct k3_ring *ring)
>> +{
>> + return !k3_ringacc_ring_get_free(ring);
>> +}
>> +EXPORT_SYMBOL_GPL(k3_ringacc_ring_is_full);
>> +
>> +enum k3_ringacc_access_mode {
>> + K3_RINGACC_ACCESS_MODE_PUSH_HEAD,
>> + K3_RINGACC_ACCESS_MODE_POP_HEAD,
>> + K3_RINGACC_ACCESS_MODE_PUSH_TAIL,
>> + K3_RINGACC_ACCESS_MODE_POP_TAIL,
>> + K3_RINGACC_ACCESS_MODE_PEEK_HEAD,
>> + K3_RINGACC_ACCESS_MODE_PEEK_TAIL,
>> +};
>> +
>> +static int k3_ringacc_ring_cfg_proxy(struct k3_ring *ring,
>> + enum k3_ringacc_proxy_access_mode mode)
>> +{
>> + u32 val;
>> +
>> + val = ring->ring_id;
>> + val |= mode << 16;
>> + val |= ring->elm_size << 24;
>
> Would be nice to have these magic shifts as defines.
OK, I'll add defines for the magic shifts.
>
>> + dbg_writel(val, &ring->proxy->control);
>> + return 0;
>> +}
>> +
Thanks for the review,
- Péter
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v2 1/2] mm/page_ext: support to record the last stack of page
From: Vlastimil Babka @ 2019-09-09 12:59 UTC (permalink / raw)
To: Walter Wu, Andrey Ryabinin, Alexander Potapenko, Dmitry Vyukov,
Matthias Brugger, Andrew Morton, Martin Schwidefsky, Will Deacon,
Andrey Konovalov, Arnd Bergmann, Thomas Gleixner, Michal Hocko,
Qian Cai
Cc: wsd_upstream, linux-kernel, kasan-dev, linux-mm, linux-mediatek,
linux-arm-kernel
In-Reply-To: <20190909085339.25350-1-walter-zh.wu@mediatek.com>
On 9/9/19 10:53 AM, Walter Wu wrote:
> KASAN will record last stack of page in order to help programmer
> to see memory corruption caused by page.
>
> What is difference between page_owner and our patch?
> page_owner records alloc stack of page, but our patch is to record
> last stack(it may be alloc or free stack of page).
>
> Signed-off-by: Walter Wu <walter-zh.wu@mediatek.com>
There's no point in separating this from patch 2 (and as David pointed
out, doesn't compile).
> ---
> mm/page_ext.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/mm/page_ext.c b/mm/page_ext.c
> index 5f5769c7db3b..7ca33dcd9ffa 100644
> --- a/mm/page_ext.c
> +++ b/mm/page_ext.c
> @@ -65,6 +65,9 @@ static struct page_ext_operations *page_ext_ops[] = {
> #if defined(CONFIG_IDLE_PAGE_TRACKING) && !defined(CONFIG_64BIT)
> &page_idle_ops,
> #endif
> +#ifdef CONFIG_KASAN
> + &page_stack_ops,
> +#endif
> };
>
> static unsigned long total_usage;
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v5 01/11] kselftest: arm64: add skeleton Makefile
From: Amit Kachhap @ 2019-09-09 12:42 UTC (permalink / raw)
To: Cristian Marussi, linux-kselftest@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, shuah@kernel.org
Cc: andreyknvl@google.com, Dave P Martin
In-Reply-To: <e7b7b3fe-aba8-a4f2-400b-7cdeebd080e8@arm.com>
Hi,
On 9/5/19 11:27 PM, Cristian Marussi wrote:
> Hi Amit
>
> On 03/09/2019 10:26, Amit Kachhap wrote:
>>
>> Hi Cristian,
>>
>> On 9/2/19 4:59 PM, Cristian Marussi wrote:
>>> Add a new arm64-specific empty subsystem amongst TARGETS of KSFT build
>>> framework; keep these new arm64 KSFT testcases separated into distinct
>>> subdirs inside tools/testing/selftests/arm64/ depending on the specific
>>> subsystem targeted.
>>>
>>> Add into toplevel arm64 KSFT Makefile a mechanism to guess the effective
>>> location of Kernel headers as installed by KSFT framework.
>>>
>>> Merge with
>>>
>>> commit 9ce1263033cd ("selftests, arm64: add a selftest for passing
>>> tagged pointers to kernel")
>>>
>>> while moving such KSFT tags tests inside their own subdirectory
>>> (arm64/tags).
>>>
>>> Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
>>> ---
>>> v4 --> v5
>>> - rebased on arm64/for-next/core
>>> - merged this patch with KSFT arm64 tags patch, while moving the latter
>>> into its own subdir
>>> - moved kernel header includes search mechanism from KSFT arm64
>>> SIGNAL Makefile
>> This approach breaks the compilation of individual test cases which need
>> to export includes individually.
>>
>> make -C tools/testing/selftests/arm64/signal
>>
>> ../../lib.mk:25: ../../../../scripts/subarch.include: No such file or
>> directory
>> Makefile:25: warning: overriding recipe for target 'clean'
>> ../../lib.mk:123: warning: ignoring old recipe for target 'clean'
>> make: *** No rule to make target '../../../../scripts/subarch.include'.
>> Stop.
>>
>> However tags test works well,
>> make -C tools/testing/selftests/arm64/tags
>>
>> aarch64-none-linux-gnu-gcc tags_test.c -o
>> /home/amikac01/work/MTE_WORK/linux-server/linux/tools/testing/selftests/arm64/tags/tags_test
>>
>>
>> Thanks,
>> Amit Daniel
>>
>
> So at the end I think I'll opt for the following in V6 regarding the issue of being able to build specific
> KSFT arm64 subsystems while properly searching kernel headers (and keeping compatible with the KSFT
> framework completely):
>
> - only arm64 toplevel KSFT Makefile searches for the kernel headers location for all and propagates down the info
>
> - you can also now optionally specify which arm64 subsystem to build (to avoid have to build, say, all of signal/
> if you are not interested into....a sort of standalone mode without all the burden of the old standalone mode)
ok.
>
> So you can issue:
>
> $ make TARGETS=arm64 kselftest
>
> or similarly:
>
> $ make -C tools/testing/selftests TARGETS=arm64 \
> INSTALL_PATH=<your-installation-path> install
>
> or select subsystems:
>
> $ make -C tools/testing/selftests TARGETS=arm64 SUBTARGETS="tags signal" \
> INSTALL_PATH=<your-installation-path> install
This option will be useful as it is better to compile just one subtarget
in development phase.
Thanks,
Amit
>
> with all of the above looking for the K headers in the proper place and without
> duplicating the search code in multiple places. (bugs apart :D)
>
> Thanks
>
> Cristian
>
>>> - export proper top_srcdir ENV for lib.mk
>>> v3 --> v4
>>> - comment reword
>>> - simplified documentation in README
>>> - dropped README about standalone
>>> ---
>>> tools/testing/selftests/Makefile | 1 +
>>> tools/testing/selftests/arm64/Makefile | 70 +++++++++++++++++--
>>> tools/testing/selftests/arm64/README | 20 ++++++
>>> tools/testing/selftests/arm64/tags/Makefile | 10 +++
>>> .../arm64/{ => tags}/run_tags_test.sh | 0
>>> .../selftests/arm64/{ => tags}/tags_test.c | 0
>>> 6 files changed, 95 insertions(+), 6 deletions(-)
>>> create mode 100644 tools/testing/selftests/arm64/README
>>> create mode 100644 tools/testing/selftests/arm64/tags/Makefile
>>> rename tools/testing/selftests/arm64/{ => tags}/run_tags_test.sh (100%)
>>> rename tools/testing/selftests/arm64/{ => tags}/tags_test.c (100%)
>>>
>>> diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
>>> index 25b43a8c2b15..1722dae9381a 100644
>>> --- a/tools/testing/selftests/Makefile
>>> +++ b/tools/testing/selftests/Makefile
>>> @@ -1,5 +1,6 @@
>>> # SPDX-License-Identifier: GPL-2.0
>>> TARGETS = android
>>> +TARGETS += arm64
>>> TARGETS += bpf
>>> TARGETS += breakpoints
>>> TARGETS += capabilities
>>> diff --git a/tools/testing/selftests/arm64/Makefile b/tools/testing/selftests/arm64/Makefile
>>> index a61b2e743e99..5dbb0ffdfc9a 100644
>>> --- a/tools/testing/selftests/arm64/Makefile
>>> +++ b/tools/testing/selftests/arm64/Makefile
>>> @@ -1,11 +1,69 @@
>>> # SPDX-License-Identifier: GPL-2.0
>>> +# Copyright (C) 2019 ARM Limited
>>>
>>> -# ARCH can be overridden by the user for cross compiling
>>> -ARCH ?= $(shell uname -m 2>/dev/null || echo not)
>>> +# When ARCH not overridden for crosscompiling, lookup machine
>>> +ARCH ?= $(shell uname -m)
>>> +ARCH := $(shell echo $(ARCH) | sed -e s/aarch64/arm64/)
>>>
>>> -ifneq (,$(filter $(ARCH),aarch64 arm64))
>>> -TEST_GEN_PROGS := tags_test
>>> -TEST_PROGS := run_tags_test.sh
>>> +ifeq ("x$(ARCH)", "xarm64")
>>> +SUBDIRS := tags
>>> +else
>>> +SUBDIRS :=
>>> endif
>>>
>>> -include ../lib.mk
>>> +CFLAGS := -Wall -O2 -g
>>> +
>>> +# A proper top_srcdir is needed by KSFT(lib.mk)
>>> +top_srcdir = ../../../../..
>>> +
>>> +# Additional include paths needed by kselftest.h and local headers
>>> +CFLAGS += -I$(top_srcdir)/tools/testing/selftests/
>>> +
>>> +# Guessing where the Kernel headers could have been installed
>>> +# depending on ENV config
>>> +ifeq ($(KBUILD_OUTPUT),)
>>> +khdr_dir = $(top_srcdir)/usr/include
>>> +else
>>> +# the KSFT preferred location when KBUILD_OUTPUT is set
>>> +khdr_dir = $(KBUILD_OUTPUT)/kselftest/usr/include
>>> +endif
>>> +
>>> +CFLAGS += -I$(khdr_dir)
>>> +
>>> +export CC
>>> +export CFLAGS
>>> +export top_srcdir
>>> +
>>> +all:
>>> + @for DIR in $(SUBDIRS); do \
>>> + BUILD_TARGET=$(OUTPUT)/$$DIR; \
>>> + mkdir -p $$BUILD_TARGET; \
>>> + make OUTPUT=$$BUILD_TARGET -C $$DIR $@; \
>>> + done
>>> +
>>> +install: all
>>> + @for DIR in $(SUBDIRS); do \
>>> + BUILD_TARGET=$(OUTPUT)/$$DIR; \
>>> + make OUTPUT=$$BUILD_TARGET -C $$DIR $@; \
>>> + done
>>> +
>>> +run_tests: all
>>> + @for DIR in $(SUBDIRS); do \
>>> + BUILD_TARGET=$(OUTPUT)/$$DIR; \
>>> + make OUTPUT=$$BUILD_TARGET -C $$DIR $@; \
>>> + done
>>> +
>>> +# Avoid any output on non arm64 on emit_tests
>>> +emit_tests: all
>>> + @for DIR in $(SUBDIRS); do \
>>> + BUILD_TARGET=$(OUTPUT)/$$DIR; \
>>> + make OUTPUT=$$BUILD_TARGET -C $$DIR $@; \
>>> + done
>>> +
>>> +clean:
>>> + @for DIR in $(SUBDIRS); do \
>>> + BUILD_TARGET=$(OUTPUT)/$$DIR; \
>>> + make OUTPUT=$$BUILD_TARGET -C $$DIR $@; \
>>> + done
>>> +
>>> +.PHONY: all clean install run_tests emit_tests
>>> diff --git a/tools/testing/selftests/arm64/README b/tools/testing/selftests/arm64/README
>>> new file mode 100644
>>> index 000000000000..aca892e62a6c
>>> --- /dev/null
>>> +++ b/tools/testing/selftests/arm64/README
>>> @@ -0,0 +1,20 @@
>>> +KSelfTest ARM64
>>> +===============
>>> +
>>> +- These tests are arm64 specific and so not built or run but just skipped
>>> + completely when env-variable ARCH is found to be different than 'arm64'
>>> + and `uname -m` reports other than 'aarch64'.
>>> +
>>> +- Holding true the above, ARM64 KSFT tests can be run within the KSelfTest
>>> + framework using standard Linux top-level-makefile targets:
>>> +
>>> + $ make TARGETS=arm64 kselftest-clean
>>> + $ make TARGETS=arm64 kselftest
>>> +
>>> + or
>>> +
>>> + $ make -C tools/testing/selftests TARGETS=arm64 \
>>> + INSTALL_PATH=<your-installation-path> install
>>> +
>>> + Further details on building and running KFST can be found in:
>>> + Documentation/dev-tools/kselftest.rst
>>> diff --git a/tools/testing/selftests/arm64/tags/Makefile b/tools/testing/selftests/arm64/tags/Makefile
>>> new file mode 100644
>>> index 000000000000..76205533135b
>>> --- /dev/null
>>> +++ b/tools/testing/selftests/arm64/tags/Makefile
>>> @@ -0,0 +1,10 @@
>>> +# SPDX-License-Identifier: GPL-2.0
>>> +# ARCH can be overridden by the user for cross compiling
>>> +ARCH ?= $(shell uname -m 2>/dev/null || echo not)
>>> +
>>> +ifneq (,$(filter $(ARCH),aarch64 arm64))
>>> +TEST_GEN_PROGS := tags_test
>>> +TEST_PROGS := run_tags_test.sh
>>> +endif
>>> +
>>> +include ../../lib.mk
>>> diff --git a/tools/testing/selftests/arm64/run_tags_test.sh b/tools/testing/selftests/arm64/tags/run_tags_test.sh
>>> similarity index 100%
>>> rename from tools/testing/selftests/arm64/run_tags_test.sh
>>> rename to tools/testing/selftests/arm64/tags/run_tags_test.sh
>>> diff --git a/tools/testing/selftests/arm64/tags_test.c b/tools/testing/selftests/arm64/tags/tags_test.c
>>> similarity index 100%
>>> rename from tools/testing/selftests/arm64/tags_test.c
>>> rename to tools/testing/selftests/arm64/tags/tags_test.c
>>>
>
>
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v4 00/10] Allwinner sunxi message box support
From: Ondřej Jirman @ 2019-09-09 12:36 UTC (permalink / raw)
To: Samuel Holland
Cc: Mark Rutland, devicetree, linux-sunxi, Maxime Ripard,
Michael Turquette, Jassi Brar, linux-kernel, Stephen Boyd,
Chen-Yu Tsai, Rob Herring, Corentin Labbe, linux-clk,
linux-arm-kernel
In-Reply-To: <bb6eab9a-f9cc-81ca-5e8c-9fb867c61ec2@sholland.org>
Hi,
On Sun, Sep 08, 2019 at 10:54:17PM -0500, Samuel Holland wrote:
> On 9/8/19 10:22 PM, Ondřej Jirman wrote:
> > Hello Samuel,
> >
> > On Mon, Aug 19, 2019 at 10:23:01PM -0500, Samuel Holland wrote:
> >> This series adds support for the "hardware message box" in sun8i, sun9i,
> >> and sun50i SoCs, used for communication with the ARISC management
> >> processor (the platform's equivalent of the ARM SCP). The end goal is to
> >> use the arm_scpi driver as a client, communicating with firmware running
> >> on the AR100 CPU, or to use the mailbox to forward NMIs that the
> >> firmware picks up from R_INTC.
> >>
> >> Unfortunately, the ARM SCPI client no longer works with this driver
> >> since it now exposes all 8 hardware FIFOs individually. The SCPI client
> >> could be made to work (and I posted proof-of-concept code to that effect
> >> with v1 of this series), but that is a low priority, as Linux does not
> >> directly use SCPI with the current firmware version; all SCPI use goes
> >> through ATF via PSCI.
> >>
> >> As requested in the comments to v3 of this patchset, a demo client is
> >> provided in the final patch. This demo goes along with a toy firmware
> >> which shows that the driver does indeed work for two-way communication
> >> on all channels. To build the firmware component, run:
> >
> > I've tried using this driver with mainline arm_scpi driver (which is probably
> > an expected future use, since crust provides SCPI interface).
>
> If you've verified in some way that this driver works on A83T, I'd appreciate
> your Tested-by, so I can send a patch for the A83T device tree node.
Tested-by: Ondrej Jirman <megous@megous.com>
(on A83T)
> > The problem I've found is that arm_scpi expects message box to be
> > bi-directional, but this driver provides uni-directional interface.
> >
> > What do you think about making this driver provide bi-directional interface?
> > We could halve the number of channels to 4 and mandate TX/RX configuration
> > (from main CPU's PoV) as ABI.
>
> Funny you mention that. That's what I did originally for v1, but it got NAKed by
> Maxime, Andre, and Jassi:
>
> https://lkml.org/lkml/2018/2/28/125
> https://lkml.org/lkml/2018/2/28/944
>
> > Otherwise it's impossible to use it with the arm_scpi driver.
> >
> > Or do you have any other ideas? I guess arm_scpi can be fixed to add a
> > property that would make it possible to use single shmem with two
> > mailboxes, one for rx and one for tx, but making sun6i mailbox have
> > bi-directional interface sounds easier.
>
> Yes, you can use the existence of the mbox-names property to determine if the
> driver needs one mailbox or two, as I did in this driver:
>
> https://lkml.org/lkml/2019/3/1/789
>
> I'll have a patch available soon that implements this for arm_scpi.
Yeah, I've patched arm_scpi too. :)
https://megous.com/git/linux/commit/?h=tbs-5.3&id=69a0cd0093a63039ace2f763e8d82009c50ff03c
(but that's just for the test, because it breaks the existing interface for
other uses)
Anyway, using mbox-names looks like a nice solution! Thanks! Though,
arm_scpi driver has a bit more complicated existing interface, where it can use
multiple mailboxes and rotates through them after every message.
BTW, I'm slowly laboring through understanding how to get suspend to ram working
on one A83T tablet. https://xnux.eu/tablet-hacking/ Which is how I tested this
driver.
regards,
o.
> Cheers,
> Samuel
>
> > regards,
> > o.
> >
> >> git clone https://github.com/crust-firmware/meta meta
> >> git clone -b mailbox-demo https://github.com/crust-firmware/crust meta/crust
> >> cd meta
> >> make
> >>
> >> That will by default produce a U-Boot + ATF + SCP firmware image in
> >> [meta/]build/pinebook/u-boot-sunxi-with-spl.bin. See the top-level
> >> README.md for more information, such as cross-compiler setup.
> >>
> >> I've now used this driver with three separate clients over the past two
> >> years, and they all work. If there are no remaining concerns with the
> >> driver, I'd like it to get merged.
> >>
> >> Even without the driver, the clock patches (1-2) can go in at any time.
> >>
> >> Changes from v3:
> >> - Rebased on sunxi-next
> >> - Added Rob's Reviewed-by for patch 3
> >> - Fixed a crash when receiving a message on a disabled channel
> >> - Cleaned up some comments/formatting in the driver
> >> - Fixed #mbox-cells in sunxi-h3-h5.dtsi (patch 7)
> >> - Removed the irqchip example (no longer relevant to the fw design)
> >> - Added a demo/example client that uses the driver and a toy firmware
> >>
> >> Changes from v2:
> >> - Merge patches 1-3
> >> - Add a comment in the code explaining the CLK_IS_CRITICAL usage
> >> - Add a patch to mark the AR100 clocks as critical
> >> - Use YAML for the device tree binding
> >> - Include a not-for-merge example usage of the mailbox
> >>
> >> Changes from v1:
> >> - Marked message box clocks as critical instead of hacks in the driver
> >> - 8 unidirectional channels instead of 4 bidirectional pairs
> >> - Use per-SoC compatible strings and an A31 fallback compatible
> >> - Dropped the mailbox framework patch
> >> - Include DT patches for SoCs that document the message box
> >>
> >> Samuel Holland (10):
> >> clk: sunxi-ng: Mark msgbox clocks as critical
> >> clk: sunxi-ng: Mark AR100 clocks as critical
> >> dt-bindings: mailbox: Add a sunxi message box binding
> >> mailbox: sunxi-msgbox: Add a new mailbox driver
> >> ARM: dts: sunxi: a80: Add msgbox node
> >> ARM: dts: sunxi: a83t: Add msgbox node
> >> ARM: dts: sunxi: h3/h5: Add msgbox node
> >> arm64: dts: allwinner: a64: Add msgbox node
> >> arm64: dts: allwinner: h6: Add msgbox node
> >> [DO NOT MERGE] drivers: firmware: msgbox demo
> >>
> >> .../mailbox/allwinner,sunxi-msgbox.yaml | 79 +++++
> >> arch/arm/boot/dts/sun8i-a83t.dtsi | 10 +
> >> arch/arm/boot/dts/sun9i-a80.dtsi | 10 +
> >> arch/arm/boot/dts/sunxi-h3-h5.dtsi | 10 +
> >> arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 34 ++
> >> arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi | 24 ++
> >> arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 10 +
> >> drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 3 +-
> >> drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c | 2 +-
> >> drivers/clk/sunxi-ng/ccu-sun50i-h6.c | 3 +-
> >> drivers/clk/sunxi-ng/ccu-sun8i-a23.c | 3 +-
> >> drivers/clk/sunxi-ng/ccu-sun8i-a33.c | 3 +-
> >> drivers/clk/sunxi-ng/ccu-sun8i-a83t.c | 3 +-
> >> drivers/clk/sunxi-ng/ccu-sun8i-h3.c | 3 +-
> >> drivers/clk/sunxi-ng/ccu-sun8i-r.c | 2 +-
> >> drivers/clk/sunxi-ng/ccu-sun9i-a80.c | 3 +-
> >> drivers/firmware/Kconfig | 6 +
> >> drivers/firmware/Makefile | 1 +
> >> drivers/firmware/sunxi_msgbox_demo.c | 307 +++++++++++++++++
> >> drivers/mailbox/Kconfig | 10 +
> >> drivers/mailbox/Makefile | 2 +
> >> drivers/mailbox/sunxi-msgbox.c | 323 ++++++++++++++++++
> >> 22 files changed, 842 insertions(+), 9 deletions(-)
> >> create mode 100644 Documentation/devicetree/bindings/mailbox/allwinner,sunxi-msgbox.yaml
> >> create mode 100644 drivers/firmware/sunxi_msgbox_demo.c
> >> create mode 100644 drivers/mailbox/sunxi-msgbox.c
> >>
> >> --
> >> 2.21.0
> >>
> >> _______________________________________________
> >> linux-arm-kernel mailing list
> >> linux-arm-kernel@lists.infradead.org
> >> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 2/2] KVM: arm/arm64: Allow user injection of external data aborts
From: Peter Maydell @ 2019-09-09 12:32 UTC (permalink / raw)
To: Christoffer Dall
Cc: Daniel P. Berrangé, Suzuki K Poulose, Marc Zyngier,
James Morse, Julien Thierry, Stefan Hajnoczi, Heinrich Schuchardt,
Alexander Graf, kvmarm, arm-mail-list
In-Reply-To: <20190909121337.27287-3-christoffer.dall@arm.com>
On Mon, 9 Sep 2019 at 13:13, Christoffer Dall <christoffer.dall@arm.com> wrote:
>
> In some scenarios, such as buggy guest or incorrect configuration of the
> VMM and firmware description data, userspace will detect a memory access
> to a portion of the IPA, which is not mapped to any MMIO region.
>
> For this purpose, the appropriate action is to inject an external abort
> to the guest. The kernel already has functionality to inject an
> external abort, but we need to wire up a signal from user space that
> lets user space tell the kernel to do this.
>
> It turns out, we already have the set event functionality which we can
> perfectly reuse for this.
>
> Signed-off-by: Christoffer Dall <christoffer.dall@arm.com>
> ---
> Documentation/virt/kvm/api.txt | 15 ++++++++++++++-
> arch/arm/include/uapi/asm/kvm.h | 3 ++-
> arch/arm/kvm/guest.c | 3 +++
> arch/arm64/include/uapi/asm/kvm.h | 3 ++-
> arch/arm64/kvm/guest.c | 3 +++
> arch/arm64/kvm/inject_fault.c | 4 ++--
> include/uapi/linux/kvm.h | 1 +
> virt/kvm/arm/arm.c | 1 +
> 8 files changed, 28 insertions(+), 5 deletions(-)
>
> diff --git a/Documentation/virt/kvm/api.txt b/Documentation/virt/kvm/api.txt
> index 02501333f746..edd6cdc470ca 100644
> --- a/Documentation/virt/kvm/api.txt
> +++ b/Documentation/virt/kvm/api.txt
> @@ -955,6 +955,8 @@ The following bits are defined in the flags field:
>
> ARM/ARM64:
>
> +User space may need to inject several types of events to the guest.
> +
> If the guest accesses a device that is being emulated by the host kernel in
> such a way that a real device would generate a physical SError, KVM may make
> a virtual SError pending for that VCPU. This system error interrupt remains
> @@ -989,12 +991,23 @@ Specifying exception.has_esr on a system that does not support it will return
> -EINVAL. Setting anything other than the lower 24bits of exception.serror_esr
> will return -EINVAL.
>
> +If the guest performed an access to I/O memory which could not be handled by
> +user space, for example because of missing instruction syndrome decode
> +information or because there is no device mapped at the accessed IPA, then
> +user space can ask the kernel to inject an external abort using the address
> +from the exiting fault on the VCPU. It is a programming error to set
> +ext_dabt_pending at the same time as any of the serror fields, or to set
> +ext_dabt_pending on an exit which was not either KVM_EXIT_MMIO or
> +KVM_EXIT_ARM_NISV. This feature is only available if the system supports
> +KVM_CAP_ARM_INJECT_EXT_DABT;
> +
> struct kvm_vcpu_events {
> struct {
> __u8 serror_pending;
> __u8 serror_has_esr;
> + __u8 ext_dabt_pending;
> /* Align it to 8 bytes */
> - __u8 pad[6];
> + __u8 pad[5];
> __u64 serror_esr;
> } exception;
> __u32 reserved[12];
This API seems to be missing support for userspace to specify
whether the ESR_ELx for the guest should have the EA bit set
(and more generally other syndrome/fault status bits). I think
if we have an API for "KVM_EXIT_MMIO but the access failed"
then it should either (a) be architecture agnostic, since
pretty much any architecture might have a concept of "access
gave some bus-error-type failure" and it would be nice if userspace
didn't have to special case them all in arch-specific code,
or (b) have the same flexibility for specifying exactly what
kind of fault as the architecture does. This sort of seems to
fall between two stools. (My ideal for KVM_EXIT_MMIO faults
would be a generic API which included space for optional
arch-specific info, which for Arm would pretty much just be
the EA bit.)
As and when we support nested virtualization, any suggestions
on how this API would extend to support userspace saying
"deliver fault to guest EL1" vs "deliver fault to guest EL2" ?
thanks
-- PMM
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH V4 00/11] clk: imx8: add new clock binding for better pm support
From: Oliver Graute @ 2019-09-09 12:21 UTC (permalink / raw)
To: Dong Aisheng
Cc: sboyd@kernel.org, mturquette@baylibre.com, linux-imx@nxp.com,
kernel@pengutronix.de, fabio.estevam@nxp.com, shawnguo@kernel.org,
linux-clk@vger.kernel.org, linux-arm-kernel@lists.infradead.org
In-Reply-To: <1566299605-15641-1-git-send-email-aisheng.dong@nxp.com>
On 20/08/19, Dong Aisheng wrote:
> This is a follow up of this patch series.
> https://patchwork.kernel.org/cover/10924029/
> [V2,0/2] clk: imx: scu: add parsing clocks from device tree support
I would like to test this version (v4) of your series on my imx8qm
board. Last time (v3) I need this patch series ontop:
https://patchwork.kernel.org/project/linux-arm-kernel/list/?series=146521
Is there an updated version too? On which linux-next branch should I
apply your changes?
Best Regards,
Oliver
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [kvmtool PATCH 5/5] arm: Inject external data aborts when accessing holes in the memory map
From: Christoffer Dall @ 2019-09-09 12:13 UTC (permalink / raw)
To: kvmarm
Cc: Peter Maydell, Daniel P. Berrangé, Suzuki K Poulose,
Marc Zyngier, Christoffer Dall, James Morse, Julien Thierry,
Stefan Hajnoczi, Heinrich Schuchardt, Alexander Graf,
linux-arm-kernel
In-Reply-To: <20190909121337.27287-1-christoffer.dall@arm.com>
Occasionally guests will attempt to access parts of the guest memory map
where there is... nothing at all. Until now, we've handled this by
either forcefully killing the guest, or silently (unless a debug option
was enabled) ignoring the access. Neither is very helpful to a user,
who is most likely running either a broken or misconfigured guest.
A more appropriate action is to inject an external abort to the guest.
Luckily, with KVM_CAP_ARM_INJECT_EXT_DABT, we can use the set event
mechanism and ask KVM to do this for us.
So we add an architecture specific hook to handle accesses to MMIO
regions which cannot be found, and allow them to return if the invalid
access was handled or not.
Signed-off-by: Christoffer Dall <christoffer.dall@arm.com>
---
arm/include/arm-common/kvm-cpu-arch.h | 16 ++++++++++++++++
arm/kvm-cpu.c | 2 +-
mips/include/kvm/kvm-cpu-arch.h | 5 +++++
mmio.c | 3 ++-
powerpc/include/kvm/kvm-cpu-arch.h | 5 +++++
x86/include/kvm/kvm-cpu-arch.h | 5 +++++
6 files changed, 34 insertions(+), 2 deletions(-)
diff --git a/arm/include/arm-common/kvm-cpu-arch.h b/arm/include/arm-common/kvm-cpu-arch.h
index 923d2c4..33defa2 100644
--- a/arm/include/arm-common/kvm-cpu-arch.h
+++ b/arm/include/arm-common/kvm-cpu-arch.h
@@ -57,6 +57,22 @@ static inline bool kvm_cpu__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr,
return kvm__emulate_mmio(vcpu, phys_addr, data, len, is_write);
}
+static inline bool kvm_cpu__mmio_not_found(struct kvm_cpu *vcpu, u64 phys_addr)
+{
+ struct kvm_vcpu_events events = {
+ .exception.ext_dabt_pending = 1,
+ };
+ int err;
+
+ if (!kvm__supports_extension(vcpu->kvm, KVM_CAP_ARM_INJECT_EXT_DABT))
+ return false;
+
+ err = ioctl(vcpu->vcpu_fd, KVM_SET_VCPU_EVENTS, &events);
+ if (err)
+ die("failed to inject external abort");
+ return true;
+}
+
unsigned long kvm_cpu__get_vcpu_mpidr(struct kvm_cpu *vcpu);
#endif /* ARM_COMMON__KVM_CPU_ARCH_H */
diff --git a/arm/kvm-cpu.c b/arm/kvm-cpu.c
index 25bd3ed..321a3e4 100644
--- a/arm/kvm-cpu.c
+++ b/arm/kvm-cpu.c
@@ -142,7 +142,7 @@ bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu)
if (!arm_addr_in_ioport_region(phys_addr) &&
!kvm__mmio_exists(vcpu, phys_addr))
- die("Guest accessed memory outside RAM and IO ranges");
+ return kvm_cpu__mmio_not_found(vcpu, phys_addr);
/*
* We cannot fetch and decode instructions from a KVM guest,
diff --git a/mips/include/kvm/kvm-cpu-arch.h b/mips/include/kvm/kvm-cpu-arch.h
index 45e69f6..512ab34 100644
--- a/mips/include/kvm/kvm-cpu-arch.h
+++ b/mips/include/kvm/kvm-cpu-arch.h
@@ -40,4 +40,9 @@ static inline bool kvm_cpu__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8
return kvm__emulate_mmio(vcpu, phys_addr, data, len, is_write);
}
+static inline bool kvm_cpu__mmio_not_found(struct kvm_cpu *vcpu, u64 phys_addr)
+{
+ return false;
+}
+
#endif /* KVM__KVM_CPU_ARCH_H */
diff --git a/mmio.c b/mmio.c
index 2ab7fa7..d6df303 100644
--- a/mmio.c
+++ b/mmio.c
@@ -130,7 +130,8 @@ bool kvm__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 *data, u32 len, u
if (mmio)
mmio->mmio_fn(vcpu, phys_addr, data, len, is_write, mmio->ptr);
else {
- if (vcpu->kvm->cfg.mmio_debug)
+ if (!kvm_cpu__mmio_not_found(vcpu, phys_addr) &&
+ vcpu->kvm->cfg.mmio_debug)
fprintf(stderr, "Warning: Ignoring MMIO %s at %016llx (length %u)\n",
to_direction(is_write),
(unsigned long long)phys_addr, len);
diff --git a/powerpc/include/kvm/kvm-cpu-arch.h b/powerpc/include/kvm/kvm-cpu-arch.h
index a69e0cc..64b69b1 100644
--- a/powerpc/include/kvm/kvm-cpu-arch.h
+++ b/powerpc/include/kvm/kvm-cpu-arch.h
@@ -76,4 +76,9 @@ static inline bool kvm_cpu__emulate_io(struct kvm_cpu *vcpu, u16 port, void *dat
bool kvm_cpu__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 *data, u32 len, u8 is_write);
+static inline bool kvm_cpu__mmio_not_found(struct kvm_cpu *vcpu, u64 phys_addr)
+{
+ return false;
+}
+
#endif /* KVM__KVM_CPU_ARCH_H */
diff --git a/x86/include/kvm/kvm-cpu-arch.h b/x86/include/kvm/kvm-cpu-arch.h
index 05e5bb6..10cbe6e 100644
--- a/x86/include/kvm/kvm-cpu-arch.h
+++ b/x86/include/kvm/kvm-cpu-arch.h
@@ -47,4 +47,9 @@ static inline bool kvm_cpu__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8
return kvm__emulate_mmio(vcpu, phys_addr, data, len, is_write);
}
+static inline bool kvm_cpu__mmio_not_found(struct kvm_cpu *vcpu, u64 phys_addr)
+{
+ return false;
+}
+
#endif /* KVM__KVM_CPU_ARCH_H */
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [kvmtool PATCH 4/5] arm: Handle exits from undecoded load/store instructions
From: Christoffer Dall @ 2019-09-09 12:13 UTC (permalink / raw)
To: kvmarm
Cc: Peter Maydell, Daniel P. Berrangé, Suzuki K Poulose,
Marc Zyngier, Christoffer Dall, James Morse, Julien Thierry,
Stefan Hajnoczi, Heinrich Schuchardt, Alexander Graf,
linux-arm-kernel
In-Reply-To: <20190909121337.27287-1-christoffer.dall@arm.com>
KVM occasionally encounters guests that attempt to access memory outside
the registered RAM memory slots using instructions that don't provide
decoding information in the ESR_EL2 (the ISV bit is not set), and
historically this has led to the kernel printing a confusing error
message in dmesg and returning -ENOYSYS from KVM_RUN.
KVM/Arm now has KVM_CAP_ARM_NISV_TO_USER, which can be enabled from
userspace, and which allows us to handle this with a little bit more
helpful information to the user. For example, we can at least tell the
user if the guest just hit a hole in the guest's memory map, or if this
appeared to be an attempt at doing MMIO.
Signed-off-by: Christoffer Dall <christoffer.dall@arm.com>
---
arm/kvm-cpu.c | 20 +++++++++++++++++++-
arm/kvm.c | 8 ++++++++
include/kvm/kvm.h | 1 +
kvm.c | 1 +
mmio.c | 11 +++++++++++
5 files changed, 40 insertions(+), 1 deletion(-)
diff --git a/arm/kvm-cpu.c b/arm/kvm-cpu.c
index 7780251..25bd3ed 100644
--- a/arm/kvm-cpu.c
+++ b/arm/kvm-cpu.c
@@ -136,7 +136,25 @@ void kvm_cpu__delete(struct kvm_cpu *vcpu)
bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu)
{
- return false;
+ switch (vcpu->kvm_run->exit_reason) {
+ case KVM_EXIT_ARM_NISV: {
+ u64 phys_addr = vcpu->kvm_run->arm_nisv.fault_ipa;
+
+ if (!arm_addr_in_ioport_region(phys_addr) &&
+ !kvm__mmio_exists(vcpu, phys_addr))
+ die("Guest accessed memory outside RAM and IO ranges");
+
+ /*
+ * We cannot fetch and decode instructions from a KVM guest,
+ * which used a load/store instruction that doesn't get
+ * decoded in the ESR towards an I/O device, so we have no
+ * choice but to exit to the user with an error.
+ */
+ die("Guest accessed I/O device with unsupported load/store instruction");
+ }
+ default:
+ return false;
+ }
}
void kvm_cpu__show_page_tables(struct kvm_cpu *vcpu)
diff --git a/arm/kvm.c b/arm/kvm.c
index 1f85fc6..2572ac2 100644
--- a/arm/kvm.c
+++ b/arm/kvm.c
@@ -59,6 +59,8 @@ void kvm__arch_set_cmdline(char *cmdline, bool video)
void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
{
+ struct kvm_enable_cap enable_cap = { .flags = 0 };
+
/*
* Allocate guest memory. We must align our buffer to 64K to
* correlate with the maximum guest page size for virtio-mmio.
@@ -83,6 +85,12 @@ void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
madvise(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size,
MADV_HUGEPAGE);
+ if (kvm__supports_extension(kvm, KVM_CAP_ARM_NISV_TO_USER)) {
+ enable_cap.cap = KVM_CAP_ARM_NISV_TO_USER;
+ if (ioctl(kvm->vm_fd, KVM_ENABLE_CAP, &enable_cap) < 0)
+ die("unable to enable NISV_TO_USER capability");
+ }
+
/* Create the virtual GIC. */
if (gic__create(kvm, kvm->cfg.arch.irqchip))
die("Failed to create virtual GIC");
diff --git a/include/kvm/kvm.h b/include/kvm/kvm.h
index 7a73818..05d90ee 100644
--- a/include/kvm/kvm.h
+++ b/include/kvm/kvm.h
@@ -107,6 +107,7 @@ bool kvm__emulate_io(struct kvm_cpu *vcpu, u16 port, void *data, int direction,
bool kvm__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 *data, u32 len, u8 is_write);
int kvm__register_mem(struct kvm *kvm, u64 guest_phys, u64 size, void *userspace_addr,
enum kvm_mem_type type);
+bool kvm__mmio_exists(struct kvm_cpu *vcpu, u64 phys_addr);
static inline int kvm__register_ram(struct kvm *kvm, u64 guest_phys, u64 size,
void *userspace_addr)
{
diff --git a/kvm.c b/kvm.c
index 57c4ff9..03ec43f 100644
--- a/kvm.c
+++ b/kvm.c
@@ -55,6 +55,7 @@ const char *kvm_exit_reasons[] = {
#ifdef CONFIG_PPC64
DEFINE_KVM_EXIT_REASON(KVM_EXIT_PAPR_HCALL),
#endif
+ DEFINE_KVM_EXIT_REASON(KVM_EXIT_ARM_NISV),
};
static int pause_event;
diff --git a/mmio.c b/mmio.c
index 61e1d47..2ab7fa7 100644
--- a/mmio.c
+++ b/mmio.c
@@ -139,3 +139,14 @@ bool kvm__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 *data, u32 len, u
return true;
}
+
+bool kvm__mmio_exists(struct kvm_cpu *vcpu, u64 phys_addr)
+{
+ struct mmio_mapping *mmio;
+
+ br_read_lock(vcpu->kvm);
+ mmio = mmio_search(&mmio_tree, phys_addr, 1);
+ br_read_unlock(vcpu->kvm);
+
+ return mmio != NULL;
+}
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [kvmtool PATCH 3/5] update headers: Update the KVM headers for new Arm fault reporting features
From: Christoffer Dall @ 2019-09-09 12:13 UTC (permalink / raw)
To: kvmarm
Cc: Peter Maydell, Daniel P. Berrangé, Suzuki K Poulose,
Marc Zyngier, Christoffer Dall, James Morse, Julien Thierry,
Stefan Hajnoczi, Heinrich Schuchardt, Alexander Graf,
linux-arm-kernel
In-Reply-To: <20190909121337.27287-1-christoffer.dall@arm.com>
In preparation for improving our handling of guest aborts with missing
decode info or outside any mapped resource, sync updated Linux header
files.
NOTE: This is a development update and these headers are not yet in an
upstream tree. DO NOT MERGE.
Signed-off-by: Christoffer Dall <christoffer.dall@arm.com>
---
arm/aarch32/include/asm/kvm.h | 3 ++-
arm/aarch64/include/asm/kvm.h | 3 ++-
include/linux/kvm.h | 8 ++++++++
3 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/arm/aarch32/include/asm/kvm.h b/arm/aarch32/include/asm/kvm.h
index 4602464..b450900 100644
--- a/arm/aarch32/include/asm/kvm.h
+++ b/arm/aarch32/include/asm/kvm.h
@@ -131,8 +131,9 @@ struct kvm_vcpu_events {
struct {
__u8 serror_pending;
__u8 serror_has_esr;
+ __u8 ext_dabt_pending;
/* Align it to 8 bytes */
- __u8 pad[6];
+ __u8 pad[5];
__u64 serror_esr;
} exception;
__u32 reserved[12];
diff --git a/arm/aarch64/include/asm/kvm.h b/arm/aarch64/include/asm/kvm.h
index 97c3478..e4cf9bd 100644
--- a/arm/aarch64/include/asm/kvm.h
+++ b/arm/aarch64/include/asm/kvm.h
@@ -160,8 +160,9 @@ struct kvm_vcpu_events {
struct {
__u8 serror_pending;
__u8 serror_has_esr;
+ __u8 ext_dabt_pending;
/* Align it to 8 bytes */
- __u8 pad[6];
+ __u8 pad[5];
__u64 serror_esr;
} exception;
__u32 reserved[12];
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 6d4ea4b..6e2d2df 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -235,6 +235,7 @@ struct kvm_hyperv_exit {
#define KVM_EXIT_S390_STSI 25
#define KVM_EXIT_IOAPIC_EOI 26
#define KVM_EXIT_HYPERV 27
+#define KVM_EXIT_ARM_NISV 28
/* For KVM_EXIT_INTERNAL_ERROR */
/* Emulate instruction failed. */
@@ -392,6 +393,11 @@ struct kvm_run {
} eoi;
/* KVM_EXIT_HYPERV */
struct kvm_hyperv_exit hyperv;
+ /* KVM_EXIT_ARM_NISV */
+ struct {
+ __u64 esr_iss;
+ __u64 fault_ipa;
+ } arm_nisv;
/* Fix the size of the union. */
char padding[256];
};
@@ -988,6 +994,8 @@ struct kvm_ppc_resize_hpt {
#define KVM_CAP_ARM_VM_IPA_SIZE 165
#define KVM_CAP_MANUAL_DIRTY_LOG_PROTECT 166
#define KVM_CAP_HYPERV_CPUID 167
+#define KVM_CAP_ARM_NISV_TO_USER 174
+#define KVM_CAP_ARM_INJECT_EXT_DABT 175
#ifdef KVM_CAP_IRQ_ROUTING
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 2/2] KVM: arm/arm64: Allow user injection of external data aborts
From: Christoffer Dall @ 2019-09-09 12:13 UTC (permalink / raw)
To: kvmarm
Cc: Peter Maydell, Daniel P. Berrangé, Suzuki K Poulose,
Marc Zyngier, Christoffer Dall, James Morse, Julien Thierry,
Stefan Hajnoczi, Heinrich Schuchardt, Alexander Graf,
linux-arm-kernel
In-Reply-To: <20190909121337.27287-1-christoffer.dall@arm.com>
In some scenarios, such as buggy guest or incorrect configuration of the
VMM and firmware description data, userspace will detect a memory access
to a portion of the IPA, which is not mapped to any MMIO region.
For this purpose, the appropriate action is to inject an external abort
to the guest. The kernel already has functionality to inject an
external abort, but we need to wire up a signal from user space that
lets user space tell the kernel to do this.
It turns out, we already have the set event functionality which we can
perfectly reuse for this.
Signed-off-by: Christoffer Dall <christoffer.dall@arm.com>
---
Documentation/virt/kvm/api.txt | 15 ++++++++++++++-
arch/arm/include/uapi/asm/kvm.h | 3 ++-
arch/arm/kvm/guest.c | 3 +++
arch/arm64/include/uapi/asm/kvm.h | 3 ++-
arch/arm64/kvm/guest.c | 3 +++
arch/arm64/kvm/inject_fault.c | 4 ++--
include/uapi/linux/kvm.h | 1 +
virt/kvm/arm/arm.c | 1 +
8 files changed, 28 insertions(+), 5 deletions(-)
diff --git a/Documentation/virt/kvm/api.txt b/Documentation/virt/kvm/api.txt
index 02501333f746..edd6cdc470ca 100644
--- a/Documentation/virt/kvm/api.txt
+++ b/Documentation/virt/kvm/api.txt
@@ -955,6 +955,8 @@ The following bits are defined in the flags field:
ARM/ARM64:
+User space may need to inject several types of events to the guest.
+
If the guest accesses a device that is being emulated by the host kernel in
such a way that a real device would generate a physical SError, KVM may make
a virtual SError pending for that VCPU. This system error interrupt remains
@@ -989,12 +991,23 @@ Specifying exception.has_esr on a system that does not support it will return
-EINVAL. Setting anything other than the lower 24bits of exception.serror_esr
will return -EINVAL.
+If the guest performed an access to I/O memory which could not be handled by
+user space, for example because of missing instruction syndrome decode
+information or because there is no device mapped at the accessed IPA, then
+user space can ask the kernel to inject an external abort using the address
+from the exiting fault on the VCPU. It is a programming error to set
+ext_dabt_pending at the same time as any of the serror fields, or to set
+ext_dabt_pending on an exit which was not either KVM_EXIT_MMIO or
+KVM_EXIT_ARM_NISV. This feature is only available if the system supports
+KVM_CAP_ARM_INJECT_EXT_DABT;
+
struct kvm_vcpu_events {
struct {
__u8 serror_pending;
__u8 serror_has_esr;
+ __u8 ext_dabt_pending;
/* Align it to 8 bytes */
- __u8 pad[6];
+ __u8 pad[5];
__u64 serror_esr;
} exception;
__u32 reserved[12];
diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h
index a4217c1a5d01..d2449a5bf8d5 100644
--- a/arch/arm/include/uapi/asm/kvm.h
+++ b/arch/arm/include/uapi/asm/kvm.h
@@ -131,8 +131,9 @@ struct kvm_vcpu_events {
struct {
__u8 serror_pending;
__u8 serror_has_esr;
+ __u8 ext_dabt_pending;
/* Align it to 8 bytes */
- __u8 pad[6];
+ __u8 pad[5];
__u64 serror_esr;
} exception;
__u32 reserved[12];
diff --git a/arch/arm/kvm/guest.c b/arch/arm/kvm/guest.c
index 684cf64b4033..4154c5589501 100644
--- a/arch/arm/kvm/guest.c
+++ b/arch/arm/kvm/guest.c
@@ -263,11 +263,14 @@ int __kvm_arm_vcpu_set_events(struct kvm_vcpu *vcpu,
{
bool serror_pending = events->exception.serror_pending;
bool has_esr = events->exception.serror_has_esr;
+ bool has_ext_dabt_pending = events->exception.ext_dabt_pending;
if (serror_pending && has_esr)
return -EINVAL;
else if (serror_pending)
kvm_inject_vabt(vcpu);
+ else if (has_ext_dabt_pending)
+ kvm_inject_dabt(vcpu, kvm_vcpu_get_hfar(vcpu));
return 0;
}
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index 9a507716ae2f..7729efdb1c0c 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -164,8 +164,9 @@ struct kvm_vcpu_events {
struct {
__u8 serror_pending;
__u8 serror_has_esr;
+ __u8 ext_dabt_pending;
/* Align it to 8 bytes */
- __u8 pad[6];
+ __u8 pad[5];
__u64 serror_esr;
} exception;
__u32 reserved[12];
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index dfd626447482..10e6e2144dca 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -720,6 +720,7 @@ int __kvm_arm_vcpu_set_events(struct kvm_vcpu *vcpu,
{
bool serror_pending = events->exception.serror_pending;
bool has_esr = events->exception.serror_has_esr;
+ bool has_ext_dabt_pending = events->exception.ext_dabt_pending;
if (serror_pending && has_esr) {
if (!cpus_have_const_cap(ARM64_HAS_RAS_EXTN))
@@ -731,6 +732,8 @@ int __kvm_arm_vcpu_set_events(struct kvm_vcpu *vcpu,
return -EINVAL;
} else if (serror_pending) {
kvm_inject_vabt(vcpu);
+ } else if (has_ext_dabt_pending) {
+ kvm_inject_dabt(vcpu, kvm_vcpu_get_hfar(vcpu));
}
return 0;
diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c
index a9d25a305af5..ccdb6a051ab2 100644
--- a/arch/arm64/kvm/inject_fault.c
+++ b/arch/arm64/kvm/inject_fault.c
@@ -109,7 +109,7 @@ static void inject_undef64(struct kvm_vcpu *vcpu)
/**
* kvm_inject_dabt - inject a data abort into the guest
- * @vcpu: The VCPU to receive the undefined exception
+ * @vcpu: The VCPU to receive the data abort
* @addr: The address to report in the DFAR
*
* It is assumed that this code is called from the VCPU thread and that the
@@ -125,7 +125,7 @@ void kvm_inject_dabt(struct kvm_vcpu *vcpu, unsigned long addr)
/**
* kvm_inject_pabt - inject a prefetch abort into the guest
- * @vcpu: The VCPU to receive the undefined exception
+ * @vcpu: The VCPU to receive the prefetch abort
* @addr: The address to report in the DFAR
*
* It is assumed that this code is called from the VCPU thread and that the
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index dd79235b6435..a80ee820e700 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -1003,6 +1003,7 @@ struct kvm_ppc_resize_hpt {
#define KVM_CAP_ARM_PTRAUTH_GENERIC 172
#define KVM_CAP_PMU_EVENT_FILTER 173
#define KVM_CAP_ARM_NISV_TO_USER 174
+#define KVM_CAP_ARM_INJECT_EXT_DABT 175
#ifdef KVM_CAP_IRQ_ROUTING
diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
index 7153504bb106..56a97dd9b292 100644
--- a/virt/kvm/arm/arm.c
+++ b/virt/kvm/arm/arm.c
@@ -217,6 +217,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
case KVM_CAP_IMMEDIATE_EXIT:
case KVM_CAP_VCPU_EVENTS:
case KVM_CAP_ARM_NISV_TO_USER:
+ case KVM_CAP_ARM_INJECT_EXT_DABT:
r = 1;
break;
case KVM_CAP_ARM_SET_DEVICE_ADDR:
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 1/2] KVM: arm/arm64: Allow reporting non-ISV data aborts to userspace
From: Christoffer Dall @ 2019-09-09 12:13 UTC (permalink / raw)
To: kvmarm
Cc: Peter Maydell, Daniel P. Berrangé, Suzuki K Poulose,
Marc Zyngier, Christoffer Dall, James Morse, Julien Thierry,
Stefan Hajnoczi, Heinrich Schuchardt, Alexander Graf,
linux-arm-kernel
In-Reply-To: <20190909121337.27287-1-christoffer.dall@arm.com>
For a long time, if a guest accessed memory outside of a memslot using
any of the load/store instructions in the architecture which doesn't
supply decoding information in the ESR_EL2 (the ISV bit is not set), the
kernel would print the following message and terminate the VM as a
result of returning -ENOSYS to userspace:
load/store instruction decoding not implemented
The reason behind this message is that KVM assumes that all accesses
outside a memslot is an MMIO access which should be handled by
userspace, and we originally expected to eventually implement some sort
of decoding of load/store instructions where the ISV bit was not set.
However, it turns out that many of the instructions which don't provide
decoding information on abort are not safe to use for MMIO accesses, and
the remaining few that would potentially make sense to use on MMIO
accesses, such as those with register writeback, are not used in
practice. It also turns out that fetching an instruction from guest
memory can be a pretty horrible affair, involving stopping all CPUs on
SMP systems, handling multiple corner cases of address translation in
software, and more. It doesn't appear likely that we'll ever implement
this in the kernel.
What is much more common is that a user has misconfigured his/her guest
and is actually not accessing an MMIO region, but just hitting some
random hole in the IPA space. In this scenario, the error message above
is almost misleading and has led to a great deal of confusion over the
years.
It is, nevertheless, ABI to userspace, and we therefore need to
introduce a new capability that userspace explicitly enables to change
behavior.
This patch introduces KVM_CAP_ARM_NISV_TO_USER (NISV meaning Non-ISV)
which does exactly that, and introduces a new exit reason to report the
event to userspace. User space can then emulate an exception to the
guest, restart the guest, suspend the guest, or take any other
appropriate action as per the policy of the running system.
Reported-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Christoffer Dall <christoffer.dall@arm.com>
---
Documentation/virt/kvm/api.txt | 29 ++++++++++++++++++++++++++++
arch/arm/include/asm/kvm_arm.h | 2 ++
arch/arm/include/asm/kvm_emulate.h | 5 +++++
arch/arm/include/asm/kvm_host.h | 8 ++++++++
arch/arm64/include/asm/kvm_emulate.h | 5 +++++
arch/arm64/include/asm/kvm_host.h | 8 ++++++++
include/uapi/linux/kvm.h | 7 +++++++
virt/kvm/arm/arm.c | 21 ++++++++++++++++++++
virt/kvm/arm/mmio.c | 11 +++++++++--
9 files changed, 94 insertions(+), 2 deletions(-)
diff --git a/Documentation/virt/kvm/api.txt b/Documentation/virt/kvm/api.txt
index 2d067767b617..02501333f746 100644
--- a/Documentation/virt/kvm/api.txt
+++ b/Documentation/virt/kvm/api.txt
@@ -4453,6 +4453,35 @@ Hyper-V SynIC state change. Notification is used to remap SynIC
event/message pages and to enable/disable SynIC messages/events processing
in userspace.
+ /* KVM_EXIT_ARM_NISV */
+ struct {
+ __u64 esr_iss;
+ __u64 fault_ipa;
+ } arm_nisv;
+
+Used on arm and arm64 systems. If a guest accesses memory not in a memslot,
+KVM will typically return to userspace and ask it to do MMIO emulation on its
+behalf. However, for certain classes of instructions, no instruction decode
+(direction, length of memory access) is provided, and fetching and decoding
+the instruction from the VM is overly complicated to live in the kernel.
+
+Historically, when this situation occurred, KVM would print a warning and kill
+the VM. KVM assumed that if the guest accessed non-memslot memory, it was
+trying to do I/O, which just couldn't be emulated, and the warning message was
+phrased accordingly. However, what happened more often was that a guest bug
+caused access outside the guest memory areas which should lead to a more
+mearningful warning message and an external abort in the guest, if the access
+did not fall within an I/O window.
+
+Userspace implementations can query for KVM_CAP_ARM_NISV_TO_USER, and enable
+this capability at VM creation. Once this is done, these types of errors will
+instead return to userspace with KVM_EXIT_ARM_NISV, with the valid bits from
+the HSR (arm) and ESR_EL2 (arm64) in the esr_iss field, and the faulting IPA
+in the fault_ipa field. Userspace can either fix up the access if it's
+actually an I/O access by decoding the instruction from guest memory (if it's
+very brave) and continue executing the guest, or it can decide to suspend,
+dump, or restart the guest.
+
/* Fix the size of the union. */
char padding[256];
};
diff --git a/arch/arm/include/asm/kvm_arm.h b/arch/arm/include/asm/kvm_arm.h
index 0125aa059d5b..ce61b3b0058d 100644
--- a/arch/arm/include/asm/kvm_arm.h
+++ b/arch/arm/include/asm/kvm_arm.h
@@ -162,6 +162,8 @@
#define HSR_ISV (_AC(1, UL) << HSR_ISV_SHIFT)
#define HSR_SRT_SHIFT (16)
#define HSR_SRT_MASK (0xf << HSR_SRT_SHIFT)
+#define HSR_CM (1 << 8)
+#define HSR_WNR (1 << 6)
#define HSR_FSC (0x3f)
#define HSR_FSC_TYPE (0x3c)
#define HSR_SSE (1 << 21)
diff --git a/arch/arm/include/asm/kvm_emulate.h b/arch/arm/include/asm/kvm_emulate.h
index 40002416efec..e8ef349c04b4 100644
--- a/arch/arm/include/asm/kvm_emulate.h
+++ b/arch/arm/include/asm/kvm_emulate.h
@@ -167,6 +167,11 @@ static inline bool kvm_vcpu_dabt_isvalid(struct kvm_vcpu *vcpu)
return kvm_vcpu_get_hsr(vcpu) & HSR_ISV;
}
+static inline unsigned long kvm_vcpu_dabt_iss_nisv_sanitized(const struct kvm_vcpu *vcpu)
+{
+ return kvm_vcpu_get_hsr(vcpu) & (HSR_CM | HSR_WNR | HSR_FSC);
+}
+
static inline bool kvm_vcpu_dabt_iswrite(struct kvm_vcpu *vcpu)
{
return kvm_vcpu_get_hsr(vcpu) & HSR_WNR;
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index 8a37c8e89777..19a92c49039c 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -76,6 +76,14 @@ struct kvm_arch {
/* Mandated version of PSCI */
u32 psci_version;
+
+ /*
+ * If we encounter a data abort without valid instruction syndrome
+ * information, report this to user space. User space can (and
+ * should) opt in to this feature if KVM_CAP_ARM_NISV_TO_USER is
+ * supported.
+ */
+ bool return_nisv_io_abort_to_user;
};
#define KVM_NR_MEM_OBJS 40
diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index d69c1efc63e7..a3c967988e1d 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -258,6 +258,11 @@ static inline bool kvm_vcpu_dabt_isvalid(const struct kvm_vcpu *vcpu)
return !!(kvm_vcpu_get_hsr(vcpu) & ESR_ELx_ISV);
}
+static inline unsigned long kvm_vcpu_dabt_iss_nisv_sanitized(const struct kvm_vcpu *vcpu)
+{
+ return kvm_vcpu_get_hsr(vcpu) & (ESR_ELx_CM | ESR_ELx_WNR | ESR_ELx_FSC);
+}
+
static inline bool kvm_vcpu_dabt_issext(const struct kvm_vcpu *vcpu)
{
return !!(kvm_vcpu_get_hsr(vcpu) & ESR_ELx_SSE);
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index f656169db8c3..019bc560edc1 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -83,6 +83,14 @@ struct kvm_arch {
/* Mandated version of PSCI */
u32 psci_version;
+
+ /*
+ * If we encounter a data abort without valid instruction syndrome
+ * information, report this to user space. User space can (and
+ * should) opt in to this feature if KVM_CAP_ARM_NISV_TO_USER is
+ * supported.
+ */
+ bool return_nisv_io_abort_to_user;
};
#define KVM_NR_MEM_OBJS 40
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 5e3f12d5359e..dd79235b6435 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -235,6 +235,7 @@ struct kvm_hyperv_exit {
#define KVM_EXIT_S390_STSI 25
#define KVM_EXIT_IOAPIC_EOI 26
#define KVM_EXIT_HYPERV 27
+#define KVM_EXIT_ARM_NISV 28
/* For KVM_EXIT_INTERNAL_ERROR */
/* Emulate instruction failed. */
@@ -392,6 +393,11 @@ struct kvm_run {
} eoi;
/* KVM_EXIT_HYPERV */
struct kvm_hyperv_exit hyperv;
+ /* KVM_EXIT_ARM_NISV */
+ struct {
+ __u64 esr_iss;
+ __u64 fault_ipa;
+ } arm_nisv;
/* Fix the size of the union. */
char padding[256];
};
@@ -996,6 +1002,7 @@ struct kvm_ppc_resize_hpt {
#define KVM_CAP_ARM_PTRAUTH_ADDRESS 171
#define KVM_CAP_ARM_PTRAUTH_GENERIC 172
#define KVM_CAP_PMU_EVENT_FILTER 173
+#define KVM_CAP_ARM_NISV_TO_USER 174
#ifdef KVM_CAP_IRQ_ROUTING
diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
index 35a069815baf..7153504bb106 100644
--- a/virt/kvm/arm/arm.c
+++ b/virt/kvm/arm/arm.c
@@ -98,6 +98,26 @@ int kvm_arch_check_processor_compat(void)
return 0;
}
+int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
+ struct kvm_enable_cap *cap)
+{
+ int r;
+
+ if (cap->flags)
+ return -EINVAL;
+
+ switch (cap->cap) {
+ case KVM_CAP_ARM_NISV_TO_USER:
+ r = 0;
+ kvm->arch.return_nisv_io_abort_to_user = true;
+ break;
+ default:
+ r = -EINVAL;
+ break;
+ }
+
+ return r;
+}
/**
* kvm_arch_init_vm - initializes a VM data structure
@@ -196,6 +216,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
case KVM_CAP_MP_STATE:
case KVM_CAP_IMMEDIATE_EXIT:
case KVM_CAP_VCPU_EVENTS:
+ case KVM_CAP_ARM_NISV_TO_USER:
r = 1;
break;
case KVM_CAP_ARM_SET_DEVICE_ADDR:
diff --git a/virt/kvm/arm/mmio.c b/virt/kvm/arm/mmio.c
index 6af5c91337f2..7b92e2744fa7 100644
--- a/virt/kvm/arm/mmio.c
+++ b/virt/kvm/arm/mmio.c
@@ -167,8 +167,15 @@ int io_mem_abort(struct kvm_vcpu *vcpu, struct kvm_run *run,
if (ret)
return ret;
} else {
- kvm_err("load/store instruction decoding not implemented\n");
- return -ENOSYS;
+ if (vcpu->kvm->arch.return_nisv_io_abort_to_user) {
+ run->exit_reason = KVM_EXIT_ARM_NISV;
+ run->arm_nisv.esr_iss = kvm_vcpu_dabt_iss_nisv_sanitized(vcpu);
+ run->arm_nisv.fault_ipa = fault_ipa;
+ return 0;
+ } else {
+ kvm_info("Encountered data abort outside memslots with no valid syndrome info\n");
+ return -ENOSYS;
+ }
}
rt = vcpu->arch.mmio_decode.rt;
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 0/2] Improve handling of stage 2 aborts without instruction decode
From: Christoffer Dall @ 2019-09-09 12:13 UTC (permalink / raw)
To: kvmarm
Cc: Peter Maydell, Daniel P. Berrangé, Suzuki K Poulose,
Marc Zyngier, Christoffer Dall, James Morse, Julien Thierry,
Stefan Hajnoczi, Heinrich Schuchardt, Alexander Graf,
linux-arm-kernel
When a guest accesses memory outside the memory slots, KVM usually
bounces the access back to userspace with KVM_EXIT_MMIO. However, on
arm/arm64 systems, certain load/store instructions did not provide
decoding info for the hypervisor to emulate the instruction, and in this
case KVM has rather rudely returned -ENOSYS and printed a not overly
helpful error message:
load/store instruction decoding not implemented
This patch series improves the error message and allows userspace to be
notified of this event instead of receiving -ENOSYS, and also allows
userspace to ask KVM to inject an external abort to the guest, which it
can use for any memory access that it either cannot handle.
One remaining case which this patch set does not address is if the guest
accesses an in-kernel emulated device, such as the VGIC, but using a
load/store instruction which doesn't provide decode info. With these
patches, this will return to userspace for it to handle, but there's no
way for userspace to return the decoding information to KVM and have KVM
complete the access to the in-kernel emulated device. I have no plans
to address this limitation.
Christoffer Dall (2):
KVM: arm/arm64: Allow reporting non-ISV data aborts to userspace
KVM: arm/arm64: Allow user injection of external data aborts
Documentation/virt/kvm/api.txt | 44 +++++++++++++++++++++++++++-
arch/arm/include/asm/kvm_arm.h | 2 ++
arch/arm/include/asm/kvm_emulate.h | 5 ++++
arch/arm/include/asm/kvm_host.h | 8 +++++
arch/arm/include/uapi/asm/kvm.h | 3 +-
arch/arm/kvm/guest.c | 3 ++
arch/arm64/include/asm/kvm_emulate.h | 5 ++++
arch/arm64/include/asm/kvm_host.h | 8 +++++
arch/arm64/include/uapi/asm/kvm.h | 3 +-
arch/arm64/kvm/guest.c | 3 ++
arch/arm64/kvm/inject_fault.c | 4 +--
include/uapi/linux/kvm.h | 8 +++++
virt/kvm/arm/arm.c | 22 ++++++++++++++
virt/kvm/arm/mmio.c | 11 +++++--
14 files changed, 122 insertions(+), 7 deletions(-)
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [RFC] ARM: omap3: Enable HWMODS for HW Random Number Generator
From: Adam Ford @ 2019-09-09 12:13 UTC (permalink / raw)
To: Tony Lindgren
Cc: Mark Rutland, devicetree, Paul Walmsley, Aaro Koskinen,
Russell King, Linux Kernel Mailing List, Tero Kristo, Rob Herring,
Benoît Cousson, Pali Rohár, Linux-OMAP, Adam Ford,
arm-soc
In-Reply-To: <20190905230443.GA52127@atomide.com>
On Thu, Sep 5, 2019 at 6:04 PM Tony Lindgren <tony@atomide.com> wrote:
>
> Hi,
>
> * Adam Ford <aford173@gmail.com> [190828 15:01]:
> > The datasheet for the AM3517 shows the RNG is connected to L4.
> > It shows the module address for the RNG is 0x480A0000, and it
> > matches the omap2.dtsi description. Since the driver can support
> > omap2 and omap4, it seems reasonable to assume the omap3 would
> > use the same core for the RNG.
> >
> > This RFC, mimics much of the omap2 hwmods on the OMAP3. It
> > also adds the necessary clock for driving the RNG. Unfortunately,
> > it appears non-functional. If anyone has any suggestions on how
> > to finish the hwmod (or port it to the newer l4 device tree
> > format), feedback is requested.
>
> Yup I'll take the bait :) The patch below seems to do the trick
> for me on dm3730 based on translating your patch to probe with
> ti-sysc.
>
> Not sure about 34xx, it seems we're missing rng_clk? Care
> to give it a try and attempt simlar patches for 34xx and
> 3517?
>
> At least I'm not needing the "ti,no-reset-on-init" property
> that your patch has a comment for. Maybe that's needed on
> some other omap3.
>
> Oh and this needs to default to status = "disabled" for
> HS devices like n900 as it needs to use the omap3-rom-rng.
>
> Regards,
>
> Tony
>
> 8< -----------------------
> diff --git a/arch/arm/boot/dts/omap36xx.dtsi b/arch/arm/boot/dts/omap36xx.dtsi
> --- a/arch/arm/boot/dts/omap36xx.dtsi
> +++ b/arch/arm/boot/dts/omap36xx.dtsi
> @@ -140,6 +140,29 @@
> };
> };
>
> + rng_target: target-module@480a0000 {
> + compatible = "ti,sysc-omap2", "ti,sysc";
> + reg = <0x480a003c 0x4>,
> + <0x480a0040 0x4>,
> + <0x480a0044 0x4>;
> + reg-names = "rev", "sysc", "syss";
> + ti,sysc-mask = <(SYSC_OMAP2_AUTOIDLE)>;
> + ti,sysc-sidle = <SYSC_IDLE_FORCE>,
> + <SYSC_IDLE_NO>;
> + ti,syss-mask = <1>;
> + clocks = <&rng_ick>;
> + clock-names = "ick";
> + #address-cells = <1>;
> + #size-cells = <1>;
> + ranges = <0 0x480a0000 0x2000>;
> +
> + rng: rng@0 {
> + compatible = "ti,omap2-rng";
> + reg = <0x0 0x2000>;
> + interrupts = <52>;
> + };
> + };
> +
Tony,
Can you tell me what branch you're using? I am not seeing the note
below, so I am not exactly sure what version to base my testing.
ada,
> /*
> * Note that the sysconfig register layout is a subset of the
> * "ti,sysc-omap4" type register with just sidle and midle bits
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v2 4/4] arm64: dts: add support for A1 based Amlogic AD401
From: Jianxin Pan @ 2019-09-09 12:04 UTC (permalink / raw)
To: Martin Blumenstingl
Cc: devicetree, Hanjie Lin, Victor Wan, Neil Armstrong, Kevin Hilman,
linux-kernel, Qiufang Dai, Rob Herring, Jian Hu, Xingyu Chen,
Tao Zeng, Carlo Caione, linux-amlogic, linux-arm-kernel,
Jerome Brunet
In-Reply-To: <CAFBinCD7gFzOsmZCB8T1KJKVsgL7WMhoEkj3dRzyqwAnjC0CNA@mail.gmail.com>
Hi Martin,
On 2019/9/7 23:02, Martin Blumenstingl wrote:
> Hi Jianxin,
>
> On Fri, Sep 6, 2019 at 7:58 AM Jianxin Pan <jianxin.pan@amlogic.com> wrote:
> [...]
>>> also I'm a bit surprised to see no busses (like aobus, cbus, periphs, ...) here
>>> aren't there any busses defined in the A1 SoC implementation or are
>>> were you planning to add them later?
>> Unlike previous series,there is no Cortex-M3 AO CPU in A1, and there is no AO/EE power domain.
>> Most of the registers are on the apb_32b bus. aobus, cbus and periphs are not used in A1.
> OK, thank you for the explanation
> since you're going to re-send the patch anyways: can you please
> include the apb_32b bus?
> all other upstream Amlogic .dts are using the bus definitions, so that
> will make A1 consistent with the other SoCs
In A1 (and the later C1), BUS is not mentioned in the memmap and register spec.
Registers are organized and grouped by functions, and we can not find information about buses from the SoC document.
Maybe it's better to remove bus definitions for these chips.
>
>
> Martin
>
> .
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH] clk: imx: lpcg: write twice when writing lpcg regs
From: Dong Aisheng @ 2019-09-09 11:51 UTC (permalink / raw)
To: Stephen Boyd
Cc: Aisheng Dong, Peng Fan, Jacky Bai, Anson Huang,
festevam@gmail.com, mturquette@baylibre.com,
linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org,
dl-linux-imx, kernel@pengutronix.de, shawnguo@kernel.org,
s.hauer@pengutronix.de, linux-arm-kernel@lists.infradead.org,
Abel Vesa
In-Reply-To: <20190906172044.B99FB20838@mail.kernel.org>
On Sat, Sep 7, 2019 at 9:47 PM Stephen Boyd <sboyd@kernel.org> wrote:
>
> Quoting Peng Fan (2019-08-27 01:17:50)
> > From: Peng Fan <peng.fan@nxp.com>
> >
> > There is hardware issue that:
> > The output clock the LPCG cell will not turn back on as expected,
> > even though a read of the IPG registers in the LPCG indicates that
> > the clock should be enabled.
> >
> > The software workaround is to write twice to enable the LPCG clock
> > output.
> >
> > Signed-off-by: Peng Fan <peng.fan@nxp.com>
>
> Does this need a Fixes tag?
Not sure as it's not code logic issue but a hardware bug.
And 4.19 LTS still have not this driver support.
Regards
Aisheng
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH] clk: imx: lpcg: write twice when writing lpcg regs
From: Dong Aisheng @ 2019-09-09 11:44 UTC (permalink / raw)
To: Peng Fan
Cc: Aisheng Dong, Jacky Bai, Anson Huang, sboyd@kernel.org,
shawnguo@kernel.org, mturquette@baylibre.com,
linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org,
dl-linux-imx, kernel@pengutronix.de, festevam@gmail.com,
s.hauer@pengutronix.de, linux-arm-kernel@lists.infradead.org,
Abel Vesa
In-Reply-To: <1566936978-28519-1-git-send-email-peng.fan@nxp.com>
On Tue, Aug 27, 2019 at 4:19 PM Peng Fan <peng.fan@nxp.com> wrote:
>
> From: Peng Fan <peng.fan@nxp.com>
>
> There is hardware issue that:
> The output clock the LPCG cell will not turn back on as expected,
> even though a read of the IPG registers in the LPCG indicates that
> the clock should be enabled.
>
> The software workaround is to write twice to enable the LPCG clock
> output.
>
> Signed-off-by: Peng Fan <peng.fan@nxp.com>
Reviewed-by: Dong Aisheng <aisheng.dong@nxp.com>
Regards
Aisheng
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 2/3] soc: amazon: al-pos: Introduce Amazon's Annapurna Labs POS driver
From: kbuild test robot @ 2019-09-09 11:51 UTC (permalink / raw)
To: Talel Shenhar
Cc: mark.rutland, mjourdan, catalin.marinas, linus.walleij,
linux-kernel, jonnyc, mchehab+samsung, ronenk, will, hanochu,
benh, devicetree, arnd, mripard, robh+dt, ssantosh, tglx, talel,
linux-arm-kernel, barakw, hhhawa, gregkh, paul.kocialkowski,
kbuild-all, venture, olof, davem, dwmw
In-Reply-To: <1568020220-7758-3-git-send-email-talel@amazon.com>
[-- Attachment #1: Type: text/plain, Size: 2407 bytes --]
Hi Talel,
I love your patch! Perhaps something to improve:
[auto build test WARNING on linus/master]
[cannot apply to v5.3-rc8 next-20190904]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Talel-Shenhar/Amazon-s-Annapurna-Labs-POS-Driver/20190909-180243
config: m68k-allmodconfig (attached as .config)
compiler: m68k-linux-gcc (GCC) 7.4.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
GCC_VERSION=7.4.0 make.cross ARCH=m68k
If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>
All warnings (new ones prefixed by >>):
drivers/soc/amazon/al_pos.c: In function 'al_pos_irq_handler':
>> drivers/soc/amazon/al_pos.c:56:57: warning: left shift count >= width of type [-Wshift-count-overflow]
addr |= (FIELD_GET(AL_POS_ERROR_LOG_1_ADDR_HIGH, log1) << 32);
^~
vim +56 drivers/soc/amazon/al_pos.c
37
38 static irqreturn_t al_pos_irq_handler(int irq, void *info)
39 {
40 struct platform_device *pdev = info;
41 struct al_pos *pos = platform_get_drvdata(pdev);
42 u32 log1;
43 u32 log0;
44 u64 addr;
45 u16 request_id;
46 u8 bresp;
47
48 log1 = readl_relaxed(pos->mmio_base + AL_POS_ERROR_LOG_1);
49 if (!FIELD_GET(AL_POS_ERROR_LOG_1_VALID, log1))
50 return IRQ_NONE;
51
52 log0 = readl_relaxed(pos->mmio_base + AL_POS_ERROR_LOG_0);
53 writel_relaxed(0, pos->mmio_base + AL_POS_ERROR_LOG_1);
54
55 addr = FIELD_GET(AL_POS_ERROR_LOG_0_ADDR_LOW, log0);
> 56 addr |= (FIELD_GET(AL_POS_ERROR_LOG_1_ADDR_HIGH, log1) << 32);
57 request_id = FIELD_GET(AL_POS_ERROR_LOG_1_REQUEST_ID, log1);
58 bresp = FIELD_GET(AL_POS_ERROR_LOG_1_BRESP, log1);
59
60 dev_err(&pdev->dev, "addr=0x%llx request_id=0x%x bresp=0x%x\n",
61 addr, request_id, bresp);
62
63 if (al_pos_panic)
64 panic("POS");
65
66 return IRQ_HANDLED;
67 }
68
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 50923 bytes --]
[-- Attachment #3: Type: text/plain, Size: 176 bytes --]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH V4 11/11] clk: imx: lpcg: add suspend/resume support
From: Dong Aisheng @ 2019-09-09 11:39 UTC (permalink / raw)
To: Stephen Boyd
Cc: Dong Aisheng, Michael Turquette, dl-linux-imx, Sascha Hauer,
Fabio Estevam, Shawn Guo, linux-clk,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <20190906171454.167BF20640@mail.kernel.org>
On Sat, Sep 7, 2019 at 9:22 PM Stephen Boyd <sboyd@kernel.org> wrote:
>
> Quoting Dong Aisheng (2019-08-20 04:13:25)
> > diff --git a/drivers/clk/imx/clk-lpcg-scu.c b/drivers/clk/imx/clk-lpcg-scu.c
> > index 3c092a0..4df0818 100644
> > --- a/drivers/clk/imx/clk-lpcg-scu.c
> > +++ b/drivers/clk/imx/clk-lpcg-scu.c
> > @@ -33,6 +33,9 @@ struct clk_lpcg_scu {
> > void __iomem *reg;
> > u8 bit_idx;
> > bool hw_gate;
> > +
> > + /* for state save&restore */
> > + u32 state;
> > };
> >
> > #define to_clk_lpcg_scu(_hw) container_of(_hw, struct clk_lpcg_scu, hw)
> > @@ -112,5 +115,35 @@ struct clk_hw *__imx_clk_lpcg_scu(struct device *dev, const char *name,
> > hw = ERR_PTR(ret);
> > }
> >
> > + if (dev)
> > + dev_set_drvdata(dev, clk);
> > +
> > return hw;
> > }
> > +
> > +int __maybe_unused imx_clk_lpcg_scu_suspend(struct device *dev)
>
> static?
>
> > +{
> > + struct clk_lpcg_scu *clk = dev_get_drvdata(dev);
> > +
> > + clk->state = readl_relaxed(clk->reg);
> > + dev_dbg(dev, "save lpcg state 0x%x\n", clk->state);
> > +
> > + return 0;
> > +}
> > +
> > +int __maybe_unused imx_clk_lpcg_scu_resume(struct device *dev)
>
> static?
>
Will fix.
> > +{
> > + struct clk_lpcg_scu *clk = dev_get_drvdata(dev);
> > +
> > + /* FIXME: double write in case a failure */
>
> What does this mean? Sometimes writes don't work unless the CPU issues
> them twice?
>
Yes, it's a hardware timing issues.
Regards
Aisheng
> > + writel(clk->state, clk->reg);
> > + writel(clk->state, clk->reg);
> > + dev_dbg(dev, "restore lpcg state 0x%x\n", clk->state);
> > +
> > + return 0;
> > +}
> > +
> > +const struct dev_pm_ops imx_clk_lpcg_scu_pm_ops = {
> > + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(imx_clk_lpcg_scu_suspend,
> > + imx_clk_lpcg_scu_resume)
> > +};
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: Status of led-backlight driver
From: Jean-Jacques Hiblot @ 2019-09-09 11:46 UTC (permalink / raw)
To: Daniel Thompson, Pavel Machek
Cc: mpartap, tony, merlijn, kernel list, sre, nekit1000,
tomi.valkeinen, linux-omap, linux-arm-kernel
In-Reply-To: <20190909111410.dwqvg6b4lgxymn2o@holly.lan>
Hi Daniel,
On 09/09/2019 13:14, Daniel Thompson wrote:
> On Sat, Sep 07, 2019 at 12:07:27PM +0200, Pavel Machek wrote:
>> Hi!
>>
>> I don't see the LED-backlight driver in -next. Could it be pushed? It
>> is one of last pieces to get working backlight on Motorola Droid 4...
> Sorry, I dropped the ball on this and was therefore rather late
> reviewing this patchset.
>
> Assuming I have read the code correctly I think there are some
> problems with the max_brightness handling in the backlight code.
Can you comment this? I'll be happy to fix the problem.
Reading the v4 again, I noticed that that I still had not removed the
brightness scaling. Is that the problem ?
JJ
>
> Daniel.
>
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 2/9] crypto: Add Allwinner sun8i-ce Crypto Engine
From: Maxime Ripard @ 2019-09-09 11:38 UTC (permalink / raw)
To: Corentin Labbe
Cc: mark.rutland, devicetree, herbert, linux-sunxi, linux,
linux-kernel, wens, robh+dt, linux-crypto, davem,
linux-arm-kernel
In-Reply-To: <20190907190408.GE2628@Red>
On Sat, Sep 07, 2019 at 09:04:08PM +0200, Corentin Labbe wrote:
> > Also, I'm not sure what is the point of having the clocks names be
> > parameters there as well. It's constant across all the compatibles,
> > the only thing that isn't is the number of clocks and the module clock
> > rate. It's what you should have in there.
>
> Since the datasheet give some max frequency, I think I will add a
> max_freq and add a check to verify if the clock is in the right
> range
It's a bit pointless. What are you going to do if it's not correct?
What are you trying to fix / report with this?
> > > + }
> > > +};
> > > +
> > > +static const struct ce_variant ce_h5_variant = {
> > > + .alg_cipher = { CE_ID_NOTSUPP, CE_ALG_AES, CE_ALG_DES, CE_ALG_3DES,
> > > + CE_ID_NOTSUPP,
> > > + },
> > > + .op_mode = { CE_ID_NOTSUPP, CE_OP_ECB, CE_OP_CBC
> > > + },
> > > + .intreg = CE_ISR,
> > > + .maxflow = 4,
> > > + .ce_clks = {
> > > + { "ahb", 200000000 },
> > > + { "mod", 300000000 },
> > > + }
> > > +};
> > > +
> > > +static const struct ce_variant ce_h6_variant = {
> > > + .alg_cipher = { CE_ID_NOTSUPP, CE_ALG_AES, CE_ALG_DES, CE_ALG_3DES,
> > > + CE_ALG_RAES,
> > > + },
> > > + .op_mode = { CE_ID_NOTSUPP, CE_OP_ECB, CE_OP_CBC
> > > + },
> > > + .model = CE_v2,
> >
> > Can't that be derived from the version register and / or the
> > compatible? This seems to be redundant with each.
>
> I could use the compatible, but I want to avoid a string comparison
> on each request.
Well, this is specifically what this structure is for then, right? So
instead of having the model, just add the information that you want
there.
> > > +int sun8i_ce_get_engine_number(struct sun8i_ce_dev *ce)
> > > +{
> > > + return atomic_inc_return(&ce->flow) % ce->variant->maxflow;
> > > +}
> >
> > I'm not sure what this is supposed to be doing, but that mod there
> > seems pretty dangerous.
> >
> > ...
>
> This mod do a round robin on each channel.
> I dont see why it is dangerous.
Well, you're using the atomic API here which is most commonly used for
refcounting, while you're using a mod.
Plus, while the increment is atomic, the modulo isn't, so you can end
up in a case where you would be preempted between the
atomic_inc_return and the mod, which is dangerous.
Again, I'm not sure what this function is doing (which is also a
problem in itself). I guess you should just make it clearer what it
does, and then we can discuss it properly.
> > > + err = clk_set_rate(ce->ceclks[i], ce->variant->ce_clks[i].freq);
> > > + if (err)
> > > + dev_err(&pdev->dev, "Fail to set %s clk speed to %lu\n",
> > > + ce->variant->ce_clks[i].name,
> > > + ce->variant->ce_clks[i].freq);
> > > + } else {
> > > + dev_info(&pdev->dev, "%s run at %lu\n",
> > > + ce->variant->ce_clks[i].name, cr);
> >
> > Ditto.
> >
> > > + }
> > > + err = clk_prepare_enable(ce->ceclks[i]);
> >
> > Do you really need this right now though?
>
> Not sure to understand, why I shouldnt do it now ?
> Does it is related to your pm_runtime remark below ?
>
> My feeling was to submit the driver without PM and convert it after.
runtime_pm would be pretty cheap to add though judging by what you're
doing there.
> > > + if (err) {
> > > + dev_err(&pdev->dev, "Cannot prepare_enable %s\n",
> > > + ce->variant->ce_clks[i].name);
> > > + return err;
> > > + }
> > > + }
> > > +
> > > + /* Get Non Secure IRQ */
> > > + irq = platform_get_irq(pdev, 0);
> > > + if (irq < 0) {
> > > + dev_err(ce->dev, "Cannot get NS IRQ\n");
> > > + return irq;
> > > + }
> > > +
> > > + err = devm_request_irq(&pdev->dev, irq, ce_irq_handler, 0,
> > > + "sun8i-ce-ns", ce);
> > > + if (err < 0) {
> > > + dev_err(ce->dev, "Cannot request NS IRQ\n");
> > > + return err;
> > > + }
> > > +
> > > + ce->reset = devm_reset_control_get_optional(&pdev->dev, "ahb");
> > > + if (IS_ERR(ce->reset)) {
> > > + if (PTR_ERR(ce->reset) == -EPROBE_DEFER)
> > > + return PTR_ERR(ce->reset);
> > > + dev_info(&pdev->dev, "No reset control found\n");
> >
> > It's not optional though.
>
> I dont understand why.
On all the SoCs, you need that reset line to be deasserted, otherwise
the IP (and therefore the driver) will be non-functional. It's not an
option to run without it.
> > > + ce->reset = NULL;
> > > + }
> > > +
> > > + err = reset_control_deassert(ce->reset);
> > > + if (err) {
> > > + dev_err(&pdev->dev, "Cannot deassert reset control\n");
> > > + goto error_clk;
> > > + }
> >
> > Again, you don't really need this at this moment. Using runtime_pm
> > would make more sense.
> >
> > > + v = readl(ce->base + CE_CTR);
> > > + v >>= 16;
> > > + v &= 0x07;
> >
> > This should be in a define
> >
>
> Will fix.
>
> > > + dev_info(&pdev->dev, "CE_NS Die ID %x\n", v);
> >
> > And if that really makes sense to print it, the error message should
> > be made less cryptic.
> >
>
> Will fix.
>
> > > +
> > > + ce->dev = &pdev->dev;
> > > + platform_set_drvdata(pdev, ce);
> > > +
> > > + mutex_init(&ce->mlock);
> > > +
> > > + ce->chanlist = devm_kcalloc(ce->dev, ce->variant->maxflow,
> > > + sizeof(struct sun8i_ce_flow), GFP_KERNEL);
> > > + if (!ce->chanlist) {
> > > + err = -ENOMEM;
> > > + goto error_flow;
> > > + }
> > > +
> > > + for (i = 0; i < ce->variant->maxflow; i++) {
> > > + init_completion(&ce->chanlist[i].complete);
> > > + mutex_init(&ce->chanlist[i].lock);
> > > +
> > > + ce->chanlist[i].engine = crypto_engine_alloc_init(ce->dev, true);
> > > + if (!ce->chanlist[i].engine) {
> > > + dev_err(ce->dev, "Cannot allocate engine\n");
> > > + i--;
> > > + goto error_engine;
> > > + }
> > > + err = crypto_engine_start(ce->chanlist[i].engine);
> > > + if (err) {
> > > + dev_err(ce->dev, "Cannot start engine\n");
> > > + goto error_engine;
> > > + }
> > > + ce->chanlist[i].tl = dma_alloc_coherent(ce->dev,
> > > + sizeof(struct ce_task),
> > > + &ce->chanlist[i].t_phy,
> > > + GFP_KERNEL);
> > > + if (!ce->chanlist[i].tl) {
> > > + dev_err(ce->dev, "Cannot get DMA memory for task %d\n",
> > > + i);
> > > + err = -ENOMEM;
> > > + goto error_engine;
> > > + }
> > > + }
> >
> > All this initialization should be done before calling
> > request_irq. You're using some of those fields in your handler.
>
> No interrupt could fire, since algorithms are still not registred.
That's not true. Spurious interrupts are a thing, the engine could
have been left in a weird state by the bootloader / kexec / reboot
with some pending interrupts, etc.
You have registered that handler already, you should expect it to be
called at any point in time.
Maxime
--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v2 4/4] arm64: dts: add support for A1 based Amlogic AD401
From: Jerome Brunet @ 2019-09-09 11:36 UTC (permalink / raw)
To: Martin Blumenstingl, Jianxin Pan, Kevin Hilman
Cc: devicetree, Hanjie Lin, Victor Wan, Neil Armstrong, linux-kernel,
Jian Hu, Xingyu Chen, Tao Zeng, Qiufang Dai, linux-amlogic,
linux-arm-kernel, Jerome Brunet
In-Reply-To: <CAFBinCD7gFzOsmZCB8T1KJKVsgL7WMhoEkj3dRzyqwAnjC0CNA@mail.gmail.com>
On Sat 07 Sep 2019 at 17:02, Martin Blumenstingl wrote:
> Hi Jianxin,
>
> On Fri, Sep 6, 2019 at 7:58 AM Jianxin Pan <jianxin.pan@amlogic.com> wrote:
> [...]
>> > also I'm a bit surprised to see no busses (like aobus, cbus, periphs, ...) here
>> > aren't there any busses defined in the A1 SoC implementation or are
>> > were you planning to add them later?
>> Unlike previous series,there is no Cortex-M3 AO CPU in A1, and there is no AO/EE power domain.
>> Most of the registers are on the apb_32b bus. aobus, cbus and periphs are not used in A1.
> OK, thank you for the explanation
> since you're going to re-send the patch anyways: can you please
> include the apb_32b bus?
unless there is an 64 bits apb bus as well, I suppose 'apb' would be enough ?
> all other upstream Amlogic .dts are using the bus definitions, so that
> will make A1 consistent with the other SoCs
>
>
> Martin
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH V4 08/11] clk: imx: imx8qxp-lpcg: add parsing clocks from device tree
From: Dong Aisheng @ 2019-09-09 11:23 UTC (permalink / raw)
To: Stephen Boyd
Cc: Dong Aisheng, Michael Turquette, dl-linux-imx, Sascha Hauer,
Fabio Estevam, Shawn Guo, linux-clk,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <20190906171323.8847820640@mail.kernel.org>
]On Sat, Sep 7, 2019 at 5:35 PM Stephen Boyd <sboyd@kernel.org> wrote:
>
> Quoting Dong Aisheng (2019-08-20 04:13:22)
> > Add parsing clocks from device tree.
>
> Please describe some more here.
Will improve.
> > + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > + base = devm_ioremap_resource(&pdev->dev, res);
> > + if (IS_ERR(base))
> > + return PTR_ERR(base);
> > +
> > + count = of_property_count_u32_elems(np, "clock-indices");
> > + if (count < 0) {
> > + dev_err(&pdev->dev, "failed to count clocks\n");
> > + return -EINVAL;
> > + }
>
> Is 'count' expected to be equal to IMX_LPCG_MAX_CLKS? Because later on
> in this function we set the num of clks to the MAX instead of the count
> from clock-indices.
>
No. Here is a tricky to ease the clk getting.
For example, one LPCG supports up to 8 clock outputs which each of them
is fixed to 4 bits. Then we can easily use the bit-offset/clk-indices
parsed from DT
to fetch the corresponding clock by hws[clkspec->args[0] / 4].
And the cost is very limited with only a few pointers.
> > +
> > + clk_data = devm_kzalloc(&pdev->dev, struct_size(clk_data, hws, IMX_LPCG_MAX_CLKS),
>
> This line is too long.
>
Will improve.
> > + GFP_KERNEL);
> > + if (!clk_data)
> > + return -ENOMEM;
> > +
> > + clk_data->num = IMX_LPCG_MAX_CLKS;
> > + clk_hws = clk_data->hws;
> > +
> > + ret = of_property_read_u32_array(np, "clock-indices", bit_offset,
> > + count);
> > + if (ret < 0) {
> > + dev_err(&pdev->dev, "failed to read clocks bit-offset\n");
>
> This isn't called bit-offset anymore.
>
Will improve.
> > + return -EINVAL;
> > + }
> > +
> > + ret = of_clk_parent_fill(np, parent_names, count);
> > + if (ret != count) {
> > + dev_err(&pdev->dev, "failed to get clock parent names\n");
> > + return -EINVAL;
>
> return count?
>
Okay
Regards
Aisheng
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
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