* [PATCH v2 2/6] arm64: Introduce config for S32
From: Stefan-gabriel Mirea @ 2019-08-09 11:29 UTC (permalink / raw)
To: corbet@lwn.net, robh+dt@kernel.org, mark.rutland@arm.com,
gregkh@linuxfoundation.org, catalin.marinas@arm.com,
will@kernel.org, shawnguo@kernel.org, Leo Li
Cc: devicetree@vger.kernel.org, linux-doc@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org,
jslaby@suse.com, Cosmin Stefan Stoica,
linux-arm-kernel@lists.infradead.org
In-Reply-To: <20190809112853.15846-1-stefan-gabriel.mirea@nxp.com>
From: Mihaela Martinas <Mihaela.Martinas@freescale.com>
Add configuration option for the Freescale S32 platform family in
Kconfig.platforms. For starters, the only SoC supported will be Treerunner
(S32V234), with a single execution target: the S32V234-EVB (rev 29288)
board.
Signed-off-by: Mihaela Martinas <Mihaela.Martinas@freescale.com>
Signed-off-by: Stoica Cosmin-Stefan <cosmin.stoica@nxp.com>
Signed-off-by: Stefan-Gabriel Mirea <stefan-gabriel.mirea@nxp.com>
---
arch/arm64/Kconfig.platforms | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 4778c775de1b..a9a6152d37eb 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -210,6 +210,11 @@ config ARCH_ROCKCHIP
This enables support for the ARMv8 based Rockchip chipsets,
like the RK3368.
+config ARCH_S32
+ bool "Freescale S32 SoC Family"
+ help
+ This enables support for the Freescale S32 family of processors.
+
config ARCH_SEATTLE
bool "AMD Seattle SoC Family"
help
--
2.22.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
* [PATCH v2 0/6] Add initial support for S32V234-EVB
From: Stefan-gabriel Mirea @ 2019-08-09 11:29 UTC (permalink / raw)
To: corbet@lwn.net, robh+dt@kernel.org, mark.rutland@arm.com,
gregkh@linuxfoundation.org, catalin.marinas@arm.com,
will@kernel.org, shawnguo@kernel.org, Leo Li
Cc: devicetree@vger.kernel.org, linux-doc@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org,
jslaby@suse.com, linux-arm-kernel@lists.infradead.org
Hello,
NXP's S32V234[1] ("Treerunner") vision microprocessors are targeted for
high-performance, computationally intensive vision and sensor fusion
applications that require automotive safety levels. They include leading
edge Camera Vision modules like APEX-2, ISP and GPU. The S32V234-EVB and
S32V234-SBC boards are available for customer evaluation.
The following patch series introduces minimal enablement support for the
NXP S32V234-EVB2[2] board, which leverages most of the SoC capabilities.
The series includes a driver for operating the on-chip LINFlexD controller
in UART mode.
In the future, we aim to submit multiple drivers upstream, which can be
found in the kernel of our Auto Linux BSP[3] ("ALB"), starting with basic
pinmuxing, clock and uSDHC drivers.
For validation, you can use the U-Boot bootloader in the ALB[4], which we
build and test with our patched version of the Linaro GCC 6.3.1 2017.05
toolchain for ARM 64-bit, with sources available on [5].
Changes in v2:
* Update the entry in fsl.yaml to apply to all S32V234 based boards;
* Add chosen node to dts, with a 'stdout-path' property for earlycon;
* Remove linflex_verify_port(), because it was only called from
uart_set_info(), which was going to always fail at the "baud_base < 9600"
check, as we are not using uartclk from uart_port yet;
* Fix compatible string used in OF_EARLYCON_DECLARE.
[1] https://www.nxp.com/products/processors-and-microcontrollers/arm-based-processors-and-mcus/s32-automotive-platform/vision-processor-for-front-and-surround-view-camera-machine-learning-and-sensor-fusion:S32V234
[2] https://www.nxp.com/support/developer-resources/evaluation-and-development-boards/ultra-reliable-dev-platforms/s32v-mpus-platforms/s32v-vision-and-sensor-fusion-evaluation-system:S32V234EVB
[3] https://source.codeaurora.org/external/autobsps32/linux/
[4] https://source.codeaurora.org/external/autobsps32/u-boot/
[5] https://source.codeaurora.org/external/s32ds/compiler/gcc/
Eddy Petrișor (1):
dt-bindings: arm: fsl: Add the S32V234-EVB board
Mihaela Martinas (2):
arm64: Introduce config for S32
arm64: defconfig: Enable configs for S32V234
Stefan-Gabriel Mirea (1):
tty: serial: Add linflexuart driver for S32V234
Stoica Cosmin-Stefan (2):
arm64: dts: fsl: Add device tree for S32V234-EVB
dt-bindings: serial: Document Freescale LINFlex UART
.../admin-guide/kernel-parameters.txt | 6 +
.../devicetree/bindings/arm/fsl.yaml | 6 +
.../bindings/serial/fsl,s32-linflexuart.txt | 24 +
arch/arm64/Kconfig.platforms | 5 +
arch/arm64/boot/dts/freescale/Makefile | 2 +
.../boot/dts/freescale/fsl-s32v234-evb.dts | 24 +
.../arm64/boot/dts/freescale/fsl-s32v234.dtsi | 130 +++
arch/arm64/configs/defconfig | 3 +
drivers/tty/serial/Kconfig | 15 +
drivers/tty/serial/Makefile | 1 +
drivers/tty/serial/fsl_linflexuart.c | 942 ++++++++++++++++++
include/uapi/linux/serial_core.h | 3 +
12 files changed, 1161 insertions(+)
create mode 100644 Documentation/devicetree/bindings/serial/fsl,s32-linflexuart.txt
create mode 100644 arch/arm64/boot/dts/freescale/fsl-s32v234-evb.dts
create mode 100644 arch/arm64/boot/dts/freescale/fsl-s32v234.dtsi
create mode 100644 drivers/tty/serial/fsl_linflexuart.c
--
2.22.0
_______________________________________________
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 13/22] input: omap: void using mach/*.h headers
From: Arnd Bergmann @ 2019-08-09 11:23 UTC (permalink / raw)
To: Sebastian Reichel
Cc: Bartlomiej Zolnierkiewicz, Tony Lindgren, Greg Kroah-Hartman,
Linus Walleij, Dmitry Torokhov, Linux Kernel Mailing List,
Tomi Valkeinen, open list:HID CORE LAYER, Aaro Koskinen,
linux-omap, Linux ARM
In-Reply-To: <20190808233941.v6elo2mdji5awylu@earth.universe>
On Fri, Aug 9, 2019 at 1:39 AM Sebastian Reichel <sre@kernel.org> wrote:
> On Thu, Aug 08, 2019 at 03:19:50PM -0700, Dmitry Torokhov wrote:
> > On Thu, Aug 08, 2019 at 11:46:45PM +0200, Arnd Bergmann wrote:
> > > On Thu, Aug 8, 2019 at 11:43 PM Dmitry Torokhov wrote:
> > > > On Thu, Aug 08, 2019 at 11:22:22PM +0200, Arnd Bergmann wrote:
> > > > > By using the new linux/soc/ti/omap1-io.h header instead,
> > > > > compile-testing can be enabled, and a CONFIG_ARCH_MULTIPLATFORM
> > > > > conversion of omap1 may eventually be possible.
> > > > >
> > > > > The warning in the header file gets removed in order to
> > > > > allow CONFIG_COMPILE_TEST.
> > > >
> > > > Given that we want to migrate people off this driver everywhere but
> > > > OMAP1 I wonder why we would want to improve compile coverage of it.
> > >
> > > Mainly for consistency: I'm converting all omap1 drivers in this series to
> > > not rely on mach/* headers and to let them be compiled standalone.
> > > The other drivers don't have a replacement, so I could treat this different
> > > from the rest and skip the Kconfig and platform_data changes if you
> > > prefer.
> >
> > Yes, because at least with the version you posted we are losing the
> > #warning telling people to move to matrix_keypad. We could do:
> >
> > #ifndef CONFIG_COMPILE_TEST
> > #warning ...
> > #endif
> >
> > if you really want to allow compiling standalone for testing.
No, I'll just drop the compile-test portion and leave the warning
untouched, leaving only the header file include as a preparation
for multiplatform support then.
> FWIW the driver depends on ARCH_OMAP1 and the warning is
> only printed for !ARCH_OMAP1. In other words: The warning
> is never printed at the moment. All OMAP2+ boards moved to
> matrix-keypad long time ago and the driver does not support
> OMAP2+ anymore since f799a3d8fe170 from 2012.
Right, it also seems extremely unlikely that any new platform
would start using the header, and it also doesn't look like
anyone is interested in moving omap1 over to matrix-keypad.
Arnd
_______________________________________________
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 v3 02/11] kselftest: arm64: adds first test and common utils
From: Dave Martin @ 2019-08-09 11:16 UTC (permalink / raw)
To: Cristian Marussi; +Cc: linux-arm-kernel, linux-kselftest
In-Reply-To: <20278fdd-95d0-060f-088d-aba8ac2b0b01@arm.com>
On Fri, Aug 09, 2019 at 11:54:06AM +0100, Cristian Marussi wrote:
> Hi
>
> On 8/2/19 6:02 PM, Cristian Marussi wrote:
> >Added some arm64/signal specific boilerplate and utility code to help
> >further testcase development.
> >
> >A simple testcase and related helpers are also introduced in this commit:
> >mangle_pstate_invalid_compat_toggle is a simple mangle testcase which
> >messes with the ucontext_t from within the sig_handler, trying to toggle
> >PSTATE state bits to switch the system between 32bit/64bit execution state.
> >Expects SIGSEGV on test PASS.
> >
> >Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
> >---
> >A few fixes:
> >- test_arm64_signals.sh runner script generation has been reviewed in order to
> > be safe against the .gitignore
> >- using kselftest.h officially provided defines for tests' return values
> >- removed SAFE_WRITE()/dump_uc()
> >- looking for si_code==SEGV_ACCERR on SEGV test cases to better understand if
> > the sigfault had been directly triggered by Kernel
> >---
> > tools/testing/selftests/arm64/Makefile | 2 +-
> > .../testing/selftests/arm64/signal/.gitignore | 6 +
> > tools/testing/selftests/arm64/signal/Makefile | 88 ++++++
> > tools/testing/selftests/arm64/signal/README | 59 ++++
> > .../arm64/signal/test_arm64_signals.src_shell | 55 ++++
> > .../selftests/arm64/signal/test_signals.c | 26 ++
> > .../selftests/arm64/signal/test_signals.h | 137 +++++++++
> > .../arm64/signal/test_signals_utils.c | 261 ++++++++++++++++++
> > .../arm64/signal/test_signals_utils.h | 13 +
> > .../arm64/signal/testcases/.gitignore | 1 +
> > .../mangle_pstate_invalid_compat_toggle.c | 25 ++
> > .../arm64/signal/testcases/testcases.c | 150 ++++++++++
> > .../arm64/signal/testcases/testcases.h | 83 ++++++
> > 13 files changed, 905 insertions(+), 1 deletion(-)
> > create mode 100644 tools/testing/selftests/arm64/signal/.gitignore
> > create mode 100644 tools/testing/selftests/arm64/signal/Makefile
> > create mode 100644 tools/testing/selftests/arm64/signal/README
> > create mode 100755 tools/testing/selftests/arm64/signal/test_arm64_signals.src_shell
> > create mode 100644 tools/testing/selftests/arm64/signal/test_signals.c
> > create mode 100644 tools/testing/selftests/arm64/signal/test_signals.h
> > create mode 100644 tools/testing/selftests/arm64/signal/test_signals_utils.c
> > create mode 100644 tools/testing/selftests/arm64/signal/test_signals_utils.h
> > create mode 100644 tools/testing/selftests/arm64/signal/testcases/.gitignore
> > create mode 100644 tools/testing/selftests/arm64/signal/testcases/mangle_pstate_invalid_compat_toggle.c
> > create mode 100644 tools/testing/selftests/arm64/signal/testcases/testcases.c
> > create mode 100644 tools/testing/selftests/arm64/signal/testcases/testcases.h
> >
>
> A few more compilation warnings triggered by GCC-8 ONLY when compiling via the top kselftest Makefile/target
> (due to some additional -W passed down and an awkward use of snprintf on my side...)
>
>
> test_signals_utils.c: In function ‘feats_to_string’:
> test_signals_utils.c:38:13: warning: passing argument 1 to restrict-qualified parameter aliases with argument 4 [-Wrestrict]
> snprintf(feats_string, MAX_FEATS_SZ - 1, "%s %s ",
> ^~~~~~~~~~~~
> test_signals_utils.c: In function ‘default_handler’:
> test_signals_utils.c:192:19: warning: format ‘%p’ expects argument of type ‘void *’, but argument 3 has type ‘long long unsigned int’ [-Wformat=]
> "SIG_OK -- SP:%p si_addr@:0x%p si_code:%d token@:0x%p offset:%ld\n",
> ~^
>
> will be fixed in V4 as:
>
>
> diff --git a/tools/testing/selftests/arm64/signal/test_signals_utils.c b/tools/testing/selftests/arm64/signal/test_signals_utils.c
> index 31788a1d33a4..c0f3cd1b560a 100644
> --- a/tools/testing/selftests/arm64/signal/test_signals_utils.c
> +++ b/tools/testing/selftests/arm64/signal/test_signals_utils.c
> @@ -23,21 +23,25 @@ extern struct tdescr *current;
> static int sig_copyctx = SIGTRAP;
> static char *feats_store[FMAX_END] = {
> - "SSBS",
> - "PAN",
> - "UAO",
> + " SSBS ",
> + " PAN ",
> + " UAO ",
> };
> #define MAX_FEATS_SZ 128
> +static char feats_string[MAX_FEATS_SZ];
> +
> static inline char *feats_to_string(unsigned long feats)
> {
> - static char feats_string[MAX_FEATS_SZ];
> + for (int i = 0; i < FMAX_END; i++) {
> + size_t tlen = 0;
> - for (int i = 0; i < FMAX_END && feats_store[i][0]; i++) {
> - if (feats & 1UL << i)
> - snprintf(feats_string, MAX_FEATS_SZ - 1, "%s %s ",
> - feats_string, feats_store[i]);
> + if (feats & 1UL << i) {
> + strncat(feats_string, feats_store[i],
Should this be feats_string + tlen?
> + MAX_FEATS_SZ - 1 - tlen);
An assert(tlen <= MAX_FEATS_SZ - 1) is probably a good idea here,
in case more features are added to feats_store[] someday.
> + tlen += strlen(feats_store[i]);
> + }
Don't we need to initialise tlen outside the loop? Otherwise we just
zero it again after the +=.
> }
> return feats_string;
> @@ -190,7 +194,7 @@ static void default_handler(int signum, siginfo_t *si, void *uc)
> /* it's a bug in the test code when this assert fail */
> assert(!current->sig_trig || current->triggered);
> fprintf(stderr,
> - "SIG_OK -- SP:%p si_addr@:0x%p si_code:%d token@:0x%p offset:%ld\n",
> + "SIG_OK -- SP:%llX si_addr@:0x%p si_code:%d token@:0x%p offset:%ld\n",
For consistency, can we have a "0x" prefix?
I think %p usually generates a "0x" prefix by itself, so 0x%p might give
a double prefix.
[...]
Cheers
---Dave
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v2 8/8] ARM: imx_v6_v7_defconfig: Enable the PSCI CPUidle driver
From: Lorenzo Pieralisi @ 2019-08-09 11:03 UTC (permalink / raw)
To: linux-pm
Cc: Mark Rutland, Ulf Hansson, Lorenzo Pieralisi, Will Deacon,
Catalin Marinas, Daniel Lezcano, Rafael J. Wysocki, LKML,
Sudeep Holla, Shawn Guo, LAKML
In-Reply-To: <cover.1565348376.git.lorenzo.pieralisi@arm.com>
Enable the PSCI CPUidle driver to replace the functionality
previously provided by the generic ARM CPUidle driver.
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Shawn Guo <shawnguo@kernel.org>
---
arch/arm/configs/imx_v6_v7_defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index a53b29251ed4..4174fd1b79e7 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -60,6 +60,7 @@ CONFIG_ARM_IMX6Q_CPUFREQ=y
CONFIG_ARM_IMX_CPUFREQ_DT=y
CONFIG_CPU_IDLE=y
CONFIG_ARM_CPUIDLE=y
+CONFIG_ARM_PSCI_CPUIDLE=y
CONFIG_VFP=y
CONFIG_NEON=y
CONFIG_PM_DEBUG=y
--
2.21.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
* [PATCH v2 7/8] arm64: defconfig: Enable the PSCI CPUidle driver
From: Lorenzo Pieralisi @ 2019-08-09 11:03 UTC (permalink / raw)
To: linux-pm
Cc: Mark Rutland, Ulf Hansson, Lorenzo Pieralisi, Catalin Marinas,
Daniel Lezcano, Rafael J. Wysocki, LKML, Sudeep Holla, Shawn Guo,
Will Deacon, LAKML
In-Reply-To: <cover.1565348376.git.lorenzo.pieralisi@arm.com>
Enable the PSCI CPUidle driver to replace the functionality
previously provided by the generic ARM CPUidle driver through
CPU operations.
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Sudeep Holla <sudeep.holla@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
---
arch/arm64/configs/defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 0e58ef02880c..c0a7cfe3aebd 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -72,6 +72,7 @@ CONFIG_RANDOMIZE_BASE=y
CONFIG_HIBERNATION=y
CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y
CONFIG_ARM_CPUIDLE=y
+CONFIG_ARM_PSCI_CPUIDLE=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_STAT=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=m
--
2.21.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
* [PATCH v2 6/8] PSCI: cpuidle: Refactor CPU suspend power_state parameter handling
From: Lorenzo Pieralisi @ 2019-08-09 11:03 UTC (permalink / raw)
To: linux-pm
Cc: Mark Rutland, Ulf Hansson, Lorenzo Pieralisi, Catalin Marinas,
Daniel Lezcano, Rafael J. Wysocki, LKML, Sudeep Holla, Shawn Guo,
Will Deacon, LAKML
In-Reply-To: <cover.1565348376.git.lorenzo.pieralisi@arm.com>
Current PSCI code handles idle state entry through the
psci_cpu_suspend_enter() API, that takes an idle state index as a
parameter and convert the index into a previously initialized
power_state parameter before calling the PSCI.CPU_SUSPEND() with it.
This is unwieldly, since it forces the PSCI firmware layer to keep track
of power_state parameter for every idle state so that the
index->power_state conversion can be made in the PSCI firmware layer
instead of the CPUidle driver implementations.
Move the power_state handling out of drivers/firmware/psci
into the respective ACPI/DT PSCI CPUidle backends and convert
the psci_cpu_suspend_enter() API to get the power_state
parameter as input, which makes it closer to its firmware
interface PSCI.CPU_SUSPEND() API.
A notable side effect is that the PSCI ACPI/DT CPUidle backends
now can directly handle (and if needed update) power_state
parameters before handing them over to the PSCI firmware
interface to trigger PSCI.CPU_SUSPEND() calls.
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Reviewed-by: Sudeep Holla <sudeep.holla@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Ulf Hansson <ulf.hansson@linaro.org>
Cc: Sudeep Holla <sudeep.holla@arm.com>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
---
arch/arm64/kernel/cpuidle.c | 49 +++++++++-
drivers/cpuidle/cpuidle-psci.c | 87 +++++++++++++++++-
drivers/firmware/psci/psci.c | 157 ++-------------------------------
include/linux/cpuidle.h | 17 +++-
include/linux/psci.h | 4 +-
5 files changed, 154 insertions(+), 160 deletions(-)
diff --git a/arch/arm64/kernel/cpuidle.c b/arch/arm64/kernel/cpuidle.c
index 619e0ebb8399..e4d6af2fdec7 100644
--- a/arch/arm64/kernel/cpuidle.c
+++ b/arch/arm64/kernel/cpuidle.c
@@ -47,17 +47,58 @@ int arm_cpuidle_suspend(int index)
#define ARM64_LPI_IS_RETENTION_STATE(arch_flags) (!(arch_flags))
+static int psci_acpi_cpu_init_idle(unsigned int cpu)
+{
+ int i, count;
+ struct acpi_lpi_state *lpi;
+ struct acpi_processor *pr = per_cpu(processors, cpu);
+
+ /*
+ * If the PSCI cpu_suspend function hook has not been initialized
+ * idle states must not be enabled, so bail out
+ */
+ if (!psci_ops.cpu_suspend)
+ return -EOPNOTSUPP;
+
+ if (unlikely(!pr || !pr->flags.has_lpi))
+ return -EINVAL;
+
+ count = pr->power.count - 1;
+ if (count <= 0)
+ return -ENODEV;
+
+ for (i = 0; i < count; i++) {
+ u32 state;
+
+ lpi = &pr->power.lpi_states[i + 1];
+ /*
+ * Only bits[31:0] represent a PSCI power_state while
+ * bits[63:32] must be 0x0 as per ARM ACPI FFH Specification
+ */
+ state = lpi->address;
+ if (!psci_power_state_is_valid(state)) {
+ pr_warn("Invalid PSCI power state %#x\n", state);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
int acpi_processor_ffh_lpi_probe(unsigned int cpu)
{
- return psci_cpu_init_idle(cpu);
+ return psci_acpi_cpu_init_idle(cpu);
}
int acpi_processor_ffh_lpi_enter(struct acpi_lpi_state *lpi)
{
+ u32 state = lpi->address;
+
if (ARM64_LPI_IS_RETENTION_STATE(lpi->arch_flags))
- return CPU_PM_CPU_IDLE_ENTER_RETENTION(psci_cpu_suspend_enter,
- lpi->index);
+ return CPU_PM_CPU_IDLE_ENTER_RETENTION_PARAM(psci_cpu_suspend_enter,
+ lpi->index, state);
else
- return CPU_PM_CPU_IDLE_ENTER(psci_cpu_suspend_enter, lpi->index);
+ return CPU_PM_CPU_IDLE_ENTER_PARAM(psci_cpu_suspend_enter,
+ lpi->index, state);
}
#endif
diff --git a/drivers/cpuidle/cpuidle-psci.c b/drivers/cpuidle/cpuidle-psci.c
index ab1dea918ea3..f3c1a2396f98 100644
--- a/drivers/cpuidle/cpuidle-psci.c
+++ b/drivers/cpuidle/cpuidle-psci.c
@@ -22,10 +22,15 @@
#include "dt_idle_states.h"
+static DEFINE_PER_CPU_READ_MOSTLY(u32 *, psci_power_state);
+
static int psci_enter_idle_state(struct cpuidle_device *dev,
struct cpuidle_driver *drv, int idx)
{
- return CPU_PM_CPU_IDLE_ENTER(psci_cpu_suspend_enter, idx);
+ u32 *state = __this_cpu_read(psci_power_state);
+
+ return CPU_PM_CPU_IDLE_ENTER_PARAM(psci_cpu_suspend_enter,
+ idx, state[idx - 1]);
}
static struct cpuidle_driver psci_idle_driver __initdata = {
@@ -51,6 +56,86 @@ static const struct of_device_id psci_idle_state_match[] __initconst = {
{ },
};
+static int __init psci_dt_parse_state_node(struct device_node *np, u32 *state)
+{
+ int err = of_property_read_u32(np, "arm,psci-suspend-param", state);
+
+ if (err) {
+ pr_warn("%pOF missing arm,psci-suspend-param property\n", np);
+ return err;
+ }
+
+ if (!psci_power_state_is_valid(*state)) {
+ pr_warn("Invalid PSCI power state %#x\n", *state);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int __init psci_dt_cpu_init_idle(struct device_node *cpu_node, int cpu)
+{
+ int i, ret = 0, count = 0;
+ u32 *psci_states;
+ struct device_node *state_node;
+
+ /* Count idle states */
+ while ((state_node = of_parse_phandle(cpu_node, "cpu-idle-states",
+ count))) {
+ count++;
+ of_node_put(state_node);
+ }
+
+ if (!count)
+ return -ENODEV;
+
+ psci_states = kcalloc(count, sizeof(*psci_states), GFP_KERNEL);
+ if (!psci_states)
+ return -ENOMEM;
+
+ for (i = 0; i < count; i++) {
+ state_node = of_parse_phandle(cpu_node, "cpu-idle-states", i);
+ ret = psci_dt_parse_state_node(state_node, &psci_states[i]);
+ of_node_put(state_node);
+
+ if (ret)
+ goto free_mem;
+
+ pr_debug("psci-power-state %#x index %d\n", psci_states[i], i);
+ }
+
+ /* Idle states parsed correctly, initialize per-cpu pointer */
+ per_cpu(psci_power_state, cpu) = psci_states;
+ return 0;
+
+free_mem:
+ kfree(psci_states);
+ return ret;
+}
+
+static __init int psci_cpu_init_idle(unsigned int cpu)
+{
+ struct device_node *cpu_node;
+ int ret;
+
+ /*
+ * If the PSCI cpu_suspend function hook has not been initialized
+ * idle states must not be enabled, so bail out
+ */
+ if (!psci_ops.cpu_suspend)
+ return -EOPNOTSUPP;
+
+ cpu_node = of_cpu_device_node_get(cpu);
+ if (!cpu_node)
+ return -ENODEV;
+
+ ret = psci_dt_cpu_init_idle(cpu_node, cpu);
+
+ of_node_put(cpu_node);
+
+ return ret;
+}
+
static int __init psci_idle_init_cpu(int cpu)
{
struct cpuidle_driver *drv;
diff --git a/drivers/firmware/psci/psci.c b/drivers/firmware/psci/psci.c
index b343f8a34c6a..84f4ff351c62 100644
--- a/drivers/firmware/psci/psci.c
+++ b/drivers/firmware/psci/psci.c
@@ -103,7 +103,7 @@ static inline bool psci_power_state_loses_context(u32 state)
return state & mask;
}
-static inline bool psci_power_state_is_valid(u32 state)
+bool psci_power_state_is_valid(u32 state)
{
const u32 valid_mask = psci_has_ext_power_state() ?
PSCI_1_0_EXT_POWER_STATE_MASK :
@@ -277,162 +277,21 @@ static int __init psci_features(u32 psci_func_id)
}
#ifdef CONFIG_CPU_IDLE
-static DEFINE_PER_CPU_READ_MOSTLY(u32 *, psci_power_state);
-
-static int psci_dt_parse_state_node(struct device_node *np, u32 *state)
-{
- int err = of_property_read_u32(np, "arm,psci-suspend-param", state);
-
- if (err) {
- pr_warn("%pOF missing arm,psci-suspend-param property\n", np);
- return err;
- }
-
- if (!psci_power_state_is_valid(*state)) {
- pr_warn("Invalid PSCI power state %#x\n", *state);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int psci_dt_cpu_init_idle(struct device_node *cpu_node, int cpu)
-{
- int i, ret = 0, count = 0;
- u32 *psci_states;
- struct device_node *state_node;
-
- /* Count idle states */
- while ((state_node = of_parse_phandle(cpu_node, "cpu-idle-states",
- count))) {
- count++;
- of_node_put(state_node);
- }
-
- if (!count)
- return -ENODEV;
-
- psci_states = kcalloc(count, sizeof(*psci_states), GFP_KERNEL);
- if (!psci_states)
- return -ENOMEM;
-
- for (i = 0; i < count; i++) {
- state_node = of_parse_phandle(cpu_node, "cpu-idle-states", i);
- ret = psci_dt_parse_state_node(state_node, &psci_states[i]);
- of_node_put(state_node);
-
- if (ret)
- goto free_mem;
-
- pr_debug("psci-power-state %#x index %d\n", psci_states[i], i);
- }
-
- /* Idle states parsed correctly, initialize per-cpu pointer */
- per_cpu(psci_power_state, cpu) = psci_states;
- return 0;
-
-free_mem:
- kfree(psci_states);
- return ret;
-}
-
-#ifdef CONFIG_ACPI
-#include <acpi/processor.h>
-
-static int __maybe_unused psci_acpi_cpu_init_idle(unsigned int cpu)
-{
- int i, count;
- u32 *psci_states;
- struct acpi_lpi_state *lpi;
- struct acpi_processor *pr = per_cpu(processors, cpu);
-
- if (unlikely(!pr || !pr->flags.has_lpi))
- return -EINVAL;
-
- count = pr->power.count - 1;
- if (count <= 0)
- return -ENODEV;
-
- psci_states = kcalloc(count, sizeof(*psci_states), GFP_KERNEL);
- if (!psci_states)
- return -ENOMEM;
-
- for (i = 0; i < count; i++) {
- u32 state;
-
- lpi = &pr->power.lpi_states[i + 1];
- /*
- * Only bits[31:0] represent a PSCI power_state while
- * bits[63:32] must be 0x0 as per ARM ACPI FFH Specification
- */
- state = lpi->address;
- if (!psci_power_state_is_valid(state)) {
- pr_warn("Invalid PSCI power state %#x\n", state);
- kfree(psci_states);
- return -EINVAL;
- }
- psci_states[i] = state;
- }
- /* Idle states parsed correctly, initialize per-cpu pointer */
- per_cpu(psci_power_state, cpu) = psci_states;
- return 0;
-}
-#else
-static int __maybe_unused psci_acpi_cpu_init_idle(unsigned int cpu)
-{
- return -EINVAL;
-}
-#endif
-
-int psci_cpu_init_idle(unsigned int cpu)
-{
- struct device_node *cpu_node;
- int ret;
-
- /*
- * If the PSCI cpu_suspend function hook has not been initialized
- * idle states must not be enabled, so bail out
- */
- if (!psci_ops.cpu_suspend)
- return -EOPNOTSUPP;
-
- if (!acpi_disabled)
- return psci_acpi_cpu_init_idle(cpu);
-
- cpu_node = of_get_cpu_node(cpu, NULL);
- if (!cpu_node)
- return -ENODEV;
-
- ret = psci_dt_cpu_init_idle(cpu_node, cpu);
-
- of_node_put(cpu_node);
-
- return ret;
-}
-
-static int psci_suspend_finisher(unsigned long index)
+static int psci_suspend_finisher(unsigned long state)
{
- u32 *state = __this_cpu_read(psci_power_state);
+ u32 power_state = state;
- return psci_ops.cpu_suspend(state[index - 1],
- __pa_symbol(cpu_resume));
+ return psci_ops.cpu_suspend(power_state, __pa_symbol(cpu_resume));
}
-int psci_cpu_suspend_enter(unsigned long index)
+int psci_cpu_suspend_enter(u32 state)
{
int ret;
- u32 *state = __this_cpu_read(psci_power_state);
- /*
- * idle state index 0 corresponds to wfi, should never be called
- * from the cpu_suspend operations
- */
- if (WARN_ON_ONCE(!index))
- return -EINVAL;
- if (!psci_power_state_loses_context(state[index - 1]))
- ret = psci_ops.cpu_suspend(state[index - 1], 0);
+ if (!psci_power_state_loses_context(state))
+ ret = psci_ops.cpu_suspend(state, 0);
else
- ret = cpu_suspend(index, psci_suspend_finisher);
+ ret = cpu_suspend(state, psci_suspend_finisher);
return ret;
}
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h
index bb9a0db89f1a..12ae4b87494e 100644
--- a/include/linux/cpuidle.h
+++ b/include/linux/cpuidle.h
@@ -256,7 +256,10 @@ static inline int cpuidle_register_governor(struct cpuidle_governor *gov)
{return 0;}
#endif
-#define __CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter, idx, is_retention) \
+#define __CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter, \
+ idx, \
+ state, \
+ is_retention) \
({ \
int __ret = 0; \
\
@@ -268,7 +271,7 @@ static inline int cpuidle_register_governor(struct cpuidle_governor *gov)
if (!is_retention) \
__ret = cpu_pm_enter(); \
if (!__ret) { \
- __ret = low_level_idle_enter(idx); \
+ __ret = low_level_idle_enter(state); \
if (!is_retention) \
cpu_pm_exit(); \
} \
@@ -277,9 +280,15 @@ static inline int cpuidle_register_governor(struct cpuidle_governor *gov)
})
#define CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter, idx) \
- __CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter, idx, 0)
+ __CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter, idx, idx, 0)
#define CPU_PM_CPU_IDLE_ENTER_RETENTION(low_level_idle_enter, idx) \
- __CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter, idx, 1)
+ __CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter, idx, idx, 1)
+
+#define CPU_PM_CPU_IDLE_ENTER_PARAM(low_level_idle_enter, idx, state) \
+ __CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter, idx, state, 0)
+
+#define CPU_PM_CPU_IDLE_ENTER_RETENTION_PARAM(low_level_idle_enter, idx, state) \
+ __CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter, idx, state, 1)
#endif /* _LINUX_CPUIDLE_H */
diff --git a/include/linux/psci.h b/include/linux/psci.h
index a8a15613c157..e2bacc6fd2f2 100644
--- a/include/linux/psci.h
+++ b/include/linux/psci.h
@@ -15,8 +15,8 @@
bool psci_tos_resident_on(int cpu);
-int psci_cpu_init_idle(unsigned int cpu);
-int psci_cpu_suspend_enter(unsigned long index);
+int psci_cpu_suspend_enter(u32 state);
+bool psci_power_state_is_valid(u32 state);
enum psci_conduit {
PSCI_CONDUIT_NONE,
--
2.21.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
* [PATCH v2 5/8] ARM: psci: cpuidle: Enable PSCI CPUidle driver
From: Lorenzo Pieralisi @ 2019-08-09 11:03 UTC (permalink / raw)
To: linux-pm
Cc: Mark Rutland, Ulf Hansson, Lorenzo Pieralisi, Catalin Marinas,
Daniel Lezcano, Rafael J. Wysocki, LKML, Sudeep Holla, Shawn Guo,
Will Deacon, LAKML
In-Reply-To: <cover.1565348376.git.lorenzo.pieralisi@arm.com>
Allow selection of the PSCI CPUidle in the kernel by updating
the respective Kconfig entry.
Remove PSCI callbacks from ARM/ARM64 generic CPU ops
to prevent the PSCI idle driver from clashing with the generic
ARM CPUidle driver initialization, that relies on CPU ops
to initialize and enter idle states.
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Cc: Will Deacon <will@kernel.org>
Cc: Ulf Hansson <ulf.hansson@linaro.org>
Cc: Sudeep Holla <sudeep.holla@arm.com>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
---
arch/arm64/kernel/cpuidle.c | 7 ++++---
arch/arm64/kernel/psci.c | 4 ----
drivers/cpuidle/Kconfig.arm | 2 +-
drivers/firmware/psci/psci.c | 10 ----------
4 files changed, 5 insertions(+), 18 deletions(-)
diff --git a/arch/arm64/kernel/cpuidle.c b/arch/arm64/kernel/cpuidle.c
index d1048173fd8a..619e0ebb8399 100644
--- a/arch/arm64/kernel/cpuidle.c
+++ b/arch/arm64/kernel/cpuidle.c
@@ -11,6 +11,7 @@
#include <linux/cpu_pm.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/psci.h>
#include <asm/cpuidle.h>
#include <asm/cpu_ops.h>
@@ -48,15 +49,15 @@ int arm_cpuidle_suspend(int index)
int acpi_processor_ffh_lpi_probe(unsigned int cpu)
{
- return arm_cpuidle_init(cpu);
+ return psci_cpu_init_idle(cpu);
}
int acpi_processor_ffh_lpi_enter(struct acpi_lpi_state *lpi)
{
if (ARM64_LPI_IS_RETENTION_STATE(lpi->arch_flags))
- return CPU_PM_CPU_IDLE_ENTER_RETENTION(arm_cpuidle_suspend,
+ return CPU_PM_CPU_IDLE_ENTER_RETENTION(psci_cpu_suspend_enter,
lpi->index);
else
- return CPU_PM_CPU_IDLE_ENTER(arm_cpuidle_suspend, lpi->index);
+ return CPU_PM_CPU_IDLE_ENTER(psci_cpu_suspend_enter, lpi->index);
}
#endif
diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c
index 85ee7d07889e..a543ab7e007c 100644
--- a/arch/arm64/kernel/psci.c
+++ b/arch/arm64/kernel/psci.c
@@ -105,10 +105,6 @@ static int cpu_psci_cpu_kill(unsigned int cpu)
const struct cpu_operations cpu_psci_ops = {
.name = "psci",
-#ifdef CONFIG_CPU_IDLE
- .cpu_init_idle = psci_cpu_init_idle,
- .cpu_suspend = psci_cpu_suspend_enter,
-#endif
.cpu_init = cpu_psci_cpu_init,
.cpu_prepare = cpu_psci_cpu_prepare,
.cpu_boot = cpu_psci_cpu_boot,
diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm
index eb014aa5ce6b..d8530475493c 100644
--- a/drivers/cpuidle/Kconfig.arm
+++ b/drivers/cpuidle/Kconfig.arm
@@ -14,7 +14,7 @@ config ARM_CPUIDLE
provided by architecture code.
config ARM_PSCI_CPUIDLE
- bool
+ bool "PSCI CPU idle Driver"
depends on ARM_PSCI_FW
select DT_IDLE_STATES
select CPU_IDLE_MULTIPLE_DRIVERS
diff --git a/drivers/firmware/psci/psci.c b/drivers/firmware/psci/psci.c
index f82ccd39a913..b343f8a34c6a 100644
--- a/drivers/firmware/psci/psci.c
+++ b/drivers/firmware/psci/psci.c
@@ -436,16 +436,6 @@ int psci_cpu_suspend_enter(unsigned long index)
return ret;
}
-
-/* ARM specific CPU idle operations */
-#ifdef CONFIG_ARM
-static const struct cpuidle_ops psci_cpuidle_ops __initconst = {
- .suspend = psci_cpu_suspend_enter,
- .init = psci_dt_cpu_init_idle,
-};
-
-CPUIDLE_METHOD_OF_DECLARE(psci, "psci", &psci_cpuidle_ops);
-#endif
#endif
static int psci_system_suspend(unsigned long unused)
--
2.21.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
* [PATCH v2 4/8] ARM: psci: cpuidle: Introduce PSCI CPUidle driver
From: Lorenzo Pieralisi @ 2019-08-09 11:03 UTC (permalink / raw)
To: linux-pm
Cc: Mark Rutland, Ulf Hansson, Lorenzo Pieralisi, Catalin Marinas,
Daniel Lezcano, Rafael J. Wysocki, LKML, Sudeep Holla, Shawn Guo,
Will Deacon, LAKML
In-Reply-To: <cover.1565348376.git.lorenzo.pieralisi@arm.com>
PSCI firmware is the standard power management control for
all ARM64 based platforms and it is also deployed on some
ARM 32 bit platforms to date.
Idle state entry in PSCI is currently achieved by calling
arm_cpuidle_init() and arm_cpuidle_suspend() in a generic
idle driver, which in turn relies on ARM/ARM64 CPUidle back-end
to relay the call into PSCI firmware if PSCI is the boot method.
Given that PSCI is the standard idle entry method on ARM64 systems
(which means that no other CPUidle driver are expected on ARM64
platforms - so PSCI is already a generic idle driver), in order to
simplify idle entry and code maintenance, it makes sense to have a PSCI
specific idle driver so that idle code that it is currently living in
drivers/firmware directory can be hoisted out of it and moved
where it belongs, into a full-fledged PSCI driver, leaving PSCI code
in drivers/firmware as a pure firmware interface, as it should be.
Implement a PSCI CPUidle driver. By default it is a silent Kconfig entry
which is left unselected, since it selection would clash with the
generic ARM CPUidle driver that provides a PSCI based idle driver
through the arm/arm64 arches back-ends CPU operations.
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Reviewed-by: Sudeep Holla <sudeep.holla@arm.com>
Cc: Ulf Hansson <ulf.hansson@linaro.org>
Cc: Sudeep Holla <sudeep.holla@arm.com>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
---
MAINTAINERS | 8 ++
drivers/cpuidle/Kconfig.arm | 10 +++
drivers/cpuidle/Makefile | 1 +
drivers/cpuidle/cpuidle-psci.c | 151 +++++++++++++++++++++++++++++++++
4 files changed, 170 insertions(+)
create mode 100644 drivers/cpuidle/cpuidle-psci.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 783569e3c4b4..c2bf8ce65e83 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4286,6 +4286,14 @@ S: Supported
F: drivers/cpuidle/cpuidle-exynos.c
F: arch/arm/mach-exynos/pm.c
+CPUIDLE DRIVER - ARM PSCI
+M: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+M: Sudeep Holla <sudeep.holla@arm.com>
+L: linux-pm@vger.kernel.org
+L: linux-arm-kernel@lists.infradead.org
+S: Supported
+F: drivers/cpuidle/cpuidle-psci.c
+
CPU IDLE TIME MANAGEMENT FRAMEWORK
M: "Rafael J. Wysocki" <rjw@rjwysocki.net>
M: Daniel Lezcano <daniel.lezcano@linaro.org>
diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm
index 48cb3d4bb7d1..eb014aa5ce6b 100644
--- a/drivers/cpuidle/Kconfig.arm
+++ b/drivers/cpuidle/Kconfig.arm
@@ -13,6 +13,16 @@ config ARM_CPUIDLE
initialized by calling the CPU operations init idle hook
provided by architecture code.
+config ARM_PSCI_CPUIDLE
+ bool
+ depends on ARM_PSCI_FW
+ select DT_IDLE_STATES
+ select CPU_IDLE_MULTIPLE_DRIVERS
+ help
+ Select this to enable PSCI firmware based CPUidle driver for ARM.
+ It provides an idle driver that is capable of detecting and
+ managing idle states through the PSCI firmware interface.
+
config ARM_BIG_LITTLE_CPUIDLE
bool "Support for ARM big.LITTLE processors"
depends on ARCH_VEXPRESS_TC2_PM || ARCH_EXYNOS
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
index 9d7176cee3d3..40d016339b29 100644
--- a/drivers/cpuidle/Makefile
+++ b/drivers/cpuidle/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_ARM_U8500_CPUIDLE) += cpuidle-ux500.o
obj-$(CONFIG_ARM_AT91_CPUIDLE) += cpuidle-at91.o
obj-$(CONFIG_ARM_EXYNOS_CPUIDLE) += cpuidle-exynos.o
obj-$(CONFIG_ARM_CPUIDLE) += cpuidle-arm.o
+obj-$(CONFIG_ARM_PSCI_CPUIDLE) += cpuidle-psci.o
###############################################################################
# MIPS drivers
diff --git a/drivers/cpuidle/cpuidle-psci.c b/drivers/cpuidle/cpuidle-psci.c
new file mode 100644
index 000000000000..ab1dea918ea3
--- /dev/null
+++ b/drivers/cpuidle/cpuidle-psci.c
@@ -0,0 +1,151 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * PSCI CPU idle driver.
+ *
+ * Copyright (C) 2019 ARM Ltd.
+ * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+ */
+
+#define pr_fmt(fmt) "CPUidle PSCI: " fmt
+
+#include <linux/cpuidle.h>
+#include <linux/cpumask.h>
+#include <linux/cpu_pm.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/psci.h>
+#include <linux/slab.h>
+
+#include <asm/cpuidle.h>
+
+#include "dt_idle_states.h"
+
+static int psci_enter_idle_state(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv, int idx)
+{
+ return CPU_PM_CPU_IDLE_ENTER(psci_cpu_suspend_enter, idx);
+}
+
+static struct cpuidle_driver psci_idle_driver __initdata = {
+ .name = "psci_idle",
+ .owner = THIS_MODULE,
+ /*
+ * PSCI idle states relies on architectural WFI to
+ * be represented as state index 0.
+ */
+ .states[0] = {
+ .enter = psci_enter_idle_state,
+ .exit_latency = 1,
+ .target_residency = 1,
+ .power_usage = UINT_MAX,
+ .name = "WFI",
+ .desc = "ARM WFI",
+ }
+};
+
+static const struct of_device_id psci_idle_state_match[] __initconst = {
+ { .compatible = "arm,idle-state",
+ .data = psci_enter_idle_state },
+ { },
+};
+
+static int __init psci_idle_init_cpu(int cpu)
+{
+ struct cpuidle_driver *drv;
+ struct device_node *cpu_node;
+ const char *enable_method;
+ int ret = 0;
+
+ cpu_node = of_cpu_device_node_get(cpu);
+ if (!cpu_node)
+ return -ENODEV;
+
+ /*
+ * Check whether the enable-method for the cpu is PSCI, fail
+ * if it is not.
+ */
+ enable_method = of_get_property(cpu_node, "enable-method", NULL);
+ if (!enable_method || (strcmp(enable_method, "psci")))
+ ret = -ENODEV;
+
+ of_node_put(cpu_node);
+ if (ret)
+ return ret;
+
+ drv = kmemdup(&psci_idle_driver, sizeof(*drv), GFP_KERNEL);
+ if (!drv)
+ return -ENOMEM;
+
+ drv->cpumask = (struct cpumask *)cpumask_of(cpu);
+
+ /*
+ * Initialize idle states data, starting at index 1, since
+ * by default idle state 0 is the quiescent state reached
+ * by the cpu by executing the wfi instruction.
+ *
+ * If no DT idle states are detected (ret == 0) let the driver
+ * initialization fail accordingly since there is no reason to
+ * initialize the idle driver if only wfi is supported, the
+ * default archictectural back-end already executes wfi
+ * on idle entry.
+ */
+ ret = dt_init_idle_driver(drv, psci_idle_state_match, 1);
+ if (ret <= 0) {
+ ret = ret ? : -ENODEV;
+ goto out_kfree_drv;
+ }
+
+ /*
+ * Initialize PSCI idle states.
+ */
+ ret = psci_cpu_init_idle(cpu);
+ if (ret) {
+ pr_err("CPU %d failed to PSCI idle\n", cpu);
+ goto out_kfree_drv;
+ }
+
+ ret = cpuidle_register(drv, NULL);
+ if (ret)
+ goto out_kfree_drv;
+
+ return 0;
+
+out_kfree_drv:
+ kfree(drv);
+ return ret;
+}
+
+/*
+ * psci_idle_init - Initializes PSCI cpuidle driver
+ *
+ * Initializes PSCI cpuidle driver for all CPUs, if any CPU fails
+ * to register cpuidle driver then rollback to cancel all CPUs
+ * registration.
+ */
+static int __init psci_idle_init(void)
+{
+ int cpu, ret;
+ struct cpuidle_driver *drv;
+ struct cpuidle_device *dev;
+
+ for_each_possible_cpu(cpu) {
+ ret = psci_idle_init_cpu(cpu);
+ if (ret)
+ goto out_fail;
+ }
+
+ return 0;
+
+out_fail:
+ while (--cpu >= 0) {
+ dev = per_cpu(cpuidle_devices, cpu);
+ drv = cpuidle_get_cpu_driver(dev);
+ cpuidle_unregister(drv);
+ kfree(drv);
+ }
+
+ return ret;
+}
+device_initcall(psci_idle_init);
--
2.21.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
* [PATCH v2 3/8] drivers: firmware: psci: Decouple checker from generic ARM CPUidle
From: Lorenzo Pieralisi @ 2019-08-09 11:03 UTC (permalink / raw)
To: linux-pm
Cc: Mark Rutland, Ulf Hansson, Lorenzo Pieralisi, Catalin Marinas,
Daniel Lezcano, Rafael J. Wysocki, LKML, Sudeep Holla, Shawn Guo,
Will Deacon, LAKML
In-Reply-To: <cover.1565348376.git.lorenzo.pieralisi@arm.com>
The PSCI checker currently relies on the generic ARM CPUidle
infrastructure to enter an idle state, which in turn creates
a dependency that is not really needed.
The PSCI checker code to test PSCI CPU suspend is built on
top of the CPUidle framework and can easily reuse the
struct cpuidle_state.enter() function (previously initialized
by an idle driver, with a PSCI back-end) to trigger an entry
into an idle state, decoupling the PSCI checker from the
generic ARM CPUidle infrastructure and simplyfing the code
in the process.
Convert the PSCI checker suspend entry function to use
the struct cpuidle_state.enter() function callback.
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Reviewed-by: Sudeep Holla <sudeep.holla@arm.com>
Cc: Sudeep Holla <sudeep.holla@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
---
drivers/firmware/psci/psci_checker.c | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/drivers/firmware/psci/psci_checker.c b/drivers/firmware/psci/psci_checker.c
index f3659443f8c2..6a445397771c 100644
--- a/drivers/firmware/psci/psci_checker.c
+++ b/drivers/firmware/psci/psci_checker.c
@@ -228,8 +228,11 @@ static int hotplug_tests(void)
static void dummy_callback(struct timer_list *unused) {}
-static int suspend_cpu(int index, bool broadcast)
+static int suspend_cpu(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv, int index)
{
+ struct cpuidle_state *state = &drv->states[index];
+ bool broadcast = state->flags & CPUIDLE_FLAG_TIMER_STOP;
int ret;
arch_cpu_idle_enter();
@@ -254,11 +257,7 @@ static int suspend_cpu(int index, bool broadcast)
}
}
- /*
- * Replicate the common ARM cpuidle enter function
- * (arm_enter_idle_state).
- */
- ret = CPU_PM_CPU_IDLE_ENTER(arm_cpuidle_suspend, index);
+ ret = state->enter(dev, drv, index);
if (broadcast)
tick_broadcast_exit();
@@ -301,9 +300,8 @@ static int suspend_test_thread(void *arg)
* doesn't use PSCI).
*/
for (index = 1; index < drv->state_count; ++index) {
- struct cpuidle_state *state = &drv->states[index];
- bool broadcast = state->flags & CPUIDLE_FLAG_TIMER_STOP;
int ret;
+ struct cpuidle_state *state = &drv->states[index];
/*
* Set the timer to wake this CPU up in some time (which
@@ -318,7 +316,7 @@ static int suspend_test_thread(void *arg)
/* IRQs must be disabled during suspend operations. */
local_irq_disable();
- ret = suspend_cpu(index, broadcast);
+ ret = suspend_cpu(dev, drv, index);
/*
* We have woken up. Re-enable IRQs to handle any
--
2.21.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
* [PATCH v2 2/8] ARM: cpuidle: Remove overzealous error logging
From: Lorenzo Pieralisi @ 2019-08-09 11:03 UTC (permalink / raw)
To: linux-pm
Cc: Mark Rutland, Ulf Hansson, Lorenzo Pieralisi, Catalin Marinas,
Daniel Lezcano, Rafael J. Wysocki, LKML, Sudeep Holla, Shawn Guo,
Will Deacon, LAKML
In-Reply-To: <cover.1565348376.git.lorenzo.pieralisi@arm.com>
CPUidle back-end operations are not implemented in some platforms
but this should not be considered an error serious enough to be
logged. Check the arm_cpuidle_init() return value to detect whether
the failure must be reported or not in the kernel log and do
not log it if the platform does not support CPUidle operations.
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Reviewed-by: Sudeep Holla <sudeep.holla@arm.com>
Cc: Ulf Hansson <ulf.hansson@linaro.org>
Cc: Sudeep Holla <sudeep.holla@arm.com>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
---
drivers/cpuidle/cpuidle-arm.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/cpuidle/cpuidle-arm.c b/drivers/cpuidle/cpuidle-arm.c
index dc33b3d2954f..9e5156d39627 100644
--- a/drivers/cpuidle/cpuidle-arm.c
+++ b/drivers/cpuidle/cpuidle-arm.c
@@ -105,11 +105,17 @@ static int __init arm_idle_init_cpu(int cpu)
ret = arm_cpuidle_init(cpu);
/*
- * Allow the initialization to continue for other CPUs, if the reported
- * failure is a HW misconfiguration/breakage (-ENXIO).
+ * Allow the initialization to continue for other CPUs, if the
+ * reported failure is a HW misconfiguration/breakage (-ENXIO).
+ *
+ * Some platforms do not support idle operations
+ * (arm_cpuidle_init() returning -EOPNOTSUPP), we should
+ * not flag this case as an error, it is a valid
+ * configuration.
*/
if (ret) {
- pr_err("CPU %d failed to init idle CPU ops\n", cpu);
+ if (ret != -EOPNOTSUPP)
+ pr_err("CPU %d failed to init idle CPU ops\n", cpu);
ret = ret == -ENXIO ? 0 : ret;
goto out_kfree_drv;
}
--
2.21.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
* [PATCH v2 0/8] ARM: psci: cpuidle: PSCI CPUidle rework
From: Lorenzo Pieralisi @ 2019-08-09 11:03 UTC (permalink / raw)
To: linux-pm
Cc: Mark Rutland, Ulf Hansson, Lorenzo Pieralisi, Catalin Marinas,
Will Deacon, Daniel Lezcano, Rafael J. Wysocki, LKML,
Sudeep Holla, Shawn Guo, LAKML
In-Reply-To: <20190722153745.32446-1-lorenzo.pieralisi@arm.com>
v2 of a previous posting:
v1: https://lore.kernel.org/linux-pm/20190722153745.32446-1-lorenzo.pieralisi@arm.com/
v1->v2:
- Split config files updates into separate patches
- Fixed minor memory leaks/bisectability issues
Original cover letter
---
Current PSCI CPUidle driver is built on top of the generic ARM
CPUidle infrastructure that relies on the architectural back-end
idle operations to initialize and enter idle states.
On ARM64 systems, PSCI is the only interface the kernel ever uses
to enter idle states, so, having to rely on a generic ARM CPUidle
driver when there is and there will always be only one method
for entering idle states proved to be overkill, more so given
that on ARM 32-bit systems (that can also enable the generic
ARM CPUidle driver) only one additional idle back-end was
ever added:
drivers/soc/qcom/spm.c
and it can be easily converted to a full-fledged CPUidle driver
without requiring the generic ARM CPUidle framework.
Furthermore, the generic ARM CPUidle infrastructure forces the
PSCI firmware layer to keep CPUidle specific information in it,
which does not really fit its purpose that should be kernel
control/data structure agnostic.
Lastly, the interface between the generic ARM CPUidle driver and
the arch back-end requires an idle state index to be passed to
suspend operations, with idle states back-end internals (such
as idle state parameters) hidden in architectural back-ends and
not available to the generic ARM CPUidle driver.
To improve the above mentioned shortcomings, implement a stand
alone PSCI CPUidle driver; this improves the current kernel
code from several perspective:
- Move CPUidle internal knowledge into CPUidle driver out of
the PSCI firmware interface
- Give the PSCI CPUidle driver control over power state parameters,
in particular in preparation for PSCI OSI support
- Remove generic CPUidle operations infrastructure from the kernel
This patchset does not go as far as removing the generic ARM CPUidle
infrastructure in order to collect feedback on the new approach
before completing the removal from the kernel, the generic and PSCI
CPUidle driver are left to co-exist.
Tested on Juno platform with both DT and ACPI boot firmwares.
Cc: Will Deacon <will@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Ulf Hansson <ulf.hansson@linaro.org>
Cc: Sudeep Holla <sudeep.holla@arm.com>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Lorenzo Pieralisi (8):
ARM: cpuidle: Remove useless header include
ARM: cpuidle: Remove overzealous error logging
drivers: firmware: psci: Decouple checker from generic ARM CPUidle
ARM: psci: cpuidle: Introduce PSCI CPUidle driver
ARM: psci: cpuidle: Enable PSCI CPUidle driver
PSCI: cpuidle: Refactor CPU suspend power_state parameter handling
arm64: defconfig: Enable the PSCI CPUidle driver
ARM: imx_v6_v7_defconfig: Enable the PSCI CPUidle driver
MAINTAINERS | 8 +
arch/arm/configs/imx_v6_v7_defconfig | 1 +
arch/arm64/configs/defconfig | 1 +
arch/arm64/kernel/cpuidle.c | 50 +++++-
arch/arm64/kernel/psci.c | 4 -
drivers/cpuidle/Kconfig.arm | 10 ++
drivers/cpuidle/Makefile | 1 +
drivers/cpuidle/cpuidle-arm.c | 13 +-
drivers/cpuidle/cpuidle-psci.c | 236 +++++++++++++++++++++++++++
drivers/firmware/psci/psci.c | 167 +------------------
drivers/firmware/psci/psci_checker.c | 16 +-
include/linux/cpuidle.h | 17 +-
include/linux/psci.h | 4 +-
13 files changed, 342 insertions(+), 186 deletions(-)
create mode 100644 drivers/cpuidle/cpuidle-psci.c
--
2.21.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v2 1/8] ARM: cpuidle: Remove useless header include
From: Lorenzo Pieralisi @ 2019-08-09 11:03 UTC (permalink / raw)
To: linux-pm
Cc: Mark Rutland, Ulf Hansson, Lorenzo Pieralisi, Catalin Marinas,
Daniel Lezcano, Rafael J. Wysocki, LKML, Sudeep Holla, Shawn Guo,
Will Deacon, LAKML
In-Reply-To: <cover.1565348376.git.lorenzo.pieralisi@arm.com>
The generic ARM CPUidle driver includes <linux/topology.h> by mistake.
Remove the topology header include.
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
Reviewed-by: Sudeep Holla <sudeep.holla@arm.com>
Cc: Ulf Hansson <ulf.hansson@linaro.org>
Cc: Sudeep Holla <sudeep.holla@arm.com>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
---
drivers/cpuidle/cpuidle-arm.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/cpuidle/cpuidle-arm.c b/drivers/cpuidle/cpuidle-arm.c
index 5bcd82c35dcf..dc33b3d2954f 100644
--- a/drivers/cpuidle/cpuidle-arm.c
+++ b/drivers/cpuidle/cpuidle-arm.c
@@ -15,7 +15,6 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/slab.h>
-#include <linux/topology.h>
#include <asm/cpuidle.h>
--
2.21.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 06/19] irqchip/mmp: add missing chained_irq_{enter, exit}()
From: Marc Zyngier @ 2019-08-09 10:56 UTC (permalink / raw)
To: Lubomir Rintel, Olof Johansson
Cc: Mark Rutland, devicetree, Jason Cooper, Stephen Boyd,
linux-kernel, Michael Turquette, Russell King,
Kishon Vijay Abraham I, Rob Herring, Thomas Gleixner, linux-clk,
linux-arm-kernel
In-Reply-To: <20190809093158.7969-7-lkundrak@v3.sk>
On 09/08/2019 10:31, Lubomir Rintel wrote:
> The lack of chained_irq_exit() leaves the muxed interrupt masked on MMP3.
> For reasons unknown this is not a problem on MMP2.
>
> Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
> ---
> drivers/irqchip/irq-mmp.c | 9 ++++++++-
> 1 file changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/irqchip/irq-mmp.c b/drivers/irqchip/irq-mmp.c
> index af9cba4a51c2e..cd8d2253f56d1 100644
> --- a/drivers/irqchip/irq-mmp.c
> +++ b/drivers/irqchip/irq-mmp.c
> @@ -13,6 +13,7 @@
> #include <linux/init.h>
> #include <linux/irq.h>
> #include <linux/irqchip.h>
> +#include <linux/irqchip/chained_irq.h>
> #include <linux/irqdomain.h>
> #include <linux/io.h>
> #include <linux/ioport.h>
> @@ -132,11 +133,14 @@ struct irq_chip icu_irq_chip = {
> static void icu_mux_irq_demux(struct irq_desc *desc)
> {
> unsigned int irq = irq_desc_get_irq(desc);
> + struct irq_chip *chip = irq_get_chip(irq);
Consider using irq_desc_get_chip() instead, which avoids going through
the irq->desc again.
> struct irq_domain *domain;
> struct icu_chip_data *data;
> int i;
> unsigned long mask, status, n;
>
> + chained_irq_enter(chip, desc);
> +
> for (i = 1; i < max_icu_nr; i++) {
> if (irq == icu_data[i].cascade_irq) {
> domain = icu_data[i].domain;
> @@ -146,7 +150,7 @@ static void icu_mux_irq_demux(struct irq_desc *desc)
> }
> if (i >= max_icu_nr) {
> pr_err("Spurious irq %d in MMP INTC\n", irq);
> - return;
> + goto out;
> }
>
> mask = readl_relaxed(data->reg_mask);
> @@ -158,6 +162,9 @@ static void icu_mux_irq_demux(struct irq_desc *desc)
> generic_handle_irq(icu_data[i].virq_base + n);
> }
> }
> +
> +out:
> + chained_irq_exit(chip, desc);
> }
>
> static int mmp_irq_domain_map(struct irq_domain *d, unsigned int irq,
>
Otherwise looks OK.
M.
--
Jazz is not dead, it just smells funny...
_______________________________________________
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/6] dt-bindings: gpio: davinci: Add new compatible for J721E SoCs
From: Keerthy @ 2019-08-09 10:55 UTC (permalink / raw)
To: Lokesh Vutla, Tero Kristo, Nishanth Menon, linus.walleij
Cc: linux-gpio, Rob Herring, Linux ARM Mailing List,
Device Tree Mailing List
In-Reply-To: <20190809082947.30590-2-lokeshvutla@ti.com>
On 09/08/19 1:59 PM, Lokesh Vutla wrote:
> J721e SoCs have same gpio IP as K2G davinci gpio. Add a new compatible to
> handle J721E SoCs.
Reviewed-by: Keerthy <j-keerthy@ti.com>
>
> Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
> ---
> Documentation/devicetree/bindings/gpio/gpio-davinci.txt | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/Documentation/devicetree/bindings/gpio/gpio-davinci.txt b/Documentation/devicetree/bindings/gpio/gpio-davinci.txt
> index bc6b4b62df83..cd91d61eac31 100644
> --- a/Documentation/devicetree/bindings/gpio/gpio-davinci.txt
> +++ b/Documentation/devicetree/bindings/gpio/gpio-davinci.txt
> @@ -6,6 +6,7 @@ Required Properties:
> 66AK2E SoCs
> "ti,k2g-gpio", "ti,keystone-gpio": for 66AK2G
> "ti,am654-gpio", "ti,keystone-gpio": for TI K3 AM654
> + "ti,j721e-gpio", "ti,keystone-gpio": for J721E SoCs
>
> - reg: Physical base address of the controller and the size of memory mapped
> registers.
>
_______________________________________________
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 v3 02/11] kselftest: arm64: adds first test and common utils
From: Cristian Marussi @ 2019-08-09 10:54 UTC (permalink / raw)
To: linux-kselftest, linux-arm-kernel; +Cc: Dave P Martin
In-Reply-To: <20190802170300.20662-3-cristian.marussi@arm.com>
Hi
On 8/2/19 6:02 PM, Cristian Marussi wrote:
> Added some arm64/signal specific boilerplate and utility code to help
> further testcase development.
>
> A simple testcase and related helpers are also introduced in this commit:
> mangle_pstate_invalid_compat_toggle is a simple mangle testcase which
> messes with the ucontext_t from within the sig_handler, trying to toggle
> PSTATE state bits to switch the system between 32bit/64bit execution state.
> Expects SIGSEGV on test PASS.
>
> Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
> ---
> A few fixes:
> - test_arm64_signals.sh runner script generation has been reviewed in order to
> be safe against the .gitignore
> - using kselftest.h officially provided defines for tests' return values
> - removed SAFE_WRITE()/dump_uc()
> - looking for si_code==SEGV_ACCERR on SEGV test cases to better understand if
> the sigfault had been directly triggered by Kernel
> ---
> tools/testing/selftests/arm64/Makefile | 2 +-
> .../testing/selftests/arm64/signal/.gitignore | 6 +
> tools/testing/selftests/arm64/signal/Makefile | 88 ++++++
> tools/testing/selftests/arm64/signal/README | 59 ++++
> .../arm64/signal/test_arm64_signals.src_shell | 55 ++++
> .../selftests/arm64/signal/test_signals.c | 26 ++
> .../selftests/arm64/signal/test_signals.h | 137 +++++++++
> .../arm64/signal/test_signals_utils.c | 261 ++++++++++++++++++
> .../arm64/signal/test_signals_utils.h | 13 +
> .../arm64/signal/testcases/.gitignore | 1 +
> .../mangle_pstate_invalid_compat_toggle.c | 25 ++
> .../arm64/signal/testcases/testcases.c | 150 ++++++++++
> .../arm64/signal/testcases/testcases.h | 83 ++++++
> 13 files changed, 905 insertions(+), 1 deletion(-)
> create mode 100644 tools/testing/selftests/arm64/signal/.gitignore
> create mode 100644 tools/testing/selftests/arm64/signal/Makefile
> create mode 100644 tools/testing/selftests/arm64/signal/README
> create mode 100755 tools/testing/selftests/arm64/signal/test_arm64_signals.src_shell
> create mode 100644 tools/testing/selftests/arm64/signal/test_signals.c
> create mode 100644 tools/testing/selftests/arm64/signal/test_signals.h
> create mode 100644 tools/testing/selftests/arm64/signal/test_signals_utils.c
> create mode 100644 tools/testing/selftests/arm64/signal/test_signals_utils.h
> create mode 100644 tools/testing/selftests/arm64/signal/testcases/.gitignore
> create mode 100644 tools/testing/selftests/arm64/signal/testcases/mangle_pstate_invalid_compat_toggle.c
> create mode 100644 tools/testing/selftests/arm64/signal/testcases/testcases.c
> create mode 100644 tools/testing/selftests/arm64/signal/testcases/testcases.h
>
A few more compilation warnings triggered by GCC-8 ONLY when compiling via the top kselftest Makefile/target
(due to some additional -W passed down and an awkward use of snprintf on my side...)
test_signals_utils.c: In function ‘feats_to_string’:
test_signals_utils.c:38:13: warning: passing argument 1 to restrict-qualified parameter aliases with argument 4 [-Wrestrict]
snprintf(feats_string, MAX_FEATS_SZ - 1, "%s %s ",
^~~~~~~~~~~~
test_signals_utils.c: In function ‘default_handler’:
test_signals_utils.c:192:19: warning: format ‘%p’ expects argument of type ‘void *’, but argument 3 has type ‘long long unsigned int’ [-Wformat=]
"SIG_OK -- SP:%p si_addr@:0x%p si_code:%d token@:0x%p offset:%ld\n",
~^
will be fixed in V4 as:
diff --git a/tools/testing/selftests/arm64/signal/test_signals_utils.c b/tools/testing/selftests/arm64/signal/test_signals_utils.c
index 31788a1d33a4..c0f3cd1b560a 100644
--- a/tools/testing/selftests/arm64/signal/test_signals_utils.c
+++ b/tools/testing/selftests/arm64/signal/test_signals_utils.c
@@ -23,21 +23,25 @@ extern struct tdescr *current;
static int sig_copyctx = SIGTRAP;
static char *feats_store[FMAX_END] = {
- "SSBS",
- "PAN",
- "UAO",
+ " SSBS ",
+ " PAN ",
+ " UAO ",
};
#define MAX_FEATS_SZ 128
+static char feats_string[MAX_FEATS_SZ];
+
static inline char *feats_to_string(unsigned long feats)
{
- static char feats_string[MAX_FEATS_SZ];
+ for (int i = 0; i < FMAX_END; i++) {
+ size_t tlen = 0;
- for (int i = 0; i < FMAX_END && feats_store[i][0]; i++) {
- if (feats & 1UL << i)
- snprintf(feats_string, MAX_FEATS_SZ - 1, "%s %s ",
- feats_string, feats_store[i]);
+ if (feats & 1UL << i) {
+ strncat(feats_string, feats_store[i],
+ MAX_FEATS_SZ - 1 - tlen);
+ tlen += strlen(feats_store[i]);
+ }
}
return feats_string;
@@ -190,7 +194,7 @@ static void default_handler(int signum, siginfo_t *si, void *uc)
/* it's a bug in the test code when this assert fail */
assert(!current->sig_trig || current->triggered);
fprintf(stderr,
- "SIG_OK -- SP:%p si_addr@:0x%p si_code:%d token@:0x%p offset:%ld\n",
+ "SIG_OK -- SP:%llX si_addr@:0x%p si_code:%d token@:0x%p offset:%ld\n",
((ucontext_t *)uc)->uc_mcontext.sp,
si->si_addr, si->si_code, current->token,
current->token - si->si_addr);
Cheers
Cristian
> diff --git a/tools/testing/selftests/arm64/Makefile b/tools/testing/selftests/arm64/Makefile
> index 03a0d4f71218..af59dc74e0dc 100644
> --- a/tools/testing/selftests/arm64/Makefile
> +++ b/tools/testing/selftests/arm64/Makefile
> @@ -6,7 +6,7 @@ ARCH ?= $(shell uname -m)
> ARCH := $(shell echo $(ARCH) | sed -e s/aarch64/arm64/)
>
> ifeq ("x$(ARCH)", "xarm64")
> -SUBDIRS :=
> +SUBDIRS := signal
> else
> SUBDIRS :=
> endif
> diff --git a/tools/testing/selftests/arm64/signal/.gitignore b/tools/testing/selftests/arm64/signal/.gitignore
> new file mode 100644
> index 000000000000..434f65c15f03
> --- /dev/null
> +++ b/tools/testing/selftests/arm64/signal/.gitignore
> @@ -0,0 +1,6 @@
> +# Helper script's internal testcases list (TPROGS) is regenerated
> +# each time by Makefile on standalone (non KSFT driven) runs.
> +# Committing such list creates a dependency between testcases
> +# patches such that they are no more easily revertable. Just ignore.
> +test_arm64_signals.src_shell
> +test_arm64_signals.sh
> diff --git a/tools/testing/selftests/arm64/signal/Makefile b/tools/testing/selftests/arm64/signal/Makefile
> new file mode 100644
> index 000000000000..8c8d08be4b0d
> --- /dev/null
> +++ b/tools/testing/selftests/arm64/signal/Makefile
> @@ -0,0 +1,88 @@
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (C) 2019 ARM Limited
> +
> +# Supports also standalone invokation out of KSFT-tree
> +# Compile standalone and run on your device with:
> +#
> +# $ make -C tools/testing/selftests/arm64/signal INSTALL_PATH=<your-dir> install
> +#
> +# Run standalone on device with:
> +#
> +# $ <your-device-instdir>/test_arm64_signals.sh [-k|-v]
> +#
> +# If INSTALL_PATH= is NOT provided it will default to ./install
> +
> +# A proper top_srcdir is needed both by KSFT(lib.mk)
> +# and standalone builds
> +top_srcdir = ../../../../..
> +
> +CFLAGS += -std=gnu99 -I. -I$(top_srcdir)/tools/testing/selftests/
> +SRCS := $(filter-out testcases/testcases.c,$(wildcard testcases/*.c))
> +PROGS := $(patsubst %.c,%,$(SRCS))
> +
> +# Guessing as best as we can where the Kernel headers
> +# could have been installed depending on ENV config and
> +# type of invocation.
> +ifeq ($(KBUILD_OUTPUT),)
> +khdr_dir = $(top_srcdir)/usr/include
> +else
> +ifeq (0,$(MAKELEVEL))
> +khdr_dir = $(KBUILD_OUTPUT)/usr/include
> +else
> +# the KSFT preferred location when KBUILD_OUTPUT is set
> +khdr_dir = $(KBUILD_OUTPUT)/kselftest/usr/include
> +endif
> +endif
> +
> +CFLAGS += -I$(khdr_dir)
> +
> +# Standalone run
> +ifeq (0,$(MAKELEVEL))
> +CC := $(CROSS_COMPILE)gcc
> +RUNNER_SRC = test_arm64_signals.src_shell
> +RUNNER = test_arm64_signals.sh
> +INSTALL_PATH ?= install/
> +
> +all: $(RUNNER)
> +
> +$(RUNNER): $(PROGS)
> + cp $(RUNNER_SRC) $(RUNNER)
> + sed -i -e 's#PROGS=.*#PROGS="$(PROGS)"#' $@
> +
> +install: all
> + mkdir -p $(INSTALL_PATH)/testcases
> + cp $(PROGS) $(INSTALL_PATH)/testcases
> + cp $(RUNNER) $(INSTALL_PATH)/
> +
> +.PHONY clean:
> + rm -f $(PROGS)
> +# KSFT run
> +else
> +# Generated binaries to be installed by top KSFT script
> +TEST_GEN_PROGS := $(notdir $(PROGS))
> +
> +# Get Kernel headers installed and use them.
> +KSFT_KHDR_INSTALL := 1
> +
> +# This include mk will also mangle the TEST_GEN_PROGS list
> +# to account for any OUTPUT target-dirs optionally provided
> +# by the toplevel makefile
> +include ../../lib.mk
> +
> +$(TEST_GEN_PROGS): $(PROGS)
> + cp $(PROGS) $(OUTPUT)/
> +
> +clean:
> + $(CLEAN)
> + rm -f $(PROGS)
> +endif
> +
> +# Common test-unit targets to build common-layout test-cases executables
> +# Needs secondary expansion to properly include the testcase c-file in pre-reqs
> +.SECONDEXPANSION:
> +$(PROGS): test_signals.c test_signals_utils.c testcases/testcases.c $$@.c test_signals.h test_signals_utils.h testcases/testcases.h
> + @if [ ! -d $(khdr_dir) ]; then \
> + echo -n "\n!!! WARNING: $(khdr_dir) NOT FOUND."; \
> + echo "===> Are you sure Kernel Headers have been installed properly ?\n"; \
> + fi
> + $(CC) $(CFLAGS) $^ -o $@
> diff --git a/tools/testing/selftests/arm64/signal/README b/tools/testing/selftests/arm64/signal/README
> new file mode 100644
> index 000000000000..53f005f7910a
> --- /dev/null
> +++ b/tools/testing/selftests/arm64/signal/README
> @@ -0,0 +1,59 @@
> +KSelfTest arm64/signal/
> +=======================
> +
> +Signals Tests
> ++++++++++++++
> +
> +- Tests are built around a common main compilation unit: such shared main
> + enforces a standard sequence of operations needed to perform a single
> + signal-test (setup/trigger/run/result/cleanup)
> +
> +- The above mentioned ops are configurable on a test-by-test basis: each test
> + is described (and configured) using the descriptor signals.h::struct tdescr
> +
> +- Each signal testcase is compiled into its own executable: a separate
> + executable is used for each test since many tests complete successfully
> + by receiving some kind of fatal signal from the Kernel, so it's safer
> + to run each test unit in its own standalone process, so as to start each
> + test from a clean slate.
> +
> +- New tests can be simply defined in testcases/ dir providing a proper struct
> + tdescr overriding all the defaults we wish to change (as of now providing a
> + custom run method is mandatory though)
> +
> +- Signals' test-cases hereafter defined belong currently to two
> + principal families:
> +
> + - 'mangle_' tests: a real signal (SIGUSR1) is raised and used as a trigger
> + and then the test case code messes-up with the sigframe ucontext_t from
> + inside the sighandler itself.
> +
> + - 'fake_sigreturn_' tests: a brand new custom artificial sigframe structure
> + is placed on the stack and a sigreturn syscall is called to simulate a
> + real signal return. This kind of tests does not use a trigger usually and
> + they are just fired using some simple included assembly trampoline code.
> +
> + - Most of these tests are successfully passing if the process gets killed by
> + some fatal signal: usually SIGSEGV or SIGBUS. Since while writing this
> + kind of tests it is extremely easy in fact to end-up injecting other
> + unrelated SEGV bugs in the testcases, it becomes extremely tricky to
> + be really sure that the tests are really addressing what they are meant
> + to address and they are not instead falling apart due to unplanned bugs
> + in the test code.
> + In order to alleviate the misery of the life of such test-developer, a few
> + helpers are provided:
> +
> + - a couple of ASSERT_BAD/GOOD_CONTEXT() macros to easily parse a ucontext_t
> + and verify if it is indeed GOOD or BAD (depending on what we were
> + expecting), using the same logic/perspective as in the arm64 Kernel signals
> + routines.
> +
> + - a sanity mechanism to be used in 'fake_sigreturn_'-alike tests: enabled by
> + default it takes care to verify that the test-execution had at least
> + successfully progressed up to the stage of triggering the fake sigreturn
> + call.
> +
> + In both cases test results are expected in terms of:
> + - some fatal signal sent by the Kernel to the test process
> + or
> + - analyzing some final regs state
> diff --git a/tools/testing/selftests/arm64/signal/test_arm64_signals.src_shell b/tools/testing/selftests/arm64/signal/test_arm64_signals.src_shell
> new file mode 100755
> index 000000000000..163e941e2997
> --- /dev/null
> +++ b/tools/testing/selftests/arm64/signal/test_arm64_signals.src_shell
> @@ -0,0 +1,55 @@
> +#!/bin/sh
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (C) 2019 ARM Limited
> +
> +ret=0
> +keep_on_fail=0
> +err_out="2> /dev/null"
> +
> +usage() {
> + echo "Usage: `basename $0` [-v] [-k]"
> + exit 1
> +}
> +
> +# avoiding getopt to avoid compatibility issues on targets
> +# with limited resources
> +while [ $# -gt 0 ]
> +do
> + case $1 in
> + "-k")
> + keep_on_fail=1
> + ;;
> + "-v")
> + err_out=
> + ;;
> + *)
> + usage
> + ;;
> + esac
> + shift
> +done
> +
> +TPROGS=
> +
> +tot=$(echo $TPROGS | wc -w)
> +
> +# Tests are expected in testcases/ subdir inside the installation path
> +workdir="`dirname $0 2>/dev/null`"
> +[ -n $workdir ] && cd $workdir
> +
> +passed=0
> +run=0
> +for test in $TPROGS
> +do
> + run=$((run + 1))
> + eval ./$test $err_out
> + if [ $? != 0 ]; then
> + [ $keep_on_fail = 0 ] && echo "===>>> FAILED:: $test <<<===" && ret=1 && break
> + else
> + passed=$((passed + 1))
> + fi
> +done
> +
> +echo "==>> PASSED: $passed/$run on $tot available tests."
> +
> +exit $ret
> diff --git a/tools/testing/selftests/arm64/signal/test_signals.c b/tools/testing/selftests/arm64/signal/test_signals.c
> new file mode 100644
> index 000000000000..3447d7011aec
> --- /dev/null
> +++ b/tools/testing/selftests/arm64/signal/test_signals.c
> @@ -0,0 +1,26 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/* Copyright (C) 2019 ARM Limited */
> +
> +#include <kselftest.h>
> +
> +#include "test_signals.h"
> +#include "test_signals_utils.h"
> +
> +struct tdescr *current;
> +extern struct tdescr tde;
> +
> +int main(int argc, char *argv[])
> +{
> + current = &tde;
> +
> + ksft_print_msg("%s :: %s - SIG_TRIG:%d SIG_OK:%d -- current:%p\n",
> + current->name, current->descr, current->sig_trig,
> + current->sig_ok, current);
> + if (test_setup(current)) {
> + if (test_run(current))
> + test_result(current);
> + test_cleanup(current);
> + }
> +
> + return current->pass ? KSFT_PASS : KSFT_FAIL;
> +}
> diff --git a/tools/testing/selftests/arm64/signal/test_signals.h b/tools/testing/selftests/arm64/signal/test_signals.h
> new file mode 100644
> index 000000000000..85db3ac44b32
> --- /dev/null
> +++ b/tools/testing/selftests/arm64/signal/test_signals.h
> @@ -0,0 +1,137 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/* Copyright (C) 2019 ARM Limited */
> +
> +#ifndef __TEST_SIGNALS_H__
> +#define __TEST_SIGNALS_H__
> +
> +#include <assert.h>
> +#include <stdbool.h>
> +#include <signal.h>
> +#include <ucontext.h>
> +#include <stdint.h>
> +
> +/*
> + * Using ARCH specific and sanitized Kernel headers installed by KSFT
> + * framework since we asked for it by setting flag KSFT_KHDR_INSTALL
> + * in our Makefile.
> + */
> +#include <asm/ptrace.h>
> +#include <asm/hwcap.h>
> +
> +/* pasted from include/linux/stringify.h */
> +#define __stringify_1(x...) #x
> +#define __stringify(x...) __stringify_1(x)
> +
> +/*
> + * Reads a sysreg using the, possibly provided, S3_ encoding in order to
> + * avoid inject any dependency on the used toolchain regarding possibly
> + * still unsupported ARMv8 extensions.
> + *
> + * Using a standard mnemonic here to indicate the specific sysreg (like SSBS)
> + * would introduce a compile-time dependency on possibly unsupported ARMv8
> + * Extensions: you could end-up failing to build the test depending on the
> + * available toolchain.
> + * This is undesirable since some tests, even if specifically targeted at some
> + * ARMv8 Extensions, can be plausibly run even on hardware lacking the above
> + * optional ARM features. (SSBS bit preservation is an example: Kernel handles
> + * it transparently not caring at all about the effective set of supported
> + * features).
> + * On the other side we will expect to observe different behaviours if the
> + * feature is supported or not: usually getting a SIGILL when trying to use
> + * unsupported features. For this reason we have anyway in place some
> + * preliminary run-time checks about the cpu effectively supported features.
> + *
> + * This helper macro is meant to be used for regs readable at EL0, BUT some
> + * EL1 sysregs are indeed readable too through MRS emulation Kernel-mechanism
> + * if the required reg is included in the supported encoding space:
> + *
> + * Documentation/arm64/cpu-feature-regsiters.txt
> + *
> + * "The infrastructure emulates only the following system register space:
> + * Op0=3, Op1=0, CRn=0, CRm=0,4,5,6,7
> + */
> +#define get_regval(regname, out) \
> + asm volatile("mrs %0, " __stringify(regname) : "=r" (out) :: "memory")
> +
> +/* Regs encoding and masks naming copied in from sysreg.h */
> +#define SYS_ID_AA64MMFR1_EL1 S3_0_C0_C7_1 /* MRS Emulated */
> +#define SYS_ID_AA64MMFR2_EL1 S3_0_C0_C7_2 /* MRS Emulated */
> +#define ID_AA64MMFR1_PAN_SHIFT 20
> +#define ID_AA64MMFR2_UAO_SHIFT 4
> +
> +/* Local Helpers */
> +#define IS_PAN_SUPPORTED(val) \
> + (!!((val) & (0xfUL << ID_AA64MMFR1_PAN_SHIFT)))
> +#define IS_UAO_SUPPORTED(val) \
> + (!!((val) & (0xfUL << ID_AA64MMFR2_UAO_SHIFT)))
> +
> +#define S3_MRS_SSBS_SYSREG S3_3_C4_C2_6 /* EL0 supported */
> +
> +/*
> + * Feature flags used in tdescr.feats_required to specify
> + * any feature by the test
> + */
> +enum {
> + FSSBS_BIT,
> + FPAN_BIT,
> + FUAO_BIT,
> + FMAX_END
> +};
> +
> +#define FEAT_SSBS (1UL << FSSBS_BIT)
> +#define FEAT_PAN (1UL << FPAN_BIT)
> +#define FEAT_UAO (1UL << FUAO_BIT)
> +
> +/*
> + * A descriptor used to describe and configure a test case.
> + * Fields with a non-trivial meaning are described inline in the following.
> + */
> +struct tdescr {
> + /* KEEP THIS FIELD FIRST for easier lookup from assembly */
> + void *token;
> + /* when disabled token based sanity checking is skipped in handler */
> + bool sanity_disabled;
> + /* just a name for the test-case; manadatory field */
> + char *name;
> + char *descr;
> + unsigned long feats_required;
> + /* bitmask of effectively supported feats: populated at run-time */
> + unsigned long feats_supported;
> + bool feats_ok;
> + bool initialized;
> + unsigned int minsigstksz;
> + /* signum used as a test trigger. Zero if no trigger-signal is used */
> + int sig_trig;
> + /*
> + * signum considered as a successful test completion.
> + * Zero when no signal is expected on success
> + */
> + int sig_ok;
> + /* signum expected on unsupported CPU features. */
> + int sig_unsupp;
> + /* a timeout in second for test completion */
> + unsigned int timeout;
> + bool triggered;
> + bool pass;
> + /* optional sa_flags for the installed handler */
> + int sa_flags;
> + ucontext_t saved_uc;
> +
> + /* a setup function to be called before test starts */
> + int (*setup)(struct tdescr *td);
> + void (*cleanup)(struct tdescr *td);
> +
> + /* an optional function to be used as a trigger for test starting */
> + int (*trigger)(struct tdescr *td);
> + /*
> + * the actual test-core: invoked differently depending on the
> + * presence of the trigger function above; this is mandatory
> + */
> + int (*run)(struct tdescr *td, siginfo_t *si, ucontext_t *uc);
> +
> + /* an optional function for custom results' processing */
> + void (*check_result)(struct tdescr *td);
> +
> + void *priv;
> +};
> +#endif
> diff --git a/tools/testing/selftests/arm64/signal/test_signals_utils.c b/tools/testing/selftests/arm64/signal/test_signals_utils.c
> new file mode 100644
> index 000000000000..ac0055f6340b
> --- /dev/null
> +++ b/tools/testing/selftests/arm64/signal/test_signals_utils.c
> @@ -0,0 +1,261 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/* Copyright (C) 2019 ARM Limited */
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <signal.h>
> +#include <string.h>
> +#include <unistd.h>
> +#include <assert.h>
> +#include <sys/auxv.h>
> +#include <linux/auxvec.h>
> +#include <ucontext.h>
> +
> +#include "test_signals.h"
> +#include "test_signals_utils.h"
> +#include "testcases/testcases.h"
> +
> +extern struct tdescr *current;
> +
> +static char *feats_store[FMAX_END] = {
> + "SSBS",
> + "PAN",
> + "UAO"
> +};
> +
> +#define MAX_FEATS_SZ 128
> +static inline char *feats_to_string(unsigned long feats)
> +{
> + static char feats_string[MAX_FEATS_SZ];
> +
> + for (int i = 0; i < FMAX_END && feats_store[i][0]; i++) {
> + if (feats & 1UL << i)
> + snprintf(feats_string, MAX_FEATS_SZ - 1, "%s %s ",
> + feats_string, feats_store[i]);
> + }
> +
> + return feats_string;
> +}
> +
> +static void unblock_signal(int signum)
> +{
> + sigset_t sset;
> +
> + sigemptyset(&sset);
> + sigaddset(&sset, signum);
> + sigprocmask(SIG_UNBLOCK, &sset, NULL);
> +}
> +
> +static void default_result(struct tdescr *td, bool force_exit)
> +{
> + if (td->pass)
> + fprintf(stderr, "==>> completed. PASS(1)\n");
> + else
> + fprintf(stdout, "==>> completed. FAIL(0)\n");
> + if (force_exit)
> + exit(td->pass ? EXIT_SUCCESS : EXIT_FAILURE);
> +}
> +
> +static inline bool are_feats_ok(struct tdescr *td)
> +{
> + return td ? td->feats_required == td->feats_supported : 0;
> +}
> +
> +static void default_handler(int signum, siginfo_t *si, void *uc)
> +{
> + if (current->sig_trig && signum == current->sig_trig) {
> + fprintf(stderr, "Handling SIG_TRIG\n");
> + current->triggered = 1;
> + /* ->run was asserted NON-NULL in test_setup() already */
> + current->run(current, si, uc);
> + } else if (signum == SIGILL && !current->initialized) {
> + /*
> + * A SIGILL here while still not initialized means we failed
> + * even to asses the existence of features during init
> + */
> + fprintf(stdout,
> + "Got SIGILL test_init. Marking ALL features UNSUPPORTED.\n");
> + current->feats_supported = 0;
> + } else if (current->sig_ok && signum == current->sig_ok) {
> + /* it's a bug in the test code when this assert fail */
> + assert(!current->sig_trig || current->triggered);
> + fprintf(stderr,
> + "SIG_OK -- SP:%p si_addr@:0x%p si_code:%d token@:0x%p offset:%ld\n",
> + ((ucontext_t *)uc)->uc_mcontext.sp,
> + si->si_addr, si->si_code, current->token,
> + current->token - si->si_addr);
> + /*
> + * fake_sigreturn tests, which have sanity_enabled=1, set, at
> + * the very last time, the token field to the SP address used
> + * to place the fake sigframe: so token==0 means we never made
> + * it to the end, segfaulting well-before, and the test is
> + * possibly broken.
> + */
> + if (!current->sanity_disabled && !current->token) {
> + fprintf(stdout,
> + "current->token ZEROED...test is probably broken!\n");
> + assert(0);
> + }
> + /*
> + * Trying to narrow down the SEGV to the ones generated by
> + * Kernel itself via arm64_notify_segfault()
> + */
> + if (current->sig_ok == SIGSEGV && si->si_code != SEGV_ACCERR) {
> + fprintf(stdout,
> + "si_code != SEGV_ACCERR...test is probably broken!\n");
> + assert(0);
> + }
> + fprintf(stderr, "Handling SIG_OK\n");
> + current->pass = 1;
> + /*
> + * Some tests can lead to SEGV loops: in such a case we want
> + * to terminate immediately exiting straight away
> + */
> + default_result(current, 1);
> + } else {
> + if (signum == current->sig_unsupp && !are_feats_ok(current)) {
> + fprintf(stderr, "-- RX SIG_UNSUPP on unsupported feature...OK\n");
> + current->pass = 1;
> + } else if (signum == SIGALRM && current->timeout) {
> + fprintf(stderr, "-- Timeout !\n");
> + } else {
> + fprintf(stderr,
> + "-- RX UNEXPECTED SIGNAL: %d\n", signum);
> + }
> + default_result(current, 1);
> + }
> +}
> +
> +static int default_setup(struct tdescr *td)
> +{
> + struct sigaction sa;
> +
> + sa.sa_sigaction = default_handler;
> + sa.sa_flags = SA_SIGINFO;
> + if (td->sa_flags)
> + sa.sa_flags |= td->sa_flags;
> + sigemptyset(&sa.sa_mask);
> + /* uncatchable signals naturally skipped ... */
> + for (int sig = 1; sig < 32; sig++)
> + sigaction(sig, &sa, NULL);
> + /*
> + * RT Signals default disposition is Term but they cannot be
> + * generated by the Kernel in response to our tests; so just catch
> + * them all and report them as UNEXPECTED signals.
> + */
> + for (int sig = SIGRTMIN; sig <= SIGRTMAX; sig++)
> + sigaction(sig, &sa, NULL);
> +
> + /* just in case...unblock explicitly all we need */
> + if (td->sig_trig)
> + unblock_signal(td->sig_trig);
> + if (td->sig_ok)
> + unblock_signal(td->sig_ok);
> + if (td->sig_unsupp)
> + unblock_signal(td->sig_unsupp);
> +
> + if (td->timeout) {
> + unblock_signal(SIGALRM);
> + alarm(td->timeout);
> + }
> + fprintf(stderr, "Registered handlers for all signals.\n");
> +
> + return 1;
> +}
> +
> +static inline int default_trigger(struct tdescr *td)
> +{
> + return !raise(td->sig_trig);
> +}
> +
> +static int test_init(struct tdescr *td)
> +{
> + td->minsigstksz = getauxval(AT_MINSIGSTKSZ);
> + if (!td->minsigstksz)
> + td->minsigstksz = MINSIGSTKSZ;
> + fprintf(stderr, "Detected MINSTKSIGSZ:%d\n", td->minsigstksz);
> +
> + if (td->feats_required) {
> + bool feats_ok = false;
> + td->feats_supported = 0;
> + /*
> + * Checking for CPU required features using both the
> + * auxval and the arm64 MRS Emulation to read sysregs.
> + */
> + if (getauxval(AT_HWCAP) & HWCAP_CPUID) {
> + uint64_t val = 0;
> +
> + if (td->feats_required & FEAT_SSBS) {
> + /* Uses HWCAP to check capability */
> + if (getauxval(AT_HWCAP) & HWCAP_SSBS)
> + td->feats_supported |= FEAT_SSBS;
> + }
> + if (td->feats_required & FEAT_PAN) {
> + /* Uses MRS emulation to check capability */
> + get_regval(SYS_ID_AA64MMFR1_EL1, val);
> + if (IS_PAN_SUPPORTED(val))
> + td->feats_supported |= FEAT_PAN;
> + }
> + if (td->feats_required & FEAT_UAO) {
> + /* Uses MRS emulation to check capability */
> + get_regval(SYS_ID_AA64MMFR2_EL1 , val);
> + if (IS_UAO_SUPPORTED(val))
> + td->feats_supported |= FEAT_UAO;
> + }
> + } else {
> + fprintf(stderr,
> + "HWCAP_CPUID NOT available. Mark ALL feats UNSUPPORTED.\n");
> + }
> + feats_ok = are_feats_ok(td);
> + fprintf(stderr,
> + "Required Features: [%s] %ssupported\n",
> + feats_ok ? feats_to_string(td->feats_supported) :
> + feats_to_string(td->feats_required ^ td->feats_supported),
> + !feats_ok ? "NOT " : "");
> + }
> +
> + td->initialized = 1;
> + return 1;
> +}
> +
> +int test_setup(struct tdescr *td)
> +{
> + /* assert core invariants symptom of a rotten testcase */
> + assert(current);
> + assert(td);
> + assert(td->name);
> + assert(td->run);
> +
> + if (!test_init(td))
> + return 0;
> +
> + if (td->setup)
> + return td->setup(td);
> + else
> + return default_setup(td);
> +}
> +
> +int test_run(struct tdescr *td)
> +{
> + if (td->sig_trig) {
> + if (td->trigger)
> + return td->trigger(td);
> + else
> + return default_trigger(td);
> + } else {
> + return td->run(td, NULL, NULL);
> + }
> +}
> +
> +void test_result(struct tdescr *td)
> +{
> + if (td->check_result)
> + td->check_result(td);
> + default_result(td, 0);
> +}
> +
> +void test_cleanup(struct tdescr *td)
> +{
> + if (td->cleanup)
> + td->cleanup(td);
> +}
> diff --git a/tools/testing/selftests/arm64/signal/test_signals_utils.h b/tools/testing/selftests/arm64/signal/test_signals_utils.h
> new file mode 100644
> index 000000000000..8658d1a7d4b9
> --- /dev/null
> +++ b/tools/testing/selftests/arm64/signal/test_signals_utils.h
> @@ -0,0 +1,13 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/* Copyright (C) 2019 ARM Limited */
> +
> +#ifndef __TEST_SIGNALS_UTILS_H__
> +#define __TEST_SIGNALS_UTILS_H__
> +
> +#include "test_signals.h"
> +
> +int test_setup(struct tdescr *td);
> +void test_cleanup(struct tdescr *td);
> +int test_run(struct tdescr *td);
> +void test_result(struct tdescr *td);
> +#endif
> diff --git a/tools/testing/selftests/arm64/signal/testcases/.gitignore b/tools/testing/selftests/arm64/signal/testcases/.gitignore
> new file mode 100644
> index 000000000000..8651272e3cfc
> --- /dev/null
> +++ b/tools/testing/selftests/arm64/signal/testcases/.gitignore
> @@ -0,0 +1 @@
> +mangle_pstate_invalid_compat_toggle
> diff --git a/tools/testing/selftests/arm64/signal/testcases/mangle_pstate_invalid_compat_toggle.c b/tools/testing/selftests/arm64/signal/testcases/mangle_pstate_invalid_compat_toggle.c
> new file mode 100644
> index 000000000000..971193e7501b
> --- /dev/null
> +++ b/tools/testing/selftests/arm64/signal/testcases/mangle_pstate_invalid_compat_toggle.c
> @@ -0,0 +1,25 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/* Copyright (C) 2019 ARM Limited */
> +
> +#include "test_signals_utils.h"
> +#include "testcases.h"
> +
> +static int mangle_invalid_pstate_run(struct tdescr *td, siginfo_t *si,
> + ucontext_t *uc)
> +{
> + ASSERT_GOOD_CONTEXT(uc);
> +
> + /* This config should trigger a SIGSEGV by Kernel */
> + uc->uc_mcontext.pstate ^= PSR_MODE32_BIT;
> +
> + return 1;
> +}
> +
> +struct tdescr tde = {
> + .sanity_disabled = true,
> + .name = "MANGLE_PSTATE_INVALID_STATE_TOGGLE",
> + .descr = "Mangling uc_mcontext with INVALID STATE_TOGGLE",
> + .sig_trig = SIGUSR1,
> + .sig_ok = SIGSEGV,
> + .run = mangle_invalid_pstate_run,
> +};
> diff --git a/tools/testing/selftests/arm64/signal/testcases/testcases.c b/tools/testing/selftests/arm64/signal/testcases/testcases.c
> new file mode 100644
> index 000000000000..a59785092e1f
> --- /dev/null
> +++ b/tools/testing/selftests/arm64/signal/testcases/testcases.c
> @@ -0,0 +1,150 @@
> +#include "testcases.h"
> +
> +struct _aarch64_ctx *get_header(struct _aarch64_ctx *head, uint32_t magic,
> + size_t resv_sz, size_t *offset)
> +{
> + size_t offs = 0;
> + struct _aarch64_ctx *found = NULL;
> +
> + if (!head || resv_sz < HDR_SZ)
> + return found;
> +
> + do {
> + if (head->magic == magic) {
> + found = head;
> + break;
> + }
> + offs += head->size;
> + head = GET_RESV_NEXT_HEAD(head);
> + } while (offs < resv_sz - HDR_SZ);
> +
> + if (offset)
> + *offset = offs;
> +
> + return found;
> +}
> +
> +bool validate_extra_context(struct extra_context *extra, char **err)
> +{
> + struct _aarch64_ctx *term;
> +
> + if (!extra || !err)
> + return false;
> +
> + fprintf(stderr, "Validating EXTRA...\n");
> + term = GET_RESV_NEXT_HEAD(extra);
> + if (!term || term->magic || term->size) {
> + *err = "UN-Terminated EXTRA context";
> + return false;
> + }
> + if (extra->datap & 0x0fUL)
> + *err = "Extra DATAP misaligned";
> + else if (extra->size & 0x0fUL)
> + *err = "Extra SIZE misaligned";
> + else if (extra->datap != (uint64_t)term + sizeof(*term))
> + *err = "Extra DATAP misplaced (not contiguos)";
> + if (*err)
> + return false;
> +
> + return true;
> +}
> +
> +bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err)
> +{
> + bool terminated = false;
> + size_t offs = 0;
> + int flags = 0;
> + struct extra_context *extra = NULL;
> + struct _aarch64_ctx *head =
> + (struct _aarch64_ctx *)uc->uc_mcontext.__reserved;
> +
> + if (!err)
> + return false;
> + /* Walk till the end terminator verifying __reserved contents */
> + while (head && !terminated && offs < resv_sz) {
> + if ((uint64_t)head & 0x0fUL) {
> + *err = "Misaligned HEAD";
> + return false;
> + }
> +
> + switch (head->magic) {
> + case 0:
> + if (head->size)
> + *err = "Bad size for MAGIC0";
> + else
> + terminated = true;
> + break;
> + case FPSIMD_MAGIC:
> + if (flags & FPSIMD_CTX)
> + *err = "Multiple FPSIMD_MAGIC";
> + else if (head->size !=
> + sizeof(struct fpsimd_context))
> + *err = "Bad size for fpsimd_context";
> + flags |= FPSIMD_CTX;
> + break;
> + case ESR_MAGIC:
> + if (head->size != sizeof(struct esr_context))
> + fprintf(stderr,
> + "Bad size for esr_context is not an error...just ignore.\n");
> + break;
> + case SVE_MAGIC:
> + if (flags & SVE_CTX)
> + *err = "Multiple SVE_MAGIC";
> + else if (head->size !=
> + sizeof(struct sve_context))
> + *err = "Bad size for sve_context";
> + flags |= SVE_CTX;
> + break;
> + case EXTRA_MAGIC:
> + if (flags & EXTRA_CTX)
> + *err = "Multiple EXTRA_MAGIC";
> + else if (head->size !=
> + sizeof(struct extra_context))
> + *err = "Bad size for extra_context";
> + flags |= EXTRA_CTX;
> + extra = (struct extra_context *)head;
> + break;
> + case KSFT_BAD_MAGIC:
> + /*
> + * This is a BAD magic header defined
> + * artificially by a testcase and surely
> + * unknown to the Kernel parse_user_sigframe().
> + * It MUST cause a Kernel induced SEGV
> + */
> + *err = "BAD MAGIC !";
> + break;
> + default:
> + /*
> + * A still unknown Magic: potentially freshly added
> + * to the Kernel code and still unknown to the
> + * tests.
> + */
> + fprintf(stdout,
> + "SKIP Unknown MAGIC: 0x%X - Is KSFT arm64/signal up to date ?\n",
> + head->magic);
> + break;
> + }
> +
> + if (*err)
> + return false;
> +
> + offs += head->size;
> + if (resv_sz - offs < sizeof(*head)) {
> + *err = "HEAD Overrun";
> + return false;
> + }
> +
> + if (flags & EXTRA_CTX)
> + if (!validate_extra_context(extra, err))
> + return false;
> +
> + head = GET_RESV_NEXT_HEAD(head);
> + }
> +
> + if (terminated && !(flags & FPSIMD_CTX)) {
> + *err = "Missing FPSIMD";
> + return false;
> + }
> +
> + return true;
> +}
> diff --git a/tools/testing/selftests/arm64/signal/testcases/testcases.h b/tools/testing/selftests/arm64/signal/testcases/testcases.h
> new file mode 100644
> index 000000000000..624717c71b1d
> --- /dev/null
> +++ b/tools/testing/selftests/arm64/signal/testcases/testcases.h
> @@ -0,0 +1,83 @@
> +#ifndef __TESTCASES_H__
> +#define __TESTCASES_H__
> +
> +#include <stdio.h>
> +#include <stdbool.h>
> +#include <stdint.h>
> +#include <unistd.h>
> +#include <ucontext.h>
> +#include <assert.h>
> +
> +/* Architecture specific sigframe definitions */
> +#include <asm/sigcontext.h>
> +
> +#define FPSIMD_CTX (1 << 0)
> +#define SVE_CTX (1 << 1)
> +#define EXTRA_CTX (1 << 2)
> +
> +#define KSFT_BAD_MAGIC 0xdeadbeef
> +
> +#define HDR_SZ \
> + sizeof(struct _aarch64_ctx)
> +
> +#define GET_SF_RESV_HEAD(sf) \
> + (struct _aarch64_ctx *)(&(sf).uc.uc_mcontext.__reserved)
> +
> +#define GET_SF_RESV_SIZE(sf) \
> + sizeof((sf).uc.uc_mcontext.__reserved)
> +
> +#define GET_UCP_RESV_SIZE(ucp) \
> + sizeof((ucp)->uc_mcontext.__reserved)
> +
> +#define ASSERT_BAD_CONTEXT(uc) do { \
> + char *err = NULL; \
> + assert(!validate_reserved((uc), GET_UCP_RESV_SIZE((uc)), &err));\
> + if (err) \
> + fprintf(stderr, \
> + "Using badly built context - ERR: %s\n", err); \
> +} while(0)
> +
> +#define ASSERT_GOOD_CONTEXT(uc) do { \
> + char *err = NULL; \
> + if (!validate_reserved((uc), GET_UCP_RESV_SIZE((uc)), &err)) { \
> + if (err) \
> + fprintf(stderr, \
> + "Detected BAD context - ERR: %s\n", err);\
> + assert(0); \
> + } else { \
> + fprintf(stderr, "uc context validated.\n"); \
> + } \
> +} while(0)
> +
> +/* head->size accounts both for payload and header _aarch64_ctx size ! */
> +#define GET_RESV_NEXT_HEAD(h) \
> + (struct _aarch64_ctx *)((char *)(h) + (h)->size)
> +
> +struct fake_sigframe {
> + siginfo_t info;
> + ucontext_t uc;
> +};
> +
> +
> +bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err);
> +
> +bool validate_extra_context(struct extra_context *extra, char **err);
> +
> +struct _aarch64_ctx *get_header(struct _aarch64_ctx *head, uint32_t magic,
> + size_t resv_sz, size_t *offset);
> +
> +static inline struct _aarch64_ctx *get_terminator(struct _aarch64_ctx *head,
> + size_t resv_sz,
> + size_t *offset)
> +{
> + return get_header(head, 0, resv_sz, offset);
> +}
> +
> +static inline void write_terminator_record(struct _aarch64_ctx *tail)
> +{
> + if (tail) {
> + tail->magic = 0;
> + tail->size = 0;
> + }
> +}
> +#endif
>
_______________________________________________
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: [RFC V2 0/1] mm/debug: Add tests for architecture exported page table helpers
From: Anshuman Khandual @ 2019-08-09 10:35 UTC (permalink / raw)
To: Matthew Wilcox
Cc: Mark Rutland, linux-ia64, linux-sh, Peter Zijlstra, James Hogan,
Tetsuo Handa, Heiko Carstens, Michal Hocko, linux-mm, Dave Hansen,
Paul Mackerras, sparclinux, Thomas Gleixner, linux-s390,
Michael Ellerman, x86, Russell King - ARM Linux, Steven Price,
Jason Gunthorpe, linux-arm-kernel, linux-snps-arc, Kees Cook,
Masahiro Yamada, Mark Brown, Dan Williams, Vlastimil Babka,
Sri Krishna chowdary, Ard Biesheuvel, Greg Kroah-Hartman,
linux-mips, Ralf Baechle, linux-kernel, Paul Burton,
Mike Rapoport, Vineet Gupta, Martin Schwidefsky, Andrew Morton,
linuxppc-dev, David S. Miller
In-Reply-To: <20190809101632.GM5482@bombadil.infradead.org>
On 08/09/2019 03:46 PM, Matthew Wilcox wrote:
> On Fri, Aug 09, 2019 at 01:03:17PM +0530, Anshuman Khandual wrote:
>> Should alloc_gigantic_page() be made available as an interface for general
>> use in the kernel. The test module here uses very similar implementation from
>> HugeTLB to allocate a PUD aligned memory block. Similar for mm_alloc() which
>> needs to be exported through a header.
>
> Why are you allocating memory at all instead of just using some
> known-to-exist PFNs like I suggested?
We needed PFN to be PUD aligned for pfn_pud() and PMD aligned for mk_pmd().
Now walking the kernel page table for a known symbol like kernel_init()
as you had suggested earlier we might encounter page table page entries at PMD
and PUD which might not be PMD or PUD aligned respectively. It seemed to me
that alignment requirement is applicable only for mk_pmd() and pfn_pud()
which create large mappings at those levels but that requirement does not
exist for page table pages pointing to next level. Is not that correct ? Or
I am missing something here ?
_______________________________________________
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 V2 0/1] mm/debug: Add tests for architecture exported page table helpers
From: Matthew Wilcox @ 2019-08-09 10:16 UTC (permalink / raw)
To: Anshuman Khandual
Cc: Mark Rutland, linux-ia64, linux-sh, Peter Zijlstra, James Hogan,
Tetsuo Handa, Heiko Carstens, Michal Hocko, linux-mm, Dave Hansen,
Paul Mackerras, sparclinux, Thomas Gleixner, linux-s390,
Michael Ellerman, x86, Russell King - ARM Linux, Steven Price,
Jason Gunthorpe, linux-arm-kernel, linux-snps-arc, Kees Cook,
Masahiro Yamada, Mark Brown, Dan Williams, Vlastimil Babka,
Sri Krishna chowdary, Ard Biesheuvel, Greg Kroah-Hartman,
linux-mips, Ralf Baechle, linux-kernel, Paul Burton,
Mike Rapoport, Vineet Gupta, Martin Schwidefsky, Andrew Morton,
linuxppc-dev, David S. Miller
In-Reply-To: <1565335998-22553-1-git-send-email-anshuman.khandual@arm.com>
On Fri, Aug 09, 2019 at 01:03:17PM +0530, Anshuman Khandual wrote:
> Should alloc_gigantic_page() be made available as an interface for general
> use in the kernel. The test module here uses very similar implementation from
> HugeTLB to allocate a PUD aligned memory block. Similar for mm_alloc() which
> needs to be exported through a header.
Why are you allocating memory at all instead of just using some
known-to-exist PFNs like I suggested?
_______________________________________________
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 00/59] KVM: arm64: ARMv8.3 Nested Virtualization support
From: Alexandru Elisei @ 2019-08-09 10:01 UTC (permalink / raw)
To: Marc Zyngier, linux-arm-kernel@lists.infradead.org,
kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org
Cc: Andre Przywara, Dave P Martin
In-Reply-To: <69cf1fe7-912c-1767-ff1b-dfcc7f549e44@arm.com>
On 8/2/19 11:11 AM, Alexandru Elisei wrote:
> Hi,
>
> On 6/21/19 10:37 AM, Marc Zyngier wrote:
>> I've taken over the maintenance of this series originally written by
>> Jintack and Christoffer. Since then, the series has been substantially
>> reworked, new features (and most probably bugs) have been added, and
>> the whole thing rebased multiple times. If anything breaks, please
>> blame me, and nobody else.
>>
>> As you can tell, this is quite big. It is also remarkably incomplete
>> (we're missing many critical bits for fully emulate EL2), but the idea
>> is to start merging things early in order to reduce the maintenance
>> headache. What we want to achieve is that with NV disabled, there is
>> no performance overhead and no regression. The only thing I intend to
>> merge ASAP is the first patch in the series, because it should have
>> zero effect and is a reasonable cleanup.
>>
>> The series is roughly divided in 4 parts: exception handling, memory
>> virtualization, interrupts and timers. There are of course some
>> dependencies, but you'll hopefully get the gist of it.
>>
>> For the most courageous of you, I've put out a branch[1] containing this
>> and a bit more. Of course, you'll need some userspace. Andre maintains
>> a hacked version of kvmtool[1] that takes a --nested option, allowing
>> the guest to be started at EL2. You can run the whole stack in the
>> Foundation model. Don't be in a hurry ;-).
>>
>> [1] git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git kvm-arm64/nv-wip-5.2-rc5
>> [2] git://linux-arm.org/kvmtool.git nv/nv-wip-5.2-rc5
>>
>> Andre Przywara (4):
>> KVM: arm64: nv: Handle virtual EL2 registers in
>> vcpu_read/write_sys_reg()
>> KVM: arm64: nv: Save/Restore vEL2 sysregs
>> KVM: arm64: nv: Handle traps for timer _EL02 and _EL2 sysregs
>> accessors
>> KVM: arm64: nv: vgic: Allow userland to set VGIC maintenance IRQ
>>
>> Christoffer Dall (16):
>> KVM: arm64: nv: Introduce nested virtualization VCPU feature
>> KVM: arm64: nv: Reset VCPU to EL2 registers if VCPU nested virt is set
>> KVM: arm64: nv: Allow userspace to set PSR_MODE_EL2x
>> KVM: arm64: nv: Add nested virt VCPU primitives for vEL2 VCPU state
>> KVM: arm64: nv: Handle trapped ERET from virtual EL2
>> KVM: arm64: nv: Emulate PSTATE.M for a guest hypervisor
>> KVM: arm64: nv: Trap EL1 VM register accesses in virtual EL2
>> KVM: arm64: nv: Only toggle cache for virtual EL2 when SCTLR_EL2
>> changes
>> KVM: arm/arm64: nv: Support multiple nested stage 2 mmu structures
>> KVM: arm64: nv: Implement nested Stage-2 page table walk logic
>> KVM: arm64: nv: Handle shadow stage 2 page faults
>> KVM: arm64: nv: Unmap/flush shadow stage 2 page tables
>> KVM: arm64: nv: arch_timer: Support hyp timer emulation
>> KVM: arm64: nv: vgic-v3: Take cpu_if pointer directly instead of vcpu
>> KVM: arm64: nv: vgic: Emulate the HW bit in software
>> KVM: arm64: nv: Add nested GICv3 tracepoints
>>
>> Dave Martin (1):
>> KVM: arm64: Migrate _elx sysreg accessors to msr_s/mrs_s
>>
>> Jintack Lim (21):
>> arm64: Add ARM64_HAS_NESTED_VIRT cpufeature
>> KVM: arm64: nv: Add EL2 system registers to vcpu context
>> KVM: arm64: nv: Support virtual EL2 exceptions
>> KVM: arm64: nv: Inject HVC exceptions to the virtual EL2
>> KVM: arm64: nv: Trap SPSR_EL1, ELR_EL1 and VBAR_EL1 from virtual EL2
>> KVM: arm64: nv: Trap CPACR_EL1 access in virtual EL2
>> KVM: arm64: nv: Set a handler for the system instruction traps
>> KVM: arm64: nv: Handle PSCI call via smc from the guest
>> KVM: arm64: nv: Respect virtual HCR_EL2.TWX setting
>> KVM: arm64: nv: Respect virtual CPTR_EL2.TFP setting
>> KVM: arm64: nv: Respect the virtual HCR_EL2.NV bit setting
>> KVM: arm64: nv: Respect virtual HCR_EL2.TVM and TRVM settings
>> KVM: arm64: nv: Respect the virtual HCR_EL2.NV1 bit setting
>> KVM: arm64: nv: Emulate EL12 register accesses from the virtual EL2
>> KVM: arm64: nv: Configure HCR_EL2 for nested virtualization
>> KVM: arm64: nv: Pretend we only support larger-than-host page sizes
>> KVM: arm64: nv: Introduce sys_reg_desc.forward_trap
>> KVM: arm64: nv: Rework the system instruction emulation framework
>> KVM: arm64: nv: Trap and emulate AT instructions from virtual EL2
>> KVM: arm64: nv: Trap and emulate TLBI instructions from virtual EL2
>> KVM: arm64: nv: Nested GICv3 Support
>>
>> Marc Zyngier (17):
>> KVM: arm64: Move __load_guest_stage2 to kvm_mmu.h
>> KVM: arm64: nv: Reset VMPIDR_EL2 and VPIDR_EL2 to sane values
>> KVM: arm64: nv: Handle SPSR_EL2 specially
>> KVM: arm64: nv: Refactor vcpu_{read,write}_sys_reg
>> KVM: arm64: nv: Don't expose SVE to nested guests
>> KVM: arm64: nv: Hide RAS from nested guests
>> KVM: arm/arm64: nv: Factor out stage 2 page table data from struct kvm
>> KVM: arm64: nv: Move last_vcpu_ran to be per s2 mmu
>> KVM: arm64: nv: Don't always start an S2 MMU search from the beginning
>> KVM: arm64: nv: Propagate CNTVOFF_EL2 to the virtual EL1 timer
>> KVM: arm64: nv: Load timer before the GIC
>> KVM: arm64: nv: Implement maintenance interrupt forwarding
>> arm64: KVM: nv: Add handling of EL2-specific timer registers
>> arm64: KVM: nv: Honor SCTLR_EL2.SPAN on entering vEL2
>> arm64: KVM: nv: Handle SCTLR_EL2 RES0/RES1 bits
>> arm64: KVM: nv: Restrict S2 RD/WR permissions to match the guest's
>> arm64: KVM: nv: Allow userspace to request KVM_ARM_VCPU_NESTED_VIRT
>>
>> .../admin-guide/kernel-parameters.txt | 4 +
>> .../virtual/kvm/devices/arm-vgic-v3.txt | 9 +
>> arch/arm/include/asm/kvm_asm.h | 5 +-
>> arch/arm/include/asm/kvm_emulate.h | 3 +
>> arch/arm/include/asm/kvm_host.h | 31 +-
>> arch/arm/include/asm/kvm_hyp.h | 25 +-
>> arch/arm/include/asm/kvm_mmu.h | 83 +-
>> arch/arm/include/asm/kvm_nested.h | 9 +
>> arch/arm/include/uapi/asm/kvm.h | 1 +
>> arch/arm/kvm/hyp/switch.c | 11 +-
>> arch/arm/kvm/hyp/tlb.c | 13 +-
>> arch/arm64/include/asm/cpucaps.h | 3 +-
>> arch/arm64/include/asm/esr.h | 4 +-
>> arch/arm64/include/asm/kvm_arm.h | 28 +-
>> arch/arm64/include/asm/kvm_asm.h | 9 +-
>> arch/arm64/include/asm/kvm_coproc.h | 2 +-
>> arch/arm64/include/asm/kvm_emulate.h | 157 +-
>> arch/arm64/include/asm/kvm_host.h | 105 +-
>> arch/arm64/include/asm/kvm_hyp.h | 82 +-
>> arch/arm64/include/asm/kvm_mmu.h | 62 +-
>> arch/arm64/include/asm/kvm_nested.h | 68 +
>> arch/arm64/include/asm/sysreg.h | 143 +-
>> arch/arm64/include/uapi/asm/kvm.h | 2 +
>> arch/arm64/kernel/cpufeature.c | 26 +
>> arch/arm64/kvm/Makefile | 4 +
>> arch/arm64/kvm/emulate-nested.c | 223 +++
>> arch/arm64/kvm/guest.c | 6 +
>> arch/arm64/kvm/handle_exit.c | 76 +-
>> arch/arm64/kvm/hyp/Makefile | 1 +
>> arch/arm64/kvm/hyp/at.c | 217 +++
>> arch/arm64/kvm/hyp/switch.c | 86 +-
>> arch/arm64/kvm/hyp/sysreg-sr.c | 267 ++-
>> arch/arm64/kvm/hyp/tlb.c | 129 +-
>> arch/arm64/kvm/hyp/vgic-v2-cpuif-proxy.c | 2 +-
>> arch/arm64/kvm/inject_fault.c | 12 -
>> arch/arm64/kvm/nested.c | 551 +++++++
>> arch/arm64/kvm/regmap.c | 4 +-
>> arch/arm64/kvm/reset.c | 7 +
>> arch/arm64/kvm/sys_regs.c | 1460 +++++++++++++++--
>> arch/arm64/kvm/sys_regs.h | 6 +
>> arch/arm64/kvm/trace.h | 58 +-
>> include/kvm/arm_arch_timer.h | 6 +
>> include/kvm/arm_vgic.h | 28 +-
>> virt/kvm/arm/arch_timer.c | 158 +-
>> virt/kvm/arm/arm.c | 62 +-
>> virt/kvm/arm/hyp/vgic-v3-sr.c | 35 +-
>> virt/kvm/arm/mmio.c | 12 +-
>> virt/kvm/arm/mmu.c | 445 +++--
>> virt/kvm/arm/trace.h | 6 +-
>> virt/kvm/arm/vgic/vgic-init.c | 30 +
>> virt/kvm/arm/vgic/vgic-kvm-device.c | 22 +
>> virt/kvm/arm/vgic/vgic-nested-trace.h | 137 ++
>> virt/kvm/arm/vgic/vgic-v2.c | 10 +-
>> virt/kvm/arm/vgic/vgic-v3-nested.c | 236 +++
>> virt/kvm/arm/vgic/vgic-v3.c | 40 +-
>> virt/kvm/arm/vgic/vgic.c | 74 +-
>> 56 files changed, 4683 insertions(+), 612 deletions(-)
>> create mode 100644 arch/arm/include/asm/kvm_nested.h
>> create mode 100644 arch/arm64/include/asm/kvm_nested.h
>> create mode 100644 arch/arm64/kvm/emulate-nested.c
>> create mode 100644 arch/arm64/kvm/hyp/at.c
>> create mode 100644 arch/arm64/kvm/nested.c
>> create mode 100644 virt/kvm/arm/vgic/vgic-nested-trace.h
>> create mode 100644 virt/kvm/arm/vgic/vgic-v3-nested.c
>>
> When working on adding support for EL2 to kvm-unit-tests I was able to trigger
> the following warning:
>
> # ./lkvm run -f psci.flat -m 128 -c 8 --console serial --irqchip gicv3 --nested
> # lkvm run --firmware psci.flat -m 128 -c 8 --name guest-151
> Info: Placing fdt at 0x80200000 - 0x80210000
> # Warning: The maximum recommended amount of VCPUs is 4
> chr_testdev_init: chr-testdev: can't find a virtio-console
> INFO: PSCI version 1.0
> PASS: invalid-function
> PASS: affinity-info-on
> PASS: affinity-info-off
> [ 24.381266] WARNING: CPU: 3 PID: 160 at
> arch/arm64/kvm/../../../virt/kvm/arm/arch_timer.c:170
> kvm_timer_irq_can_fire+0xc/0x30
> [ 24.381366] Modules linked in:
> [ 24.381466] CPU: 3 PID: 160 Comm: kvm-vcpu-1 Not tainted
> 5.2.0-rc5-00060-g7dbce63bd1c7 #145
> [ 24.381566] Hardware name: Foundation-v8A (DT)
> [ 24.381566] pstate: 40400009 (nZcv daif +PAN -UAO)
> [ 24.381666] pc : kvm_timer_irq_can_fire+0xc/0x30
> [ 24.381766] lr : timer_emulate+0x24/0x98
> [ 24.381766] sp : ffff000013d8b780
> [ 24.381866] x29: ffff000013d8b780 x28: ffff80087a639b80
> [ 24.381966] x27: ffff000010ba8648 x26: ffff000010b71b40
> [ 24.382066] x25: ffff80087a63a100 x24: 0000000000000000
> [ 24.382111] x23: 000080086ca54000 x22: ffff0000100ce260
> [ 24.382166] x21: ffff800875e7c918 x20: ffff800875e7a800
> [ 24.382275] x19: ffff800875e7ca08 x18: 0000000000000000
> [ 24.382366] x17: 0000000000000000 x16: 0000000000000000
> [ 24.382466] x15: 0000000000000000 x14: 0000000000002118
> [ 24.382566] x13: 0000000000002190 x12: 0000000000002280
> [ 24.382566] x11: 0000000000002208 x10: 0000000000000040
> [ 24.382666] x9 : ffff000012dc3b38 x8 : 0000000000000000
> [ 24.382766] x7 : 0000000000000000 x6 : ffff80087ac00248
> [ 24.382866] x5 : 000080086ca54000 x4 : 0000000000002118
> [ 24.382966] x3 : eeeeeeeeeeeeeeef x2 : ffff800875e7c918
> [ 24.383066] x1 : 0000000000000001 x0 : ffff800875e7ca08
> [ 24.383066] Call trace:
> [ 24.383166] kvm_timer_irq_can_fire+0xc/0x30
> [ 24.383266] kvm_timer_vcpu_load+0x9c/0x1a0
> [ 24.383366] kvm_arch_vcpu_load+0xb0/0x1f0
> [ 24.383366] kvm_sched_in+0x1c/0x28
> [ 24.383466] finish_task_switch+0xd8/0x1d8
> [ 24.383566] __schedule+0x248/0x4a0
> [ 24.383666] preempt_schedule_irq+0x60/0x90
> [ 24.383666] el1_irq+0xd0/0x180
> [ 24.383766] kvm_handle_guest_abort+0x0/0x3a0
> [ 24.383866] kvm_arch_vcpu_ioctl_run+0x41c/0x688
> [ 24.383866] kvm_vcpu_ioctl+0x4c0/0x838
> [ 24.383966] do_vfs_ioctl+0xb8/0x878
> [ 24.384077] ksys_ioctl+0x84/0x90
> [ 24.384166] __arm64_sys_ioctl+0x18/0x28
> [ 24.384166] el0_svc_common.constprop.0+0xb0/0x168
> [ 24.384266] el0_svc_handler+0x28/0x78
> [ 24.384366] el0_svc+0x8/0xc
> [ 24.384366] ---[ end trace 37a32293e43ac12c ]---
> [ 24.384666] WARNING: CPU: 3 PID: 160 at
> arch/arm64/kvm/../../../virt/kvm/arm/arch_timer.c:170
> kvm_timer_irq_can_fire+0xc/0x30
> [ 24.384766] Modules linked in:
> [ 24.384866] CPU: 3 PID: 160 Comm: kvm-vcpu-1 Tainted: G W
> 5.2.0-rc5-00060-g7dbce63bd1c7 #145
> [ 24.384966] Hardware name: Foundation-v8A (DT)
> [ 24.384966] pstate: 40400009 (nZcv daif +PAN -UAO)
> [ 24.385066] pc : kvm_timer_irq_can_fire+0xc/0x30
> [ 24.385166] lr : timer_emulate+0x24/0x98
> [ 24.385166] sp : ffff000013d8b780
> [ 24.385266] x29: ffff000013d8b780 x28: ffff80087a639b80
> [ 24.385366] x27: ffff000010ba8648 x26: ffff000010b71b40
> [ 24.385466] x25: ffff80087a63a100 x24: 0000000000000000
> [ 24.385466] x23: 000080086ca54000 x22: ffff0000100ce260
> [ 24.385566] x21: ffff800875e7c918 x20: ffff800875e7a800
> [ 24.385666] x19: ffff800875e7ca80 x18: 0000000000000000
> [ 24.385766] x17: 0000000000000000 x16: 0000000000000000
> [ 24.385866] x15: 0000000000000000 x14: 0000000000002118
> [ 24.385966] x13: 0000000000002190 x12: 0000000000002280
> [ 24.385966] x11: 0000000000002208 x10: 0000000000000040
> [ 24.386066] x9 : ffff000012dc3b38 x8 : 0000000000000000
> [ 24.386166] x7 : 0000000000000000 x6 : ffff80087ac00248
> [ 24.386266] x5 : 000080086ca54000 x4 : 0000000000002118
> [ 24.386366] x3 : eeeeeeeeeeeeeeef x2 : ffff800875e7c918
> [ 24.386466] x1 : 0000000000000001 x0 : ffff800875e7ca80
> [ 24.386466] Call trace:
> [ 24.386566] kvm_timer_irq_can_fire+0xc/0x30
> [ 24.386666] kvm_timer_vcpu_load+0xa8/0x1a0
> [ 24.386666] kvm_arch_vcpu_load+0xb0/0x1f0
> [ 24.386898] kvm_sched_in+0x1c/0x28
> [ 24.386966] finish_task_switch+0xd8/0x1d8
> [ 24.387166] __schedule+0x248/0x4a0
> [ 24.387354] preempt_schedule_irq+0x60/0x90
> [ 24.387366] el1_irq+0xd0/0x180
> [ 24.387466] kvm_handle_guest_abort+0x0/0x3a0
> [ 24.387566] kvm_arch_vcpu_ioctl_run+0x41c/0x688
> [ 24.387566] kvm_vcpu_ioctl+0x4c0/0x838
> [ 24.387666] do_vfs_ioctl+0xb8/0x878
> [ 24.387766] ksys_ioctl+0x84/0x90
> [ 24.387866] __arm64_sys_ioctl+0x18/0x28
> [ 24.387866] el0_svc_common.constprop.0+0xb0/0x168
> [ 24.387966] el0_svc_handler+0x28/0x78
> [ 24.388066] el0_svc+0x8/0xc
> [ 24.388066] ---[ end trace 37a32293e43ac12d ]---
> PASS: cpu-on
> SUMMARY: 4 te[ 24.390266] WARNING: CPU: 3 PID: 160 at
> arch/arm64/kvm/../../../virt/kvm/arm/arch_timer.c:170
> kvm_timer_irq_can_fire+0xc/0x30
> s[ 24.390366] Modules linked in:
> ts[ 24.390366] CPU: 3 PID: 160 Comm: kvm-vcpu-1 Tainted: G W
> 5.2.0-rc5-00060-g7dbce63bd1c7 #145
> [ 24.390566] Hardware name: Foundation-v8A (DT)
>
> [ 24.390795] pstate: 40400009 (nZcv daif +PAN -UAO)
> [ 24.390866] pc : kvm_timer_irq_can_fire+0xc/0x30
> [ 24.390966] lr : timer_emulate+0x24/0x98
> [ 24.391066] sp : ffff000013d8b780
> [ 24.391066] x29: ffff000013d8b780 x28: ffff80087a639b80
> [ 24.391166] x27: ffff000010ba8648 x26: ffff000010b71b40
> [ 24.391266] x25: ffff80087a63a100 x24: 0000000000000000
> [ 24.391366] x23: 000080086ca54000 x22: 0000000000000003
> [ 24.391466] x21: ffff800875e7c918 x20: ffff800875e7a800
> [ 24.391466] x19: ffff800875e7ca08 x18: 0000000000000000
> [ 24.391566] x17: 0000000000000000 x16: 0000000000000000
> [ 24.391666] x15: 0000000000000000 x14: 0000000000002118
> [ 24.391766] x13: 0000000000002190 x12: 0000000000002280
> [ 24.391866] x11: 0000000000002208 x10: 0000000000000040
> [ 24.391942] x9 : ffff000012dc3b38 x8 : 0000000000000000
> [ 24.391966] x7 : 0000000000000000 x6 : ffff80087ac00248
> [ 24.392066] x5 : 000080086ca54000 x4 : 0000000000002118
> [ 24.392166] x3 : eeeeeeeeeeeeeeef x2 : ffff800875e7c918
> [ 24.392269] x1 : 0000000000000001 x0 : ffff800875e7ca08
> [ 24.392366] Call trace:
> [ 24.392433] kvm_timer_irq_can_fire+0xc/0x30
> [ 24.392466] kvm_timer_vcpu_load+0x9c/0x1a0
> [ 24.392597] kvm_arch_vcpu_load+0xb0/0x1f0
> [ 24.392666] kvm_sched_in+0x1c/0x28
> [ 24.392766] finish_task_switch+0xd8/0x1d8
> [ 24.392766] __schedule+0x248/0x4a0
> [ 24.392866] preempt_schedule_irq+0x60/0x90
> [ 24.392966] el1_irq+0xd0/0x180
> [ 24.392966] kvm_handle_guest_abort+0x0/0x3a0
> [ 24.393066] kvm_arch_vcpu_ioctl_run+0x41c/0x688
> [ 24.393166] kvm_vcpu_ioctl+0x4c0/0x838
> [ 24.393266] do_vfs_ioctl+0xb8/0x878
> [ 24.393266] ksys_ioctl+0x84/0x90
> [ 24.393366] __arm64_sys_ioctl+0x18/0x28
> [ 24.393466] el0_svc_common.constprop.0+0xb0/0x168
> [ 24.393566] el0_svc_handler+0x28/0x78
> [ 24.393566] el0_svc+0x8/0xc
> [ 24.393666] ---[ end trace 37a32293e43ac12e ]---
> [ 24.393866] WARNING: CPU: 3 PID: 160 at
> arch/arm64/kvm/../../../virt/kvm/arm/arch_timer.c:170
> kvm_timer_irq_can_fire+0xc/0x30
> [ 24.394066] Modules linked in:
> [ 24.394266] CPU: 3 PID: 160 Comm: kvm-vcpu-1 Tainted: G W
> 5.2.0-rc5-00060-g7dbce63bd1c7 #145
> [ 24.394366] Hardware name: Foundation-v8A (DT)
> [ 24.394466] pstate: 40400009 (nZcv daif +PAN -UAO)
> [ 24.394466] pc : kvm_timer_irq_can_fire+0xc/0x30
> [ 24.394566] lr : timer_emulate+0x24/0x98
> [ 24.394666] sp : ffff000013d8b780
> [ 24.394727] x29: ffff000013d8b780 x28: ffff80087a639b80
> [ 24.394766] x27: ffff000010ba8648 x26: ffff000010b71b40
> [ 24.394866] x25: ffff80087a63a100 x24: 0000000000000000
> [ 24.394966] x23: 000080086ca54000 x22: 0000000000000003
> [ 24.394966] x21: ffff800875e7c918 x20: ffff800875e7a800
> [ 24.395066] x19: ffff800875e7ca80 x18: 0000000000000000
> [ 24.395166] x17: 0000000000000000 x16: 0000000000000000
> [ 24.395266] x15: 0000000000000000 x14: 0000000000002118
> [ 24.395383] x13: 0000000000002190 x12: 0000000000002280
> [ 24.395466] x11: 0000000000002208 x10: 0000000000000040
> [ 24.395547] x9 : ffff000012dc3b38 x8 : 0000000000000000
> [ 24.395666] x7 : 0000000000000000 x6 : ffff80087ac00248
> [ 24.395866] x5 : 000080086ca54000 x4 : 0000000000002118
> [ 24.395966] x3 : eeeeeeeeeeeeeeef x2 : ffff800875e7c918
> [ 24.396066] x1 : 0000000000000001 x0 : ffff800875e7ca80
> [ 24.396066] Call trace:
> [ 24.396166] kvm_timer_irq_can_fire+0xc/0x30
> [ 24.396266] kvm_timer_vcpu_load+0xa8/0x1a0
> [ 24.396366] kvm_arch_vcpu_load+0xb0/0x1f0
> [ 24.396366] kvm_sched_in+0x1c/0x28
> [ 24.396466] finish_task_switch+0xd8/0x1d8
> [ 24.396566] __schedule+0x248/0x4a0
> [ 24.396666] preempt_schedule_irq+0x60/0x90
> [ 24.396666] el1_irq+0xd0/0x180
> [ 24.396766] kvm_handle_guest_abort+0x0/0x3a0
> [ 24.396866] kvm_arch_vcpu_ioctl_run+0x41c/0x688
> [ 24.396866] kvm_vcpu_ioctl+0x4c0/0x838
> [ 24.397021] do_vfs_ioctl+0xb8/0x878
> [ 24.397066] ksys_ioctl+0x84/0x90
> [ 24.397166] __arm64_sys_ioctl+0x18/0x28
> [ 24.397348] el0_svc_common.constprop.0+0xb0/0x168
> [ 24.397366] el0_svc_handler+0x28/0x78
> [ 24.397566] el0_svc+0x8/0xc
> [ 24.397676] ---[ end trace 37a32293e43ac12f ]---
>
> # KVM compatibility warning.
> virtio-9p device was not detected.
> While you have requested a virtio-9p device, the guest kernel did not
> initialize it.
> Please make sure that the guest kernel was compiled with
> CONFIG_NET_9P_VIRTIO=y enabled in .config.
>
> # KVM compatibility warning.
> virtio-net device was not detected.
> While you have requested a virtio-net device, the guest kernel did not
> initialize it.
> Please make sure that the guest kernel was compiled with CONFIG_VIRTIO_NET=y
> enabled in .config.
>
> [..]
Did some investigating and this was caused by a bug in kvm-unit-tests (the fix
for it will be part of the EL2 patches for kvm-unit-tests). The guest was trying
to fetch an instruction from address 0x200, which KVM interprets as a prefetch
abort on an I/O address and ends up calling kvm_inject_pabt. The code from
arch/arm64/kvm/inject_fault.c doesn't know anything about nested virtualization,
and it sets the VCPU mode directly to PSR_MODE_EL1h. This makes_hyp_ctxt return
false, and get_timer_map will return an incorrect mapping.
On next kvm_timer_vcpu_put, the direct timers will be {p,v}timer, and
h{p,v}timer->loaded will not be set to false. In the corresponding call to
kvm_timer_vcpu_load, KVM will try to emulate the hptimer and hvtimer, which
still have loaded = true. And this causes the warning I saw.
_______________________________________________
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 5/6] tty: serial: Add linflexuart driver for S32V234
From: Stefan-gabriel Mirea @ 2019-08-09 9:57 UTC (permalink / raw)
To: Will Deacon
Cc: mark.rutland@arm.com, devicetree@vger.kernel.org, corbet@lwn.net,
gregkh@linuxfoundation.org, jslaby@suse.com,
linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, Leo Li,
Cosmin Stefan Stoica, robh+dt@kernel.org,
linux-serial@vger.kernel.org, catalin.marinas@arm.com,
shawnguo@kernel.org, linux-arm-kernel@lists.infradead.org,
Larisa Ileana Grigore
In-Reply-To: <20190809095338.d73fomq424gayf2b@willie-the-truck>
On 8/9/2019 12:53 PM, Will Deacon wrote:
> On Fri, Aug 09, 2019 at 09:45:40AM +0000, Stefan-gabriel Mirea wrote:
>> On 8/8/2019 8:17 PM, Will Deacon wrote:
>>> On Thu, Aug 08, 2019 at 12:47:00PM +0000, Stefan-gabriel Mirea wrote:
>>>> On 8/8/2019 11:08 AM, Will Deacon wrote:
>>>>> On Fri, Aug 02, 2019 at 07:47:23PM +0000, Stefan-gabriel Mirea wrote:
>>>>>> + linflex,<addr>
>>>>>> + Use early console provided by Freescale LinFlex UART
>>>>>> + serial driver for NXP S32V234 SoCs. A valid base
>>>>>> + address must be provided, and the serial port must
>>>>>> + already be setup and configured.
>>>>>
>>>>> Why isn't earlycon= sufficient for this?
>>>>
>>>> "earlycon=" is not actually supported. I will fix this in the next
>>>> version by adding a /chosen/stdout-path to the dts. The compatible
>>>> string provided to OF_EARLYCON_DECLARE will also be changed from
>>>> "fsl,s32v234-linflexuart" to "fsl,s32-linflexuart" to match the one in
>>>> the device tree nodes. I missed this after importing a rename from our
>>>> codebase.
>>>>
>>>> Should I remove this addition from kernel-parameters.txt after that?
>>>
>>> Yes, if you can use earlycon instead, then you can drop your custom option
>>> entirely and therefore there's no need to document it either.
>>
>> Can you please clarify what you mean by "drop your custom option"? The
>> "linflex" option documented in the paragraph is the name of the
>> earlycon_id declared via "OF_EARLYCON_DECLARE(linflex, ...)". We have
>> not done anything particular to accept it in the parameter value.
>
> My apologies, I completely misread your patch and thought your were adding
> a *new* kernel parameter. Having looked at the context, I now see you're
> adding a new earlycon option, which is what I was suggesting :)
>
> By all means, please update the stdout-path, because then you can just pass
> "earlycon" and things will work as expected.
No problem, I will submit the new version soon. Thank you!
Regards,
Stefan
_______________________________________________
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 5/6] tty: serial: Add linflexuart driver for S32V234
From: Will Deacon @ 2019-08-09 9:53 UTC (permalink / raw)
To: Stefan-gabriel Mirea
Cc: mark.rutland@arm.com, devicetree@vger.kernel.org, corbet@lwn.net,
gregkh@linuxfoundation.org, jslaby@suse.com,
linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, Leo Li,
Cosmin Stefan Stoica, robh+dt@kernel.org,
linux-serial@vger.kernel.org, catalin.marinas@arm.com,
shawnguo@kernel.org, linux-arm-kernel@lists.infradead.org,
Larisa Ileana Grigore
In-Reply-To: <VI1PR0402MB2863B3E3E2F93CBA8ADB96E5DFD60@VI1PR0402MB2863.eurprd04.prod.outlook.com>
On Fri, Aug 09, 2019 at 09:45:40AM +0000, Stefan-gabriel Mirea wrote:
> On 8/8/2019 8:17 PM, Will Deacon wrote:
> > On Thu, Aug 08, 2019 at 12:47:00PM +0000, Stefan-gabriel Mirea wrote:
> >> On 8/8/2019 11:08 AM, Will Deacon wrote:
> >>> On Fri, Aug 02, 2019 at 07:47:23PM +0000, Stefan-gabriel Mirea wrote:
> >>>> + linflex,<addr>
> >>>> + Use early console provided by Freescale LinFlex UART
> >>>> + serial driver for NXP S32V234 SoCs. A valid base
> >>>> + address must be provided, and the serial port must
> >>>> + already be setup and configured.
> >>>
> >>> Why isn't earlycon= sufficient for this?
> >>
> >> "earlycon=" is not actually supported. I will fix this in the next
> >> version by adding a /chosen/stdout-path to the dts. The compatible
> >> string provided to OF_EARLYCON_DECLARE will also be changed from
> >> "fsl,s32v234-linflexuart" to "fsl,s32-linflexuart" to match the one in
> >> the device tree nodes. I missed this after importing a rename from our
> >> codebase.
> >>
> >> Should I remove this addition from kernel-parameters.txt after that?
> >
> > Yes, if you can use earlycon instead, then you can drop your custom option
> > entirely and therefore there's no need to document it either.
>
> Can you please clarify what you mean by "drop your custom option"? The
> "linflex" option documented in the paragraph is the name of the
> earlycon_id declared via "OF_EARLYCON_DECLARE(linflex, ...)". We have
> not done anything particular to accept it in the parameter value.
My apologies, I completely misread your patch and thought your were adding
a *new* kernel parameter. Having looked at the context, I now see you're
adding a new earlycon option, which is what I was suggesting :)
By all means, please update the stdout-path, because then you can just pass
"earlycon" and things will work as expected.
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 v6 11/14] mips: Adjust brk randomization offset to fit generic version
From: Alexandre Ghiti @ 2019-08-09 9:45 UTC (permalink / raw)
To: Sergei Shtylyov, Andrew Morton
Cc: Albert Ou, Kees Cook, James Hogan, Catalin Marinas,
Palmer Dabbelt, Will Deacon, Russell King, Ralf Baechle,
linux-kernel, linux-mm, Luis Chamberlain, Paul Burton,
Paul Walmsley, linux-fsdevel, linux-riscv, linux-mips,
Christoph Hellwig, linux-arm-kernel, Alexander Viro
In-Reply-To: <68ec5cf6-6ba3-68ab-aa01-668b701c642f@cogentembedded.com>
On 8/8/19 11:19 AM, Sergei Shtylyov wrote:
> Hello!
>
> On 08.08.2019 9:17, Alexandre Ghiti wrote:
>
>> This commit simply bumps up to 32MB and 1GB the random offset
>> of brk, compared to 8MB and 256MB, for 32bit and 64bit respectively.
>>
>> Suggested-by: Kees Cook <keescook@chromium.org>
>> Signed-off-by: Alexandre Ghiti <alex@ghiti.fr>
>> Acked-by: Paul Burton <paul.burton@mips.com>
>> Reviewed-by: Kees Cook <keescook@chromium.org>
>> Reviewed-by: Luis Chamberlain <mcgrof@kernel.org>
>> ---
>> arch/mips/mm/mmap.c | 7 ++++---
>> 1 file changed, 4 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c
>> index a7e84b2e71d7..ff6ab87e9c56 100644
>> --- a/arch/mips/mm/mmap.c
>> +++ b/arch/mips/mm/mmap.c
> [...]
>> @@ -189,11 +190,11 @@ static inline unsigned long brk_rnd(void)
>> unsigned long rnd = get_random_long();
>> rnd = rnd << PAGE_SHIFT;
>> - /* 8MB for 32bit, 256MB for 64bit */
>> + /* 32MB for 32bit, 1GB for 64bit */
>> if (TASK_IS_32BIT_ADDR)
>> - rnd = rnd & 0x7ffffful;
>> + rnd = rnd & (SZ_32M - 1);
>> else
>> - rnd = rnd & 0xffffffful;
>> + rnd = rnd & (SZ_1G - 1);
>
> Why not make these 'rnd &= SZ_* - 1', while at it anyways?
You're right, I could have. Again, this code gets removed afterwards, so
I think it's ok
to leave it as is.
Anyway, thanks for your remarks Sergei !
Alex
>
> [...]
>
> MBR, Sergei
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv
_______________________________________________
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 5/6] tty: serial: Add linflexuart driver for S32V234
From: Stefan-gabriel Mirea @ 2019-08-09 9:45 UTC (permalink / raw)
To: Will Deacon
Cc: mark.rutland@arm.com, devicetree@vger.kernel.org, corbet@lwn.net,
gregkh@linuxfoundation.org, jslaby@suse.com,
linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, Leo Li,
Cosmin Stefan Stoica, robh+dt@kernel.org,
linux-serial@vger.kernel.org, catalin.marinas@arm.com,
shawnguo@kernel.org, linux-arm-kernel@lists.infradead.org,
Larisa Ileana Grigore
In-Reply-To: <20190808171711.nk7ljqkugtketu4q@willie-the-truck>
On 8/8/2019 8:17 PM, Will Deacon wrote:
> On Thu, Aug 08, 2019 at 12:47:00PM +0000, Stefan-gabriel Mirea wrote:
>> On 8/8/2019 11:08 AM, Will Deacon wrote:
>>> On Fri, Aug 02, 2019 at 07:47:23PM +0000, Stefan-gabriel Mirea wrote:
>>>> + linflex,<addr>
>>>> + Use early console provided by Freescale LinFlex UART
>>>> + serial driver for NXP S32V234 SoCs. A valid base
>>>> + address must be provided, and the serial port must
>>>> + already be setup and configured.
>>>
>>> Why isn't earlycon= sufficient for this?
>>
>> "earlycon=" is not actually supported. I will fix this in the next
>> version by adding a /chosen/stdout-path to the dts. The compatible
>> string provided to OF_EARLYCON_DECLARE will also be changed from
>> "fsl,s32v234-linflexuart" to "fsl,s32-linflexuart" to match the one in
>> the device tree nodes. I missed this after importing a rename from our
>> codebase.
>>
>> Should I remove this addition from kernel-parameters.txt after that?
>
> Yes, if you can use earlycon instead, then you can drop your custom option
> entirely and therefore there's no need to document it either.
Can you please clarify what you mean by "drop your custom option"? The
"linflex" option documented in the paragraph is the name of the
earlycon_id declared via "OF_EARLYCON_DECLARE(linflex, ...)". We have
not done anything particular to accept it in the parameter value.
We do use earlycon (e.g. "earlycon=linflex,0x40053000"), we just do not
support an empty value after "=", which needs to be fixed as I
understand, because it does not respect the comment[1] about ARM64.
Regards,
Stefan
[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/admin-guide/kernel-parameters.txt?h=v5.3-rc3#n980
_______________________________________________
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 v6 09/14] mips: Properly account for stack randomization and stack guard gap
From: Alexandre Ghiti @ 2019-08-09 9:44 UTC (permalink / raw)
To: Sergei Shtylyov, Andrew Morton
Cc: Albert Ou, Kees Cook, James Hogan, Catalin Marinas,
Palmer Dabbelt, Will Deacon, Russell King, Ralf Baechle,
linux-kernel, linux-mm, Luis Chamberlain, Paul Burton,
Paul Walmsley, linux-fsdevel, linux-riscv, linux-mips,
Christoph Hellwig, linux-arm-kernel, Alexander Viro
In-Reply-To: <bd67507e-8a5b-34b5-1a33-5500bbb724b2@cogentembedded.com>
On 8/8/19 11:16 AM, Sergei Shtylyov wrote:
> Hello!
>
> On 08.08.2019 9:17, Alexandre Ghiti wrote:
>
>> This commit takes care of stack randomization and stack guard gap when
>> computing mmap base address and checks if the task asked for
>> randomization.
>>
>> This fixes the problem uncovered and not fixed for arm here:
>> https://lkml.kernel.org/r/20170622200033.25714-1-riel@redhat.com
>>
>> Signed-off-by: Alexandre Ghiti <alex@ghiti.fr>
>> Acked-by: Kees Cook <keescook@chromium.org>
>> Acked-by: Paul Burton <paul.burton@mips.com>
>> Reviewed-by: Luis Chamberlain <mcgrof@kernel.org>
>> ---
>> arch/mips/mm/mmap.c | 14 ++++++++++++--
>> 1 file changed, 12 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c
>> index d79f2b432318..f5c778113384 100644
>> --- a/arch/mips/mm/mmap.c
>> +++ b/arch/mips/mm/mmap.c
>> @@ -21,8 +21,9 @@ unsigned long shm_align_mask = PAGE_SIZE - 1; /*
>> Sane caches */
>> EXPORT_SYMBOL(shm_align_mask);
>> /* gap between mmap and stack */
>> -#define MIN_GAP (128*1024*1024UL)
>> -#define MAX_GAP ((TASK_SIZE)/6*5)
>> +#define MIN_GAP (128*1024*1024UL)
>> +#define MAX_GAP ((TASK_SIZE)/6*5)
>
> Could add spaces around *, while touching this anyway? And parens
> around TASK_SIZE shouldn't be needed...
>
I did not fix checkpatch warnings here since this code gets removed
afterwards.
>> +#define STACK_RND_MASK (0x7ff >> (PAGE_SHIFT - 12))
>> static int mmap_is_legacy(struct rlimit *rlim_stack)
>> {
>> @@ -38,6 +39,15 @@ static int mmap_is_legacy(struct rlimit *rlim_stack)
>> static unsigned long mmap_base(unsigned long rnd, struct rlimit
>> *rlim_stack)
>> {
>> unsigned long gap = rlim_stack->rlim_cur;
>> + unsigned long pad = stack_guard_gap;
>> +
>> + /* Account for stack randomization if necessary */
>> + if (current->flags & PF_RANDOMIZE)
>> + pad += (STACK_RND_MASK << PAGE_SHIFT);
>
> Parens not needed here.
Belt and braces approach here as I'm never sure about priorities.
Thanks for your time,
Alex
>
>> +
>> + /* Values close to RLIM_INFINITY can overflow. */
>> + if (gap + pad > gap)
>> + gap += pad;
>> if (gap < MIN_GAP)
>> gap = MIN_GAP;
>>
>
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv
_______________________________________________
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] arm-nommu: call dma_mmap_from_dev_coherent directly
From: Sergei Shtylyov @ 2019-08-09 9:35 UTC (permalink / raw)
To: Christoph Hellwig, iommu, Marek Szyprowski
Cc: linux-xtensa, Michal Simek, Vladimir Murzin, linux-parisc,
linux-sh, Takashi Iwai, linuxppc-dev, Helge Deller, x86,
linux-kernel, linux-m68k, Robin Murphy, linux-arm-kernel
In-Reply-To: <20190808160005.10325-7-hch@lst.de>
On 08.08.2019 19:00, Christoph Hellwig wrote:
> Ther is no need to go through dma_common_mmap for the arm-nommu
There. :-)
> dma mmap implementation as the only possible memory not handled above
> could be that from the per-device coherent pool.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
[...]
MBR, Sergei
_______________________________________________
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