* Re: [PATCH] mm: consolidate pgtable_cache_init() and pgd_cache_init()
From: Will Deacon @ 2019-08-21 16:34 UTC (permalink / raw)
To: Mike Rapoport
Cc: Catalin Marinas, x86, linux-kernel, linux-mm, Ingo Molnar,
Borislav Petkov, Andrew Morton, Thomas Gleixner, linux-arm-kernel
In-Reply-To: <20190821160159.GG26713@rapoport-lnx>
On Wed, Aug 21, 2019 at 07:01:59PM +0300, Mike Rapoport wrote:
> On Wed, Aug 21, 2019 at 04:49:42PM +0100, Will Deacon wrote:
> > On Wed, Aug 21, 2019 at 06:06:58PM +0300, Mike Rapoport wrote:
> > > diff --git a/init/main.c b/init/main.c
> > > index b90cb5f..2fa8038 100644
> > > --- a/init/main.c
> > > +++ b/init/main.c
> > > @@ -507,7 +507,7 @@ void __init __weak mem_encrypt_init(void) { }
> > >
> > > void __init __weak poking_init(void) { }
> > >
> > > -void __init __weak pgd_cache_init(void) { }
> > > +void __init __weak pgtable_cache_init(void) { }
> > >
> > > bool initcall_debug;
> > > core_param(initcall_debug, initcall_debug, bool, 0644);
> > > @@ -565,7 +565,6 @@ static void __init mm_init(void)
> > > init_espfix_bsp();
> > > /* Should be run after espfix64 is set up. */
> > > pti_init();
> > > - pgd_cache_init();
> > > }
> >
> > AFAICT, this change means we now initialise our pgd cache before
> > debug_objects_mem_init() has run.
>
> Right.
>
> > Is that going to cause fireworks with CONFIG_DEBUG_OBJECTS when we later
> > free a pgd?
>
> We don't allocate a pgd at that time, we only create the kmem cache for the
> future allocations. And that cache is never destroyed anyway.
Thanks for the explanation. In which case, for arm64:
Acked-by: Will Deacon <will@kernel.org>
Will
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH] soc: imx: gpcv2: Print the correct error code
From: Guido Günther @ 2019-08-21 16:33 UTC (permalink / raw)
To: Shawn Guo, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
NXP Linux Team, Lucas Stach, Anson Huang, Andrey Smirnov,
Rob Herring, Guido Günther, linux-arm-kernel, linux-kernel
The current code prints 'ret' (thus 0) while it should use 'err'.
Signed-off-by: Guido Günther <agx@sigxcpu.org>
---
drivers/soc/imx/gpcv2.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c
index 31b8d002d855..b0dffb06c05d 100644
--- a/drivers/soc/imx/gpcv2.c
+++ b/drivers/soc/imx/gpcv2.c
@@ -198,7 +198,7 @@ static int imx_gpc_pu_pgc_sw_pxx_req(struct generic_pm_domain *genpd,
err = regulator_disable(domain->regulator);
if (err)
dev_err(domain->dev,
- "failed to disable regulator: %d\n", ret);
+ "failed to disable regulator: %d\n", err);
/* Preserve earlier error code */
ret = ret ?: err;
}
--
2.20.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
* Re: [PATCH 3/3] watchdog/aspeed: add support for dual boot
From: Guenter Roeck @ 2019-08-21 16:32 UTC (permalink / raw)
To: Ivan Mikhaylov
Cc: linux-watchdog, linux-aspeed, Andrew Jeffery, Alexander Amelkin,
linux-kernel, Joel Stanley, Wim Van Sebroeck, linux-arm-kernel
In-Reply-To: <1f2cd155057e5ab0cdb20a9a11614bbb09bb49ad.camel@yadro.com>
On Wed, Aug 21, 2019 at 06:57:43PM +0300, Ivan Mikhaylov wrote:
> Set WDT_CLEAR_TIMEOUT_AND_BOOT_CODE_SELECTION into WDT_CLEAR_TIMEOUT_STATUS
> to clear out boot code source and re-enable access to the primary SPI flash
> chip while booted via wdt2 from the alternate chip.
>
> AST2400 datasheet says:
> "In the 2nd flash booting mode, all the address mapping to CS0# would be
> re-directed to CS1#. And CS0# is not accessable under this mode. To access
> CS0#, firmware should clear the 2nd boot mode register in the WDT2 status
> register WDT30.bit[1]."
Is there reason to not do this automatically when loading the module
in alt-boot mode ? What means does userspace have to determine if CS0
or CS1 is active at any given time ? If there is reason to ever have CS1
active instead of CS0, what means would userspace have to enable it ?
If userspace can not really determine if CS1 or CS0 is active, all it could
ever do was to enable CS0 to be in a deterministic state. If so, it doesn't
make sense to ever have CS1 active, and re-enabling CS0 could be automatic.
Similar, if CS1 can ever be enabled, there is no means for userspace to ensure
that some other application did not re-enable CS0 while it believes that CS1
is enabled. If there is no means for userspace to enable CS1, it can never be
sure what is enabled (because some other entity may have enabled CS0 while
userspace just thought that CS1 is still enabled). Again, the only means
to guarantee a well defined state would be to explicitly enable CS0 and provive
no means to enable CS1. Again, this could be done during boot, not requiring
an explicit request from userspace.
>
> Signed-off-by: Ivan Mikhaylov <i.mikhaylov@yadro.com>
> ---
> drivers/watchdog/aspeed_wdt.c | 30 ++++++++++++++++++++++++++++++
> 1 file changed, 30 insertions(+)
>
> diff --git a/drivers/watchdog/aspeed_wdt.c b/drivers/watchdog/aspeed_wdt.c
> index cc71861e033a..858e62f1c7ba 100644
> --- a/drivers/watchdog/aspeed_wdt.c
> +++ b/drivers/watchdog/aspeed_wdt.c
> @@ -53,6 +53,8 @@ MODULE_DEVICE_TABLE(of, aspeed_wdt_of_table);
> #define WDT_CTRL_ENABLE BIT(0)
> #define WDT_TIMEOUT_STATUS 0x10
> #define WDT_TIMEOUT_STATUS_BOOT_SECONDARY BIT(1)
> +#define WDT_CLEAR_TIMEOUT_STATUS 0x14
> +#define WDT_CLEAR_TIMEOUT_AND_BOOT_CODE_SELECTION BIT(0)
>
> /*
> * WDT_RESET_WIDTH controls the characteristics of the external pulse (if
> @@ -165,6 +167,29 @@ static int aspeed_wdt_restart(struct watchdog_device *wdd,
> return 0;
> }
>
> +static ssize_t access_cs0_store(struct device *dev,
> + struct device_attribute *attr,
> + const char *buf, size_t size)
> +{
> + struct aspeed_wdt *wdt = dev_get_drvdata(dev);
> +
> + if (unlikely(!wdt))
> + return -ENODEV;
> +
How would this ever happen, and how / where is drvdata set to NULL ?
> + writel(WDT_CLEAR_TIMEOUT_AND_BOOT_CODE_SELECTION,
> + wdt->base + WDT_CLEAR_TIMEOUT_STATUS);
> + wdt->wdd.bootstatus |= WDIOF_EXTERN1;
The variable reflects the _boot status_. It should not change after booting.
> +
> + return size;
> +}
> +static DEVICE_ATTR_WO(access_cs0);
> +
> +static struct attribute *bswitch_attrs[] = {
> + &dev_attr_access_cs0.attr,
> + NULL
> +};
> +ATTRIBUTE_GROUPS(bswitch);
> +
> static const struct watchdog_ops aspeed_wdt_ops = {
> .start = aspeed_wdt_start,
> .stop = aspeed_wdt_stop,
> @@ -223,6 +248,9 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
>
> wdt->ctrl = WDT_CTRL_1MHZ_CLK;
>
> + if (of_property_read_bool(np, "aspeed,alt-boot"))
> + wdt->wdd.groups = bswitch_groups;
> +
Why does this have to be separate to the existing evaluation of
aspeed,alt-boot, and why does the existing code not work ?
Also, is it guaranteed that this does not interfer with existing
support for alt-boot ?
> /*
> * Control reset on a per-device basis to ensure the
> * host is not affected by a BMC reboot
> @@ -309,6 +337,8 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
> if (status & WDT_TIMEOUT_STATUS_BOOT_SECONDARY)
> wdt->wdd.bootstatus = WDIOF_CARDRESET;
>
> + dev_set_drvdata(dev, wdt);
> +
> return devm_watchdog_register_device(dev, &wdt->wdd);
> }
>
> --
> 2.20.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: [PATCH v2 2/2] dt-bindings: arm: rockchip: remove reference to fennec board
From: Rob Herring @ 2019-08-21 16:23 UTC (permalink / raw)
To: Kever Yang
Cc: Mark Rutland, devicetree, heiko@sntech.de, Tomeu Vizoso,
Akash Gajjar, Douglas Anderson, linux-kernel@vger.kernel.org,
open list:ARM/Rockchip SoC..., Jagan Teki, Robin Murphy,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <20190821031124.17806-2-kever.yang@rock-chips.com>
On Tue, Aug 20, 2019 at 10:11 PM Kever Yang <kever.yang@rock-chips.com> wrote:
>
> The rk3288 fennec board has been removed, remove the binding document at
> the same time.
>
> Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
> ---
>
> Changes in v2: None
>
> Documentation/devicetree/bindings/arm/rockchip.yaml | 5 -----
> 1 file changed, 5 deletions(-)
Acked-by: Rob Herring <robh@kernel.org>
_______________________________________________
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 1/7] dt-bindings: arm: cpus: Add ASPEED SMP
From: Rob Herring @ 2019-08-21 16:23 UTC (permalink / raw)
To: Joel Stanley
Cc: Mark Rutland, devicetree, Ryan Chen, linux-aspeed, Arnd Bergmann,
Andrew Jeffery, Cédric Le Goater, Olof Johansson,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
In-Reply-To: <20190821055530.8720-2-joel@jms.id.au>
On Wed, Aug 21, 2019 at 12:55 AM Joel Stanley <joel@jms.id.au> wrote:
>
> The AST2600 SoC contains two CPUs and requires the operating system to
> bring the second one out of firmware.
>
> Signed-off-by: Joel Stanley <joel@jms.id.au>
> ---
> Documentation/devicetree/bindings/arm/cpus.yaml | 1 +
> 1 file changed, 1 insertion(+)
Acked-by: Rob Herring <robh@kernel.org>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH] ASoC: sun4i-i2s: incorrect regmap for A83t
From: codekipper @ 2019-08-21 16:23 UTC (permalink / raw)
To: mripard, wens, linux-sunxi
Cc: alsa-devel, Marcus Cooper, lgirdwood, linux-kernel, be17068,
broonie, linux-arm-kernel
From: Marcus Cooper <codekipper@gmail.com>
Fixes: 21faaea1343f ("ASoC: sun4i-i2s: Add support for A83T")
Signed-off-by: Marcus Cooper <codekipper@gmail.com>
---
sound/soc/sunxi/sun4i-i2s.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index cbc6e59aa089..056a299c03fb 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -1109,7 +1109,7 @@ static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = {
static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks = {
.has_reset = true,
.reg_offset_txdata = SUN8I_I2S_FIFO_TX_REG,
- .sun4i_i2s_regmap = &sun4i_i2s_regmap_config,
+ .sun4i_i2s_regmap = &sun8i_i2s_regmap_config,
.field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8),
.field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 2),
.field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 6),
--
2.23.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH v8 2/3] fdt: add support for rng-seed
From: Theodore Y. Ts'o @ 2019-08-21 16:21 UTC (permalink / raw)
To: Ard Biesheuvel
Cc: Mark Rutland, Devicetree List, Yu Zhao, Kees Cook,
Catalin Marinas, Stephen Boyd, Will Deacon, lkml, Mike Rapoport,
Jun Yao, Miles Chen, Rob Herring, James Morse, Hsin-Yi Wang,
Andrew Murray, Andrew Morton, Laura Abbott, Frank Rowand,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
Robin Murphy
In-Reply-To: <CAKv+Gu-kp-LqCCx=h2TJxzns4KpM-UEjz3md0u3hbVOyp+iFtA@mail.gmail.com>
On Wed, Aug 21, 2019 at 09:39:28AM +0300, Ard Biesheuvel wrote:
>
> Whether to trust the firmware provided entropy is a policy decision,
> and typically, we try to avoid dictating policy in the kernel, and
> instead, we try to provide a sane default but give the user control
> over it.
>
> So in this case, we should probably introduce
> add_firmware_randomness() with a Kconfig/cmdline option pair to decide
> whether it should be trusted or not (or reuse the one we have for
> trusting RDRAND etc)
I'd call it add_bootloader_randomness(), since we are trusting the
*bootloader*; it's the bootloader which is vouching for the security /
validity of the passed-in entropy. Furthermore, the bootloader on
some architectures might be fetching directly from some secure
element.
And for that reason, I'd use a different Kconfig/cmdline option pair
than the one used for trusting CPU-provided randomness.
- Ted
_______________________________________________
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 1/3] serial: atmel: Don't check for mctrl_gpio_to_gpiod() returning error
From: Geert Uytterhoeven @ 2019-08-21 16:04 UTC (permalink / raw)
To: Richard Genoud
Cc: Alexandre Belloni, Pengutronix Kernel Team, Geert Uytterhoeven,
open list:SERIAL DRIVERS, Greg Kroah-Hartman, Sascha Hauer,
Uwe Kleine-König, Frieder Schrempf, Linux-Renesas,
Ludovic Desroches, NXP Linux Team, Fabio Estevam, Jiri Slaby,
Shawn Guo, Linux ARM
In-Reply-To: <352d8f55-afe2-9f76-ad92-f15a9faa16a8@gmail.com>
Hi Richard,
On Wed, Aug 21, 2019 at 5:27 PM Richard Genoud <richard.genoud@gmail.com> wrote:
> Le 20/08/2019 à 17:47, Richard Genoud a écrit :
> > Le 14/08/2019 à 13:08, Uwe Kleine-König a écrit :
> >> On Wed, Aug 14, 2019 at 12:20:33PM +0200, Geert Uytterhoeven wrote:
> >>> Hi Uwe,
> >>>
> >>> On Wed, Aug 14, 2019 at 11:36 AM Uwe Kleine-König
> >>> <u.kleine-koenig@pengutronix.de> wrote:
> >>>> On Wed, Aug 14, 2019 at 11:29:22AM +0200, Geert Uytterhoeven wrote:
> >>>>> Since commit 1d267ea6539f2663 ("serial: mctrl-gpio: simplify init
> >>>>> routine"), mctrl_gpio_init() returns failure if the assignment to any
> >>>>> member of the gpio array results in an error pointer.
> >>>>> Since commit c359522194593815 ("serial: mctrl_gpio: Avoid probe failures
> >>>>> in case of missing gpiolib"), mctrl_gpio_to_gpiod() returns NULL in the
> >>>>> !CONFIG_GPIOLIB case.
> >>>>> Hence there is no longer a need to check for mctrl_gpio_to_gpiod()
> >>>>> returning an error value. A simple NULL check is sufficient.
> >>>>>
> >>>>> This follows the spirit of commit 445df7ff3fd1a0a9 ("serial: mctrl-gpio:
> >>>>> drop usages of IS_ERR_OR_NULL") in the mctrl-gpio core.
> >>>>>
> >>>>> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
> >>>>> ---
> >>>>> drivers/tty/serial/atmel_serial.c | 12 ++++--------
> >>>>> 1 file changed, 4 insertions(+), 8 deletions(-)
> >>>>>
> >>>>> diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
> >>>>> index 19a85d6fe3d20541..e9620a81166b7dc1 100644
> >>>>> --- a/drivers/tty/serial/atmel_serial.c
> >>>>> +++ b/drivers/tty/serial/atmel_serial.c
> >>>>> @@ -303,32 +303,28 @@ static unsigned int atmel_get_lines_status(struct uart_port *port)
> >>>>>
> >>>>> mctrl_gpio_get(atmel_port->gpios, &ret);
> >>>>>
> >>>>> - if (!IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(atmel_port->gpios,
> >>>>> - UART_GPIO_CTS))) {
> >>>>> + if (mctrl_gpio_to_gpiod(atmel_port->gpios, UART_GPIO_CTS)) {
> >>>>> if (ret & TIOCM_CTS)
> >>>>> status &= ~ATMEL_US_CTS;
> >>>>> else
> >>>>> status |= ATMEL_US_CTS;
> >>>>> }
> >>>>
> >>>> The change is fine, but it seems the atmel driver doesn't use mctrl_gpio
> >>>> as expected (at least as expected by me). IMHO driving the hardware
> >>>> function of the CTS pin shouldn't be conditional on the presence of a
> >>>> cts-gpio. Is there a reason not to just drop the if completely?
> >>>
> >>> The above code returns the hardware status if CTS is not a GPIO, and
> >>> returns (overrides with) the GPIO status if CTS is a GPIO.
> >>> Isn't that correct, or am I missing something?
> >>
> >> I took a deeper look into this driver now. The task for
> >> atmel_get_lines_status() isn't to implement the get_mctrl() callback.
> >>
> >> Instead this is called in the irqhandler to set ATMEL_US_RI in a
> >> "pending" value that then later in atmel_handle_status() is translated
> >> to a "ring" event that is handled there.
> >>
> >> So the right cleanup would be to let atmel_get_lines_status() just be
> >>
> >> return atmel_uart_readl(port, ATMEL_US_CSR);
> >>
> >> . If something happend on the lines implemented as gpio the driver's irq
> >> function isn't called anyhow.
> >
> > I'd like to give it a good test to be sure, and I'll get back to you.
>
> So, Uwe is right.
> Since commit ce59e48fdbad ("serial: mctrl_gpio: implement interrupt handling"),
> atmel_get_lines_status() can be completly killed and replaced by :
> atmel_uart_readl(port, ATMEL_US_CSR);
>
> Geert, do you want to send a patch for that, or should I do it ?
Feel free to send a patch.
I don't have the Atmel hardware anyway.
Thanks!
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
_______________________________________________
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] mm: consolidate pgtable_cache_init() and pgd_cache_init()
From: Mike Rapoport @ 2019-08-21 16:01 UTC (permalink / raw)
To: Will Deacon
Cc: Catalin Marinas, x86, linux-kernel, linux-mm, Ingo Molnar,
Borislav Petkov, Andrew Morton, Thomas Gleixner, linux-arm-kernel
In-Reply-To: <20190821154942.js4u466rolnekwmq@willie-the-truck>
On Wed, Aug 21, 2019 at 04:49:42PM +0100, Will Deacon wrote:
> On Wed, Aug 21, 2019 at 06:06:58PM +0300, Mike Rapoport wrote:
> > Both pgtable_cache_init() and pgd_cache_init() are used to initialize kmem
> > cache for page table allocations on several architectures that do not use
> > PAGE_SIZE tables for one or more levels of the page table hierarchy.
> >
> > Most architectures do not implement these functions and use __week default
> > NOP implementation of pgd_cache_init(). Since there is no such default for
> > pgtable_cache_init(), its empty stub is duplicated among most
> > architectures.
> >
> > Rename the definitions of pgd_cache_init() to pgtable_cache_init() and drop
> > empty stubs of pgtable_cache_init().
> >
> > Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
> > ---
>
> [...]
>
> > diff --git a/arch/arm64/mm/pgd.c b/arch/arm64/mm/pgd.c
> > index 7548f9c..4a64089 100644
> > --- a/arch/arm64/mm/pgd.c
> > +++ b/arch/arm64/mm/pgd.c
> > @@ -35,7 +35,7 @@ void pgd_free(struct mm_struct *mm, pgd_t *pgd)
> > kmem_cache_free(pgd_cache, pgd);
> > }
> >
> > -void __init pgd_cache_init(void)
> > +void __init pgtable_cache_init(void)
> > {
> > if (PGD_SIZE == PAGE_SIZE)
> > return;
>
> [...]
>
> > diff --git a/init/main.c b/init/main.c
> > index b90cb5f..2fa8038 100644
> > --- a/init/main.c
> > +++ b/init/main.c
> > @@ -507,7 +507,7 @@ void __init __weak mem_encrypt_init(void) { }
> >
> > void __init __weak poking_init(void) { }
> >
> > -void __init __weak pgd_cache_init(void) { }
> > +void __init __weak pgtable_cache_init(void) { }
> >
> > bool initcall_debug;
> > core_param(initcall_debug, initcall_debug, bool, 0644);
> > @@ -565,7 +565,6 @@ static void __init mm_init(void)
> > init_espfix_bsp();
> > /* Should be run after espfix64 is set up. */
> > pti_init();
> > - pgd_cache_init();
> > }
>
> AFAICT, this change means we now initialise our pgd cache before
> debug_objects_mem_init() has run.
Right.
> Is that going to cause fireworks with CONFIG_DEBUG_OBJECTS when we later
> free a pgd?
We don't allocate a pgd at that time, we only create the kmem cache for the
future allocations. And that cache is never destroyed anyway.
> Will
--
Sincerely yours,
Mike.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH 3/3] watchdog/aspeed: add support for dual boot
From: Ivan Mikhaylov @ 2019-08-21 15:57 UTC (permalink / raw)
To: Wim Van Sebroeck, Guenter Roeck
Cc: linux-watchdog, linux-aspeed, Andrew Jeffery, Alexander Amelkin,
linux-kernel, Joel Stanley, linux-arm-kernel
Set WDT_CLEAR_TIMEOUT_AND_BOOT_CODE_SELECTION into WDT_CLEAR_TIMEOUT_STATUS
to clear out boot code source and re-enable access to the primary SPI flash
chip while booted via wdt2 from the alternate chip.
AST2400 datasheet says:
"In the 2nd flash booting mode, all the address mapping to CS0# would be
re-directed to CS1#. And CS0# is not accessable under this mode. To access
CS0#, firmware should clear the 2nd boot mode register in the WDT2 status
register WDT30.bit[1]."
Signed-off-by: Ivan Mikhaylov <i.mikhaylov@yadro.com>
---
drivers/watchdog/aspeed_wdt.c | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/drivers/watchdog/aspeed_wdt.c b/drivers/watchdog/aspeed_wdt.c
index cc71861e033a..858e62f1c7ba 100644
--- a/drivers/watchdog/aspeed_wdt.c
+++ b/drivers/watchdog/aspeed_wdt.c
@@ -53,6 +53,8 @@ MODULE_DEVICE_TABLE(of, aspeed_wdt_of_table);
#define WDT_CTRL_ENABLE BIT(0)
#define WDT_TIMEOUT_STATUS 0x10
#define WDT_TIMEOUT_STATUS_BOOT_SECONDARY BIT(1)
+#define WDT_CLEAR_TIMEOUT_STATUS 0x14
+#define WDT_CLEAR_TIMEOUT_AND_BOOT_CODE_SELECTION BIT(0)
/*
* WDT_RESET_WIDTH controls the characteristics of the external pulse (if
@@ -165,6 +167,29 @@ static int aspeed_wdt_restart(struct watchdog_device *wdd,
return 0;
}
+static ssize_t access_cs0_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct aspeed_wdt *wdt = dev_get_drvdata(dev);
+
+ if (unlikely(!wdt))
+ return -ENODEV;
+
+ writel(WDT_CLEAR_TIMEOUT_AND_BOOT_CODE_SELECTION,
+ wdt->base + WDT_CLEAR_TIMEOUT_STATUS);
+ wdt->wdd.bootstatus |= WDIOF_EXTERN1;
+
+ return size;
+}
+static DEVICE_ATTR_WO(access_cs0);
+
+static struct attribute *bswitch_attrs[] = {
+ &dev_attr_access_cs0.attr,
+ NULL
+};
+ATTRIBUTE_GROUPS(bswitch);
+
static const struct watchdog_ops aspeed_wdt_ops = {
.start = aspeed_wdt_start,
.stop = aspeed_wdt_stop,
@@ -223,6 +248,9 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
wdt->ctrl = WDT_CTRL_1MHZ_CLK;
+ if (of_property_read_bool(np, "aspeed,alt-boot"))
+ wdt->wdd.groups = bswitch_groups;
+
/*
* Control reset on a per-device basis to ensure the
* host is not affected by a BMC reboot
@@ -309,6 +337,8 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
if (status & WDT_TIMEOUT_STATUS_BOOT_SECONDARY)
wdt->wdd.bootstatus = WDIOF_CARDRESET;
+ dev_set_drvdata(dev, wdt);
+
return devm_watchdog_register_device(dev, &wdt->wdd);
}
--
2.20.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/3] vesnin: add secondary SPI flash chip
From: Ivan Mikhaylov @ 2019-08-21 15:56 UTC (permalink / raw)
To: Wim Van Sebroeck, Guenter Roeck
Cc: linux-watchdog, linux-aspeed, Andrew Jeffery, Alexander Amelkin,
linux-kernel, Joel Stanley, linux-arm-kernel
Adds secondary SPI flash chip into dts for vesnin.
Signed-off-by: Ivan Mikhaylov <i.mikhaylov@yadro.com>
---
arch/arm/boot/dts/aspeed-bmc-opp-vesnin.dts | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arch/arm/boot/dts/aspeed-bmc-opp-vesnin.dts b/arch/arm/boot/dts/aspeed-bmc-opp-vesnin.dts
index 2ee26c86a32e..db4cc3df61ce 100644
--- a/arch/arm/boot/dts/aspeed-bmc-opp-vesnin.dts
+++ b/arch/arm/boot/dts/aspeed-bmc-opp-vesnin.dts
@@ -81,6 +81,14 @@
label = "bmc";
#include "openbmc-flash-layout.dtsi"
};
+
+ flash@1 {
+ status = "okay";
+ reg = < 1 >;
+ compatible = "jedec,spi-nor";
+ m25p,fast-read;
+ label = "alt";
+ };
};
&spi {
--
2.20.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/3] vesnin: add wdt2 section with alt-boot option
From: Ivan Mikhaylov @ 2019-08-21 15:54 UTC (permalink / raw)
To: Wim Van Sebroeck, Guenter Roeck
Cc: linux-watchdog, linux-aspeed, Andrew Jeffery, Alexander Amelkin,
linux-kernel, Joel Stanley, linux-arm-kernel
Adds wdt2 section with 'alt-boot' option into dts for vesnin.
Signed-off-by: Ivan Mikhaylov <i.mikhaylov@yadro.com>
---
arch/arm/boot/dts/aspeed-bmc-opp-vesnin.dts | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/arm/boot/dts/aspeed-bmc-opp-vesnin.dts b/arch/arm/boot/dts/aspeed-bmc-opp-vesnin.dts
index 0b9e29c3212e..2ee26c86a32e 100644
--- a/arch/arm/boot/dts/aspeed-bmc-opp-vesnin.dts
+++ b/arch/arm/boot/dts/aspeed-bmc-opp-vesnin.dts
@@ -222,3 +222,7 @@
&vuart {
status = "okay";
};
+
+&wdt2 {
+ aspeed,alt-boot;
+};
--
2.20.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/3] add dual-boot support
From: Ivan Mikhaylov @ 2019-08-21 15:52 UTC (permalink / raw)
To: Wim Van Sebroeck, Guenter Roeck
Cc: linux-watchdog, linux-aspeed, Andrew Jeffery, Alexander Amelkin,
linux-kernel, Joel Stanley, linux-arm-kernel
ASPEED SoCs support dual-boot feature for SPI Flash.
When strapped appropriately, the SoC starts wdt2 (/dev/watchdog1)
and if within a minute it is not disabled, it goes off and reboots
the SoC from an alternate SPI Flash chip by changing CS0 controls
to actually drive CS1 line.
When booted from alternate chip, in order to access the main chip
at CS0, the user must reset the appropriate bit in the watchdog
hardware. There is no interface that would allow to do that from
an embedded firmware startup script.
This commit implements support for that feature:
* Enable 'alt-boot' option for wdt2
* Enable secondary SPI flash chip
* Make it possible to get access to the primary SPI flash chip at CS0
after booting from the alternate chip at CS1. A sysfs interface is added
to provide an easy way for embedded firmware startup scripts to clear
the chip select bit to gain access to the primary flash chip in order
to allow for recovery of its contents.
Ivan Mikhaylov (3):
vesnin: add wdt2 section with alt-boot option
vesnin: add secondary SPI flash chip
watchdog/aspeed: add support for dual boot
arch/arm/boot/dts/aspeed-bmc-opp-vesnin.dts | 12 +++++++++
drivers/watchdog/aspeed_wdt.c | 30 +++++++++++++++++++++
2 files changed, 42 insertions(+)
--
2.20.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: [PATCH] mm: consolidate pgtable_cache_init() and pgd_cache_init()
From: Will Deacon @ 2019-08-21 15:49 UTC (permalink / raw)
To: Mike Rapoport
Cc: Catalin Marinas, x86, linux-kernel, linux-mm, Ingo Molnar,
Borislav Petkov, Andrew Morton, Thomas Gleixner, linux-arm-kernel
In-Reply-To: <1566400018-15607-1-git-send-email-rppt@linux.ibm.com>
On Wed, Aug 21, 2019 at 06:06:58PM +0300, Mike Rapoport wrote:
> Both pgtable_cache_init() and pgd_cache_init() are used to initialize kmem
> cache for page table allocations on several architectures that do not use
> PAGE_SIZE tables for one or more levels of the page table hierarchy.
>
> Most architectures do not implement these functions and use __week default
> NOP implementation of pgd_cache_init(). Since there is no such default for
> pgtable_cache_init(), its empty stub is duplicated among most
> architectures.
>
> Rename the definitions of pgd_cache_init() to pgtable_cache_init() and drop
> empty stubs of pgtable_cache_init().
>
> Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
> ---
[...]
> diff --git a/arch/arm64/mm/pgd.c b/arch/arm64/mm/pgd.c
> index 7548f9c..4a64089 100644
> --- a/arch/arm64/mm/pgd.c
> +++ b/arch/arm64/mm/pgd.c
> @@ -35,7 +35,7 @@ void pgd_free(struct mm_struct *mm, pgd_t *pgd)
> kmem_cache_free(pgd_cache, pgd);
> }
>
> -void __init pgd_cache_init(void)
> +void __init pgtable_cache_init(void)
> {
> if (PGD_SIZE == PAGE_SIZE)
> return;
[...]
> diff --git a/init/main.c b/init/main.c
> index b90cb5f..2fa8038 100644
> --- a/init/main.c
> +++ b/init/main.c
> @@ -507,7 +507,7 @@ void __init __weak mem_encrypt_init(void) { }
>
> void __init __weak poking_init(void) { }
>
> -void __init __weak pgd_cache_init(void) { }
> +void __init __weak pgtable_cache_init(void) { }
>
> bool initcall_debug;
> core_param(initcall_debug, initcall_debug, bool, 0644);
> @@ -565,7 +565,6 @@ static void __init mm_init(void)
> init_espfix_bsp();
> /* Should be run after espfix64 is set up. */
> pti_init();
> - pgd_cache_init();
> }
AFAICT, this change means we now initialise our pgd cache before
debug_objects_mem_init() has run. Is that going to cause fireworks with
CONFIG_DEBUG_OBJECTS when we later free a pgd?
Will
_______________________________________________
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 6/8] soc: ti: omap_prm: add data for am33xx
From: Suman Anna @ 2019-08-21 15:49 UTC (permalink / raw)
To: Tero Kristo, ssantosh, linux-arm-kernel, linux-omap, robh+dt
Cc: tony, devicetree
In-Reply-To: <8f5f86db-270a-7278-9d9c-e84c0fa9b73c@ti.com>
On 8/21/19 2:23 AM, Tero Kristo wrote:
> On 20.8.2019 21.48, Suman Anna wrote:
>> Hi Tero,
>>
>> On 8/7/19 2:48 AM, Tero Kristo wrote:
>>> Add PRM instance data for AM33xx SoC. Includes some basic register
>>> definitions and reset data for now.
>>>
>>> Signed-off-by: Tero Kristo <t-kristo@ti.com>
>>> ---
>>> drivers/soc/ti/omap_prm.c | 17 +++++++++++++++++
>>> 1 file changed, 17 insertions(+)
>>>
>>> diff --git a/drivers/soc/ti/omap_prm.c b/drivers/soc/ti/omap_prm.c
>>> index 9b8d5945..fadfc7f 100644
>>> --- a/drivers/soc/ti/omap_prm.c
>>> +++ b/drivers/soc/ti/omap_prm.c
>>> @@ -73,8 +73,25 @@ struct omap_prm_data omap4_prm_data[] = {
>>> { },
>>> };
>>> +struct omap_rst_map am3_wkup_rst_map[] = {
>>> + { .rst = 3, .st = 5 },
>>> + { .rst = -1 },
>>> +};
>>> +
>>> +struct omap_prm_data am3_prm_data[] = {
>>> + { .name = "per", .base = 0x44e00c00, .pwstctrl = 0xc, .pwstst =
>>> 0x8, .flags = OMAP_PRM_NO_RSTST },
>>> + { .name = "wkup", .base = 0x44e00d00, .pwstctrl = 0x4, .pwstst =
>>> 0x8, .rstst = 0xc, .rstmap = am3_wkup_rst_map },
>>> + { .name = "mpu", .base = 0x44e00e00, .pwstst = 0x4 },
>>
>> Has a rstst but no rstctrl, but your registration logic takes care of
>> this. Somewhat confusing, when you just look at the data. Should you
>> limit the check to only rstctrl and OMAP_PRM_NO_RSTST?
>
> I think its probably better I invert the flags and explicitly state
> OMAP_PRM_HAS_RSTST | OMAP_PRM_HAS_RSTCTRL, in case any zero value is
> used for these.
Yeah, something similar to HWMOD_OMAP4_ZERO_CLKCTRL_OFFSET in current
hwmod code.
>
>>
>>> + { .name = "device", .base = 0x44e00f00, .rstctl = 0x0, .rstst =
>>> 0x8 },
>>
>> No pwrstctrl and pwrstst registers, so same comment as on OMAP4 data.
>
> I should probably add some flag for this in future once the support for
> power domains is added.
>
> Anyway, I'll ditch all pwstctrl / pwstst data for now as it seems to
> bother you too much.
OK, that's probably cleaner, and the code and data can be handled when
you implement the power-domain pieces.
regards
Suman
>
> -Tero
>
>>
>>> + { .name = "rtc", .base = 0x44e01000, .pwstst = 0x4 },
>>> + { .name = "gfx", .base = 0x44e01100, .pwstst = 0x10, .rstctl =
>>> 0x4, .rstst = 0x14 },
>>> + { .name = "cefuse", .base = 0x44e01200, .pwstst = 0x4 },
>>
>> I am not sure if it is better to explicitly list the registers at 0
>> offset rather than using the implied value of 0, since there are some
>> registers that do not exist on some PRM instances which are also not
>> defined.
>>
>> regards
>> Suman
>>
>>> + { },
>>> +};
>>> +
>>> static const struct of_device_id omap_prm_id_table[] = {
>>> { .compatible = "ti,omap4-prm-inst", .data = omap4_prm_data },
>>> + { .compatible = "ti,am3-prm-inst", .data = am3_prm_data },
>>> { },
>>> };
>>>
>>
>
> --
> 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 2/8] soc: ti: add initial PRM driver with reset control support
From: Suman Anna @ 2019-08-21 15:45 UTC (permalink / raw)
To: Philipp Zabel, Tero Kristo, Keerthy, ssantosh, linux-arm-kernel,
linux-omap, robh+dt
Cc: tony, devicetree
In-Reply-To: <1566400237.4193.15.camel@pengutronix.de>
On 8/21/19 10:10 AM, Philipp Zabel wrote:
> On Tue, 2019-08-20 at 11:47 -0500, Suman Anna wrote:
>> On 8/20/19 2:37 AM, Tero Kristo wrote:
>>> On 20.8.2019 2.01, Suman Anna wrote:
>>>> Hi Tero,
>>>>
>>>> On 8/19/19 4:32 AM, Tero Kristo wrote:
> [...]
>>>>>>> +{
>>>>>>> + struct omap_reset_data *reset;
>>>>>>> +
>>>>>>> + /*
>>>>>>> + * Check if we have resets. If either rstctl or rstst is
>>>>>>> + * non-zero, we have reset registers in place. Additionally
>>>>>>> + * the flag OMAP_PRM_NO_RSTST implies that we have resets.
>>>>>>> + */
>>>>>>> + if (!prm->data->rstctl && !prm->data->rstst &&
>>>>>>> + !(prm->data->flags & OMAP_PRM_NO_RSTST))
>>>>>>> + return 0;
>>>>>>> +
>>>>>>> + reset = devm_kzalloc(&pdev->dev, sizeof(*reset), GFP_KERNEL);
>>>>>>> + if (!reset)
>>>>>>> + return -ENOMEM;
>>>>>>> +
>>>>>>> + reset->rcdev.owner = THIS_MODULE;
>>>>>>> + reset->rcdev.ops = &omap_reset_ops;
>>>>>>> + reset->rcdev.of_node = pdev->dev.of_node;
>>>>>>> + reset->rcdev.nr_resets = OMAP_MAX_RESETS;
>>>>
>>>> Suggest adding a number of resets to prm->data, and using it so that we
>>>> don't even entertain any resets beyond the actual number of resets.
>>>
>>> Hmm why bother? Accessing a stale reset bit will just cause access to a
>>> reserved bit in the reset register, doing basically nothing. Also, this
>>> would not work for am3/am4 wkup, as there is a single reset bit at an
>>> arbitrary position.
>>
>> The generic convention seems to be defining a reset id value defined
>> from include/dt-bindings/reset/ that can be used to match between the
>> dt-nodes and the reset-controller driver.
>>
>> Philipp,
>> Any comments?
>
> Are there only reset bits and reserved bits in the range accessible by
> [0..OMAP_MAX_RESETS] or are ther bits with another function as well?
Thanks Philipp, these are just reset bits and reserved bits.
> If the latter is the case, I would prefer enumerating the resets in a
> dt-bindings header, with the driver containing an enum -> reg/bit
> position lookup table.
>
> In general, assuming the device tree contains no errors, this should not
> matter much, but I think it is nice if the reset driver, even with a
> misconfigured device tree, can't write into arbitrary bit fields.
Tero,
Can you add a check for this if possible?
regards
Suman
_______________________________________________
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] ARM: dts: vf610-zii-cfu1: Slow I2C0 down to 100 kHz
From: Andrew Lunn @ 2019-08-21 15:44 UTC (permalink / raw)
To: Andrey Smirnov
Cc: Shawn Guo, Chris Healy, Fabio Estevam, linux-kernel,
linux-arm-kernel
In-Reply-To: <20190821013936.12223-1-andrew.smirnov@gmail.com>
On Tue, Aug 20, 2019 at 06:39:36PM -0700, Andrey Smirnov wrote:
> Fiber-optic modules attached to the bus are only rated to work at
> 100 kHz, so decrease the bus frequency to accommodate that.
>
> Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Chris Healy <cphealy@gmail.com>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-kernel@vger.kernel.org
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
I took a quick look at some of the SFP standards. 100KHz is part of
the standard. So we should try to remember to keep an eye of this as
other boards are merged.
Andrew
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH 1/1] rtc: sun6i: Support for wake alarm resume from suspend
From: Alejandro @ 2019-08-21 15:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CA+wirGq=rry-b57PR8B-wZ9zH__dCMNYQR4FXhDVRCbVTG9FMg@mail.gmail.com>
---------- Forwarded message ---------
De: Alejandro <alejandro.gonzalez.correo@gmail.com>
Date: mié., 21 ago. 2019 a las 17:37
Subject: [PATCH 1/1] rtc: sun6i: Support for wake alarm resume from suspend
To: <maxime.ripard@bootlin.com>, <wens@csie.org>,
<linux-arm-kernel@lists.infradead.org>, <linux-kernel@vger.kernel.org>
Cc: <linux-sunxi@googlegroups.com>
This patch allows userspace to set up wakeup alarms on any RTC handled by the
sun6i driver, and adds the necessary PM operations to allow resuming from
suspend when the configured wakeup alarm fires a IRQ. Of course, that the
device actually resumes depends on the suspend state and how a particular
hardware reacts to it, but that is out of scope for this patch.
I've tested these changes on a Pine H64 model B, which contains a
Allwinner H6 SoC, with the help of CONFIG_PM_TEST_SUSPEND kernel option.
These are the interesting outputs from the kernel and/or commands which
show that it works. As every RTC handled by this driver is largely the
same, I think that it shouldn't introduce any regression on other SoCs,
but I may be wrong.
[ 1.092705] PM: test RTC wakeup from 'freeze' suspend
[ 1.098230] PM: suspend entry (s2idle)
[ 1.212907] PM: suspend devices took 0.080 seconds
(The SoC freezes for some seconds)
[ 3.197604] PM: resume devices took 0.104 seconds
[ 3.215937] PM: suspend exit
[ 1.092812] PM: test RTC wakeup from 'mem' suspend
[ 1.098089] PM: suspend entry (deep)
[ 1.102033] PM: suspend exit
[ 1.105205] PM: suspend test failed, error -22
In any case, the RTC alarm interrupt gets fired as exptected:
$ echo +5 > /sys/class/rtc/rtc0/wakealarm && sleep 5 && grep rtc
/proc/interrupts
29: 1 0 0 0 GICv2 133 Level
7000000.rtc
Signed-off-by: Alejandro González <alejandro.gonzalez.correo@gmail.com>
---
drivers/rtc/rtc-sun6i.c | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c
index c0e75c373605..b7611e5dea3f 100644
--- a/drivers/rtc/rtc-sun6i.c
+++ b/drivers/rtc/rtc-sun6i.c
@@ -598,6 +598,33 @@ static const struct rtc_class_ops sun6i_rtc_ops = {
.alarm_irq_enable = sun6i_rtc_alarm_irq_enable
};
+#ifdef CONFIG_PM_SLEEP
+/* Enable IRQ wake on suspend, to wake up from RTC. */
+static int sun6i_rtc_suspend(struct device *dev)
+{
+ struct sun6i_rtc_dev *chip = dev_get_drvdata(dev);
+
+ if (device_may_wakeup(dev))
+ enable_irq_wake(chip->irq);
+
+ return 0;
+}
+
+/* Disable IRQ wake on resume. */
+static int sun6i_rtc_resume(struct device *dev)
+{
+ struct sun6i_rtc_dev *chip = dev_get_drvdata(dev);
+
+ if (device_may_wakeup(dev))
+ disable_irq_wake(chip->irq);
+
+ return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(sun6i_rtc_pm_ops,
+ sun6i_rtc_suspend, sun6i_rtc_resume);
+
static int sun6i_rtc_probe(struct platform_device *pdev)
{
struct sun6i_rtc_dev *chip = sun6i_rtc;
@@ -650,6 +677,8 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
clk_prepare_enable(chip->losc);
+ device_init_wakeup(&pdev->dev, 1);
+
chip->rtc = devm_rtc_device_register(&pdev->dev, "rtc-sun6i",
&sun6i_rtc_ops, THIS_MODULE);
if (IS_ERR(chip->rtc)) {
@@ -684,6 +713,7 @@ static struct platform_driver sun6i_rtc_driver = {
.driver = {
.name = "sun6i-rtc",
.of_match_table = sun6i_rtc_dt_ids,
+ .pm = &sun6i_rtc_pm_ops,
},
};
builtin_platform_driver(sun6i_rtc_driver);
--
2.20.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 v2] soc: samsung: Select missing dependency for EXYNOS_CHIPID
From: Sylwester Nawrocki @ 2019-08-21 15:39 UTC (permalink / raw)
To: krzk
Cc: linux-samsung-soc, b.zolnierkie, pankaj.dubey, linux-kernel,
kgene, Sylwester Nawrocki, linux-arm-kernel, m.szyprowski
In-Reply-To: <20190821150711.31398-1-s.nawrocki@samsung.com>
The chipid driver uses the MFD syscon API but it was not covered
properly in Kconfig.
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
---
drivers/soc/samsung/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
index 2905f5262197..33ad0de2de3c 100644
--- a/drivers/soc/samsung/Kconfig
+++ b/drivers/soc/samsung/Kconfig
@@ -10,6 +10,7 @@ if SOC_SAMSUNG
config EXYNOS_CHIPID
bool "Exynos Chipid controller driver" if COMPILE_TEST
depends on ARCH_EXYNOS || COMPILE_TEST
+ select MFD_SYSCON
select SOC_BUS
config EXYNOS_PMU
--
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 v3 10/10] arm64: Retrieve stolen time as paravirtualized guest
From: Steven Price @ 2019-08-21 15:36 UTC (permalink / raw)
To: Marc Zyngier, Will Deacon, linux-arm-kernel, kvmarm
Cc: Mark Rutland, linux-kernel, kvm, Radim Krčmář,
Catalin Marinas, Suzuki K Pouloze, linux-doc, Russell King,
Steven Price, James Morse, Paolo Bonzini, Julien Thierry
In-Reply-To: <20190821153656.33429-1-steven.price@arm.com>
Enable paravirtualization features when running under a hypervisor
supporting the PV_TIME_ST hypercall.
For each (v)CPU, we ask the hypervisor for the location of a shared
page which the hypervisor will use to report stolen time to us. We set
pv_time_ops to the stolen time function which simply reads the stolen
value from the shared page for a VCPU. We guarantee single-copy
atomicity using READ_ONCE which means we can also read the stolen
time for another VCPU than the currently running one while it is
potentially being updated by the hypervisor.
Signed-off-by: Steven Price <steven.price@arm.com>
---
arch/arm64/include/asm/paravirt.h | 9 +-
arch/arm64/kernel/paravirt.c | 148 ++++++++++++++++++++++++++++++
arch/arm64/kernel/time.c | 3 +
include/linux/cpuhotplug.h | 1 +
4 files changed, 160 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/include/asm/paravirt.h b/arch/arm64/include/asm/paravirt.h
index 799d9dd6f7cc..125c26c42902 100644
--- a/arch/arm64/include/asm/paravirt.h
+++ b/arch/arm64/include/asm/paravirt.h
@@ -21,6 +21,13 @@ static inline u64 paravirt_steal_clock(int cpu)
{
return pv_ops.time.steal_clock(cpu);
}
-#endif
+
+int __init kvm_guest_init(void);
+
+#else
+
+#define kvm_guest_init()
+
+#endif // CONFIG_PARAVIRT
#endif
diff --git a/arch/arm64/kernel/paravirt.c b/arch/arm64/kernel/paravirt.c
index 4cfed91fe256..ea8dbbbd3293 100644
--- a/arch/arm64/kernel/paravirt.c
+++ b/arch/arm64/kernel/paravirt.c
@@ -6,13 +6,161 @@
* Author: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
*/
+#define pr_fmt(fmt) "kvmarm-pv: " fmt
+
+#include <linux/arm-smccc.h>
+#include <linux/cpuhotplug.h>
#include <linux/export.h>
+#include <linux/io.h>
#include <linux/jump_label.h>
+#include <linux/printk.h>
+#include <linux/psci.h>
+#include <linux/reboot.h>
+#include <linux/slab.h>
#include <linux/types.h>
+
#include <asm/paravirt.h>
+#include <asm/pvclock-abi.h>
+#include <asm/smp_plat.h>
struct static_key paravirt_steal_enabled;
struct static_key paravirt_steal_rq_enabled;
struct paravirt_patch_template pv_ops;
EXPORT_SYMBOL_GPL(pv_ops);
+
+struct kvmarm_stolen_time_region {
+ struct pvclock_vcpu_stolen_time *kaddr;
+};
+
+static DEFINE_PER_CPU(struct kvmarm_stolen_time_region, stolen_time_region);
+
+static bool steal_acc = true;
+static int __init parse_no_stealacc(char *arg)
+{
+ steal_acc = false;
+ return 0;
+}
+
+early_param("no-steal-acc", parse_no_stealacc);
+
+/* return stolen time in ns by asking the hypervisor */
+static u64 kvm_steal_clock(int cpu)
+{
+ struct kvmarm_stolen_time_region *reg;
+
+ reg = per_cpu_ptr(&stolen_time_region, cpu);
+ if (!reg->kaddr) {
+ pr_warn_once("stolen time enabled but not configured for cpu %d\n",
+ cpu);
+ return 0;
+ }
+
+ return le64_to_cpu(READ_ONCE(reg->kaddr->stolen_time));
+}
+
+static int disable_stolen_time_current_cpu(void)
+{
+ struct kvmarm_stolen_time_region *reg;
+
+ reg = this_cpu_ptr(&stolen_time_region);
+ if (!reg->kaddr)
+ return 0;
+
+ memunmap(reg->kaddr);
+ memset(reg, 0, sizeof(*reg));
+
+ return 0;
+}
+
+static int stolen_time_dying_cpu(unsigned int cpu)
+{
+ return disable_stolen_time_current_cpu();
+}
+
+static int init_stolen_time_cpu(unsigned int cpu)
+{
+ struct kvmarm_stolen_time_region *reg;
+ struct arm_smccc_res res;
+
+ reg = this_cpu_ptr(&stolen_time_region);
+
+ arm_smccc_1_1_invoke(ARM_SMCCC_HV_PV_TIME_ST, &res);
+
+ if ((long)res.a0 < 0)
+ return -EINVAL;
+
+ reg->kaddr = memremap(res.a0,
+ sizeof(struct pvclock_vcpu_stolen_time),
+ MEMREMAP_WB);
+
+ if (!reg->kaddr) {
+ pr_warn("Failed to map stolen time data structure\n");
+ return -ENOMEM;
+ }
+
+ if (le32_to_cpu(reg->kaddr->revision) != 0 ||
+ le32_to_cpu(reg->kaddr->attributes) != 0) {
+ pr_warn("Unexpected revision or attributes in stolen time data\n");
+ return -ENXIO;
+ }
+
+ return 0;
+}
+
+static int kvm_arm_init_stolen_time(void)
+{
+ int ret;
+
+ ret = cpuhp_setup_state(CPUHP_AP_ARM_KVMPV_STARTING,
+ "hypervisor/kvmarm/pv:starting",
+ init_stolen_time_cpu, stolen_time_dying_cpu);
+ if (ret < 0)
+ return ret;
+ return 0;
+}
+
+static bool has_kvm_steal_clock(void)
+{
+ struct arm_smccc_res res;
+
+ /* To detect the presence of PV time support we require SMCCC 1.1+ */
+ if (psci_ops.smccc_version < SMCCC_VERSION_1_1)
+ return false;
+
+ arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
+ ARM_SMCCC_HV_PV_FEATURES, &res);
+
+ if (res.a0 != SMCCC_RET_SUCCESS)
+ return false;
+
+ arm_smccc_1_1_invoke(ARM_SMCCC_HV_PV_FEATURES,
+ ARM_SMCCC_HV_PV_TIME_ST, &res);
+
+ if (res.a0 != SMCCC_RET_SUCCESS)
+ return false;
+
+ return true;
+}
+
+int __init kvm_guest_init(void)
+{
+ int ret = 0;
+
+ if (!has_kvm_steal_clock())
+ return 0;
+
+ ret = kvm_arm_init_stolen_time();
+ if (ret)
+ return ret;
+
+ pv_ops.time.steal_clock = kvm_steal_clock;
+
+ static_key_slow_inc(¶virt_steal_enabled);
+ if (steal_acc)
+ static_key_slow_inc(¶virt_steal_rq_enabled);
+
+ pr_info("using stolen time PV\n");
+
+ return 0;
+}
diff --git a/arch/arm64/kernel/time.c b/arch/arm64/kernel/time.c
index 0b2946414dc9..a52aea14c6ec 100644
--- a/arch/arm64/kernel/time.c
+++ b/arch/arm64/kernel/time.c
@@ -30,6 +30,7 @@
#include <asm/thread_info.h>
#include <asm/stacktrace.h>
+#include <asm/paravirt.h>
unsigned long profile_pc(struct pt_regs *regs)
{
@@ -65,4 +66,6 @@ void __init time_init(void)
/* Calibrate the delay loop directly */
lpj_fine = arch_timer_rate / HZ;
+
+ kvm_guest_init();
}
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
index 068793a619ca..89d75edb5750 100644
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -136,6 +136,7 @@ enum cpuhp_state {
/* Must be the last timer callback */
CPUHP_AP_DUMMY_TIMER_STARTING,
CPUHP_AP_ARM_XEN_STARTING,
+ CPUHP_AP_ARM_KVMPV_STARTING,
CPUHP_AP_ARM_CORESIGHT_STARTING,
CPUHP_AP_ARM64_ISNDEP_STARTING,
CPUHP_AP_SMPCFD_DYING,
--
2.20.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 v3 09/10] arm/arm64: Make use of the SMCCC 1.1 wrapper
From: Steven Price @ 2019-08-21 15:36 UTC (permalink / raw)
To: Marc Zyngier, Will Deacon, linux-arm-kernel, kvmarm
Cc: Mark Rutland, linux-kernel, kvm, Radim Krčmář,
Catalin Marinas, Suzuki K Pouloze, linux-doc, Russell King,
Steven Price, James Morse, Paolo Bonzini, Julien Thierry
In-Reply-To: <20190821153656.33429-1-steven.price@arm.com>
Rather than directly choosing which function to use based on
psci_ops.conduit, use the new arm_smccc_1_1 wrapper instead.
In some cases we still need to do some operations based on the
conduit, but the code duplication is removed.
No functional change.
Signed-off-by: Steven Price <steven.price@arm.com>
---
arch/arm/mm/proc-v7-bugs.c | 13 +++---
arch/arm64/kernel/cpu_errata.c | 80 ++++++++++++----------------------
2 files changed, 33 insertions(+), 60 deletions(-)
diff --git a/arch/arm/mm/proc-v7-bugs.c b/arch/arm/mm/proc-v7-bugs.c
index 9a07916af8dd..8eb52f3385e7 100644
--- a/arch/arm/mm/proc-v7-bugs.c
+++ b/arch/arm/mm/proc-v7-bugs.c
@@ -78,12 +78,13 @@ static void cpu_v7_spectre_init(void)
if (psci_ops.smccc_version == SMCCC_VERSION_1_0)
break;
+ arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
+ ARM_SMCCC_ARCH_WORKAROUND_1, &res);
+ if ((int)res.a0 != 0)
+ return;
+
switch (psci_ops.conduit) {
case PSCI_CONDUIT_HVC:
- arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
- ARM_SMCCC_ARCH_WORKAROUND_1, &res);
- if ((int)res.a0 != 0)
- break;
per_cpu(harden_branch_predictor_fn, cpu) =
call_hvc_arch_workaround_1;
cpu_do_switch_mm = cpu_v7_hvc_switch_mm;
@@ -91,10 +92,6 @@ static void cpu_v7_spectre_init(void)
break;
case PSCI_CONDUIT_SMC:
- arm_smccc_1_1_smc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
- ARM_SMCCC_ARCH_WORKAROUND_1, &res);
- if ((int)res.a0 != 0)
- break;
per_cpu(harden_branch_predictor_fn, cpu) =
call_smc_arch_workaround_1;
cpu_do_switch_mm = cpu_v7_smc_switch_mm;
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 1e43ba5c79b7..400a49aaae85 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -215,40 +215,31 @@ static int detect_harden_bp_fw(void)
if (psci_ops.smccc_version == SMCCC_VERSION_1_0)
return -1;
+ arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
+ ARM_SMCCC_ARCH_WORKAROUND_1, &res);
+
+ switch ((int)res.a0) {
+ case 1:
+ /* Firmware says we're just fine */
+ return 0;
+ case 0:
+ break;
+ default:
+ return -1;
+ }
+
switch (psci_ops.conduit) {
case PSCI_CONDUIT_HVC:
- arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
- ARM_SMCCC_ARCH_WORKAROUND_1, &res);
- switch ((int)res.a0) {
- case 1:
- /* Firmware says we're just fine */
- return 0;
- case 0:
- cb = call_hvc_arch_workaround_1;
- /* This is a guest, no need to patch KVM vectors */
- smccc_start = NULL;
- smccc_end = NULL;
- break;
- default:
- return -1;
- }
+ cb = call_hvc_arch_workaround_1;
+ /* This is a guest, no need to patch KVM vectors */
+ smccc_start = NULL;
+ smccc_end = NULL;
break;
case PSCI_CONDUIT_SMC:
- arm_smccc_1_1_smc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
- ARM_SMCCC_ARCH_WORKAROUND_1, &res);
- switch ((int)res.a0) {
- case 1:
- /* Firmware says we're just fine */
- return 0;
- case 0:
- cb = call_smc_arch_workaround_1;
- smccc_start = __smccc_workaround_1_smc_start;
- smccc_end = __smccc_workaround_1_smc_end;
- break;
- default:
- return -1;
- }
+ cb = call_smc_arch_workaround_1;
+ smccc_start = __smccc_workaround_1_smc_start;
+ smccc_end = __smccc_workaround_1_smc_end;
break;
default:
@@ -338,6 +329,7 @@ void __init arm64_enable_wa2_handling(struct alt_instr *alt,
void arm64_set_ssbd_mitigation(bool state)
{
+ int conduit;
if (!IS_ENABLED(CONFIG_ARM64_SSBD)) {
pr_info_once("SSBD disabled by kernel configuration\n");
return;
@@ -351,19 +343,10 @@ void arm64_set_ssbd_mitigation(bool state)
return;
}
- switch (psci_ops.conduit) {
- case PSCI_CONDUIT_HVC:
- arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_WORKAROUND_2, state, NULL);
- break;
+ conduit = arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_WORKAROUND_2, state,
+ NULL);
- case PSCI_CONDUIT_SMC:
- arm_smccc_1_1_smc(ARM_SMCCC_ARCH_WORKAROUND_2, state, NULL);
- break;
-
- default:
- WARN_ON_ONCE(1);
- break;
- }
+ WARN_ON_ONCE(conduit == PSCI_CONDUIT_NONE);
}
static bool has_ssbd_mitigation(const struct arm64_cpu_capabilities *entry,
@@ -373,6 +356,7 @@ static bool has_ssbd_mitigation(const struct arm64_cpu_capabilities *entry,
bool required = true;
s32 val;
bool this_cpu_safe = false;
+ int conduit;
WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
@@ -397,18 +381,10 @@ static bool has_ssbd_mitigation(const struct arm64_cpu_capabilities *entry,
return false;
}
- switch (psci_ops.conduit) {
- case PSCI_CONDUIT_HVC:
- arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
- ARM_SMCCC_ARCH_WORKAROUND_2, &res);
- break;
-
- case PSCI_CONDUIT_SMC:
- arm_smccc_1_1_smc(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
- ARM_SMCCC_ARCH_WORKAROUND_2, &res);
- break;
+ conduit = arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
+ ARM_SMCCC_ARCH_WORKAROUND_2, &res);
- default:
+ if (conduit == PSCI_CONDUIT_NONE) {
ssbd_state = ARM64_SSBD_UNKNOWN;
if (!this_cpu_safe)
__ssb_safe = false;
--
2.20.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 v3 08/10] arm/arm64: Provide a wrapper for SMCCC 1.1 calls
From: Steven Price @ 2019-08-21 15:36 UTC (permalink / raw)
To: Marc Zyngier, Will Deacon, linux-arm-kernel, kvmarm
Cc: Mark Rutland, linux-kernel, kvm, Radim Krčmář,
Catalin Marinas, Suzuki K Pouloze, linux-doc, Russell King,
Steven Price, James Morse, Paolo Bonzini, Julien Thierry
In-Reply-To: <20190821153656.33429-1-steven.price@arm.com>
SMCCC 1.1 calls may use either HVC or SMC depending on the PSCI
conduit. Rather than coding this in every call site provide a macro
which uses the correct instruction. The macro also handles the case
where no PSCI conduit is configured returning a not supported error
in res, along with returning the conduit used for the call.
This allow us to remove some duplicated code and will be useful later
when adding paravirtualized time hypervisor calls.
Signed-off-by: Steven Price <steven.price@arm.com>
Acked-by: Will Deacon <will@kernel.org>
---
include/linux/arm-smccc.h | 44 +++++++++++++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h
index e7f129f26ebd..eee1e832221d 100644
--- a/include/linux/arm-smccc.h
+++ b/include/linux/arm-smccc.h
@@ -303,6 +303,50 @@ asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1,
#define SMCCC_RET_NOT_SUPPORTED -1
#define SMCCC_RET_NOT_REQUIRED -2
+/* Like arm_smccc_1_1* but always returns SMCCC_RET_NOT_SUPPORTED.
+ * Used when the PSCI conduit is not defined. The empty asm statement
+ * avoids compiler warnings about unused variables.
+ */
+#define __fail_smccc_1_1(...) \
+ do { \
+ __declare_args(__count_args(__VA_ARGS__), __VA_ARGS__); \
+ asm ("" __constraints(__count_args(__VA_ARGS__))); \
+ if (___res) \
+ ___res->a0 = SMCCC_RET_NOT_SUPPORTED; \
+ } while (0)
+
+/*
+ * arm_smccc_1_1_invoke() - make an SMCCC v1.1 compliant call
+ *
+ * This is a variadic macro taking one to eight source arguments, and
+ * an optional return structure.
+ *
+ * @a0-a7: arguments passed in registers 0 to 7
+ * @res: result values from registers 0 to 3
+ *
+ * This macro will make either an HVC call or an SMC call depending on the
+ * current PSCI conduit. If no valid conduit is available then -1
+ * (SMCCC_RET_NOT_SUPPORTED) is returned in @res.a0 (if supplied).
+ *
+ * The return value also provides the conduit that was used.
+ */
+#define arm_smccc_1_1_invoke(...) ({ \
+ int method = psci_ops.conduit; \
+ switch (method) { \
+ case PSCI_CONDUIT_HVC: \
+ arm_smccc_1_1_hvc(__VA_ARGS__); \
+ break; \
+ case PSCI_CONDUIT_SMC: \
+ arm_smccc_1_1_smc(__VA_ARGS__); \
+ break; \
+ default: \
+ __fail_smccc_1_1(__VA_ARGS__); \
+ method = PSCI_CONDUIT_NONE; \
+ break; \
+ } \
+ method; \
+ })
+
/* Paravirtualised time calls (defined by ARM DEN0057A) */
#define ARM_SMCCC_HV_PV_FEATURES \
ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
--
2.20.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 v3 07/10] KVM: arm64: Provide a PV_TIME device to user space
From: Steven Price @ 2019-08-21 15:36 UTC (permalink / raw)
To: Marc Zyngier, Will Deacon, linux-arm-kernel, kvmarm
Cc: Mark Rutland, linux-kernel, kvm, Radim Krčmář,
Catalin Marinas, Suzuki K Pouloze, linux-doc, Russell King,
Steven Price, James Morse, Paolo Bonzini, Julien Thierry
In-Reply-To: <20190821153656.33429-1-steven.price@arm.com>
Allow user space to inform the KVM host where in the physical memory
map the paravirtualized time structures should be located.
A device is created which provides the base address of an array of
Stolen Time (ST) structures, one for each VCPU. There must be (64 *
total number of VCPUs) bytes of memory available at this location.
The address is given in terms of the physical address visible to
the guest and must be page aligned. The guest will discover the address
via a hypercall.
Signed-off-by: Steven Price <steven.price@arm.com>
---
arch/arm/include/asm/kvm_host.h | 4 ++
arch/arm64/include/asm/kvm_host.h | 1 +
arch/arm64/include/uapi/asm/kvm.h | 8 +++
include/uapi/linux/kvm.h | 2 +
virt/kvm/arm/arm.c | 1 +
virt/kvm/arm/pvtime.c | 94 +++++++++++++++++++++++++++++++
6 files changed, 110 insertions(+)
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index 47d2ced99421..b6c8dbc0556b 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -325,6 +325,10 @@ static inline int kvm_arch_vm_ioctl_check_extension(struct kvm *kvm, long ext)
int kvm_perf_init(void);
int kvm_perf_teardown(void);
+static inline void kvm_pvtime_init(void)
+{
+}
+
static inline int kvm_hypercall_pv_features(struct kvm_vcpu *vcpu)
{
return SMCCC_RET_NOT_SUPPORTED;
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index b6fa7beffd8a..7b2147f62c16 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -489,6 +489,7 @@ void handle_exit_early(struct kvm_vcpu *vcpu, struct kvm_run *run,
int kvm_perf_init(void);
int kvm_perf_teardown(void);
+void kvm_pvtime_init(void);
int kvm_hypercall_pv_features(struct kvm_vcpu *vcpu);
int kvm_hypercall_stolen_time(struct kvm_vcpu *vcpu);
int kvm_update_stolen_time(struct kvm_vcpu *vcpu, bool init);
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index 9a507716ae2f..209c4de67306 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -367,6 +367,14 @@ struct kvm_vcpu_events {
#define KVM_PSCI_RET_INVAL PSCI_RET_INVALID_PARAMS
#define KVM_PSCI_RET_DENIED PSCI_RET_DENIED
+/* Device Control API: PV_TIME */
+#define KVM_DEV_ARM_PV_TIME_REGION 0
+#define KVM_DEV_ARM_PV_TIME_ST 0
+struct kvm_dev_arm_st_region {
+ __u64 gpa;
+ __u64 size;
+};
+
#endif
#endif /* __ARM_KVM_H__ */
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 5e3f12d5359e..265156a984f2 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -1222,6 +1222,8 @@ enum kvm_device_type {
#define KVM_DEV_TYPE_ARM_VGIC_ITS KVM_DEV_TYPE_ARM_VGIC_ITS
KVM_DEV_TYPE_XIVE,
#define KVM_DEV_TYPE_XIVE KVM_DEV_TYPE_XIVE
+ KVM_DEV_TYPE_ARM_PV_TIME,
+#define KVM_DEV_TYPE_ARM_PV_TIME KVM_DEV_TYPE_ARM_PV_TIME
KVM_DEV_TYPE_MAX,
};
diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
index 5e8343e2dd62..bfb5a842e6ab 100644
--- a/virt/kvm/arm/arm.c
+++ b/virt/kvm/arm/arm.c
@@ -1494,6 +1494,7 @@ static int init_subsystems(void)
kvm_perf_init();
kvm_coproc_table_init();
+ kvm_pvtime_init();
out:
on_each_cpu(_kvm_arch_hardware_disable, NULL, 1);
diff --git a/virt/kvm/arm/pvtime.c b/virt/kvm/arm/pvtime.c
index 28603689f6e0..3e55c1fb6a49 100644
--- a/virt/kvm/arm/pvtime.c
+++ b/virt/kvm/arm/pvtime.c
@@ -2,7 +2,9 @@
// Copyright (C) 2019 Arm Ltd.
#include <linux/arm-smccc.h>
+#include <linux/kvm_host.h>
+#include <asm/kvm_mmu.h>
#include <asm/pvclock-abi.h>
#include <kvm/arm_hypercalls.h>
@@ -86,3 +88,95 @@ int kvm_hypercall_stolen_time(struct kvm_vcpu *vcpu)
return ret;
}
+
+static int kvm_arm_pvtime_create(struct kvm_device *dev, u32 type)
+{
+ return 0;
+}
+
+static void kvm_arm_pvtime_destroy(struct kvm_device *dev)
+{
+ struct kvm_arch_pvtime *pvtime = &dev->kvm->arch.pvtime;
+
+ pvtime->st_base = GPA_INVALID;
+ kfree(dev);
+}
+
+static int kvm_arm_pvtime_set_attr(struct kvm_device *dev,
+ struct kvm_device_attr *attr)
+{
+ struct kvm *kvm = dev->kvm;
+ struct kvm_arch_pvtime *pvtime = &kvm->arch.pvtime;
+ u64 __user *user = (u64 __user *)attr->addr;
+ struct kvm_dev_arm_st_region region;
+
+ switch (attr->group) {
+ case KVM_DEV_ARM_PV_TIME_REGION:
+ if (copy_from_user(®ion, user, sizeof(region)))
+ return -EFAULT;
+ if (region.gpa & ~PAGE_MASK)
+ return -EINVAL;
+ if (region.size & ~PAGE_MASK)
+ return -EINVAL;
+ switch (attr->attr) {
+ case KVM_DEV_ARM_PV_TIME_ST:
+ if (pvtime->st_base != GPA_INVALID)
+ return -EEXIST;
+ pvtime->st_base = region.gpa;
+ pvtime->st_size = region.size;
+ return 0;
+ }
+ break;
+ }
+ return -ENXIO;
+}
+
+static int kvm_arm_pvtime_get_attr(struct kvm_device *dev,
+ struct kvm_device_attr *attr)
+{
+ struct kvm_arch_pvtime *pvtime = &dev->kvm->arch.pvtime;
+ u64 __user *user = (u64 __user *)attr->addr;
+ struct kvm_dev_arm_st_region region;
+
+ switch (attr->group) {
+ case KVM_DEV_ARM_PV_TIME_REGION:
+ switch (attr->attr) {
+ case KVM_DEV_ARM_PV_TIME_ST:
+ region.gpa = pvtime->st_base;
+ region.size = pvtime->st_size;
+ if (copy_to_user(user, ®ion, sizeof(region)))
+ return -EFAULT;
+ return 0;
+ }
+ break;
+ }
+ return -ENXIO;
+}
+
+static int kvm_arm_pvtime_has_attr(struct kvm_device *dev,
+ struct kvm_device_attr *attr)
+{
+ switch (attr->group) {
+ case KVM_DEV_ARM_PV_TIME_REGION:
+ switch (attr->attr) {
+ case KVM_DEV_ARM_PV_TIME_ST:
+ return 0;
+ }
+ break;
+ }
+ return -ENXIO;
+}
+
+static const struct kvm_device_ops pvtime_ops = {
+ "Arm PV time",
+ .create = kvm_arm_pvtime_create,
+ .destroy = kvm_arm_pvtime_destroy,
+ .set_attr = kvm_arm_pvtime_set_attr,
+ .get_attr = kvm_arm_pvtime_get_attr,
+ .has_attr = kvm_arm_pvtime_has_attr
+};
+
+void kvm_pvtime_init(void)
+{
+ kvm_register_device_ops(&pvtime_ops, KVM_DEV_TYPE_ARM_PV_TIME);
+}
--
2.20.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 v3 06/10] KVM: Allow kvm_device_ops to be const
From: Steven Price @ 2019-08-21 15:36 UTC (permalink / raw)
To: Marc Zyngier, Will Deacon, linux-arm-kernel, kvmarm
Cc: Mark Rutland, linux-kernel, kvm, Radim Krčmář,
Catalin Marinas, Suzuki K Pouloze, linux-doc, Russell King,
Steven Price, James Morse, Paolo Bonzini, Julien Thierry
In-Reply-To: <20190821153656.33429-1-steven.price@arm.com>
Currently a kvm_device_ops structure cannot be const without triggering
compiler warnings. However the structure doesn't need to be written to
and, by marking it const, it can be read-only in memory. Add some more
const keywords to allow this.
Signed-off-by: Steven Price <steven.price@arm.com>
---
include/linux/kvm_host.h | 4 ++--
virt/kvm/kvm_main.c | 6 +++---
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index e154a1897e20..c5c1a923f21b 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -1262,7 +1262,7 @@ extern unsigned int halt_poll_ns_grow_start;
extern unsigned int halt_poll_ns_shrink;
struct kvm_device {
- struct kvm_device_ops *ops;
+ const struct kvm_device_ops *ops;
struct kvm *kvm;
void *private;
struct list_head vm_node;
@@ -1315,7 +1315,7 @@ struct kvm_device_ops {
void kvm_device_get(struct kvm_device *dev);
void kvm_device_put(struct kvm_device *dev);
struct kvm_device *kvm_device_from_filp(struct file *filp);
-int kvm_register_device_ops(struct kvm_device_ops *ops, u32 type);
+int kvm_register_device_ops(const struct kvm_device_ops *ops, u32 type);
void kvm_unregister_device_ops(u32 type);
extern struct kvm_device_ops kvm_mpic_ops;
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index c6a91b044d8d..75488ebb87c9 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -3046,14 +3046,14 @@ struct kvm_device *kvm_device_from_filp(struct file *filp)
return filp->private_data;
}
-static struct kvm_device_ops *kvm_device_ops_table[KVM_DEV_TYPE_MAX] = {
+static const struct kvm_device_ops *kvm_device_ops_table[KVM_DEV_TYPE_MAX] = {
#ifdef CONFIG_KVM_MPIC
[KVM_DEV_TYPE_FSL_MPIC_20] = &kvm_mpic_ops,
[KVM_DEV_TYPE_FSL_MPIC_42] = &kvm_mpic_ops,
#endif
};
-int kvm_register_device_ops(struct kvm_device_ops *ops, u32 type)
+int kvm_register_device_ops(const struct kvm_device_ops *ops, u32 type)
{
if (type >= ARRAY_SIZE(kvm_device_ops_table))
return -ENOSPC;
@@ -3074,7 +3074,7 @@ void kvm_unregister_device_ops(u32 type)
static int kvm_ioctl_create_device(struct kvm *kvm,
struct kvm_create_device *cd)
{
- struct kvm_device_ops *ops = NULL;
+ const struct kvm_device_ops *ops = NULL;
struct kvm_device *dev;
bool test = cd->flags & KVM_CREATE_DEVICE_TEST;
int type;
--
2.20.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 v3 05/10] KVM: arm64: Support stolen time reporting via shared structure
From: Steven Price @ 2019-08-21 15:36 UTC (permalink / raw)
To: Marc Zyngier, Will Deacon, linux-arm-kernel, kvmarm
Cc: Mark Rutland, linux-kernel, kvm, Radim Krčmář,
Catalin Marinas, Suzuki K Pouloze, linux-doc, Russell King,
Steven Price, James Morse, Paolo Bonzini, Julien Thierry
In-Reply-To: <20190821153656.33429-1-steven.price@arm.com>
Implement the service call for configuring a shared structure between a
VCPU and the hypervisor in which the hypervisor can write the time
stolen from the VCPU's execution time by other tasks on the host.
The hypervisor allocates memory which is placed at an IPA chosen by user
space. The hypervisor then updates the shared structure using
kvm_put_guest() to ensure single copy atomicity of the 64-bit value
reporting the stolen time in nanoseconds.
Whenever stolen time is enabled by the guest, the stolen time counter is
reset.
The stolen time itself is retrieved from the sched_info structure
maintained by the Linux scheduler code. We enable SCHEDSTATS when
selecting KVM Kconfig to ensure this value is meaningful.
Signed-off-by: Steven Price <steven.price@arm.com>
---
arch/arm/include/asm/kvm_host.h | 20 +++++++++
arch/arm64/include/asm/kvm_host.h | 25 +++++++++++-
arch/arm64/kvm/Kconfig | 1 +
include/linux/kvm_types.h | 2 +
virt/kvm/arm/arm.c | 10 +++++
virt/kvm/arm/hypercalls.c | 3 ++
virt/kvm/arm/pvtime.c | 67 +++++++++++++++++++++++++++++++
7 files changed, 127 insertions(+), 1 deletion(-)
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index 369b5d2d54bf..47d2ced99421 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -39,6 +39,7 @@
KVM_ARCH_REQ_FLAGS(0, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
#define KVM_REQ_IRQ_PENDING KVM_ARCH_REQ(1)
#define KVM_REQ_VCPU_RESET KVM_ARCH_REQ(2)
+#define KVM_REQ_RECORD_STEAL KVM_ARCH_REQ(3)
DECLARE_STATIC_KEY_FALSE(userspace_irqchip_in_use);
@@ -329,6 +330,25 @@ static inline int kvm_hypercall_pv_features(struct kvm_vcpu *vcpu)
return SMCCC_RET_NOT_SUPPORTED;
}
+static inline int kvm_hypercall_stolen_time(struct kvm_vcpu *vcpu)
+{
+ return SMCCC_RET_NOT_SUPPORTED;
+}
+
+static inline int kvm_update_stolen_time(struct kvm_vcpu *vcpu, bool init)
+{
+ return -ENOTSUPP;
+}
+
+static inline void kvm_pvtime_init_vm(struct kvm_arch *kvm_arch)
+{
+}
+
+static inline bool kvm_is_pvtime_enabled(struct kvm_arch *kvm_arch)
+{
+ return false;
+}
+
void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot);
struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr);
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 583b3639062a..b6fa7beffd8a 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -44,6 +44,7 @@
KVM_ARCH_REQ_FLAGS(0, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
#define KVM_REQ_IRQ_PENDING KVM_ARCH_REQ(1)
#define KVM_REQ_VCPU_RESET KVM_ARCH_REQ(2)
+#define KVM_REQ_RECORD_STEAL KVM_ARCH_REQ(3)
DECLARE_STATIC_KEY_FALSE(userspace_irqchip_in_use);
@@ -83,6 +84,11 @@ struct kvm_arch {
/* Mandated version of PSCI */
u32 psci_version;
+
+ struct kvm_arch_pvtime {
+ gpa_t st_base;
+ u64 st_size;
+ } pvtime;
};
#define KVM_NR_MEM_OBJS 40
@@ -338,8 +344,13 @@ struct kvm_vcpu_arch {
/* True when deferrable sysregs are loaded on the physical CPU,
* see kvm_vcpu_load_sysregs and kvm_vcpu_put_sysregs. */
bool sysregs_loaded_on_cpu;
-};
+ /* Guest PV state */
+ struct {
+ u64 steal;
+ u64 last_steal;
+ } steal;
+};
/* Pointer to the vcpu's SVE FFR for sve_{save,load}_state() */
#define vcpu_sve_pffr(vcpu) ((void *)((char *)((vcpu)->arch.sve_state) + \
sve_ffr_offset((vcpu)->arch.sve_max_vl)))
@@ -479,6 +490,18 @@ int kvm_perf_init(void);
int kvm_perf_teardown(void);
int kvm_hypercall_pv_features(struct kvm_vcpu *vcpu);
+int kvm_hypercall_stolen_time(struct kvm_vcpu *vcpu);
+int kvm_update_stolen_time(struct kvm_vcpu *vcpu, bool init);
+
+static inline void kvm_pvtime_init_vm(struct kvm_arch *kvm_arch)
+{
+ kvm_arch->pvtime.st_base = GPA_INVALID;
+}
+
+static inline bool kvm_is_pvtime_enabled(struct kvm_arch *kvm_arch)
+{
+ return (kvm_arch->pvtime.st_base != GPA_INVALID);
+}
void kvm_set_sei_esr(struct kvm_vcpu *vcpu, u64 syndrome);
diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index a67121d419a2..d8b88e40d223 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -39,6 +39,7 @@ config KVM
select IRQ_BYPASS_MANAGER
select HAVE_KVM_IRQ_BYPASS
select HAVE_KVM_VCPU_RUN_PID_CHANGE
+ select SCHEDSTATS
---help---
Support hosting virtualized guest machines.
We don't support KVM with 16K page tables yet, due to the multiple
diff --git a/include/linux/kvm_types.h b/include/linux/kvm_types.h
index bde5374ae021..1c88e69db3d9 100644
--- a/include/linux/kvm_types.h
+++ b/include/linux/kvm_types.h
@@ -35,6 +35,8 @@ typedef unsigned long gva_t;
typedef u64 gpa_t;
typedef u64 gfn_t;
+#define GPA_INVALID (~(gpa_t)0)
+
typedef unsigned long hva_t;
typedef u64 hpa_t;
typedef u64 hfn_t;
diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
index 35a069815baf..5e8343e2dd62 100644
--- a/virt/kvm/arm/arm.c
+++ b/virt/kvm/arm/arm.c
@@ -40,6 +40,10 @@
#include <asm/kvm_coproc.h>
#include <asm/sections.h>
+#include <kvm/arm_hypercalls.h>
+#include <kvm/arm_pmu.h>
+#include <kvm/arm_psci.h>
+
#ifdef REQUIRES_VIRT
__asm__(".arch_extension virt");
#endif
@@ -135,6 +139,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
kvm->arch.max_vcpus = vgic_present ?
kvm_vgic_get_max_vcpus() : KVM_MAX_VCPUS;
+ kvm_pvtime_init_vm(&kvm->arch);
return ret;
out_free_stage2_pgd:
kvm_free_stage2_pgd(kvm);
@@ -379,6 +384,8 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
kvm_vcpu_load_sysregs(vcpu);
kvm_arch_vcpu_load_fp(vcpu);
kvm_vcpu_pmu_restore_guest(vcpu);
+ if (kvm_is_pvtime_enabled(&vcpu->kvm->arch))
+ kvm_make_request(KVM_REQ_RECORD_STEAL, vcpu);
if (single_task_running())
vcpu_clear_wfe_traps(vcpu);
@@ -644,6 +651,9 @@ static void check_vcpu_requests(struct kvm_vcpu *vcpu)
* that a VCPU sees new virtual interrupts.
*/
kvm_check_request(KVM_REQ_IRQ_PENDING, vcpu);
+
+ if (kvm_check_request(KVM_REQ_RECORD_STEAL, vcpu))
+ kvm_update_stolen_time(vcpu, false);
}
}
diff --git a/virt/kvm/arm/hypercalls.c b/virt/kvm/arm/hypercalls.c
index 63ae629c466a..ac678eabf15f 100644
--- a/virt/kvm/arm/hypercalls.c
+++ b/virt/kvm/arm/hypercalls.c
@@ -56,6 +56,9 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
case ARM_SMCCC_HV_PV_FEATURES:
val = kvm_hypercall_pv_features(vcpu);
break;
+ case ARM_SMCCC_HV_PV_TIME_ST:
+ val = kvm_hypercall_stolen_time(vcpu);
+ break;
default:
return kvm_psci_call(vcpu);
}
diff --git a/virt/kvm/arm/pvtime.c b/virt/kvm/arm/pvtime.c
index 6201d71cb1f8..28603689f6e0 100644
--- a/virt/kvm/arm/pvtime.c
+++ b/virt/kvm/arm/pvtime.c
@@ -3,8 +3,51 @@
#include <linux/arm-smccc.h>
+#include <asm/pvclock-abi.h>
+
#include <kvm/arm_hypercalls.h>
+int kvm_update_stolen_time(struct kvm_vcpu *vcpu, bool init)
+{
+ struct kvm *kvm = vcpu->kvm;
+ struct kvm_arch_pvtime *pvtime = &kvm->arch.pvtime;
+ u64 steal;
+ u64 steal_le;
+ u64 offset;
+ int idx;
+ const int stride = sizeof(struct pvclock_vcpu_stolen_time);
+
+ if (pvtime->st_base == GPA_INVALID)
+ return -ENOTSUPP;
+
+ /* Let's do the local bookkeeping */
+ steal = vcpu->arch.steal.steal;
+ steal += current->sched_info.run_delay - vcpu->arch.steal.last_steal;
+ vcpu->arch.steal.last_steal = current->sched_info.run_delay;
+ vcpu->arch.steal.steal = steal;
+
+ offset = stride * kvm_vcpu_get_idx(vcpu);
+
+ if (unlikely(offset + stride > pvtime->st_size))
+ return -EINVAL;
+
+ steal_le = cpu_to_le64(steal);
+ idx = srcu_read_lock(&kvm->srcu);
+ if (init) {
+ struct pvclock_vcpu_stolen_time init_values = {
+ .revision = 0,
+ .attributes = 0
+ };
+ kvm_write_guest(kvm, pvtime->st_base + offset, &init_values,
+ sizeof(init_values));
+ }
+ offset += offsetof(struct pvclock_vcpu_stolen_time, stolen_time);
+ kvm_put_guest(kvm, pvtime->st_base + offset, steal_le, u64);
+ srcu_read_unlock(&kvm->srcu, idx);
+
+ return 0;
+}
+
int kvm_hypercall_pv_features(struct kvm_vcpu *vcpu)
{
u32 feature = smccc_get_arg1(vcpu);
@@ -12,6 +55,7 @@ int kvm_hypercall_pv_features(struct kvm_vcpu *vcpu)
switch (feature) {
case ARM_SMCCC_HV_PV_FEATURES:
+ case ARM_SMCCC_HV_PV_TIME_ST:
val = SMCCC_RET_SUCCESS;
break;
}
@@ -19,3 +63,26 @@ int kvm_hypercall_pv_features(struct kvm_vcpu *vcpu)
return val;
}
+int kvm_hypercall_stolen_time(struct kvm_vcpu *vcpu)
+{
+ u64 ret;
+ int err;
+
+ /*
+ * Start counting stolen time from the time the guest requests
+ * the feature enabled.
+ */
+ vcpu->arch.steal.steal = 0;
+ vcpu->arch.steal.last_steal = current->sched_info.run_delay;
+
+ err = kvm_update_stolen_time(vcpu, true);
+
+ if (err)
+ ret = SMCCC_RET_NOT_SUPPORTED;
+ else
+ ret = vcpu->kvm->arch.pvtime.st_base +
+ (sizeof(struct pvclock_vcpu_stolen_time) *
+ kvm_vcpu_get_idx(vcpu));
+
+ return ret;
+}
--
2.20.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
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