* [PATCH 01/10] perf tools: Integrating the CoreSight decoding library
From: Mathieu Poirier @ 2017-12-15 16:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1513356299-26274-1-git-send-email-mathieu.poirier@linaro.org>
The Open CoreSight Decoding Library (openCSD) is a free and open
library to decode traces collected by the CoreSight hardware
infrastructure.
This patch adds the required mechanic to recognise the presence
of the openCSD library on a system and set up miscellaneous flags
to be used in the compilation of the trace decoding feature.
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
---
tools/build/Makefile.feature | 6 ++++--
tools/build/feature/Makefile | 6 +++++-
tools/build/feature/test-all.c | 5 +++++
tools/build/feature/test-libopencsd.c | 8 ++++++++
tools/perf/Makefile.config | 13 +++++++++++++
5 files changed, 35 insertions(+), 3 deletions(-)
create mode 100644 tools/build/feature/test-libopencsd.c
diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature
index e52fcefee379..dc3d97b248ab 100644
--- a/tools/build/Makefile.feature
+++ b/tools/build/Makefile.feature
@@ -66,7 +66,8 @@ FEATURE_TESTS_BASIC := \
bpf \
sched_getcpu \
sdt \
- setns
+ setns \
+ libopencsd
# FEATURE_TESTS_BASIC + FEATURE_TESTS_EXTRA is the complete list
# of all feature tests
@@ -108,7 +109,8 @@ FEATURE_DISPLAY ?= \
zlib \
lzma \
get_cpuid \
- bpf
+ bpf \
+ libopencsd
# Set FEATURE_CHECK_(C|LD)FLAGS-all for all FEATURE_TESTS features.
# If in the future we need per-feature checks/flags for features not
diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile
index cff38f342283..2aae2d3fb5f6 100644
--- a/tools/build/feature/Makefile
+++ b/tools/build/feature/Makefile
@@ -52,7 +52,8 @@ FILES= \
test-cxx.bin \
test-jvmti.bin \
test-sched_getcpu.bin \
- test-setns.bin
+ test-setns.bin \
+ test-libopencsd.bin
FILES := $(addprefix $(OUTPUT),$(FILES))
@@ -104,6 +105,9 @@ $(OUTPUT)test-sched_getcpu.bin:
$(OUTPUT)test-setns.bin:
$(BUILD)
+$(OUTPUT)test-libopencsd.bin:
+ $(BUILD) -lopencsd_c_api
+
DWARFLIBS := -ldw
ifeq ($(findstring -static,${LDFLAGS}),-static)
DWARFLIBS += -lelf -lebl -lz -llzma -lbz2
diff --git a/tools/build/feature/test-all.c b/tools/build/feature/test-all.c
index 6fdf83263ab7..38ab0fd7a74c 100644
--- a/tools/build/feature/test-all.c
+++ b/tools/build/feature/test-all.c
@@ -162,6 +162,10 @@
# include "test-setns.c"
#undef main
+#define main main_test_setns
+# include "test-libopencsd.c"
+#undef main
+
int main(int argc, char *argv[])
{
main_test_libpython();
@@ -199,6 +203,7 @@ int main(int argc, char *argv[])
main_test_sched_getcpu();
main_test_sdt();
main_test_setns();
+ main_test_libopencsd();
return 0;
}
diff --git a/tools/build/feature/test-libopencsd.c b/tools/build/feature/test-libopencsd.c
new file mode 100644
index 000000000000..cd4fb99eb9d3
--- /dev/null
+++ b/tools/build/feature/test-libopencsd.c
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <opencsd/c_api/opencsd_c_api.h>
+
+int main(void)
+{
+ (void)ocsd_get_version();
+ return 0;
+}
diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 79b117a03fd7..2d0b99f7b4e7 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -346,6 +346,19 @@ ifeq ($(feature-setns), 1)
$(call detected,CONFIG_SETNS)
endif
+ifeq ($(feature-libopencsd), 1)
+ CFLAGS += -DHAVE_CSTRACE_SUPPORT
+ LIBCSTRACE = -lopencsd_c_api -lopencsd
+ EXTLIBS += $(LIBCSTRACE)
+ $(call detected,CONFIG_LIBOPENCSD)
+ ifdef CSTRACE_RAW
+ CFLAGS += -DCS_DEBUG_RAW
+ ifeq (${CSTRACE_RAW}, packed)
+ CFLAGS += -DCS_RAW_PACKED
+ endif
+ endif
+endif
+
ifndef NO_LIBELF
CFLAGS += -DHAVE_LIBELF_SUPPORT
EXTLIBS += -lelf
--
2.7.4
^ permalink raw reply related
* [PATCH 00/10] perf tools: Add support for CoreSight trace decoding
From: Mathieu Poirier @ 2017-12-15 16:44 UTC (permalink / raw)
To: linux-arm-kernel
This patchset adds support for per-thread CoreSight trace decoding from the
"perf report" interface. It is largely modelled on what has been done for
intelPT traces and currently targets the ETMv4 architecture. Support for
cpu-wide scenarios and ETMv3/PTMv1.1 will follow shortly.
The trace decoding support is done using the Open CoreSight Decoding
Library (openCSD), a stand alone open source project available here [1].
Integration of the openCSD library with the perf tools follow what has
been done for other support libraries. If the library has been installed
on a system the build scripts will include support for CoreSight trace
decoding:
... zlib: [ on ]
... lzma: [ OFF ]
... get_cpuid: [ on ]
... bpf: [ on ]
... libopencsd: [ on ] <------
Instructions on how to build and install the openCSD library are provided
in the HOWTO.md of the project repository. We elected to keep the decoder
library independent of the kernel tree as it is also used outside of the
perf toolset and various non-linux projects.
The work applies cleanly to [2] and proper functionning of the feature
depends on this patch [3].
Review and comments would be greatly appreciated.
Regards,
Mathieu
[1]. https://github.com/Linaro/OpenCSD
[2]. git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git perf/core
[3]. https://lkml.org/lkml/2017/12/14/612
Mathieu Poirier (8):
perf tools: Integrating the CoreSight decoding library
perf tools: Add initial entry point for decoder CoreSight traces
perf tools: Add decoder mechanic to support dumping trace data
perf tools: Add support for decoding CoreSight trace data
perf tools: Add functionality to communicate with the openCSD decoder
pert tools: Add queue management functionality
perf tools: Add full support for CoreSight trace decoding
perf tools: Add mechanic to synthesise CoreSight trace packets
Tor Jeremiassen (2):
perf tools: Add processing of coresight metadata
MAINTAINERS: Adding entry for CoreSight trace decoding
MAINTAINERS | 3 +-
tools/build/Makefile.feature | 6 +-
tools/build/feature/Makefile | 6 +-
tools/build/feature/test-all.c | 5 +
tools/build/feature/test-libopencsd.c | 8 +
tools/perf/Makefile.config | 13 +
tools/perf/util/Build | 6 +
tools/perf/util/auxtrace.c | 2 +
tools/perf/util/cs-etm-decoder/Build | 1 +
tools/perf/util/cs-etm-decoder/cs-etm-decoder.c | 513 ++++++++++++
tools/perf/util/cs-etm-decoder/cs-etm-decoder.h | 105 +++
tools/perf/util/cs-etm.c | 1023 +++++++++++++++++++++++
tools/perf/util/cs-etm.h | 18 +
13 files changed, 1705 insertions(+), 4 deletions(-)
create mode 100644 tools/build/feature/test-libopencsd.c
create mode 100644 tools/perf/util/cs-etm-decoder/Build
create mode 100644 tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
create mode 100644 tools/perf/util/cs-etm-decoder/cs-etm-decoder.h
create mode 100644 tools/perf/util/cs-etm.c
--
2.7.4
^ permalink raw reply
* [PATCH] ARM: dts: am43xx: Fix inverted DS0_PULL_UP_DOWN_EN macro
From: Tony Lindgren @ 2017-12-15 16:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171213212443.22632-1-d-gerlach@ti.com>
* Dave Gerlach <d-gerlach@ti.com> [171213 13:27]:
> Due to a mistake in documentation the DS0_PULL_UP_DOWN_EN macro was
> mistakenly defined as an active high bit, however setting the bit
> actually disables the internal pull resistor on the pin, so correct this
> macro and introduce a new DS0_PULL_UP_DOWN_DIS macro with the proper bit
> value set now that the documentation has been updated.
>
> Change based on AM437x Techninal Reference Manual SPRUHL7G Revised June
> 2017 Section 7.2.1.
Applying into omap-for-v4.16/dt thanks,
Tony
^ permalink raw reply
* [PATCH] ARM: dts: am43xx-epos-evm: Add phandle for the backlight for the panel
From: Tony Lindgren @ 2017-12-15 16:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171215120954.21711-1-peter.ujfalusi@ti.com>
* Peter Ujfalusi <peter.ujfalusi@ti.com> [171215 04:12]:
> With the backlight phandle the driver can manage the backlight on/off in
> sync with the panel enable/disable.
Applying into omap-for-v4.16/dt thanks,
Tony
^ permalink raw reply
* [PATCH] ARM: dts: am437x-sk-evm: Add phandle for the backlight for the panel
From: Tony Lindgren @ 2017-12-15 16:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171215120941.21638-1-peter.ujfalusi@ti.com>
* Peter Ujfalusi <peter.ujfalusi@ti.com> [171215 04:12]:
> With the backlight phandle the driver can manage the backlight on/off in
> sync with the panel enable/disable.
Applying into omap-for-v4.16/dt thanks,
Tony
^ permalink raw reply
* [PATCH] ARM: dts: am437x-gp-evm: Add phandle for the backlight for the panel
From: Tony Lindgren @ 2017-12-15 16:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171215120932.21572-1-peter.ujfalusi@ti.com>
* Peter Ujfalusi <peter.ujfalusi@ti.com> [171215 04:12]:
> With the backlight phandle the driver can manage the backlight on/off in
> sync with the panel enable/disable.
Applying into omap-for-v4.16/dt thanks,
Tony
^ permalink raw reply
* [PATCH 18/25] arm: am3/am4/dra7/omap: dts: Remove leading 0x and 0s from bindings notation
From: Tony Lindgren @ 2017-12-15 16:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171215124651.30793-1-malat@debian.org>
* Mathieu Malaterre <malat@debian.org> [171215 04:49]:
> Improve the DTS files by removing all the leading "0x" and zeros to fix the
> following dtc warnings:
>
> Warning (unit_address_format): Node /XXX unit name should not have leading "0x"
>
> and
>
> Warning (unit_address_format): Node /XXX unit name should not have leading 0s
Thanks applying this patch into omap-for-v4.16/dt.
Regards,
Tony
^ permalink raw reply
* [PATCH v5 7/9] arm64: Topology, rename cluster_id
From: Jeremy Linton @ 2017-12-15 16:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171213180217.GB4060@red-moon>
Hi,
On 12/13/2017 12:02 PM, Lorenzo Pieralisi wrote:
> [+Morten, Dietmar]
>
> $SUBJECT should be:
>
> arm64: topology: rename cluster_id
Sure..
>
> On Fri, Dec 01, 2017 at 04:23:28PM -0600, Jeremy Linton wrote:
>> Lets match the name of the arm64 topology field
>> to the kernel macro that uses it.
>>
>> Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
>> ---
>> arch/arm64/include/asm/topology.h | 4 ++--
>> arch/arm64/kernel/topology.c | 27 ++++++++++++++-------------
>> 2 files changed, 16 insertions(+), 15 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/topology.h b/arch/arm64/include/asm/topology.h
>> index c4f2d50491eb..118136268f66 100644
>> --- a/arch/arm64/include/asm/topology.h
>> +++ b/arch/arm64/include/asm/topology.h
>> @@ -7,14 +7,14 @@
>> struct cpu_topology {
>> int thread_id;
>> int core_id;
>> - int cluster_id;
>> + int physical_id;
>
> package_id ?
Given the macro is topology_physical_package_id, either makes sense to
me. <shrug> I will change it in the next set.
>
> It has been debated before, I know. Should we keep the cluster_id too
> (even if it would be 1:1 mapped to package_id - for now) ?
Well given that this patch replaces the patch that did that at your
request..
I was hoping someone else would comment here, but my take at this point
is that it doesn't really matter in a functional sense at the moment.
Like the chiplet discussion it can be the subject of a future patch
along with the patches which tweak the scheduler to understand the split.
BTW, given that i'm OoO next week, and the following that are the
holidays, I don't intend to repost this for a couple weeks. I don't
think there are any issues with this set.
>
> There is also arch/arm to take into account, again, this patch is
> just renaming (as it should have named since the beginning) a
> topology level but we should consider everything from a legacy
> perspective.
>
> Lorenzo
>
>> cpumask_t thread_sibling;
>> cpumask_t core_sibling;
>> };
>>
>> extern struct cpu_topology cpu_topology[NR_CPUS];
>>
>> -#define topology_physical_package_id(cpu) (cpu_topology[cpu].cluster_id)
>> +#define topology_physical_package_id(cpu) (cpu_topology[cpu].physical_id)
>> #define topology_core_id(cpu) (cpu_topology[cpu].core_id)
>> #define topology_core_cpumask(cpu) (&cpu_topology[cpu].core_sibling)
>> #define topology_sibling_cpumask(cpu) (&cpu_topology[cpu].thread_sibling)
>> diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c
>> index 8d48b233e6ce..74a8a5173a35 100644
>> --- a/arch/arm64/kernel/topology.c
>> +++ b/arch/arm64/kernel/topology.c
>> @@ -51,7 +51,7 @@ static int __init get_cpu_for_node(struct device_node *node)
>> return -1;
>> }
>>
>> -static int __init parse_core(struct device_node *core, int cluster_id,
>> +static int __init parse_core(struct device_node *core, int physical_id,
>> int core_id)
>> {
>> char name[10];
>> @@ -67,7 +67,7 @@ static int __init parse_core(struct device_node *core, int cluster_id,
>> leaf = false;
>> cpu = get_cpu_for_node(t);
>> if (cpu >= 0) {
>> - cpu_topology[cpu].cluster_id = cluster_id;
>> + cpu_topology[cpu].physical_id = physical_id;
>> cpu_topology[cpu].core_id = core_id;
>> cpu_topology[cpu].thread_id = i;
>> } else {
>> @@ -89,7 +89,7 @@ static int __init parse_core(struct device_node *core, int cluster_id,
>> return -EINVAL;
>> }
>>
>> - cpu_topology[cpu].cluster_id = cluster_id;
>> + cpu_topology[cpu].physical_id = physical_id;
>> cpu_topology[cpu].core_id = core_id;
>> } else if (leaf) {
>> pr_err("%pOF: Can't get CPU for leaf core\n", core);
>> @@ -105,7 +105,7 @@ static int __init parse_cluster(struct device_node *cluster, int depth)
>> bool leaf = true;
>> bool has_cores = false;
>> struct device_node *c;
>> - static int cluster_id __initdata;
>> + static int physical_id __initdata;
>> int core_id = 0;
>> int i, ret;
>>
>> @@ -144,7 +144,7 @@ static int __init parse_cluster(struct device_node *cluster, int depth)
>> }
>>
>> if (leaf) {
>> - ret = parse_core(c, cluster_id, core_id++);
>> + ret = parse_core(c, physical_id, core_id++);
>> } else {
>> pr_err("%pOF: Non-leaf cluster with core %s\n",
>> cluster, name);
>> @@ -162,7 +162,7 @@ static int __init parse_cluster(struct device_node *cluster, int depth)
>> pr_warn("%pOF: empty cluster\n", cluster);
>>
>> if (leaf)
>> - cluster_id++;
>> + physical_id++;
>>
>> return 0;
>> }
>> @@ -198,7 +198,7 @@ static int __init parse_dt_topology(void)
>> * only mark cores described in the DT as possible.
>> */
>> for_each_possible_cpu(cpu)
>> - if (cpu_topology[cpu].cluster_id == -1)
>> + if (cpu_topology[cpu].physical_id == -1)
>> ret = -EINVAL;
>>
>> out_map:
>> @@ -228,7 +228,7 @@ static void update_siblings_masks(unsigned int cpuid)
>> for_each_possible_cpu(cpu) {
>> cpu_topo = &cpu_topology[cpu];
>>
>> - if (cpuid_topo->cluster_id != cpu_topo->cluster_id)
>> + if (cpuid_topo->physical_id != cpu_topo->physical_id)
>> continue;
>>
>> cpumask_set_cpu(cpuid, &cpu_topo->core_sibling);
>> @@ -249,7 +249,7 @@ void store_cpu_topology(unsigned int cpuid)
>> struct cpu_topology *cpuid_topo = &cpu_topology[cpuid];
>> u64 mpidr;
>>
>> - if (cpuid_topo->cluster_id != -1)
>> + if (cpuid_topo->physical_id != -1)
>> goto topology_populated;
>>
>> mpidr = read_cpuid_mpidr();
>> @@ -263,19 +263,19 @@ void store_cpu_topology(unsigned int cpuid)
>> /* Multiprocessor system : Multi-threads per core */
>> cpuid_topo->thread_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
>> cpuid_topo->core_id = MPIDR_AFFINITY_LEVEL(mpidr, 1);
>> - cpuid_topo->cluster_id = MPIDR_AFFINITY_LEVEL(mpidr, 2) |
>> + cpuid_topo->physical_id = MPIDR_AFFINITY_LEVEL(mpidr, 2) |
>> MPIDR_AFFINITY_LEVEL(mpidr, 3) << 8;
>> } else {
>> /* Multiprocessor system : Single-thread per core */
>> cpuid_topo->thread_id = -1;
>> cpuid_topo->core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
>> - cpuid_topo->cluster_id = MPIDR_AFFINITY_LEVEL(mpidr, 1) |
>> + cpuid_topo->physical_id = MPIDR_AFFINITY_LEVEL(mpidr, 1) |
>> MPIDR_AFFINITY_LEVEL(mpidr, 2) << 8 |
>> MPIDR_AFFINITY_LEVEL(mpidr, 3) << 16;
>> }
>>
>> pr_debug("CPU%u: cluster %d core %d thread %d mpidr %#016llx\n",
>> - cpuid, cpuid_topo->cluster_id, cpuid_topo->core_id,
>> + cpuid, cpuid_topo->physical_id, cpuid_topo->core_id,
>> cpuid_topo->thread_id, mpidr);
>>
>> topology_populated:
>> @@ -291,7 +291,7 @@ static void __init reset_cpu_topology(void)
>>
>> cpu_topo->thread_id = -1;
>> cpu_topo->core_id = 0;
>> - cpu_topo->cluster_id = -1;
>> + cpu_topo->physical_id = -1;
>>
>> cpumask_clear(&cpu_topo->core_sibling);
>> cpumask_set_cpu(cpu, &cpu_topo->core_sibling);
>> @@ -300,6 +300,7 @@ static void __init reset_cpu_topology(void)
>> }
>> }
>>
>> +
>> void __init init_cpu_topology(void)
>> {
>> reset_cpu_topology();
>> --
>> 2.13.5
>>
^ permalink raw reply
* [PATCH 04/14] ARM: dts: dra76x: Create a common file with MMC/SD IOdelay data
From: Tony Lindgren @ 2017-12-15 16:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <be4d8cfd-bdd3-aedf-9d9c-156de39d2621@ti.com>
* Kishon Vijay Abraham I <kishon@ti.com> [171215 06:12]:
> Hi Tony,
>
> On Thursday 14 December 2017 08:45 PM, Tony Lindgren wrote:
> > * Kishon Vijay Abraham I <kishon@ti.com> [171214 13:44]:
> >> +&dra7_pmx_core {
> >> + mmc1_pins_default: mmc1_pins_default {
> >> + pinctrl-single,pins = <
> >> + DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_clk.clk */
> >> + DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_cmd.cmd */
> >> + DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat0.dat0 */
> >> + DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat1.dat1 */
> >> + DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat2.dat2 */
> >> + DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat3.dat3 */
> >> + >;
> >> + };
> >> +
> >> + mmc1_pins_sdr12: mmc1_pins_sdr12 {
> >> + pinctrl-single,pins = <
> >> + DRA7XX_CORE_IOPAD(0x3754, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_clk.clk */
> >> + DRA7XX_CORE_IOPAD(0x3758, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_cmd.cmd */
> >> + DRA7XX_CORE_IOPAD(0x375c, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat0.dat0 */
> >> + DRA7XX_CORE_IOPAD(0x3760, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat1.dat1 */
> >> + DRA7XX_CORE_IOPAD(0x3764, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat2.dat2 */
> >> + DRA7XX_CORE_IOPAD(0x3768, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat3.dat3 */
> >> + >;
> >> + };
> >
> > Can't you just do:
> >
> > pinctrl-0 = <&mmc1_pins_default>;
> > pinctrl-1 = <&mmc1_pins_default>;
> > pinctrl-2 = <&mmc1_pins_hs>;
> > pinctrl-names = "default", "sdr12", "sdr25";
>
> just wanted to make sure every mode has it's own pinctrl group so that it's
> easy to review. Initially we were thinking something like
> mmc1_pins_default_sdr12_sdr25.
OK that naming works fine for me.
> But if you'd prefer we just use mmc1_pins_default for all modes that uses
> default pinmux configuration, I can change it that way too.
No up to you with the naming thanks.
Regards,
Tony
^ permalink raw reply
* [PATCH v2 0/4] PM / OPP: Introduce ti-opp-supply driver
From: Tony Lindgren @ 2017-12-15 16:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171215042528.28715-1-d-gerlach@ti.com>
* Dave Gerlach <d-gerlach@ti.com> [171215 04:28]:
> Hi,
> This is v2 of the series to introduce the ti-opp-supply driver which makes
> use of the OPP core to enable multiple regulator DVFS and AVS Class0 for
> TI DRA7 and AM57 platforms. Version 1 of this series can be found here [1].
Good to see this :) For the whole series:
Acked-by: Tony Lindgren <tony@atomide.com>
^ permalink raw reply
* [PATCH v2 26/36] KVM: arm64: Defer saving/restoring system registers to vcpu load/put on VHE
From: Christoffer Dall @ 2017-12-15 16:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <c45eaebe-57a1-7737-c515-111d497dd06e@arm.com>
On Mon, Dec 11, 2017 at 01:20:03PM +0000, Marc Zyngier wrote:
> On 07/12/17 17:06, Christoffer Dall wrote:
> > Some system registers do not affect the host kernel's execution and can
> > therefore be loaded when we are about to run a VCPU and we don't have to
> > restore the host state to the hardware before the time when we are
> > actually about to return to userspace or schedule out the VCPU thread.
> >
> > The EL1 system registers and the userspace state registers, which only
> > affect EL0 execution, do not affect the host kernel's execution.
> >
> > The 32-bit system registers are not used by a VHE host kernel and
> > therefore don't need to be saved/restored on every entry/exit to/from
> > the guest, but can be deferred to vcpu_load and vcpu_put, respectively.
>
> Note that they are not used by the !VHE host kernel either, and I
> believe they could be deferred too, although that would imply a round
> trip to HYP to save/restore them. We already have such a hook there when
> configuring ICH_VMCR_EL2, so we may not need much of a new infrastructure.
>
This turned out to be a bit trickier than I initial thought, and I think
it also revealed a bug around running 32-bit guests on VHE systems,
related to how DBGVCR32_EL2 is currently handled.
The result will look something like this (depending a bit on the rework
for the system register accesses discussed in the earlier patch):
diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index 0488841c6341..de98b99b1eec 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -92,13 +92,18 @@ static inline bool vcpu_mode_is_32bit(const struct kvm_vcpu *vcpu)
static inline void vcpu_set_spsr(struct kvm_vcpu *vcpu, u64 val)
{
if (vcpu_mode_is_32bit(vcpu)) {
- if (vcpu->arch.sysregs_loaded_on_cpu)
- __sysreg32_save_state(vcpu);
+ bool loaded;
+
+ preempt_disable();
+ loaded = vcpu->arch.sysregs32_loaded_on_cpu;
+ if (loaded)
+ kvm_call_hyp(__sysreg32_save_state, vcpu);
*vcpu_spsr32(vcpu) = val;
- if (vcpu->arch.sysregs_loaded_on_cpu)
- __sysreg32_restore_state(vcpu);
+ if (loaded)
+ kvm_call_hyp(__sysreg32_restore_state, vcpu);
+ preempt_enable();
}
if (vcpu->arch.sysregs_loaded_on_cpu)
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 992c19816893..bc116d6c8756 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -283,6 +283,7 @@ struct kvm_vcpu_arch {
/* True when deferrable sysregs are loaded on the physical CPU,
* see kvm_vcpu_load_sysregs and kvm_vcpu_put_sysregs. */
bool sysregs_loaded_on_cpu;
+ bool sysregs32_loaded_on_cpu;
};
#define vcpu_gp_regs(v) (&(v)->arch.ctxt.gp_regs)
diff --git a/arch/arm64/kvm/hyp/debug-sr.c b/arch/arm64/kvm/hyp/debug-sr.c
index ee87115eb12f..d80037b655b4 100644
--- a/arch/arm64/kvm/hyp/debug-sr.c
+++ b/arch/arm64/kvm/hyp/debug-sr.c
@@ -20,6 +20,7 @@
#include <asm/debug-monitors.h>
#include <asm/kvm_asm.h>
+#include <asm/kvm_emulate.h>
#include <asm/kvm_hyp.h>
#define read_debug(r,n) read_sysreg(r##n##_el1)
@@ -169,6 +170,9 @@ void __hyp_text __debug_switch_to_guest(struct kvm_vcpu *vcpu)
__debug_save_state(vcpu, host_dbg, host_ctxt);
__debug_restore_state(vcpu, guest_dbg, guest_ctxt);
+
+ if (vcpu_el1_is_32bit(vcpu))
+ write_sysreg(vcpu->arch.ctxt.sys_regs[DBGVCR32_EL2], dbgvcr32_el2);
}
void __hyp_text __debug_switch_to_host(struct kvm_vcpu *vcpu)
@@ -192,6 +196,9 @@ void __hyp_text __debug_switch_to_host(struct kvm_vcpu *vcpu)
__debug_save_state(vcpu, guest_dbg, guest_ctxt);
__debug_restore_state(vcpu, host_dbg, host_ctxt);
+ if (vcpu_el1_is_32bit(vcpu))
+ vcpu->arch.ctxt.sys_regs[DBGVCR32_EL2] = read_sysreg(dbgvcr32_el2);
+
vcpu->arch.debug_flags &= ~KVM_ARM64_DEBUG_DIRTY;
}
diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
index 05f266b505ce..48dc2c0b10d0 100644
--- a/arch/arm64/kvm/hyp/switch.c
+++ b/arch/arm64/kvm/hyp/switch.c
@@ -402,7 +402,6 @@ int __hyp_text __kvm_vcpu_run_nvhe(struct kvm_vcpu *vcpu)
* We must restore the 32-bit state before the sysregs, thanks
* to erratum #852523 (Cortex-A57) or #853709 (Cortex-A72).
*/
- __sysreg32_restore_state(vcpu);
__sysreg_restore_state_nvhe(guest_ctxt);
__debug_switch_to_guest(vcpu);
@@ -414,7 +413,6 @@ int __hyp_text __kvm_vcpu_run_nvhe(struct kvm_vcpu *vcpu)
} while (fixup_guest_exit(vcpu, &exit_code));
__sysreg_save_state_nvhe(guest_ctxt);
- __sysreg32_save_state(vcpu);
__timer_disable_traps(vcpu);
__vgic_save_state(vcpu);
diff --git a/arch/arm64/kvm/hyp/sysreg-sr.c b/arch/arm64/kvm/hyp/sysreg-sr.c
index 3c62c1c14b22..42eb0cc68079 100644
--- a/arch/arm64/kvm/hyp/sysreg-sr.c
+++ b/arch/arm64/kvm/hyp/sysreg-sr.c
@@ -181,7 +181,9 @@ void __hyp_text __sysreg32_save_state(struct kvm_vcpu *vcpu)
{
u64 *spsr, *sysreg;
- if (!vcpu_el1_is_32bit(vcpu))
+ vcpu = kern_hyp_va(vcpu);
+
+ if (!vcpu_el1_is_32bit(vcpu) || !vcpu->arch.sysregs32_loaded_on_cpu)
return;
spsr = vcpu->arch.ctxt.gp_regs.spsr;
@@ -195,15 +197,18 @@ void __hyp_text __sysreg32_save_state(struct kvm_vcpu *vcpu)
sysreg[DACR32_EL2] = read_sysreg(dacr32_el2);
sysreg[IFSR32_EL2] = read_sysreg(ifsr32_el2);
- if (vcpu->arch.debug_flags & KVM_ARM64_DEBUG_DIRTY)
- sysreg[DBGVCR32_EL2] = read_sysreg(dbgvcr32_el2);
+ sysreg[DBGVCR32_EL2] = read_sysreg(dbgvcr32_el2);
+
+ vcpu->arch.sysregs32_loaded_on_cpu = false;
}
void __hyp_text __sysreg32_restore_state(struct kvm_vcpu *vcpu)
{
u64 *spsr, *sysreg;
- if (!vcpu_el1_is_32bit(vcpu))
+ vcpu = kern_hyp_va(vcpu);
+
+ if (!vcpu_el1_is_32bit(vcpu) || vcpu->arch.sysregs32_loaded_on_cpu)
return;
spsr = vcpu->arch.ctxt.gp_regs.spsr;
@@ -217,8 +222,9 @@ void __hyp_text __sysreg32_restore_state(struct kvm_vcpu *vcpu)
write_sysreg(sysreg[DACR32_EL2], dacr32_el2);
write_sysreg(sysreg[IFSR32_EL2], ifsr32_el2);
- if (vcpu->arch.debug_flags & KVM_ARM64_DEBUG_DIRTY)
- write_sysreg(sysreg[DBGVCR32_EL2], dbgvcr32_el2);
+ write_sysreg(sysreg[DBGVCR32_EL2], dbgvcr32_el2);
+
+ vcpu->arch.sysregs32_loaded_on_cpu = true;
}
/**
@@ -237,19 +243,19 @@ void kvm_vcpu_load_sysregs(struct kvm_vcpu *vcpu)
struct kvm_cpu_context *host_ctxt = vcpu->arch.host_cpu_context;
struct kvm_cpu_context *guest_ctxt = &vcpu->arch.ctxt;
+ /*
+ * Erratum #852523 (Cortex-A57) or #853709 (Cortex-A72) requires us to
+ * restore the 32-bit state before the sysregs, which will happen on
+ * both VHE (below) and on non-VHE in the world-switch path.
+ */
+ kvm_call_hyp(__sysreg32_restore_state, vcpu);
+
if (!has_vhe())
return;
__sysreg_save_user_state(host_ctxt);
-
- /*
- * Load guest EL1 and user state
- *
- * We must restore the 32-bit state before the sysregs, thanks
- * to erratum #852523 (Cortex-A57) or #853709 (Cortex-A72).
- */
- __sysreg32_restore_state(vcpu);
+ /* Load guest EL1 and user state */
__sysreg_restore_user_state(guest_ctxt);
__sysreg_restore_el1_state(guest_ctxt);
@@ -283,12 +289,13 @@ void kvm_vcpu_put_sysregs(struct kvm_vcpu *vcpu)
vcpu->arch.guest_vfp_loaded = 0;
}
+ kvm_call_hyp(__sysreg32_save_state, vcpu);
+
if (!has_vhe())
return;
__sysreg_save_el1_state(guest_ctxt);
__sysreg_save_user_state(guest_ctxt);
- __sysreg32_save_state(vcpu);
/* Restore host user state */
__sysreg_restore_user_state(host_ctxt);
For now, I'll stash this as a separate patch as it will improve
readability and make it easier to bisect things.
Thanks,
-Christoffer
^ permalink raw reply related
* [PATCH 0/2] Use SPDX-License-Identifier for rockchip devicetree files
From: klaus.goger at theobroma-systems.com @ 2017-12-15 16:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <63058496.Aj9cacRib9@diego>
> On 15.12.2017, at 16:20, Heiko St?bner <heiko@sntech.de> wrote:
>
> Am Freitag, 15. Dezember 2017, 15:42:48 CET schrieb Philippe Ombredanne:
>> On Fri, Dec 15, 2017 at 3:28 PM, Heiko St?bner <heiko@sntech.de> wrote:
>>> Am Freitag, 15. Dezember 2017, 14:45:34 CET schrieb Philippe Ombredanne:
>>>> Klaus,
>>>>
>>>> On Fri, Dec 15, 2017 at 12:44 PM, Klaus Goger
>>>>
>>>> <klaus.goger@theobroma-systems.com> wrote:
>>>>> This patch series replaces all the license text in rockchip devicetree
>>>>> files text with a proper SPDX-License-Identifier.
>>>>> It follows the guidelines submitted[1] by Thomas Gleixner that are not
>>>>> yet merged.
>>>>>
>>>>> These series also fixes the issue with contradicting statements in most
>>>>> licenses. The introduction text claims to be GPL or X11[2] but the
>>>>> following verbatim copy of the license is actually a MIT[3] license.
>>>>> The X11 license includes a advertise clause and trademark information
>>>>> related to the X Consortium. As these X Consortium specfic points are
>>>>> irrelevant for us we stick with the actuall license text.
>>>>>
>>>>> [1] https://patchwork.kernel.org/patch/10091607/
>>>>> [2] https://spdx.org/licenses/X11.html
>>>>> [3] https://spdx.org/licenses/MIT.html
>>>>
>>>> FWIW, the X11 license name was not always something clearly defined.
>>>> SPDX calls it clearly MIT which is the most widely accepted name for
>>>> the corresponding text. And this is also what we have in Thomas doc
>>>> patches that should be the kernel reference.
>>>>
>>>> Also, as a general note, you want to make sure that such as patch set
>>>> is not merged by mistake until you have collected an explicit review
>>>> or ack from all the copyright holders involved.
>>>
>>> Just for my understanding, is it really necessary to get Acks from _all_
>>> previous contributors?
>>>
>>> I see that Thomas patches moving license texts into the kernel itself do
>>> not seem to have landed yet, but when the actual license text does _not_
>>> change and only its location to a common place inside the kernel sources,
>>> it feels a bit overkill trying to get Acks from _everybody_ that
>>> contributed to Rockchip devicetrees for the last 4 years.
>>>
>>> If we would actually want to change the license I would definitly feel
>>> differently, but the license text does not change.
>>
>> Well you are technically right. But there is a social and politeness
>> angle to this too. So may be getting the ack of all contributors is
>> not always needed, but getting it is best and the right to do and at
>> least getting for the named copyright holders should be there.
>>
>> That's only only my take: leaving aside any technical legal issue, say
>> I would be on the receiving end as one of the holder or contributors:
>> I would find it really great and nice to have my ack requested. And I
>> would be a dork not to give it. So I like to do to others the same I
>> would appreciate done to me (within reason, as I sometimes shoot
>> myself in the foot ;) )
>
> Hehe ... I didn't plan on merging this without ample time for people
> to either ACK or NAK the change, so was planning on keeping to social
> protocol ;-) . Just the "all" threw me for a loop.
>
> And having that as PATCH without RFC also communicates that people
> should take a look, as RFC patches are often overlooked.
>
> As Klaus seems to have included most people that have contributed in the
> past, I would guess we should receive any existing complaints about that
> change :-) .
I added the full list from the get_maintainers script. Some of the original authors
got dropped as the current contribution level dropped below the scripts limit.
I added the missing email addresses from the copyright headers to the CC list.
Convenience links to the original patches for the added people:
https://patchwork.kernel.org/patch/10114845/
https://patchwork.kernel.org/patch/10114843/
> So I'll definitly let this simmer for quite a bit and do a best-effort Ack
> collection.
Thanks,
Klaus
^ permalink raw reply
* [PATCH v5 01/13] arm64: cpufeature: __this_cpu_has_cap() shouldn't stop early
From: Suzuki K Poulose @ 2017-12-15 16:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171215155101.23505-2-james.morse@arm.com>
On 15/12/17 15:50, James Morse wrote:
> this_cpu_has_cap() tests caps->desc not caps->matches, so it stops
> walking the list when it finds a 'silent' feature, instead of
> walking to the end of the list.
>
> Prior to v4.6's 644c2ae198412 ("arm64: cpufeature: Test 'matches' pointer
> to find the end of the list") we always tested desc to find the end of
> a capability list. This was changed for dubious things like PAN_NOT_UAO.
> v4.7's e3661b128e53e ("arm64: Allow a capability to be checked on
> single CPU") added this_cpu_has_cap() using the old desc style test.
>
> CC: Suzuki K Poulose <suzuki.poulose@arm.com>
> CC: Marc Zyngier <marc.zyngier@arm.com>
> Signed-off-by: James Morse <james.morse@arm.com>
> ---
> So far only ARM64_HAS_SYSREG_GIC_CPUIF and errata use this_cpu_has_cap(),
> all the errata have descriptions, and the GIC_CPUIF feature is first in
> the list, so its not possible to hit this with mainline. I don't think
> this should go to stable - this is not intended as a fix.
>
> arch/arm64/kernel/cpufeature.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> index c5ba0097887f..68a49f7fb75c 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -1236,8 +1236,8 @@ static bool __this_cpu_has_cap(const struct arm64_cpu_capabilities *cap_array,
> if (WARN_ON(preemptible()))
> return false;
>
> - for (caps = cap_array; caps->desc; caps++)
> - if (caps->capability == cap && caps->matches)
> + for (caps = cap_array; caps->matches; caps++)
> + if (caps->capability == cap)
> return caps->matches(caps, SCOPE_LOCAL_CPU);
Thanks for catching this !
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
^ permalink raw reply
* arm64: unhandled level 0 translation fault
From: Will Deacon @ 2017-12-15 16:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAMuHMdUaVUrqPUxHkt-FaYkHn9XQzOP3_1YJ+xFHj7id0cMoUA@mail.gmail.com>
On Fri, Dec 15, 2017 at 04:59:28PM +0100, Geert Uytterhoeven wrote:
> On Fri, Dec 15, 2017 at 3:27 PM, Will Deacon <will.deacon@arm.com> wrote:
> > On Fri, Dec 15, 2017 at 02:30:00PM +0100, Geert Uytterhoeven wrote:
> >> On Fri, Dec 15, 2017 at 12:23 PM, Dave Martin <Dave.Martin@arm.com> wrote:
> >> > The two important differences here seem to be
> >> >
> >> > 1) Staging the state via current->thread.fpsimd_state instead of loading
> >> > directly:
> >> >
> >> > - fpsimd_load_state(state);
> >> > + current->thread.fpsimd_state = *state;
> >> > + fpsimd_load_state(¤t->thread.fpsimd_state);
> >>
> >> The change above introduces the breakage.
> >
> > I finally managed to reproduce this, but only by using the exact same
> > compiler as Geert:
> >
> > https://www.kernel.org/pub/tools/crosstool/files/bin/x86_64/4.9.0/x86_64-gcc-4.9.0-nolibc_aarch64-linux.tar.xz
> >
> > I then reliably see the problem if I run:
> >
> > # /usr/bin/update-ca-certificates
>
> /usr/sbin/... ?
>
> > from Debian Jessie.
>
> Funny, I've just got both
>
> *** Error in `/bin/sh': free(): invalid pointer: 0x0000aaaac17d4988 ***
>
> and
>
> mountall.sh[2172]: unhandled level 0 translation fault (11) at
> 0x0000004d, esr 0x92000004, in dash[aaaace7e5000+1a000]
>
> during boot up, but I can't get update-ca-certificates to fail...
Can you try the diff below, please?
Will
--->8
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 540a1e010eb5..fae81f7964b4 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -1043,7 +1043,7 @@ void fpsimd_update_current_state(struct fpsimd_state *state)
local_bh_disable();
- current->thread.fpsimd_state = *state;
+ current->thread.fpsimd_state.user_fpsimd = state->user_fpsimd;
if (system_supports_sve() && test_thread_flag(TIF_SVE))
fpsimd_to_sve(current);
^ permalink raw reply related
* [PATCH] arm64: rockchip: enable Rockchip IO domain support
From: klaus.goger at theobroma-systems.com @ 2017-12-15 16:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <8456682.qhFfChmmK7@diego>
> On 15.12.2017, at 16:55, Heiko St?bner <heiko@sntech.de> wrote:
>
> Am Freitag, 15. Dezember 2017, 16:51:39 CET schrieb klaus.goger at theobroma-
> systems.com:
>>> On 15.12.2017, at 16:33, Heiko St?bner <heiko@sntech.de> wrote:
>>>
>>> Am Freitag, 15. Dezember 2017, 13:20:10 CET schrieb Klaus Goger:
>>>> Make sure the IO domain support is active. This requires to enable
>>>> Adaptive Voltage Scaling class support too.
>>>>
>>>> Without Rockchip IO domain support the internal level shifter on the
>>>> RK3399
>>>> will be misconfigured if used in the other voltage domain then the
>>>> default.
>>>>
>>>> Signed-off-by: Klaus Goger <klaus.goger@theobroma-systems.com>
>>>>
>>>> ---
>>>>
>>>> arch/arm64/Kconfig.platforms | 2 ++
>>>> 1 file changed, 2 insertions(+)
>>>>
>>>> diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
>>>> index 2401373565ff..7c0b0ab12f18 100644
>>>> --- a/arch/arm64/Kconfig.platforms
>>>> +++ b/arch/arm64/Kconfig.platforms
>>>> @@ -150,6 +150,8 @@ config ARCH_ROCKCHIP
>>>>
>>>> select GPIOLIB
>>>> select PINCTRL
>>>> select PINCTRL_ROCKCHIP
>>>>
>>>> + select POWER_AVS
>>>> + select ROCKCHIP_IODOMAIN
>>>
>>> I'm not sure if we really want this in the default arch Kconfig or if
>>> there
>>> are cases where the iodomain driver is not necessary.
>>>
>>> On arm32 it just gets selected in the regular defconfig [0]
>>
>> At least all currently supported 64bit Rockchip SoCs do have matching VSEL
>> GRF settings. For me it looked essential enough to enable for all as not
>> setting the correct I/O voltage will result in no output signal at all.
>> But I?m fine with a defconfig change if that?s the way to go.
>> Should I resend a patch or wait for other opinions?
>
> Personally I would go with a defconfig change. I'd really like to keep the
> kconfig stuff minimal and at least all arm64 Rockchip boards can at least
> boot without the iodomain driver.
As the gpio driver currently does not depend on iodomain bootup would be an issue
anyway. That's why we currently have to configure boot essential pins that are effected
in U-Boot anyway. So let us drop this patch and I will resend a defconfig one.
Thanks,
Klaus
^ permalink raw reply
* arm64: unhandled level 0 translation fault
From: Geert Uytterhoeven @ 2017-12-15 15:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171215142732.GL25650@arm.com>
Hi Will,
On Fri, Dec 15, 2017 at 3:27 PM, Will Deacon <will.deacon@arm.com> wrote:
> On Fri, Dec 15, 2017 at 02:30:00PM +0100, Geert Uytterhoeven wrote:
>> On Fri, Dec 15, 2017 at 12:23 PM, Dave Martin <Dave.Martin@arm.com> wrote:
>> > The two important differences here seem to be
>> >
>> > 1) Staging the state via current->thread.fpsimd_state instead of loading
>> > directly:
>> >
>> > - fpsimd_load_state(state);
>> > + current->thread.fpsimd_state = *state;
>> > + fpsimd_load_state(¤t->thread.fpsimd_state);
>>
>> The change above introduces the breakage.
>
> I finally managed to reproduce this, but only by using the exact same
> compiler as Geert:
>
> https://www.kernel.org/pub/tools/crosstool/files/bin/x86_64/4.9.0/x86_64-gcc-4.9.0-nolibc_aarch64-linux.tar.xz
>
> I then reliably see the problem if I run:
>
> # /usr/bin/update-ca-certificates
/usr/sbin/... ?
> from Debian Jessie.
Funny, I've just got both
*** Error in `/bin/sh': free(): invalid pointer: 0x0000aaaac17d4988 ***
and
mountall.sh[2172]: unhandled level 0 translation fault (11) at
0x0000004d, esr 0x92000004, in dash[aaaace7e5000+1a000]
during boot up, but I can't get update-ca-certificates to fail...
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* arm64: unhandled level 0 translation fault
From: Geert Uytterhoeven @ 2017-12-15 15:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171215142732.GL25650@arm.com>
On Fri, Dec 15, 2017 at 3:27 PM, Will Deacon <will.deacon@arm.com> wrote:
> On Fri, Dec 15, 2017 at 02:30:00PM +0100, Geert Uytterhoeven wrote:
>> On Fri, Dec 15, 2017 at 12:23 PM, Dave Martin <Dave.Martin@arm.com> wrote:
>> > The two important differences here seem to be
>> >
>> > 1) Staging the state via current->thread.fpsimd_state instead of loading
>> > directly:
>> >
>> > - fpsimd_load_state(state);
>> > + current->thread.fpsimd_state = *state;
>> > + fpsimd_load_state(¤t->thread.fpsimd_state);
>>
>> The change above introduces the breakage.
>
> I finally managed to reproduce this, but only by using the exact same
> compiler as Geert:
>
> https://www.kernel.org/pub/tools/crosstool/files/bin/x86_64/4.9.0/x86_64-gcc-4.9.0-nolibc_aarch64-linux.tar.xz
>
> I then reliably see the problem if I run:
>
> # /usr/bin/update-ca-certificates
>
> from Debian Jessie.
>
> Note that my normal toolchain (Linaro 7.1.1 build) works fine and also
> if I use the toolchain above but disable CONFIG_ARM64_CRYPTO then things
> work too.
>
> So there's some toolchain-specific interaction between this change and the
> crypto code...
>
> Will
--
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* [PATCH] arm64: rockchip: enable Rockchip IO domain support
From: Heiko Stübner @ 2017-12-15 15:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <DB44D3E4-2CB5-452E-BE79-982225CB9E8F@theobroma-systems.com>
Am Freitag, 15. Dezember 2017, 16:51:39 CET schrieb klaus.goger at theobroma-
systems.com:
> > On 15.12.2017, at 16:33, Heiko St?bner <heiko@sntech.de> wrote:
> >
> > Am Freitag, 15. Dezember 2017, 13:20:10 CET schrieb Klaus Goger:
> >> Make sure the IO domain support is active. This requires to enable
> >> Adaptive Voltage Scaling class support too.
> >>
> >> Without Rockchip IO domain support the internal level shifter on the
> >> RK3399
> >> will be misconfigured if used in the other voltage domain then the
> >> default.
> >>
> >> Signed-off-by: Klaus Goger <klaus.goger@theobroma-systems.com>
> >>
> >> ---
> >>
> >> arch/arm64/Kconfig.platforms | 2 ++
> >> 1 file changed, 2 insertions(+)
> >>
> >> diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
> >> index 2401373565ff..7c0b0ab12f18 100644
> >> --- a/arch/arm64/Kconfig.platforms
> >> +++ b/arch/arm64/Kconfig.platforms
> >> @@ -150,6 +150,8 @@ config ARCH_ROCKCHIP
> >>
> >> select GPIOLIB
> >> select PINCTRL
> >> select PINCTRL_ROCKCHIP
> >>
> >> + select POWER_AVS
> >> + select ROCKCHIP_IODOMAIN
> >
> > I'm not sure if we really want this in the default arch Kconfig or if
> > there
> > are cases where the iodomain driver is not necessary.
> >
> > On arm32 it just gets selected in the regular defconfig [0]
>
> At least all currently supported 64bit Rockchip SoCs do have matching VSEL
> GRF settings. For me it looked essential enough to enable for all as not
> setting the correct I/O voltage will result in no output signal at all.
> But I?m fine with a defconfig change if that?s the way to go.
> Should I resend a patch or wait for other opinions?
Personally I would go with a defconfig change. I'd really like to keep the
kconfig stuff minimal and at least all arm64 Rockchip boards can at least
boot without the iodomain driver.
Heiko
^ permalink raw reply
* [PATCH 0/4 v5] Support bridge timings
From: Daniel Vetter @ 2017-12-15 15:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CACRpkdYjSy5t_73g1UejxcL1JXcFUVntA_oDHV2G4ro4zaHNVw@mail.gmail.com>
On Fri, Dec 15, 2017 at 01:30:24PM +0100, Linus Walleij wrote:
> On Fri, Dec 15, 2017 at 1:10 PM, Linus Walleij <linus.walleij@linaro.org> wrote:
>
> > - The connector is apparently not the right abstraction to carry
> > the detailed timings specification between DRI drivers and bridge
> > drivers.
> >
> > - Instead put detailed timing data into the bridge itself as an
> > optional information pointer.
>
> Notice that this is just my fumbling attempts to deal with the situation.
>
> Laurent made me understand what the actual technical problem was,
> how come my pixels were flickering.
>
> Both Laurent and DVetter mentioned that we may need to convey
> information between the bridge and the display engine in some
> way.
>
> Alternatively I could go and hack on adding this to e.g. drm_display_info
> which was used in the previous patch sets by setting the negede flag
> in bus_formats.
>
> I don't know. struct drm_display_info is getting a bit heavy as
> container of misc settings related to "some kind of display".
> The bridge isn't even a display itself, that is on the other side
> of it. So using the connector and treating a bridge as "some kind
> of display" seems wrong too.
>
> Is there a third way?
If you don't plan to nest bridges too deeply, there is. Atm we have 2
modes in drm_crtc_state:
- mode, which is what userspace requested, and what it expects logically
to be the actual real thing. I.e. timing, resolution and all that that
userspace can observe (through plane positioning and vblank timestamps)
should match this mode. For external screens this should also match
what's physically going over the cable.
- adjusted_mode, which is something entirely undefined and to be used by
drivers internally. Most drivers use it as the thing that's actually
transported between the CRTC and the encoder.
There's a few common reasons for adjusted mode to be different:
- integrated panel, and your CRTC has a scaler. In that case the
userspace-requested mode is what you feed into into the scaler, and the
adjusted mode is what comes out of your scaler and then goes down the
wire to the panel.
- your encoder is funky, and e.g. transcodes to the output mode itself,
but expects that you program the input mode always the same. Usual
reasons for this are transcoders that always want non-interlaced mode
(and do the interlacing themselves), if the transcoder has some scaler
itself (some TV-out transcoders had that), or if it has a strict
expectation about signalling edges and stuff (and then transcodes the
signal again). DACs are common doing that.
Anyway, sounds like your bridge is of the 2nd kind, so all you have to do
is
- in your bridge->mode_fixup function, adjust the adjusted_mode as needed
- in your pl111 driver, program the adjusted mode, not the originally
requested mode
adjusted mode is set to be a copy of the requested mode by atomic helpers,
so this should keep working as-is on any other bridge driver.
No idea why I didn't tell you this right away, or maybe I'm missing
something this time around.
> I'm just a bit lost.
Once your un-lost, pls review the docs for drm_crtc_state and the various
mode_fixup functions, to make sure they're clear on how this is supposed
to work. Might need a new overview DOC: comment that ties it all together.
Cheers, Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
^ permalink raw reply
* WARNING: suspicious RCU usage
From: Paul E. McKenney @ 2017-12-15 15:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAOMZO5Cte467YdvOvg_teuKdP435nFd0_t1j6Mxtax43GqMqYw@mail.gmail.com>
On Fri, Dec 15, 2017 at 11:16:43AM -0200, Fabio Estevam wrote:
> Hi Paul,
>
> On Fri, Dec 15, 2017 at 4:38 AM, Paul E. McKenney
> <paulmck@linux.vnet.ibm.com> wrote:
>
> > For your amusement, I have a patch below that takes a paranoid view of
> > the possible answers to these questions. This patch is untested and
> > probably does not even build. Plus its polling loop is quite naive.
>
> I tried to build it, but if fails to link:
>
> LD vmlinux.o
> MODPOST vmlinux.o
> arch/arm/kernel/smp.o: In function `__cpu_die':
> smp.c:(.text+0x44c): undefined reference to `__bad_xchg'
> Makefile:1024: recipe for target 'vmlinux' failed
> make: *** [vmlinux] Error 1
OK, I will need to make a better choice of atomic operation.
Thank you for testing this!
Thanx, Paul
^ permalink raw reply
* [PATCH v5 13/13] KVM: arm64: Emulate RAS error registers and set HCR_EL2's TERR & TEA
From: James Morse @ 2017-12-15 15:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171215155101.23505-1-james.morse@arm.com>
From: Dongjiu Geng <gengdongjiu@huawei.com>
ARMv8.2 adds a new bit HCR_EL2.TEA which routes synchronous external
aborts to EL2, and adds a trap control bit HCR_EL2.TERR which traps
all Non-secure EL1&0 error record accesses to EL2.
This patch enables the two bits for the guest OS, guaranteeing that
KVM takes external aborts and traps attempts to access the physical
error registers.
ERRIDR_EL1 advertises the number of error records, we return
zero meaning we can treat all the other registers as RAZ/WI too.
Signed-off-by: Dongjiu Geng <gengdongjiu@huawei.com>
[removed specific emulation, use trap_raz_wi() directly for everything,
rephrased parts of the commit message]
Signed-off-by: James Morse <james.morse@arm.com>
---
arch/arm64/include/asm/kvm_arm.h | 2 ++
arch/arm64/include/asm/kvm_emulate.h | 7 +++++++
arch/arm64/include/asm/sysreg.h | 10 ++++++++++
arch/arm64/kvm/sys_regs.c | 10 ++++++++++
4 files changed, 29 insertions(+)
diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 715d395ef45b..b0c84171e6a3 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -23,6 +23,8 @@
#include <asm/types.h>
/* Hyp Configuration Register (HCR) bits */
+#define HCR_TEA (UL(1) << 37)
+#define HCR_TERR (UL(1) << 36)
#define HCR_E2H (UL(1) << 34)
#define HCR_ID (UL(1) << 33)
#define HCR_CD (UL(1) << 32)
diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index e002ab7f919a..413dc82b1e89 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -50,6 +50,13 @@ static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu)
vcpu->arch.hcr_el2 = HCR_GUEST_FLAGS;
if (is_kernel_in_hyp_mode())
vcpu->arch.hcr_el2 |= HCR_E2H;
+ if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN)) {
+ /* route synchronous external abort exceptions to EL2 */
+ vcpu->arch.hcr_el2 |= HCR_TEA;
+ /* trap error record accesses */
+ vcpu->arch.hcr_el2 |= HCR_TERR;
+ }
+
if (test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features))
vcpu->arch.hcr_el2 &= ~HCR_RW;
}
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 1e5228024c7b..bf9a6f15b605 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -176,6 +176,16 @@
#define SYS_AFSR0_EL1 sys_reg(3, 0, 5, 1, 0)
#define SYS_AFSR1_EL1 sys_reg(3, 0, 5, 1, 1)
#define SYS_ESR_EL1 sys_reg(3, 0, 5, 2, 0)
+
+#define SYS_ERRIDR_EL1 sys_reg(3, 0, 5, 3, 0)
+#define SYS_ERRSELR_EL1 sys_reg(3, 0, 5, 3, 1)
+#define SYS_ERXFR_EL1 sys_reg(3, 0, 5, 4, 0)
+#define SYS_ERXCTLR_EL1 sys_reg(3, 0, 5, 4, 1)
+#define SYS_ERXSTATUS_EL1 sys_reg(3, 0, 5, 4, 2)
+#define SYS_ERXADDR_EL1 sys_reg(3, 0, 5, 4, 3)
+#define SYS_ERXMISC0_EL1 sys_reg(3, 0, 5, 5, 0)
+#define SYS_ERXMISC1_EL1 sys_reg(3, 0, 5, 5, 1)
+
#define SYS_FAR_EL1 sys_reg(3, 0, 6, 0, 0)
#define SYS_PAR_EL1 sys_reg(3, 0, 7, 4, 0)
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 9edf4ac8a320..50a43c7b97ca 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1159,6 +1159,16 @@ static const struct sys_reg_desc sys_reg_descs[] = {
{ SYS_DESC(SYS_AFSR0_EL1), access_vm_reg, reset_unknown, AFSR0_EL1 },
{ SYS_DESC(SYS_AFSR1_EL1), access_vm_reg, reset_unknown, AFSR1_EL1 },
{ SYS_DESC(SYS_ESR_EL1), access_vm_reg, reset_unknown, ESR_EL1 },
+
+ { SYS_DESC(SYS_ERRIDR_EL1), trap_raz_wi },
+ { SYS_DESC(SYS_ERRSELR_EL1), trap_raz_wi },
+ { SYS_DESC(SYS_ERXFR_EL1), trap_raz_wi },
+ { SYS_DESC(SYS_ERXCTLR_EL1), trap_raz_wi },
+ { SYS_DESC(SYS_ERXSTATUS_EL1), trap_raz_wi },
+ { SYS_DESC(SYS_ERXADDR_EL1), trap_raz_wi },
+ { SYS_DESC(SYS_ERXMISC0_EL1), trap_raz_wi },
+ { SYS_DESC(SYS_ERXMISC1_EL1), trap_raz_wi },
+
{ SYS_DESC(SYS_FAR_EL1), access_vm_reg, reset_unknown, FAR_EL1 },
{ SYS_DESC(SYS_PAR_EL1), NULL, reset_unknown, PAR_EL1 },
--
2.15.0
^ permalink raw reply related
* [PATCH v5 12/13] KVM: arm64: Handle RAS SErrors from EL2 on guest exit
From: James Morse @ 2017-12-15 15:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171215155101.23505-1-james.morse@arm.com>
We expect to have firmware-first handling of RAS SErrors, with errors
notified via an APEI method. For systems without firmware-first, add
some minimal handling to KVM.
There are two ways KVM can take an SError due to a guest, either may be a
RAS error: we exit the guest due to an SError routed to EL2 by HCR_EL2.AMO,
or we take an SError from EL2 when we unmask PSTATE.A from __guest_exit.
The current SError from EL2 code unmasks SError and tries to fence any
pending SError into a single instruction window. It then leaves SError
unmasked.
With the v8.2 RAS Extensions we may take an SError for a 'corrected'
error, but KVM is only able to handle SError from EL2 if they occur
during this single instruction window...
The RAS Extensions give us a new instruction to synchronise and
consume SErrors. The RAS Extensions document (ARM DDI0587),
'2.4.1 ESB and Unrecoverable errors' describes ESB as synchronising
SError interrupts generated by 'instructions, translation table walks,
hardware updates to the translation tables, and instruction fetches on
the same PE'. This makes ESB equivalent to KVMs existing
'dsb, mrs-daifclr, isb' sequence.
Use the alternatives to synchronise and consume any SError using ESB
instead of unmasking and taking the SError. Set ARM_EXIT_WITH_SERROR_BIT
in the exit_code so that we can restart the vcpu if it turns out this
SError has no impact on the vcpu.
Signed-off-by: James Morse <james.morse@arm.com>
---
Changse since v4:
* Moved the SError handling into handle_exit_early()
* Dropped Marc & Christoffer's Reviewed-by due to handle_exit_early().
Changes since v3:
* Moved that nop out of the firing line
arch/arm64/include/asm/kvm_emulate.h | 5 +++++
arch/arm64/include/asm/kvm_host.h | 1 +
arch/arm64/kernel/asm-offsets.c | 1 +
arch/arm64/kvm/handle_exit.c | 14 +++++++++++++-
arch/arm64/kvm/hyp/entry.S | 13 +++++++++++++
5 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index 6d3614795197..e002ab7f919a 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -176,6 +176,11 @@ static inline phys_addr_t kvm_vcpu_get_fault_ipa(const struct kvm_vcpu *vcpu)
return ((phys_addr_t)vcpu->arch.fault.hpfar_el2 & HPFAR_MASK) << 8;
}
+static inline u64 kvm_vcpu_get_disr(const struct kvm_vcpu *vcpu)
+{
+ return vcpu->arch.fault.disr_el1;
+}
+
static inline u32 kvm_vcpu_hvc_get_imm(const struct kvm_vcpu *vcpu)
{
return kvm_vcpu_get_hsr(vcpu) & ESR_ELx_xVC_IMM_MASK;
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 34f1c4e88c98..0683199eb514 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -90,6 +90,7 @@ struct kvm_vcpu_fault_info {
u32 esr_el2; /* Hyp Syndrom Register */
u64 far_el2; /* Hyp Fault Address Register */
u64 hpfar_el2; /* Hyp IPA Fault Address Register */
+ u64 disr_el1; /* Deferred [SError] Status Register */
};
/*
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index 71bf088f1e4b..121889c49542 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -130,6 +130,7 @@ int main(void)
BLANK();
#ifdef CONFIG_KVM_ARM_HOST
DEFINE(VCPU_CONTEXT, offsetof(struct kvm_vcpu, arch.ctxt));
+ DEFINE(VCPU_FAULT_DISR, offsetof(struct kvm_vcpu, arch.fault.disr_el1));
DEFINE(CPU_GP_REGS, offsetof(struct kvm_cpu_context, gp_regs));
DEFINE(CPU_USER_PT_REGS, offsetof(struct kvm_regs, regs));
DEFINE(CPU_FP_REGS, offsetof(struct kvm_regs, fp_regs));
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 6a5a5db4292f..c09fc5a576c7 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -23,6 +23,7 @@
#include <linux/kvm_host.h>
#include <asm/esr.h>
+#include <asm/exception.h>
#include <asm/kvm_asm.h>
#include <asm/kvm_coproc.h>
#include <asm/kvm_emulate.h>
@@ -249,7 +250,6 @@ int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
*vcpu_pc(vcpu) -= adj;
}
- kvm_inject_vabt(vcpu);
return 1;
}
@@ -286,6 +286,18 @@ int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
void handle_exit_early(struct kvm_vcpu *vcpu, struct kvm_run *run,
int exception_index)
{
+ if (ARM_SERROR_PENDING(exception_index)) {
+ if (this_cpu_has_cap(ARM64_HAS_RAS_EXTN)) {
+ u64 disr = kvm_vcpu_get_disr(vcpu);
+
+ kvm_handle_guest_serror(vcpu, disr_to_esr(disr));
+ } else {
+ kvm_inject_vabt(vcpu);
+ }
+
+ return;
+ }
+
exception_index = ARM_EXCEPTION_CODE(exception_index);
if (exception_index == ARM_EXCEPTION_EL1_SERROR)
diff --git a/arch/arm64/kvm/hyp/entry.S b/arch/arm64/kvm/hyp/entry.S
index 12ee62d6d410..024c7afc78f8 100644
--- a/arch/arm64/kvm/hyp/entry.S
+++ b/arch/arm64/kvm/hyp/entry.S
@@ -124,6 +124,17 @@ ENTRY(__guest_exit)
// Now restore the host regs
restore_callee_saved_regs x2
+alternative_if ARM64_HAS_RAS_EXTN
+ // If we have the RAS extensions we can consume a pending error
+ // without an unmask-SError and isb.
+ esb
+ mrs_s x2, SYS_DISR_EL1
+ str x2, [x1, #(VCPU_FAULT_DISR - VCPU_CONTEXT)]
+ cbz x2, 1f
+ msr_s SYS_DISR_EL1, xzr
+ orr x0, x0, #(1<<ARM_EXIT_WITH_SERROR_BIT)
+1: ret
+alternative_else
// If we have a pending asynchronous abort, now is the
// time to find out. From your VAXorcist book, page 666:
// "Threaten me not, oh Evil one! For I speak with
@@ -134,7 +145,9 @@ ENTRY(__guest_exit)
mov x5, x0
dsb sy // Synchronize against in-flight ld/st
+ nop
msr daifclr, #4 // Unmask aborts
+alternative_endif
// This is our single instruction exception window. A pending
// SError is guaranteed to occur@the earliest when we unmask
--
2.15.0
^ permalink raw reply related
* [PATCH v5 11/13] KVM: arm64: Handle RAS SErrors from EL1 on guest exit
From: James Morse @ 2017-12-15 15:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171215155101.23505-1-james.morse@arm.com>
We expect to have firmware-first handling of RAS SErrors, with errors
notified via an APEI method. For systems without firmware-first, add
some minimal handling to KVM.
There are two ways KVM can take an SError due to a guest, either may be a
RAS error: we exit the guest due to an SError routed to EL2 by HCR_EL2.AMO,
or we take an SError from EL2 when we unmask PSTATE.A from __guest_exit.
For SError that interrupt a guest and are routed to EL2 the existing
behaviour is to inject an impdef SError into the guest.
Add code to handle RAS SError based on the ESR. For uncontained and
uncategorized errors arm64_is_fatal_ras_serror() will panic(), these
errors compromise the host too. All other error types are contained:
For the fatal errors the vCPU can't make progress, so we inject a virtual
SError. We ignore contained errors where we can make progress as if
we're lucky, we may not hit them again.
If only some of the CPUs support RAS the guest will see the cpufeature
sanitised version of the id registers, but we may still take RAS SError
on this CPU. Move the SError handling out of handle_exit() into a new
handler that runs before we can be preempted. This allows us to use
this_cpu_has_cap(), via arm64_is_ras_serror().
Signed-off-by: James Morse <james.morse@arm.com>
---
Changes since v4:
* Moved SError handling into handle_exit_early(). This will need to move
earlier, into an SError-masked region once we support kernel-first.
(hence the vauge name)
* Dropped Marc & Christoffer's Reviewed-by due to handle_exit_early().
arch/arm/include/asm/kvm_host.h | 3 +++
arch/arm64/include/asm/kvm_host.h | 2 ++
arch/arm64/kvm/handle_exit.c | 18 +++++++++++++++++-
virt/kvm/arm/arm.c | 3 +++
4 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index b86fc4162539..acbf9ec7b396 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -238,6 +238,9 @@ int kvm_arm_coproc_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *);
int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
int exception_index);
+static inline void handle_exit_early(struct kvm_vcpu *vcpu, struct kvm_run *run,
+ int exception_index) {}
+
static inline void __cpu_init_hyp_mode(phys_addr_t pgd_ptr,
unsigned long hyp_stack_ptr,
unsigned long vector_ptr)
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 9391a076de58..34f1c4e88c98 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -345,6 +345,8 @@ void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot);
int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
int exception_index);
+void handle_exit_early(struct kvm_vcpu *vcpu, struct kvm_run *run,
+ int exception_index);
int kvm_perf_init(void);
int kvm_perf_teardown(void);
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 304203fa9e33..6a5a5db4292f 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -29,12 +29,19 @@
#include <asm/kvm_mmu.h>
#include <asm/kvm_psci.h>
#include <asm/debug-monitors.h>
+#include <asm/traps.h>
#define CREATE_TRACE_POINTS
#include "trace.h"
typedef int (*exit_handle_fn)(struct kvm_vcpu *, struct kvm_run *);
+static void kvm_handle_guest_serror(struct kvm_vcpu *vcpu, u32 esr)
+{
+ if (!arm64_is_ras_serror(esr) || arm64_is_fatal_ras_serror(NULL, esr))
+ kvm_inject_vabt(vcpu);
+}
+
static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run *run)
{
int ret;
@@ -252,7 +259,6 @@ int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
case ARM_EXCEPTION_IRQ:
return 1;
case ARM_EXCEPTION_EL1_SERROR:
- kvm_inject_vabt(vcpu);
/* We may still need to return for single-step */
if (!(*vcpu_cpsr(vcpu) & DBG_SPSR_SS)
&& kvm_arm_handle_step_debug(vcpu, run))
@@ -275,3 +281,13 @@ int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
return 0;
}
}
+
+/* For exit types that need handling before we can be preempted */
+void handle_exit_early(struct kvm_vcpu *vcpu, struct kvm_run *run,
+ int exception_index)
+{
+ exception_index = ARM_EXCEPTION_CODE(exception_index);
+
+ if (exception_index == ARM_EXCEPTION_EL1_SERROR)
+ kvm_handle_guest_serror(vcpu, kvm_vcpu_get_hsr(vcpu));
+}
diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
index 86059a478a0a..a11040be0443 100644
--- a/virt/kvm/arm/arm.c
+++ b/virt/kvm/arm/arm.c
@@ -763,6 +763,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
guest_exit();
trace_kvm_exit(ret, kvm_vcpu_trap_get_class(vcpu), *vcpu_pc(vcpu));
+ /* Exit types that need handling before we can be preempted */
+ handle_exit_early(vcpu, run, ret);
+
preempt_enable();
ret = handle_exit(vcpu, run, ret);
--
2.15.0
^ permalink raw reply related
* [PATCH v5 10/13] KVM: arm64: Save ESR_EL2 on guest SError
From: James Morse @ 2017-12-15 15:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171215155101.23505-1-james.morse@arm.com>
When we exit a guest due to an SError the vcpu fault info isn't updated
with the ESR. Today this is only done for traps.
The v8.2 RAS Extensions define ISS values for SError. Update the vcpu's
fault_info with the ESR on SError so that handle_exit() can determine
if this was a RAS SError and decode its severity.
Signed-off-by: James Morse <james.morse@arm.com>
---
Changes since v4:
* Switched to Marc's exit_code != irq version
(Christoffer gave Reviewed-by for v2, which I missed (sorry))
arch/arm64/kvm/hyp/switch.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
index 51e65fc1b0cd..1ae349fe0568 100644
--- a/arch/arm64/kvm/hyp/switch.c
+++ b/arch/arm64/kvm/hyp/switch.c
@@ -238,11 +238,12 @@ static bool __hyp_text __translate_far_to_hpfar(u64 far, u64 *hpfar)
static bool __hyp_text __populate_fault_info(struct kvm_vcpu *vcpu)
{
- u64 esr = read_sysreg_el2(esr);
- u8 ec = ESR_ELx_EC(esr);
+ u8 ec;
+ u64 esr;
u64 hpfar, far;
- vcpu->arch.fault.esr_el2 = esr;
+ esr = vcpu->arch.fault.esr_el2;
+ ec = ESR_ELx_EC(esr);
if (ec != ESR_ELx_EC_DABT_LOW && ec != ESR_ELx_EC_IABT_LOW)
return true;
@@ -335,6 +336,8 @@ int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu)
exit_code = __guest_enter(vcpu, host_ctxt);
/* And we're baaack! */
+ if (ARM_EXCEPTION_CODE(exit_code) != ARM_EXCEPTION_IRQ)
+ vcpu->arch.fault.esr_el2 = read_sysreg_el2(esr);
/*
* We're using the raw exception code in order to only process
* the trap if no SError is pending. We will come back to the
--
2.15.0
^ permalink raw reply related
* [PATCH v5 09/13] KVM: arm64: Save/Restore guest DISR_EL1
From: James Morse @ 2017-12-15 15:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171215155101.23505-1-james.morse@arm.com>
If we deliver a virtual SError to the guest, the guest may defer it
with an ESB instruction. The guest reads the deferred value via DISR_EL1,
but the guests view of DISR_EL1 is re-mapped to VDISR_EL2 when HCR_EL2.AMO
is set.
Add the KVM code to save/restore VDISR_EL2, and make it accessible to
userspace as DISR_EL1.
Signed-off-by: James Morse <james.morse@arm.com>
---
arch/arm64/include/asm/kvm_host.h | 1 +
arch/arm64/include/asm/sysreg.h | 1 +
arch/arm64/kvm/hyp/sysreg-sr.c | 6 ++++++
arch/arm64/kvm/sys_regs.c | 1 +
4 files changed, 9 insertions(+)
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index c626c081ce9a..9391a076de58 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -121,6 +121,7 @@ enum vcpu_sysreg {
PAR_EL1, /* Physical Address Register */
MDSCR_EL1, /* Monitor Debug System Control Register */
MDCCINT_EL1, /* Monitor Debug Comms Channel Interrupt Enable Reg */
+ DISR_EL1, /* Deferred Interrupt Status Register */
/* Performance Monitors Registers */
PMCR_EL0, /* Control Register */
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 6afbf2334763..1e5228024c7b 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -358,6 +358,7 @@
#define SYS_VSESR_EL2 sys_reg(3, 4, 5, 2, 3)
#define SYS_FPEXC32_EL2 sys_reg(3, 4, 5, 3, 0)
+#define SYS_VDISR_EL2 sys_reg(3, 4, 12, 1, 1)
#define __SYS__AP0Rx_EL2(x) sys_reg(3, 4, 12, 8, x)
#define SYS_ICH_AP0R0_EL2 __SYS__AP0Rx_EL2(0)
#define SYS_ICH_AP0R1_EL2 __SYS__AP0Rx_EL2(1)
diff --git a/arch/arm64/kvm/hyp/sysreg-sr.c b/arch/arm64/kvm/hyp/sysreg-sr.c
index 934137647837..f4d604803b29 100644
--- a/arch/arm64/kvm/hyp/sysreg-sr.c
+++ b/arch/arm64/kvm/hyp/sysreg-sr.c
@@ -66,6 +66,9 @@ static void __hyp_text __sysreg_save_state(struct kvm_cpu_context *ctxt)
ctxt->gp_regs.sp_el1 = read_sysreg(sp_el1);
ctxt->gp_regs.elr_el1 = read_sysreg_el1(elr);
ctxt->gp_regs.spsr[KVM_SPSR_EL1]= read_sysreg_el1(spsr);
+
+ if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN))
+ ctxt->sys_regs[DISR_EL1] = read_sysreg_s(SYS_VDISR_EL2);
}
static hyp_alternate_select(__sysreg_call_save_host_state,
@@ -119,6 +122,9 @@ static void __hyp_text __sysreg_restore_state(struct kvm_cpu_context *ctxt)
write_sysreg(ctxt->gp_regs.sp_el1, sp_el1);
write_sysreg_el1(ctxt->gp_regs.elr_el1, elr);
write_sysreg_el1(ctxt->gp_regs.spsr[KVM_SPSR_EL1],spsr);
+
+ if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN))
+ write_sysreg_s(ctxt->sys_regs[DISR_EL1], SYS_VDISR_EL2);
}
static hyp_alternate_select(__sysreg_call_restore_host_state,
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 1830ebc227d1..9edf4ac8a320 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1169,6 +1169,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
{ SYS_DESC(SYS_AMAIR_EL1), access_vm_reg, reset_amair_el1, AMAIR_EL1 },
{ SYS_DESC(SYS_VBAR_EL1), NULL, reset_val, VBAR_EL1, 0 },
+ { SYS_DESC(SYS_DISR_EL1), NULL, reset_val, DISR_EL1, 0 },
{ SYS_DESC(SYS_ICC_IAR0_EL1), write_to_read_only },
{ SYS_DESC(SYS_ICC_EOIR0_EL1), read_from_write_only },
--
2.15.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox