* [PATCH 07/14] arm64: ssbd: Skip apply_ssbd if not using dynamic mitigation
From: Marc Zyngier @ 2018-05-22 15:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180522150648.28297-1-marc.zyngier@arm.com>
In order to avoid checking arm64_ssbd_callback_required on each
kernel entry/exit even if no mitigation is required, let's
add yet another alternative that by default jumps over the mitigation,
and that gets nop'ed out if we're doing dynamic mitigation.
Think of it as a poor man's static key...
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm64/kernel/cpu_errata.c | 14 ++++++++++++++
arch/arm64/kernel/entry.S | 3 +++
2 files changed, 17 insertions(+)
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index f1d4e75b0ddd..8f686f39b9c1 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -283,6 +283,20 @@ void __init arm64_update_smccc_conduit(struct alt_instr *alt,
*updptr = cpu_to_le32(insn);
}
+void __init arm64_enable_wa2_handling(struct alt_instr *alt,
+ __le32 *origptr, __le32 *updptr,
+ int nr_inst)
+{
+ BUG_ON(nr_inst != 1);
+ /*
+ * Only allow mitigation on EL1 entry/exit and guest
+ * ARCH_WORKAROUND_2 handling if the SSBD state allows it to
+ * be flipped.
+ */
+ if (arm64_get_ssbd_state() == ARM64_SSBD_EL1_ENTRY)
+ *updptr = cpu_to_le32(aarch64_insn_gen_nop());
+}
+
static void do_ssbd(bool state)
{
switch (psci_ops.conduit) {
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 29ad672a6abd..e6f6e2339b22 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -142,6 +142,9 @@ alternative_else_nop_endif
// to save/restore them if required.
.macro apply_ssbd, state, targ, tmp1, tmp2
#ifdef CONFIG_ARM64_SSBD
+alternative_cb arm64_enable_wa2_handling
+ b \targ
+alternative_cb_end
ldr_this_cpu \tmp2, arm64_ssbd_callback_required, \tmp1
cbz \tmp2, \targ
mov w0, #ARM_SMCCC_ARCH_WORKAROUND_2
--
2.14.2
^ permalink raw reply related
* [PATCH 08/14] arm64: ssbd: Disable mitigation on CPU resume if required by user
From: Marc Zyngier @ 2018-05-22 15:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180522150648.28297-1-marc.zyngier@arm.com>
On a system where firmware can dynamically change the state of the
mitigation, the CPU will always come up with the mitigation enabled,
including when coming back from suspend.
If the user has requested "no mitigation" via a command line option,
let's enforce it by calling into the firmware again to disable it.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm64/include/asm/cpufeature.h | 6 ++++++
arch/arm64/kernel/cpu_errata.c | 8 ++++----
arch/arm64/kernel/suspend.c | 8 ++++++++
3 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 1bacdf57f0af..d9dcb683259e 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -553,6 +553,12 @@ static inline int arm64_get_ssbd_state(void)
#endif
}
+#ifdef CONFIG_ARM64_SSBD
+void arm64_set_ssbd_mitigation(bool state);
+#else
+static inline void arm64_set_ssbd_mitigation(bool state) {}
+#endif
+
#endif /* __ASSEMBLY__ */
#endif
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 8f686f39b9c1..b4c12e9140f0 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -297,7 +297,7 @@ void __init arm64_enable_wa2_handling(struct alt_instr *alt,
*updptr = cpu_to_le32(aarch64_insn_gen_nop());
}
-static void do_ssbd(bool state)
+void arm64_set_ssbd_mitigation(bool state)
{
switch (psci_ops.conduit) {
case PSCI_CONDUIT_HVC:
@@ -371,20 +371,20 @@ static bool has_ssbd_mitigation(const struct arm64_cpu_capabilities *entry,
switch (ssbd_state) {
case ARM64_SSBD_FORCE_DISABLE:
pr_info_once("%s disabled from command-line\n", entry->desc);
- do_ssbd(false);
+ arm64_set_ssbd_mitigation(false);
required = false;
break;
case ARM64_SSBD_EL1_ENTRY:
if (required) {
__this_cpu_write(arm64_ssbd_callback_required, 1);
- do_ssbd(true);
+ arm64_set_ssbd_mitigation(true);
}
break;
case ARM64_SSBD_FORCE_ENABLE:
pr_info_once("%s forced from command-line\n", entry->desc);
- do_ssbd(true);
+ arm64_set_ssbd_mitigation(true);
required = true;
break;
diff --git a/arch/arm64/kernel/suspend.c b/arch/arm64/kernel/suspend.c
index a307b9e13392..70c283368b64 100644
--- a/arch/arm64/kernel/suspend.c
+++ b/arch/arm64/kernel/suspend.c
@@ -62,6 +62,14 @@ void notrace __cpu_suspend_exit(void)
*/
if (hw_breakpoint_restore)
hw_breakpoint_restore(cpu);
+
+ /*
+ * On resume, firmware implementing dynamic mitigation will
+ * have turned the mitigation on. If the user has forcefully
+ * disabled it, make sure their wishes are obeyed.
+ */
+ if (arm64_get_ssbd_state() == ARM64_SSBD_FORCE_DISABLE)
+ arm64_set_ssbd_mitigation(false);
}
/*
--
2.14.2
^ permalink raw reply related
* [PATCH 09/14] arm64: ssbd: Introduce thread flag to control userspace mitigation
From: Marc Zyngier @ 2018-05-22 15:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180522150648.28297-1-marc.zyngier@arm.com>
In order to allow userspace to be mitigated on demand, let's
introduce a new thread flag that prevents the mitigation from
being turned off when exiting to userspace, and doesn't turn
it on on entry into the kernel (with the assumtion that the
mitigation is always enabled in the kernel itself).
This will be used by a prctl interface introduced in a later
patch.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm64/include/asm/thread_info.h | 1 +
arch/arm64/kernel/entry.S | 2 ++
2 files changed, 3 insertions(+)
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index 740aa03c5f0d..cbcf11b5e637 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -94,6 +94,7 @@ void arch_release_task_struct(struct task_struct *tsk);
#define TIF_32BIT 22 /* 32bit process */
#define TIF_SVE 23 /* Scalable Vector Extension in use */
#define TIF_SVE_VL_INHERIT 24 /* Inherit sve_vl_onexec across exec */
+#define TIF_SSBD 25 /* Wants SSB mitigation */
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index e6f6e2339b22..28ad8799406f 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -147,6 +147,8 @@ alternative_cb arm64_enable_wa2_handling
alternative_cb_end
ldr_this_cpu \tmp2, arm64_ssbd_callback_required, \tmp1
cbz \tmp2, \targ
+ ldr \tmp2, [tsk, #TSK_TI_FLAGS]
+ tbnz \tmp2, #TIF_SSBD, \targ
mov w0, #ARM_SMCCC_ARCH_WORKAROUND_2
mov w1, #\state
alternative_cb arm64_update_smccc_conduit
--
2.14.2
^ permalink raw reply related
* [PATCH 10/14] arm64: ssbd: Add prctl interface for per-thread mitigation
From: Marc Zyngier @ 2018-05-22 15:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180522150648.28297-1-marc.zyngier@arm.com>
If running on a system that performs dynamic SSBD mitigation, allow
userspace to request the mitigation for itself. This is implemented
as a prctl call, allowing the mitigation to be enabled or disabled at
will for this particular thread.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm64/kernel/Makefile | 1 +
arch/arm64/kernel/ssbd.c | 107 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 108 insertions(+)
create mode 100644 arch/arm64/kernel/ssbd.c
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index bf825f38d206..0025f8691046 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -54,6 +54,7 @@ arm64-obj-$(CONFIG_ARM64_RELOC_TEST) += arm64-reloc-test.o
arm64-reloc-test-y := reloc_test_core.o reloc_test_syms.o
arm64-obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
arm64-obj-$(CONFIG_ARM_SDE_INTERFACE) += sdei.o
+arm64-obj-$(CONFIG_ARM64_SSBD) += ssbd.o
obj-y += $(arm64-obj-y) vdso/ probes/
obj-m += $(arm64-obj-m)
diff --git a/arch/arm64/kernel/ssbd.c b/arch/arm64/kernel/ssbd.c
new file mode 100644
index 000000000000..34e3c430176b
--- /dev/null
+++ b/arch/arm64/kernel/ssbd.c
@@ -0,0 +1,107 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 ARM Ltd, All Rights Reserved.
+ */
+
+#include <linux/sched.h>
+#include <linux/thread_info.h>
+
+#include <asm/cpufeature.h>
+
+/*
+ * prctl interface for SSBD
+ * FIXME: Drop the below ifdefery once the common interface has been merged.
+ */
+#ifdef PR_SPEC_STORE_BYPASS
+static int ssbd_prctl_set(struct task_struct *task, unsigned long ctrl)
+{
+ int state = arm64_get_ssbd_state();
+
+ /* Unsupported or already mitigated */
+ if (state == ARM64_SSBD_UNKNOWN)
+ return -EINVAL;
+ if (state == ARM64_SSBD_MITIGATED)
+ return -EPERM;
+
+ /*
+ * Things are a bit backward here: the arm64 internal API
+ * *enables the mitigation* when the userspace API *disables
+ * speculation*. So much fun.
+ */
+ switch (ctrl) {
+ case PR_SPEC_ENABLE:
+ /* If speculation is force disabled, enable is not allowed */
+ if (state == ARM64_SSBD_FORCE_ENABLE ||
+ task_spec_ssb_force_disable(task))
+ return -EPERM;
+ task_clear_spec_ssb_disable(task);
+ clear_tsk_thread_flag(task, TIF_SSBD);
+ break;
+ case PR_SPEC_DISABLE:
+ if (state == ARM64_SSBD_FORCE_DISABLE)
+ return -EPERM;
+ task_set_spec_ssb_disable(task);
+ set_tsk_thread_flag(task, TIF_SSBD);
+ break;
+ case PR_SPEC_FORCE_DISABLE:
+ if (state == ARM64_SSBD_FORCE_DISABLE)
+ return -EPERM;
+ task_set_spec_ssb_disable(task);
+ task_set_spec_ssb_force_disable(task);
+ set_tsk_thread_flag(task, TIF_SSBD);
+ break;
+ default:
+ return -ERANGE;
+ }
+
+ return 0;
+}
+
+int arch_prctl_spec_ctrl_set(struct task_struct *task, unsigned long which,
+ unsigned long ctrl)
+{
+ switch (which) {
+ case PR_SPEC_STORE_BYPASS:
+ return ssbd_prctl_set(task, ctrl);
+ default:
+ return -ENODEV;
+ }
+}
+
+#ifdef CONFIG_SECCOMP
+void arch_seccomp_spec_mitigate(struct task_struct *task)
+{
+ ssbd_prctl_set(task, PR_SPEC_FORCE_DISABLE);
+}
+#endif
+
+static int ssbd_prctl_get(struct task_struct *task)
+{
+ switch (arm64_get_ssbd_state()) {
+ case ARM64_SSBD_UNKNOWN:
+ return -EINVAL;
+ case ARM64_SSBD_FORCE_ENABLE:
+ return PR_SPEC_DISABLE;
+ case ARM64_SSBD_EL1_ENTRY:
+ if (task_spec_ssb_force_disable(task))
+ return PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE;
+ if (task_spec_ssb_disable(task))
+ return PR_SPEC_PRCTL | PR_SPEC_DISABLE;
+ return PR_SPEC_PRCTL | PR_SPEC_ENABLE;
+ case ARM64_SSBD_FORCE_DISABLE:
+ return PR_SPEC_ENABLE;
+ default:
+ return PR_SPEC_NOT_AFFECTED;
+ }
+}
+
+int arch_prctl_spec_ctrl_get(struct task_struct *task, unsigned long which)
+{
+ switch (which) {
+ case PR_SPEC_STORE_BYPASS:
+ return ssbd_prctl_get(task);
+ default:
+ return -ENODEV;
+ }
+}
+#endif /* PR_SPEC_STORE_BYPASS */
--
2.14.2
^ permalink raw reply related
* [PATCH 11/14] arm64: KVM: Add HYP per-cpu accessors
From: Marc Zyngier @ 2018-05-22 15:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180522150648.28297-1-marc.zyngier@arm.com>
As we're going to require to access per-cpu variables at EL2,
let's craft the minimum set of accessors required to implement
reading a per-cpu variable, relying on tpidr_el2 to contain the
per-cpu offset.
Reviewed-by: Christoffer Dall <christoffer.dall@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm64/include/asm/kvm_asm.h | 27 +++++++++++++++++++++++++--
1 file changed, 25 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index f6648a3e4152..fefd8cf42c35 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -71,14 +71,37 @@ extern u32 __kvm_get_mdcr_el2(void);
extern u32 __init_stage2_translation(void);
+/* Home-grown __this_cpu_{ptr,read} variants that always work at HYP */
+#define __hyp_this_cpu_ptr(sym) \
+ ({ \
+ void *__ptr = hyp_symbol_addr(sym); \
+ __ptr += read_sysreg(tpidr_el2); \
+ (typeof(&sym))__ptr; \
+ })
+
+#define __hyp_this_cpu_read(sym) \
+ ({ \
+ *__hyp_this_cpu_ptr(sym); \
+ })
+
#else /* __ASSEMBLY__ */
-.macro get_host_ctxt reg, tmp
- adr_l \reg, kvm_host_cpu_state
+.macro hyp_adr_this_cpu reg, sym, tmp
+ adr_l \reg, \sym
mrs \tmp, tpidr_el2
add \reg, \reg, \tmp
.endm
+.macro hyp_ldr_this_cpu reg, sym, tmp
+ adr_l \reg, \sym
+ mrs \tmp, tpidr_el2
+ ldr \reg, [\reg, \tmp]
+.endm
+
+.macro get_host_ctxt reg, tmp
+ hyp_adr_this_cpu \reg, kvm_host_cpu_state, \tmp
+.endm
+
.macro get_vcpu_ptr vcpu, ctxt
get_host_ctxt \ctxt, \vcpu
ldr \vcpu, [\ctxt, #HOST_CONTEXT_VCPU]
--
2.14.2
^ permalink raw reply related
* [PATCH 12/14] arm64: KVM: Add ARCH_WORKAROUND_2 support for guests
From: Marc Zyngier @ 2018-05-22 15:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180522150648.28297-1-marc.zyngier@arm.com>
In order to offer ARCH_WORKAROUND_2 support to guests, we need
a bit of infrastructure.
Let's add a flag indicating whether or not the guest uses
SSBD mitigation. Depending on the state of this flag, allow
KVM to disable ARCH_WORKAROUND_2 before entering the guest,
and enable it when exiting it.
Reviewed-by: Christoffer Dall <christoffer.dall@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm/include/asm/kvm_mmu.h | 5 +++++
arch/arm64/include/asm/kvm_asm.h | 3 +++
arch/arm64/include/asm/kvm_host.h | 3 +++
arch/arm64/include/asm/kvm_mmu.h | 24 ++++++++++++++++++++++
arch/arm64/kvm/hyp/switch.c | 42 +++++++++++++++++++++++++++++++++++++++
virt/kvm/arm/arm.c | 4 ++++
6 files changed, 81 insertions(+)
diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h
index 707a1f06dc5d..b0c17d88ed40 100644
--- a/arch/arm/include/asm/kvm_mmu.h
+++ b/arch/arm/include/asm/kvm_mmu.h
@@ -319,6 +319,11 @@ static inline int kvm_map_vectors(void)
return 0;
}
+static inline int hyp_map_aux_data(void)
+{
+ return 0;
+}
+
#define kvm_phys_to_vttbr(addr) (addr)
#endif /* !__ASSEMBLY__ */
diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index fefd8cf42c35..d4fbb1356c4c 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -33,6 +33,9 @@
#define KVM_ARM64_DEBUG_DIRTY_SHIFT 0
#define KVM_ARM64_DEBUG_DIRTY (1 << KVM_ARM64_DEBUG_DIRTY_SHIFT)
+#define VCPU_WORKAROUND_2_FLAG_SHIFT 0
+#define VCPU_WORKAROUND_2_FLAG (_AC(1, UL) << VCPU_WORKAROUND_2_FLAG_SHIFT)
+
/* Translate a kernel address of @sym into its equivalent linear mapping */
#define kvm_ksym_ref(sym) \
({ \
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 469de8acd06f..9bef3f69bdcd 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -216,6 +216,9 @@ struct kvm_vcpu_arch {
/* Exception Information */
struct kvm_vcpu_fault_info fault;
+ /* State of various workarounds, see kvm_asm.h for bit assignment */
+ u64 workaround_flags;
+
/* Guest debug state */
u64 debug_flags;
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index 082110993647..eb7a5c2a2bfb 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -457,6 +457,30 @@ static inline int kvm_map_vectors(void)
}
#endif
+#ifdef CONFIG_ARM64_SSBD
+DECLARE_PER_CPU_READ_MOSTLY(u64, arm64_ssbd_callback_required);
+
+static inline int hyp_map_aux_data(void)
+{
+ int cpu, err;
+
+ for_each_possible_cpu(cpu) {
+ u64 *ptr;
+
+ ptr = per_cpu_ptr(&arm64_ssbd_callback_required, cpu);
+ err = create_hyp_mappings(ptr, ptr + 1, PAGE_HYP);
+ if (err)
+ return err;
+ }
+ return 0;
+}
+#else
+static inline int hyp_map_aux_data(void)
+{
+ return 0;
+}
+#endif
+
#define kvm_phys_to_vttbr(addr) phys_to_ttbr(addr)
#endif /* __ASSEMBLY__ */
diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
index d9645236e474..c50cedc447f1 100644
--- a/arch/arm64/kvm/hyp/switch.c
+++ b/arch/arm64/kvm/hyp/switch.c
@@ -15,6 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <linux/arm-smccc.h>
#include <linux/types.h>
#include <linux/jump_label.h>
#include <uapi/linux/psci.h>
@@ -389,6 +390,39 @@ static bool __hyp_text fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
return false;
}
+static inline bool __hyp_text __needs_ssbd_off(struct kvm_vcpu *vcpu)
+{
+ if (!cpus_have_const_cap(ARM64_SSBD))
+ return false;
+
+ return !(vcpu->arch.workaround_flags & VCPU_WORKAROUND_2_FLAG);
+}
+
+static void __hyp_text __set_guest_arch_workaround_state(struct kvm_vcpu *vcpu)
+{
+#ifdef CONFIG_ARM64_SSBD
+ /*
+ * The host runs with the workaround always present. If the
+ * guest wants it disabled, so be it...
+ */
+ if (__needs_ssbd_off(vcpu) &&
+ __hyp_this_cpu_read(arm64_ssbd_callback_required))
+ arm_smccc_1_1_smc(ARM_SMCCC_ARCH_WORKAROUND_2, 0, NULL);
+#endif
+}
+
+static void __hyp_text __set_host_arch_workaround_state(struct kvm_vcpu *vcpu)
+{
+#ifdef CONFIG_ARM64_SSBD
+ /*
+ * If the guest has disabled the workaround, bring it back on.
+ */
+ if (__needs_ssbd_off(vcpu) &&
+ __hyp_this_cpu_read(arm64_ssbd_callback_required))
+ arm_smccc_1_1_smc(ARM_SMCCC_ARCH_WORKAROUND_2, 1, NULL);
+#endif
+}
+
/* Switch to the guest for VHE systems running in EL2 */
int kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu)
{
@@ -409,6 +443,8 @@ int kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu)
sysreg_restore_guest_state_vhe(guest_ctxt);
__debug_switch_to_guest(vcpu);
+ __set_guest_arch_workaround_state(vcpu);
+
do {
/* Jump in the fire! */
exit_code = __guest_enter(vcpu, host_ctxt);
@@ -416,6 +452,8 @@ int kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu)
/* And we're baaack! */
} while (fixup_guest_exit(vcpu, &exit_code));
+ __set_host_arch_workaround_state(vcpu);
+
fp_enabled = fpsimd_enabled_vhe();
sysreg_save_guest_state_vhe(guest_ctxt);
@@ -465,6 +503,8 @@ int __hyp_text __kvm_vcpu_run_nvhe(struct kvm_vcpu *vcpu)
__sysreg_restore_state_nvhe(guest_ctxt);
__debug_switch_to_guest(vcpu);
+ __set_guest_arch_workaround_state(vcpu);
+
do {
/* Jump in the fire! */
exit_code = __guest_enter(vcpu, host_ctxt);
@@ -472,6 +512,8 @@ int __hyp_text __kvm_vcpu_run_nvhe(struct kvm_vcpu *vcpu)
/* And we're baaack! */
} while (fixup_guest_exit(vcpu, &exit_code));
+ __set_host_arch_workaround_state(vcpu);
+
fp_enabled = __fpsimd_enabled_nvhe();
__sysreg_save_state_nvhe(guest_ctxt);
diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
index a4c1b76240df..2d9b4795edb2 100644
--- a/virt/kvm/arm/arm.c
+++ b/virt/kvm/arm/arm.c
@@ -1490,6 +1490,10 @@ static int init_hyp_mode(void)
}
}
+ err = hyp_map_aux_data();
+ if (err)
+ kvm_err("Cannot map host auxilary data: %d\n", err);
+
return 0;
out_err:
--
2.14.2
^ permalink raw reply related
* [PATCH 13/14] arm64: KVM: Handle guest's ARCH_WORKAROUND_2 requests
From: Marc Zyngier @ 2018-05-22 15:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180522150648.28297-1-marc.zyngier@arm.com>
In order to forward the guest's ARCH_WORKAROUND_2 calls to EL3,
add a small(-ish) sequence to handle it at EL2. Special care must
be taken to track the state of the guest itself by updating the
workaround flags. We also rely on patching to enable calls into
the firmware.
Note that since we need to execute branches, this always executes
after the Spectre-v2 mitigation has been applied.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm64/kernel/asm-offsets.c | 1 +
arch/arm64/kvm/hyp/hyp-entry.S | 38 +++++++++++++++++++++++++++++++++++++-
2 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index 5bdda651bd05..323aeb5f2fe6 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -136,6 +136,7 @@ int main(void)
#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(VCPU_WORKAROUND_FLAGS, offsetof(struct kvm_vcpu, arch.workaround_flags));
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/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S
index bffece27b5c1..5b1fa37ca1f4 100644
--- a/arch/arm64/kvm/hyp/hyp-entry.S
+++ b/arch/arm64/kvm/hyp/hyp-entry.S
@@ -106,8 +106,44 @@ el1_hvc_guest:
*/
ldr x1, [sp] // Guest's x0
eor w1, w1, #ARM_SMCCC_ARCH_WORKAROUND_1
+ cbz w1, wa_epilogue
+
+ /* ARM_SMCCC_ARCH_WORKAROUND_2 handling */
+ eor w1, w1, #(ARM_SMCCC_ARCH_WORKAROUND_1 ^ \
+ ARM_SMCCC_ARCH_WORKAROUND_2)
cbnz w1, el1_trap
- mov x0, x1
+
+#ifdef CONFIG_ARM64_SSBD
+alternative_cb arm64_enable_wa2_handling
+ b wa2_end
+alternative_cb_end
+ get_vcpu_ptr x2, x0
+ ldr x0, [x2, #VCPU_WORKAROUND_FLAGS]
+
+ /* Sanitize the argument and update the guest flags*/
+ ldr x1, [sp, #8] // Guest's x1
+ clz w1, w1 // Murphy's device:
+ lsr w1, w1, #5 // w1 = !!w1 without using
+ eor w1, w1, #1 // the flags...
+ bfi x0, x1, #VCPU_WORKAROUND_2_FLAG_SHIFT, #1
+ str x0, [x2, #VCPU_WORKAROUND_FLAGS]
+
+ /* Check that we actually need to perform the call */
+ hyp_ldr_this_cpu x0, arm64_ssbd_callback_required, x2
+ cbz x0, wa2_end
+
+ mov w0, #ARM_SMCCC_ARCH_WORKAROUND_2
+ smc #0
+
+ /* Don't leak data from the SMC call */
+ mov x3, xzr
+wa2_end:
+ mov x2, xzr
+ mov x1, xzr
+#endif
+
+wa_epilogue:
+ mov x0, xzr
add sp, sp, #16
eret
--
2.14.2
^ permalink raw reply related
* [PATCH 14/14] arm64: KVM: Add ARCH_WORKAROUND_2 discovery through ARCH_FEATURES_FUNC_ID
From: Marc Zyngier @ 2018-05-22 15:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180522150648.28297-1-marc.zyngier@arm.com>
Now that all our infrastructure is in place, let's expose the
availability of ARCH_WORKAROUND_2 to guests. We take this opportunity
to tidy up a couple of SMCCC constants.
Acked-by: Christoffer Dall <christoffer.dall@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm/include/asm/kvm_host.h | 12 ++++++++++++
arch/arm64/include/asm/kvm_host.h | 23 +++++++++++++++++++++++
arch/arm64/kvm/reset.c | 4 ++++
virt/kvm/arm/psci.c | 18 ++++++++++++++++--
4 files changed, 55 insertions(+), 2 deletions(-)
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index c7c28c885a19..d478766b56c1 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -315,6 +315,18 @@ static inline bool kvm_arm_harden_branch_predictor(void)
return false;
}
+#define KVM_SSBD_UNKNOWN -1
+#define KVM_SSBD_FORCE_DISABLE 0
+#define KVM_SSBD_EL1_ENTRY 1
+#define KVM_SSBD_FORCE_ENABLE 2
+#define KVM_SSBD_MITIGATED 3
+
+static inline int kvm_arm_have_ssbd(void)
+{
+ /* No way to detect it yet, pretend it is not there. */
+ return KVM_SSBD_UNKNOWN;
+}
+
static inline void kvm_vcpu_load_sysregs(struct kvm_vcpu *vcpu) {}
static inline void kvm_vcpu_put_sysregs(struct kvm_vcpu *vcpu) {}
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 9bef3f69bdcd..082b0dbb85c6 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -455,6 +455,29 @@ static inline bool kvm_arm_harden_branch_predictor(void)
return cpus_have_const_cap(ARM64_HARDEN_BRANCH_PREDICTOR);
}
+#define KVM_SSBD_UNKNOWN -1
+#define KVM_SSBD_FORCE_DISABLE 0
+#define KVM_SSBD_EL1_ENTRY 1
+#define KVM_SSBD_FORCE_ENABLE 2
+#define KVM_SSBD_MITIGATED 3
+
+static inline int kvm_arm_have_ssbd(void)
+{
+ switch (arm64_get_ssbd_state()) {
+ case ARM64_SSBD_FORCE_DISABLE:
+ return KVM_SSBD_FORCE_DISABLE;
+ case ARM64_SSBD_EL1_ENTRY:
+ return KVM_SSBD_EL1_ENTRY;
+ case ARM64_SSBD_FORCE_ENABLE:
+ return KVM_SSBD_FORCE_ENABLE;
+ case ARM64_SSBD_MITIGATED:
+ return KVM_SSBD_MITIGATED;
+ case ARM64_SSBD_UNKNOWN:
+ default:
+ return KVM_SSBD_UNKNOWN;
+ }
+}
+
void kvm_vcpu_load_sysregs(struct kvm_vcpu *vcpu);
void kvm_vcpu_put_sysregs(struct kvm_vcpu *vcpu);
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 3256b9228e75..20a7dfee8494 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -122,6 +122,10 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
/* Reset PMU */
kvm_pmu_vcpu_reset(vcpu);
+ /* Default workaround setup is enabled (if supported) */
+ if (kvm_arm_have_ssbd() == KVM_SSBD_EL1_ENTRY)
+ vcpu->arch.workaround_flags |= VCPU_WORKAROUND_2_FLAG;
+
/* Reset timer */
return kvm_timer_vcpu_reset(vcpu);
}
diff --git a/virt/kvm/arm/psci.c b/virt/kvm/arm/psci.c
index c4762bef13c6..4843bfa1f986 100644
--- a/virt/kvm/arm/psci.c
+++ b/virt/kvm/arm/psci.c
@@ -405,7 +405,7 @@ static int kvm_psci_call(struct kvm_vcpu *vcpu)
int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
{
u32 func_id = smccc_get_function(vcpu);
- u32 val = PSCI_RET_NOT_SUPPORTED;
+ u32 val = SMCCC_RET_NOT_SUPPORTED;
u32 feature;
switch (func_id) {
@@ -417,7 +417,21 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
switch(feature) {
case ARM_SMCCC_ARCH_WORKAROUND_1:
if (kvm_arm_harden_branch_predictor())
- val = 0;
+ val = SMCCC_RET_SUCCESS;
+ break;
+ case ARM_SMCCC_ARCH_WORKAROUND_2:
+ switch (kvm_arm_have_ssbd()) {
+ case KVM_SSBD_FORCE_DISABLE:
+ case KVM_SSBD_UNKNOWN:
+ break;
+ case KVM_SSBD_EL1_ENTRY:
+ val = SMCCC_RET_SUCCESS;
+ break;
+ case KVM_SSBD_FORCE_ENABLE:
+ case KVM_SSBD_MITIGATED:
+ val = SMCCC_RET_NOT_REQUIRED;
+ break;
+ }
break;
}
break;
--
2.14.2
^ permalink raw reply related
* [PATCH] arm64: alternative:flush cache with unpatched code
From: Suzuki K Poulose @ 2018-05-22 15:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1526952438-22126-1-git-send-email-rokhanna@nvidia.com>
Rohit,
On 22/05/18 02:27, Rohit Khanna wrote:
> In the current implementation, __apply_alternatives patches
> flush_icache_range and then executes it without invalidating the icache.
> Thus, icache can contain some of the old instructions for
> flush_icache_range. This can cause unpredictable behavior as during
> execution we can get a mix of old and new instructions for
> flush_icache_range.
>
> This patch :
>
> 1. Adds a new function flush_cache_kernel_range for flushing kernel
> memory range. This function is not patched during boot and can be safely
> used to flush cache during code patching.
>
> 2. Modifies __apply_alternatives so that it uses
> flush_cache_kernel_range to flush the cache range after patching code.
>
> Signed-off-by: Rohit Khanna <rokhanna@nvidia.com>
> ---
> arch/arm64/include/asm/cacheflush.h | 1 +
> arch/arm64/kernel/alternative.c | 2 +-
> arch/arm64/mm/cache.S | 42 +++++++++++++++++++++++++++++++++++++
> 3 files changed, 44 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/include/asm/cacheflush.h b/arch/arm64/include/asm/cacheflush.h
> index 0094c6653b06..54692fabdf74 100644
> --- a/arch/arm64/include/asm/cacheflush.h
> +++ b/arch/arm64/include/asm/cacheflush.h
> @@ -73,6 +73,7 @@
> */
> extern void flush_icache_range(unsigned long start, unsigned long end);
> extern int invalidate_icache_range(unsigned long start, unsigned long end);
> +extern void flush_cache_kernel_range(unsigned long start, unsigned long end);
> extern void __flush_dcache_area(void *addr, size_t len);
> extern void __inval_dcache_area(void *addr, size_t len);
> extern void __clean_dcache_area_poc(void *addr, size_t len);
> diff --git a/arch/arm64/kernel/alternative.c b/arch/arm64/kernel/alternative.c
> index 5c4bce4ac381..a5408a3c297a 100644
> --- a/arch/arm64/kernel/alternative.c
> +++ b/arch/arm64/kernel/alternative.c
> @@ -155,7 +155,7 @@ static void __apply_alternatives(void *alt_region, bool use_linear_alias)
>
> alt_cb(alt, origptr, updptr, nr_inst);
>
> - flush_icache_range((uintptr_t)origptr,
> + flush_cache_kernel_range((uintptr_t)origptr,
> (uintptr_t)(origptr + nr_inst));
> }
> }
> diff --git a/arch/arm64/mm/cache.S b/arch/arm64/mm/cache.S
> index 30334d81b021..4dd09352a044 100644
> --- a/arch/arm64/mm/cache.S
> +++ b/arch/arm64/mm/cache.S
> @@ -81,6 +81,48 @@ ENDPROC(flush_icache_range)
> ENDPROC(__flush_cache_user_range)
>
> /*
> + * flush_cache_kernel_range(start,end)
> + *
> + * Ensure that the I and D caches are coherent within specified kernel
> + * region.
> + * This is typically used when code has been written to a kernel memory
> + * region and will be executed.
> + *
> + * NOTE - This macro cannot have "alternatives" applied to it as its
> + * used to update alternatives
> + *
> + * - start - virtual start address of region
> + * - end - virtual end address of region
> + */
> +ENTRY(flush_cache_kernel_range)
> + dcache_line_size x2, x3
...
> + icache_line_size x2, x3
You must use raw_{d,i}cache_line_size helpers above to avoid
using hot-patched code. The above helpers are patched if you
have mismatched cache line sizes.
Suzuki
^ permalink raw reply
* [rjarzmik:work/dma_slave_map 12/15] drivers/mtd/nand/marvell_nand.c:2621:42: error: 'pxad_filter_fn' undeclared; did you mean 'dma_filter_fn'?
From: kbuild test robot @ 2018-05-22 15:10 UTC (permalink / raw)
To: linux-arm-kernel
Hi Robert,
FYI, the error/warning still remains.
tree: https://github.com/rjarzmik/linux work/dma_slave_map
head: 51b9077eb5c5f055bbbc8138b08830ce23ad340e
commit: 308214fe387eaf6b5547d01e573c41bb309a59fb [12/15] dmaengine: pxa: make the filter function internal
config: i386-allmodconfig (attached as .config)
compiler: gcc-7 (Debian 7.3.0-16) 7.3.0
reproduce:
git checkout 308214fe387eaf6b5547d01e573c41bb309a59fb
# save the attached .config to linux build tree
make ARCH=i386
All errors (new ones prefixed by >>):
In file included from drivers/mtd/nand/marvell_nand.c:21:0:
drivers/mtd/nand/marvell_nand.c: In function 'marvell_nfc_init_dma':
>> drivers/mtd/nand/marvell_nand.c:2621:42: error: 'pxad_filter_fn' undeclared (first use in this function); did you mean 'dma_filter_fn'?
dma_request_slave_channel_compat(mask, pxad_filter_fn,
^
include/linux/dmaengine.h:1408:46: note: in definition of macro 'dma_request_slave_channel_compat'
__dma_request_slave_channel_compat(&(mask), x, y, dev, name)
^
drivers/mtd/nand/marvell_nand.c:2621:42: note: each undeclared identifier is reported only once for each function it appears in
dma_request_slave_channel_compat(mask, pxad_filter_fn,
^
include/linux/dmaengine.h:1408:46: note: in definition of macro 'dma_request_slave_channel_compat'
__dma_request_slave_channel_compat(&(mask), x, y, dev, name)
^
vim +2621 drivers/mtd/nand/marvell_nand.c
02f26ecf Miquel Raynal 2018-01-09 2588
02f26ecf Miquel Raynal 2018-01-09 2589 static int marvell_nfc_init_dma(struct marvell_nfc *nfc)
02f26ecf Miquel Raynal 2018-01-09 2590 {
02f26ecf Miquel Raynal 2018-01-09 2591 struct platform_device *pdev = container_of(nfc->dev,
02f26ecf Miquel Raynal 2018-01-09 2592 struct platform_device,
02f26ecf Miquel Raynal 2018-01-09 2593 dev);
02f26ecf Miquel Raynal 2018-01-09 2594 struct dma_slave_config config = {};
02f26ecf Miquel Raynal 2018-01-09 2595 struct resource *r;
02f26ecf Miquel Raynal 2018-01-09 2596 dma_cap_mask_t mask;
02f26ecf Miquel Raynal 2018-01-09 2597 struct pxad_param param;
02f26ecf Miquel Raynal 2018-01-09 2598 int ret;
02f26ecf Miquel Raynal 2018-01-09 2599
02f26ecf Miquel Raynal 2018-01-09 2600 if (!IS_ENABLED(CONFIG_PXA_DMA)) {
02f26ecf Miquel Raynal 2018-01-09 2601 dev_warn(nfc->dev,
02f26ecf Miquel Raynal 2018-01-09 2602 "DMA not enabled in configuration\n");
02f26ecf Miquel Raynal 2018-01-09 2603 return -ENOTSUPP;
02f26ecf Miquel Raynal 2018-01-09 2604 }
02f26ecf Miquel Raynal 2018-01-09 2605
02f26ecf Miquel Raynal 2018-01-09 2606 ret = dma_set_mask_and_coherent(nfc->dev, DMA_BIT_MASK(32));
02f26ecf Miquel Raynal 2018-01-09 2607 if (ret)
02f26ecf Miquel Raynal 2018-01-09 2608 return ret;
02f26ecf Miquel Raynal 2018-01-09 2609
02f26ecf Miquel Raynal 2018-01-09 2610 r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
02f26ecf Miquel Raynal 2018-01-09 2611 if (!r) {
02f26ecf Miquel Raynal 2018-01-09 2612 dev_err(nfc->dev, "No resource defined for data DMA\n");
02f26ecf Miquel Raynal 2018-01-09 2613 return -ENXIO;
02f26ecf Miquel Raynal 2018-01-09 2614 }
02f26ecf Miquel Raynal 2018-01-09 2615
02f26ecf Miquel Raynal 2018-01-09 2616 param.drcmr = r->start;
02f26ecf Miquel Raynal 2018-01-09 2617 param.prio = PXAD_PRIO_LOWEST;
02f26ecf Miquel Raynal 2018-01-09 2618 dma_cap_zero(mask);
02f26ecf Miquel Raynal 2018-01-09 2619 dma_cap_set(DMA_SLAVE, mask);
02f26ecf Miquel Raynal 2018-01-09 2620 nfc->dma_chan =
02f26ecf Miquel Raynal 2018-01-09 @2621 dma_request_slave_channel_compat(mask, pxad_filter_fn,
02f26ecf Miquel Raynal 2018-01-09 2622 ¶m, nfc->dev,
02f26ecf Miquel Raynal 2018-01-09 2623 "data");
02f26ecf Miquel Raynal 2018-01-09 2624 if (!nfc->dma_chan) {
02f26ecf Miquel Raynal 2018-01-09 2625 dev_err(nfc->dev,
02f26ecf Miquel Raynal 2018-01-09 2626 "Unable to request data DMA channel\n");
02f26ecf Miquel Raynal 2018-01-09 2627 return -ENODEV;
02f26ecf Miquel Raynal 2018-01-09 2628 }
02f26ecf Miquel Raynal 2018-01-09 2629
02f26ecf Miquel Raynal 2018-01-09 2630 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
02f26ecf Miquel Raynal 2018-01-09 2631 if (!r)
02f26ecf Miquel Raynal 2018-01-09 2632 return -ENXIO;
02f26ecf Miquel Raynal 2018-01-09 2633
02f26ecf Miquel Raynal 2018-01-09 2634 config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
02f26ecf Miquel Raynal 2018-01-09 2635 config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
02f26ecf Miquel Raynal 2018-01-09 2636 config.src_addr = r->start + NDDB;
02f26ecf Miquel Raynal 2018-01-09 2637 config.dst_addr = r->start + NDDB;
02f26ecf Miquel Raynal 2018-01-09 2638 config.src_maxburst = 32;
02f26ecf Miquel Raynal 2018-01-09 2639 config.dst_maxburst = 32;
02f26ecf Miquel Raynal 2018-01-09 2640 ret = dmaengine_slave_config(nfc->dma_chan, &config);
02f26ecf Miquel Raynal 2018-01-09 2641 if (ret < 0) {
02f26ecf Miquel Raynal 2018-01-09 2642 dev_err(nfc->dev, "Failed to configure DMA channel\n");
02f26ecf Miquel Raynal 2018-01-09 2643 return ret;
02f26ecf Miquel Raynal 2018-01-09 2644 }
02f26ecf Miquel Raynal 2018-01-09 2645
02f26ecf Miquel Raynal 2018-01-09 2646 /*
02f26ecf Miquel Raynal 2018-01-09 2647 * DMA must act on length multiple of 32 and this length may be
02f26ecf Miquel Raynal 2018-01-09 2648 * bigger than the destination buffer. Use this buffer instead
02f26ecf Miquel Raynal 2018-01-09 2649 * for DMA transfers and then copy the desired amount of data to
02f26ecf Miquel Raynal 2018-01-09 2650 * the provided buffer.
02f26ecf Miquel Raynal 2018-01-09 2651 */
c495a927 Miquel Raynal 2018-01-19 2652 nfc->dma_buf = kmalloc(MAX_CHUNK_SIZE, GFP_KERNEL | GFP_DMA);
02f26ecf Miquel Raynal 2018-01-09 2653 if (!nfc->dma_buf)
02f26ecf Miquel Raynal 2018-01-09 2654 return -ENOMEM;
02f26ecf Miquel Raynal 2018-01-09 2655
02f26ecf Miquel Raynal 2018-01-09 2656 nfc->use_dma = true;
02f26ecf Miquel Raynal 2018-01-09 2657
02f26ecf Miquel Raynal 2018-01-09 2658 return 0;
02f26ecf Miquel Raynal 2018-01-09 2659 }
02f26ecf Miquel Raynal 2018-01-09 2660
:::::: The code at line 2621 was first introduced by commit
:::::: 02f26ecf8c772751d4b24744d487f6b1b20e75d4 mtd: nand: add reworked Marvell NAND controller driver
:::::: TO: Miquel Raynal <miquel.raynal@free-electrons.com>
:::::: CC: Boris Brezillon <boris.brezillon@free-electrons.com>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 63067 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180522/2702c73e/attachment-0001.gz>
^ permalink raw reply
* [PATCH 1/8] dt-bindings: tegra186-hsp: Add shared interrupts
From: Jon Hunter @ 2018-05-22 15:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180508114403.14499-2-mperttunen@nvidia.com>
On 08/05/18 12:43, Mikko Perttunen wrote:
> Non-doorbell interrupts are routed through "shared interrupts". These
> interrupts can be mapped to various internal interrupt lines. Add
> interrupt properties for shared interrupts to the tegra186-hsp device
> tree bindings.
Reading the Tegra documentation, although the doorbells have dedicated
interrupts, it appears that the doorbell interrupts can also be routed
via these shared interrupts.
> Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
> ---
> Documentation/devicetree/bindings/mailbox/nvidia,tegra186-hsp.txt | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/mailbox/nvidia,tegra186-hsp.txt b/Documentation/devicetree/bindings/mailbox/nvidia,tegra186-hsp.txt
> index b99d25fc2f26..9edcdf82d719 100644
> --- a/Documentation/devicetree/bindings/mailbox/nvidia,tegra186-hsp.txt
> +++ b/Documentation/devicetree/bindings/mailbox/nvidia,tegra186-hsp.txt
> @@ -21,6 +21,8 @@ Required properties:
> Contains a list of names for the interrupts described by the interrupt
> property. May contain the following entries, in any order:
> - "doorbell"
> + - "sharedN", where 'N' is a number from zero up to the number of
> + external interrupts supported by the HSP instance minus one.
> Users of this binding MUST look up entries in the interrupt property
> by name, using this interrupt-names property to do so.
> - interrupts
How is the mapping of shared-mailboxes interrupts to the actual
'sharedN' interrupt managed?
Cheers
Jon
--
nvpublic
^ permalink raw reply
* [PATCH 2/8] dt-bindings: serial: Add bindings for nvidia,tegra194-tcu
From: Jon Hunter @ 2018-05-22 15:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180508114403.14499-3-mperttunen@nvidia.com>
On 08/05/18 12:43, Mikko Perttunen wrote:
> Add bindings for the Tegra Combined UART device used to talk to the
> UART console on Tegra194 systems.
>
> Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
> ---
> .../bindings/serial/nvidia,tegra194-tcu.txt | 35 ++++++++++++++++++++++
> 1 file changed, 35 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/serial/nvidia,tegra194-tcu.txt
>
> diff --git a/Documentation/devicetree/bindings/serial/nvidia,tegra194-tcu.txt b/Documentation/devicetree/bindings/serial/nvidia,tegra194-tcu.txt
> new file mode 100644
> index 000000000000..86763bc5d74f
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/serial/nvidia,tegra194-tcu.txt
> @@ -0,0 +1,35 @@
> +NVIDIA Tegra Combined UART (TCU)
> +
> +The TCU is a system for sharing a hardware UART instance among multiple
> +systems withing the Tegra SoC. It is implemented through a mailbox-
> +based protocol where each "virtual UART" has a pair of mailboxes, one
> +for transmitting and one for receiving, that is used to communicate
> +with the hardware implementing the TCU.
> +
> +Required properties:
> +- name : Should be tcu
> +- compatible
> + Array of strings
> + One of:
> + - "nvidia,tegra194-tcu"
Nit. We should say what device the above compatibility is applicable for ...
- "nvidia,tegra194-tcu": for Tegra194
Cheers
Jon
--
nvpublic
^ permalink raw reply
* [PATCH 05/14] arm64: Add 'ssbd' command-line option
From: Randy Dunlap @ 2018-05-22 15:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180522150648.28297-6-marc.zyngier@arm.com>
On 05/22/2018 08:06 AM, Marc Zyngier wrote:
> On a system where the firmware implements ARCH_WORKAROUND_2,
> it may be useful to either permanently enable or disable the
> workaround for cases where the user decides that they'd rather
> not get a trap overhead, and keep the mitigation permanently
> on or off instead of switching it on exception entry/exit.
>
> In any case, default to the mitigation being enabled.
>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
> Documentation/admin-guide/kernel-parameters.txt | 17 ++++
> arch/arm64/include/asm/cpufeature.h | 6 ++
> arch/arm64/kernel/cpu_errata.c | 102 ++++++++++++++++++++----
> 3 files changed, 109 insertions(+), 16 deletions(-)
>
> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> index f2040d46f095..646e112c6f63 100644
> --- a/Documentation/admin-guide/kernel-parameters.txt
> +++ b/Documentation/admin-guide/kernel-parameters.txt
> @@ -4092,6 +4092,23 @@
> expediting. Set to zero to disable automatic
> expediting.
>
> + ssbd= [ARM64,HW]
> + Speculative Store Bypass Disable control
> +
> + On CPUs that are vulnerable to the Speculative
> + Store Bypass vulnerability and offer a
> + firmware based mitigation, this parameter
> + indicates how the mitigation should be used:
> +
> + force-on: Unconditionnaly enable mitigation for
Unconditionally
> + for both kernel and userspace
> + force-off: Unconditionnaly disable mitigation for
Unconditionally
> + for both kernel and userspace
> + kernel: Always enable mitigation in the
> + kernel, and offer a prctl interface
> + to allow userspace to register its
> + interest in being mitigated too.
> +
> stack_guard_gap= [MM]
> override the default stack gap protection. The value
> is in page units and it defines how many pages prior
--
~Randy
^ permalink raw reply
* [PATCH 4/8] mailbox: tegra-hsp: Refactor in preparation of mailboxes
From: Jon Hunter @ 2018-05-22 15:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180508114403.14499-5-mperttunen@nvidia.com>
On 08/05/18 12:43, Mikko Perttunen wrote:
> The HSP driver is currently in many places written with the assumption
> of only supporting doorbells. Prepare for the addition of shared
> mailbox support by removing these assumptions and cleaning up the code.
>
> Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
> ---
> drivers/mailbox/tegra-hsp.c | 124 +++++++++++++++++++++++++++++---------------
> 1 file changed, 82 insertions(+), 42 deletions(-)
>
> diff --git a/drivers/mailbox/tegra-hsp.c b/drivers/mailbox/tegra-hsp.c
> index 0cde356c11ab..16eb970f2c9f 100644
> --- a/drivers/mailbox/tegra-hsp.c
> +++ b/drivers/mailbox/tegra-hsp.c
> @@ -1,5 +1,5 @@
> /*
> - * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
> + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved.
> *
> * This program is free software; you can redistribute it and/or modify it
> * under the terms and conditions of the GNU General Public License,
> @@ -42,6 +42,7 @@ struct tegra_hsp_channel;
> struct tegra_hsp;
>
> struct tegra_hsp_channel {
> + unsigned int type;
> struct tegra_hsp *hsp;
> struct mbox_chan *chan;
> void __iomem *regs;
> @@ -55,6 +56,12 @@ struct tegra_hsp_doorbell {
> unsigned int index;
> };
>
> +static inline struct tegra_hsp_doorbell *
> +channel_to_doorbell(struct tegra_hsp_channel *channel)
> +{
> + return container_of(channel, struct tegra_hsp_doorbell, channel);
> +}
> +
> struct tegra_hsp_db_map {
> const char *name;
> unsigned int master;
> @@ -69,7 +76,7 @@ struct tegra_hsp {
> const struct tegra_hsp_soc *soc;
> struct mbox_controller mbox;
> void __iomem *regs;
> - unsigned int irq;
> + unsigned int doorbell_irq;
> unsigned int num_sm;
> unsigned int num_as;
> unsigned int num_ss;
> @@ -194,7 +201,7 @@ tegra_hsp_doorbell_create(struct tegra_hsp *hsp, const char *name,
> if (!db)
> return ERR_PTR(-ENOMEM);
>
> - offset = (1 + (hsp->num_sm / 2) + hsp->num_ss + hsp->num_as) << 16;
> + offset = (1 + (hsp->num_sm / 2) + hsp->num_ss + hsp->num_as) * SZ_64K;
> offset += index * 0x100;
>
> db->channel.regs = hsp->regs + offset;
> @@ -218,18 +225,8 @@ static void __tegra_hsp_doorbell_destroy(struct tegra_hsp_doorbell *db)
> kfree(db);
> }
>
> -static int tegra_hsp_doorbell_send_data(struct mbox_chan *chan, void *data)
> -{
> - struct tegra_hsp_doorbell *db = chan->con_priv;
> -
> - tegra_hsp_channel_writel(&db->channel, 1, HSP_DB_TRIGGER);
> -
> - return 0;
> -}
> -
> -static int tegra_hsp_doorbell_startup(struct mbox_chan *chan)
> +static int tegra_hsp_doorbell_startup(struct tegra_hsp_doorbell *db)
> {
> - struct tegra_hsp_doorbell *db = chan->con_priv;
> struct tegra_hsp *hsp = db->channel.hsp;
> struct tegra_hsp_doorbell *ccplex;
> unsigned long flags;
> @@ -260,9 +257,8 @@ static int tegra_hsp_doorbell_startup(struct mbox_chan *chan)
> return 0;
> }
>
> -static void tegra_hsp_doorbell_shutdown(struct mbox_chan *chan)
> +static void tegra_hsp_doorbell_shutdown(struct tegra_hsp_doorbell *db)
> {
> - struct tegra_hsp_doorbell *db = chan->con_priv;
> struct tegra_hsp *hsp = db->channel.hsp;
> struct tegra_hsp_doorbell *ccplex;
> unsigned long flags;
> @@ -281,35 +277,61 @@ static void tegra_hsp_doorbell_shutdown(struct mbox_chan *chan)
> spin_unlock_irqrestore(&hsp->lock, flags);
> }
>
> -static const struct mbox_chan_ops tegra_hsp_doorbell_ops = {
> - .send_data = tegra_hsp_doorbell_send_data,
> - .startup = tegra_hsp_doorbell_startup,
> - .shutdown = tegra_hsp_doorbell_shutdown,
> +static int tegra_hsp_send_data(struct mbox_chan *chan, void *data)
> +{
> + struct tegra_hsp_channel *channel = chan->con_priv;
> + struct tegra_hsp_doorbell *db;
> +
> + switch (channel->type) {
> + case TEGRA_HSP_MBOX_TYPE_DB:
> + db = channel_to_doorbell(channel);
> + tegra_hsp_channel_writel(&db->channel, 1, HSP_DB_TRIGGER);
The above appears to be redundant. We go from channel to db and then end
up passing channels. Do we really need the 'db' struct above?
> + }
> +
> + return -EINVAL;
Does this function always return -EINVAL?
> +}
> +
> +static int tegra_hsp_startup(struct mbox_chan *chan)
> +{
> + struct tegra_hsp_channel *channel = chan->con_priv;
> +
> + switch (channel->type) {
> + case TEGRA_HSP_MBOX_TYPE_DB:
> + return tegra_hsp_doorbell_startup(channel_to_doorbell(channel));
> + }
> +
> + return -EINVAL;
> +}
> +
> +static void tegra_hsp_shutdown(struct mbox_chan *chan)
> +{
> + struct tegra_hsp_channel *channel = chan->con_priv;
> +
> + switch (channel->type) {
> + case TEGRA_HSP_MBOX_TYPE_DB:
> + tegra_hsp_doorbell_shutdown(channel_to_doorbell(channel));
> + break;
> + }
> +}
> +
> +static const struct mbox_chan_ops tegra_hsp_ops = {
> + .send_data = tegra_hsp_send_data,
> + .startup = tegra_hsp_startup,
> + .shutdown = tegra_hsp_shutdown,
> };
>
> -static struct mbox_chan *of_tegra_hsp_xlate(struct mbox_controller *mbox,
> - const struct of_phandle_args *args)
> +static struct mbox_chan *tegra_hsp_doorbell_xlate(struct tegra_hsp *hsp,
> + unsigned int master)
> {
> struct tegra_hsp_channel *channel = ERR_PTR(-ENODEV);
> - struct tegra_hsp *hsp = to_tegra_hsp(mbox);
> - unsigned int type = args->args[0];
> - unsigned int master = args->args[1];
> struct tegra_hsp_doorbell *db;
> struct mbox_chan *chan;
> unsigned long flags;
> unsigned int i;
>
> - switch (type) {
> - case TEGRA_HSP_MBOX_TYPE_DB:
> - db = tegra_hsp_doorbell_get(hsp, master);
> - if (db)
> - channel = &db->channel;
> -
> - break;
> -
> - default:
> - break;
> - }
> + db = tegra_hsp_doorbell_get(hsp, master);
> + if (db)
> + channel = &db->channel;
>
> if (IS_ERR(channel))
> return ERR_CAST(channel);
> @@ -321,6 +343,7 @@ static struct mbox_chan *of_tegra_hsp_xlate(struct mbox_controller *mbox,
> if (!chan->con_priv) {
> chan->con_priv = channel;
> channel->chan = chan;
> + channel->type = TEGRA_HSP_MBOX_TYPE_DB;
> break;
I see that you are making the above only used for doorbells, but don't
we still need to set the chan->con_priv for shared mailboxes as well?
Cheers
Jon
--
nvpublic
^ permalink raw reply
* [PATCH 1/2] arm64: dts: renesas: r8a77980: add GEther support
From: Sergei Shtylyov @ 2018-05-22 15:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAMuHMdW9UzOGV_zh3NxugYrj0j0qszX+NFoZtFvZRD9CNMHt+w@mail.gmail.com>
On 05/22/2018 02:48 PM, Geert Uytterhoeven wrote:
>> Define the generic R8A77980 part of the GEther device node.
>>
>> Based on the original (and large) patch by Vladimir Barinov.
>>
>> Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
>> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
>
> Thanks for your patch!
>
> With the below addressed:
> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Thanks!
>> --- renesas.orig/arch/arm64/boot/dts/renesas/r8a77980.dtsi
>> +++ renesas/arch/arm64/boot/dts/renesas/r8a77980.dtsi
>> @@ -417,6 +417,17 @@
>> dma-channels = <16>;
>> };
>>
>> + gether: ethernet at e7400000 {
>> + compatible = "renesas,gether-r8a77980";
>> + reg = <0 0xe7400000 0 0x1000>;
>> + interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
>> + clocks = <&cpg CPG_MOD 813>;
>> + power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
>
> resets = <&cpg 813>;
As usual...
>
>> + #address-cells = <1>;
>> + #size-cells = <0>;
>> + status = "disabled";
>
> Any default phy-mode needed?
A default "phy-mode" IMO make sense when the MAC supports a single
PHY interface mode. In this case, both RMII and RGMII are supported, so
I coulsn't choose a default...
>> + };
>> +
>> mmc0: mmc at ee140000 {
>> compatible = "renesas,sdhi-r8a77980",
>> "renesas,rcar-gen3-sdhi";
>
>
> Gr{oetje,eeting}s,
>
> Geert
>
^ permalink raw reply
* [PATCH v3] ARM: dts: stm32: Add ADC support to stm32mp157c
From: Fabrice Gasnier @ 2018-05-22 15:45 UTC (permalink / raw)
To: linux-arm-kernel
stm32mp157c has an ADC block with two physical ADCs.
Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com>
---
Changes in v3:
- Add dmas since dmamux1 has been added on top of stm32-next
---
arch/arm/boot/dts/stm32mp157c.dtsi | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/arch/arm/boot/dts/stm32mp157c.dtsi b/arch/arm/boot/dts/stm32mp157c.dtsi
index b66f673..66d7496 100644
--- a/arch/arm/boot/dts/stm32mp157c.dtsi
+++ b/arch/arm/boot/dts/stm32mp157c.dtsi
@@ -600,6 +600,42 @@
clocks = <&rcc DMAMUX>;
};
+ adc: adc at 48003000 {
+ compatible = "st,stm32mp1-adc-core";
+ reg = <0x48003000 0x400>;
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&rcc ADC12>, <&rcc ADC12_K>;
+ clock-names = "bus", "adc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+
+ adc1: adc at 0 {
+ compatible = "st,stm32mp1-adc";
+ #io-channel-cells = <1>;
+ reg = <0x0>;
+ interrupt-parent = <&adc>;
+ interrupts = <0>;
+ dmas = <&dmamux1 9 0x400 0x01>;
+ dma-names = "rx";
+ status = "disabled";
+ };
+
+ adc2: adc at 100 {
+ compatible = "st,stm32mp1-adc";
+ #io-channel-cells = <1>;
+ reg = <0x100>;
+ interrupt-parent = <&adc>;
+ interrupts = <1>;
+ dmas = <&dmamux1 10 0x400 0x01>;
+ dma-names = "rx";
+ status = "disabled";
+ };
+ };
+
rcc: rcc at 50000000 {
compatible = "st,stm32mp1-rcc", "syscon";
reg = <0x50000000 0x1000>;
--
1.9.1
^ permalink raw reply related
* [PATCH 10/14] arm64: ssbd: Add prctl interface for per-thread mitigation
From: Dominik Brodowski @ 2018-05-22 15:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180522150648.28297-11-marc.zyngier@arm.com>
On Tue, May 22, 2018 at 04:06:44PM +0100, Marc Zyngier wrote:
> If running on a system that performs dynamic SSBD mitigation, allow
> userspace to request the mitigation for itself. This is implemented
> as a prctl call, allowing the mitigation to be enabled or disabled at
> will for this particular thread.
>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
> arch/arm64/kernel/Makefile | 1 +
> arch/arm64/kernel/ssbd.c | 107 +++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 108 insertions(+)
> create mode 100644 arch/arm64/kernel/ssbd.c
>
> diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
> index bf825f38d206..0025f8691046 100644
> --- a/arch/arm64/kernel/Makefile
> +++ b/arch/arm64/kernel/Makefile
> @@ -54,6 +54,7 @@ arm64-obj-$(CONFIG_ARM64_RELOC_TEST) += arm64-reloc-test.o
> arm64-reloc-test-y := reloc_test_core.o reloc_test_syms.o
> arm64-obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
> arm64-obj-$(CONFIG_ARM_SDE_INTERFACE) += sdei.o
> +arm64-obj-$(CONFIG_ARM64_SSBD) += ssbd.o
>
> obj-y += $(arm64-obj-y) vdso/ probes/
> obj-m += $(arm64-obj-m)
> diff --git a/arch/arm64/kernel/ssbd.c b/arch/arm64/kernel/ssbd.c
> new file mode 100644
> index 000000000000..34e3c430176b
> --- /dev/null
> +++ b/arch/arm64/kernel/ssbd.c
> @@ -0,0 +1,107 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2018 ARM Ltd, All Rights Reserved.
> + */
> +
> +#include <linux/sched.h>
> +#include <linux/thread_info.h>
> +
> +#include <asm/cpufeature.h>
> +
> +/*
> + * prctl interface for SSBD
> + * FIXME: Drop the below ifdefery once the common interface has been merged.
> + */
> +#ifdef PR_SPEC_STORE_BYPASS
That FIXME wants to be looked at.
Thanks,
Dominik
^ permalink raw reply
* [PATCH v2 3/3] ARM: dts: stm32: Add ADC support to stm32mp157c
From: Fabrice Gasnier @ 2018-05-22 15:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180507182317.7406c682@archlinux>
On 05/07/2018 07:23 PM, Jonathan Cameron wrote:
> On Wed, 2 May 2018 09:44:51 +0200
> Fabrice Gasnier <fabrice.gasnier@st.com> wrote:
>
>> stm32mp157c has an ADC block with two physical ADCs.
>>
>> Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com>
> The driver support is now queued up in the IIO tree and should
> be in Linux next later this week.
Hi,
Many Thanks Jonathan :-)
Alex, I just sent an updated version (v3) of this patch (with additional
dmas).
Best Regards,
Fabrice
>
> Thanks,
>
> Jonathan
>
>> ---
>> arch/arm/boot/dts/stm32mp157c.dtsi | 32 ++++++++++++++++++++++++++++++++
>> 1 file changed, 32 insertions(+)
>>
>> diff --git a/arch/arm/boot/dts/stm32mp157c.dtsi b/arch/arm/boot/dts/stm32mp157c.dtsi
>> index bc3eddc..7758a90 100644
>> --- a/arch/arm/boot/dts/stm32mp157c.dtsi
>> +++ b/arch/arm/boot/dts/stm32mp157c.dtsi
>> @@ -160,6 +160,38 @@
>> status = "disabled";
>> };
>>
>> + adc: adc at 48003000 {
>> + compatible = "st,stm32mp1-adc-core";
>> + reg = <0x48003000 0x400>;
>> + interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
>> + <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
>> + clocks = <&rcc ADC12>, <&rcc ADC12_K>;
>> + clock-names = "bus", "adc";
>> + interrupt-controller;
>> + #interrupt-cells = <1>;
>> + #address-cells = <1>;
>> + #size-cells = <0>;
>> + status = "disabled";
>> +
>> + adc1: adc at 0 {
>> + compatible = "st,stm32mp1-adc";
>> + #io-channel-cells = <1>;
>> + reg = <0x0>;
>> + interrupt-parent = <&adc>;
>> + interrupts = <0>;
>> + status = "disabled";
>> + };
>> +
>> + adc2: adc at 100 {
>> + compatible = "st,stm32mp1-adc";
>> + #io-channel-cells = <1>;
>> + reg = <0x100>;
>> + interrupt-parent = <&adc>;
>> + interrupts = <1>;
>> + status = "disabled";
>> + };
>> + };
>> +
>> rcc: rcc at 50000000 {
>> compatible = "st,stm32mp1-rcc", "syscon";
>> reg = <0x50000000 0x1000>;
>
^ permalink raw reply
* [PATCH] drivers/perf: Remove ARM_SPE_PMU explicit PERF_EVENTS dependency
From: John Garry @ 2018-05-22 15:54 UTC (permalink / raw)
To: linux-arm-kernel
Since commit bddb9b68d3fb ("drivers/perf: commonise PERF_EVENTS
dependency"), all perf drivers depend on PERF_EVENTS config under a
common menu.
Config ARM_SPE_PMU still declares explicitly a dependency on
PERF_EVENTS, which is unneeded, so remove it.
Signed-off-by: John Garry <john.garry@huawei.com>
diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
index 28bb5a0..90ce4da 100644
--- a/drivers/perf/Kconfig
+++ b/drivers/perf/Kconfig
@@ -94,7 +94,7 @@ config XGENE_PMU
config ARM_SPE_PMU
tristate "Enable support for the ARMv8.2 Statistical Profiling Extension"
- depends on PERF_EVENTS && ARM64
+ depends on ARM64
help
Enable perf support for the ARMv8.2 Statistical Profiling
Extension, which provides periodic sampling of operations in
--
1.9.1
^ permalink raw reply related
* [PATCH v9 11/15] dt-bindings: cpufreq: Document operating-points-v2-kryo-cpu
From: Rob Herring @ 2018-05-22 15:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1526901932-9514-12-git-send-email-ilialin@codeaurora.org>
On Mon, May 21, 2018 at 02:25:28PM +0300, Ilia Lin wrote:
> The qcom-cpufreq-kryo driver reads the msm-id and efuse value from the SoC
> to provide the OPP framework with required information.
> This is used to determine the voltage and frequency value for each OPP of
> operating-points-v2 table when it is parsed by the OPP framework.
>
> This change adds documentation for the DT bindings.
> The "operating-points-v2-kryo-cpu" DT extends the "operating-points-v2"
> with following parameters:
> - nvmem-cells (NVMEM area containig the speedbin information)
> - opp-supported-hw: A single 32 bit bitmap value,
> representing compatible HW:
> 0: MSM8996 V3, speedbin 0
> 1: MSM8996 V3, speedbin 1
> 2: MSM8996 V3, speedbin 2
> 3: unused
> 4: MSM8996 SG, speedbin 0
> 5: MSM8996 SG, speedbin 1
> 6: MSM8996 SG, speedbin 2
> 7-31: unused
>
> Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
> Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Please add acks/reviewed-bys when posting new versions.
Rob
^ permalink raw reply
* [PATCH v6 2/5] Documentation: dt-bindings: phy: add phy_config for Rockchip USB Type-C PHY
From: Rob Herring @ 2018-05-22 15:58 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1526895424-22894-2-git-send-email-hl@rock-chips.com>
On Mon, May 21, 2018 at 05:37:01PM +0800, Lin Huang wrote:
> If want to do training outside DP Firmware, need phy voltage swing
> and pre_emphasis value.
>
> Signed-off-by: Lin Huang <hl@rock-chips.com>
> ---
> Changes in v2:
> - None
> Changes in v3:
> - modify property description and add this property to Example
> Changes in v4:
> - None
> Changes in v5:
> - None
> Changes in v6:
> - change rockchip,phy_config to rockchip,phy-config and descript it in detail.
>
> .../devicetree/bindings/phy/phy-rockchip-typec.txt | 36 +++++++++++++++++++++-
> 1 file changed, 35 insertions(+), 1 deletion(-)
Reviewed-by: Rob Herring <robh@kernel.org>
^ permalink raw reply
* [PATCH v10 00/18] KVM: arm64: Optimise FPSIMD context switching
From: Dave Martin @ 2018-05-22 16:05 UTC (permalink / raw)
To: linux-arm-kernel
Note: Most of these patches are Arm-specific. People not Cc'd on the
whole series can find it in the linux-arm-kernel archive [2].
This series aims to improve the way FPSIMD context is handled by KVM.
Changes since the previous v9 [1] are mostly minor, but there are some
fixes worthy of closer attention.
In addition to addressing a review comment by Marc on the changes in v9,
this series attempts to fix a NULL-dereference bug observed by Marc on
ESPRESSOBin [5]. A reproducer for a similar bug is documented in [6],
and this series fixes the observed bug (in patches 1 and 7). At the
moment, this is my best hypothesis for the ESPRESSOBin failure, though
the relationship is unproven and we have no reproducer for the latter.
The changes are summarised in the individual patches.
Reviewers please note:
* Since v8, patches 10 and 14 have changed. Reviewer tags have been
stripped from patch 14, due to non-trivial changes in v9 of the
series: see the patch for details.
* Since v9, patches 1 and 7 are also new, and correct a latent bug in
FPSIMD context handling which is exposed by this series.
If people could take a close look at the above patches, that would be
much appreciated.
Cheers
---Dave
[1] [PATCH v9 00/16] KVM: arm64: Optimise FPSIMD context switching
http://lists.infradead.org/pipermail/linux-arm-kernel/2018-May/579569.html
[2] linux-arm-kernel archive
http://lists.infradead.org/pipermail/linux-arm-kernel/2018-May/thread.html
[3] [kvmarm:queue 9/29] arch/arm/kvm/../../../virt/kvm/arm/arm.c:783:3: error: implicit declaration of function 'kvm_arch_vcpu_ctxsync_fp'; did you mean 'kvm_arch_vcpu_put_fp'?
http://lists.infradead.org/pipermail/linux-arm-kernel/2018-May/579400.html
[4] [kvmarm:queue 13/29] arch/arm/kvm/../../../virt/kvm/arm/arm.c:1598:6: error: implicit declaration of function 'system_supports_sve'
http://lists.infradead.org/pipermail/linux-arm-kernel/2018-May/579399.html
[5] [PULL v8] KVM: arm64: Optimise FPSIMD context switching
http://lists.infradead.org/pipermail/linux-arm-kernel/2018-May/579353.html
Christoffer Dall (1):
KVM: arm/arm64: Introduce kvm_arch_vcpu_run_pid_change
Dave Martin (17):
arm64: fpsimd: Fix TIF_FOREIGN_FPSTATE after invalidating cpu regs
thread_info: Add update_thread_flag() helpers
arm64: Use update{,_tsk}_thread_flag()
KVM: arm64: Convert lazy FPSIMD context switch trap to C
arm64: fpsimd: Generalise context saving for non-task contexts
arm64: fpsimd: Eliminate task->mm checks
arm64/sve: Refactor user SVE trap maintenance for external use
KVM: arm64: Repurpose vcpu_arch.debug_flags for general-purpose flags
KVM: arm64: Optimise FPSIMD handling to reduce guest/host thrashing
arm64/sve: Move read_zcr_features() out of cpufeature.h
arm64/sve: Switch sve_pffr() argument from task to thread
arm64/sve: Move sve_pffr() to fpsimd.h and make inline
KVM: arm64: Save host SVE context as appropriate
KVM: arm64: Remove eager host SVE state saving
KVM: arm64: Remove redundant *exit_code changes in fpsimd_guest_exit()
KVM: arm64: Fold redundant exit code checks out of fixup_guest_exit()
KVM: arm64: Invoke FPSIMD context switch trap from C
arch/arm/include/asm/kvm_host.h | 10 +-
arch/arm64/Kconfig | 7 ++
arch/arm64/include/asm/cpufeature.h | 29 ------
arch/arm64/include/asm/fpsimd.h | 21 +++++
arch/arm64/include/asm/kvm_asm.h | 3 -
arch/arm64/include/asm/kvm_host.h | 45 +++++++--
arch/arm64/include/asm/processor.h | 2 +
arch/arm64/include/asm/thread_info.h | 1 +
arch/arm64/kernel/fpsimd.c | 176 +++++++++++++++++------------------
arch/arm64/kernel/ptrace.c | 1 +
arch/arm64/kvm/Kconfig | 1 +
arch/arm64/kvm/Makefile | 2 +-
arch/arm64/kvm/debug.c | 8 +-
arch/arm64/kvm/fpsimd.c | 110 ++++++++++++++++++++++
arch/arm64/kvm/hyp/debug-sr.c | 6 +-
arch/arm64/kvm/hyp/entry.S | 43 ---------
arch/arm64/kvm/hyp/hyp-entry.S | 19 ----
arch/arm64/kvm/hyp/switch.c | 124 ++++++++++++++++--------
arch/arm64/kvm/hyp/sysreg-sr.c | 4 +-
arch/arm64/kvm/sys_regs.c | 9 +-
include/linux/kvm_host.h | 9 ++
include/linux/sched.h | 6 ++
include/linux/thread_info.h | 11 +++
virt/kvm/Kconfig | 3 +
virt/kvm/arm/arm.c | 14 ++-
virt/kvm/kvm_main.c | 7 +-
26 files changed, 416 insertions(+), 255 deletions(-)
create mode 100644 arch/arm64/kvm/fpsimd.c
--
2.1.4
^ permalink raw reply
* [PATCH v10 01/18] arm64: fpsimd: Fix TIF_FOREIGN_FPSTATE after invalidating cpu regs
From: Dave Martin @ 2018-05-22 16:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1527005119-6842-1-git-send-email-Dave.Martin@arm.com>
fpsimd_last_state.st is set to NULL as a way of indicating that
current's FPSIMD registers are no longer loaded in the cpu. In
particular, this is done when the kernel temporarily uses or
clobbers the FPSIMD registers for its own purposes, as in CPU PM or
kernel-mode NEON, resulting in them being populated with garbage
data not belonging to a task.
Commit 17eed27b02da ("arm64/sve: KVM: Prevent guests from using
SVE") factors this operation out as a new helper
fpsimd_flush_cpu_state() to make it clearer what is being done
here, and on SVE systems this helper is now used, via
kvm_fpsimd_flush_cpu_state(), to invalidate the registers after KVM
has run a vcpu. The reason for this is that KVM does not yet
understand how to restore the full host SVE registers itself after
loading the guest FPSIMD context into them.
This exposes a particular problem: if fpsimd_last_state.st is set
to NULL without also setting TIF_FOREIGN_FPSTATE, the kernel may
continue to think that current's FPSIMD registers are live even
though they have actually been clobbered.
Prior to the aforementioned commit, the only path where
fpsimd_last_state.st is set to NULL without setting
TIF_FOREIGN_FPSTATE is when kernel_neon_begin() is called by a
kernel thread (where current->mm can be NULL). This does not
matter, because the only harm is that at context-switch time
fpsimd_thread_switch() may unnecessarily save the FPSIMD registers
back to current's thread_struct (even though kernel threads are not
considered to have any FPSIMD context of their own and the
registers will never be reloaded).
Note that although CPU_PM_ENTER lacks the TIF_FOREIGN_FPSTATE
setting, every CPU passing through that path must subsequently pass
through CPU_PM_EXIT before it can re-enter the kernel proper.
CPU_PM_EXIT sets the flag.
The sve_flush_cpu_state() function added by commit 17eed27b02da
also lacks the proper maintenance of TIF_FOREIGN_FPSTATE. This may
cause the bits of a host task's SVE registers that do not alias the
FPSIMD register file to spontaneously appear zeroed if a KVM vcpu
runs in the same task in the meantime. Although this effect is
hidden by the fact that the non-FPSIMD bits of the SVE registers
are zeroed by a syscall anyway, it is doubtless a bad idea to rely
on these different code paths interacting correctly under future
maintenance.
This patch makes TIF_FOREIGN_FPSTATE an unconditional side-effect
of fpsimd_flush_cpu_state(), and removes the set_thread_flag()
calls that become redunant as a result. This ensures that
TIF_FOREIGN_FPSTATE cannot remain clear if the FPSIMD state in the
FPSIMD registers is invalid.
Signed-off-by: Dave Martin <Dave.Martin@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
Changes since v9:
* New patch (bugfix to subsequent commits).
---
arch/arm64/kernel/fpsimd.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 87a3536..12e1c96 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -1067,6 +1067,7 @@ void fpsimd_flush_task_state(struct task_struct *t)
static inline void fpsimd_flush_cpu_state(void)
{
__this_cpu_write(fpsimd_last_state.st, NULL);
+ set_thread_flag(TIF_FOREIGN_FPSTATE);
}
/*
@@ -1121,10 +1122,8 @@ void kernel_neon_begin(void)
__this_cpu_write(kernel_neon_busy, true);
/* Save unsaved task fpsimd state, if any: */
- if (current->mm) {
+ if (current->mm)
task_fpsimd_save();
- set_thread_flag(TIF_FOREIGN_FPSTATE);
- }
/* Invalidate any task state remaining in the fpsimd regs: */
fpsimd_flush_cpu_state();
@@ -1251,8 +1250,6 @@ static int fpsimd_cpu_pm_notifier(struct notifier_block *self,
fpsimd_flush_cpu_state();
break;
case CPU_PM_EXIT:
- if (current->mm)
- set_thread_flag(TIF_FOREIGN_FPSTATE);
break;
case CPU_PM_ENTER_FAILED:
default:
--
2.1.4
^ permalink raw reply related
* [PATCH v10 02/18] thread_info: Add update_thread_flag() helpers
From: Dave Martin @ 2018-05-22 16:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1527005119-6842-1-git-send-email-Dave.Martin@arm.com>
There are a number of bits of code sprinkled around the kernel to
set a thread flag if a certain condition is true, and clear it
otherwise.
To help make those call sites terser and less cumbersome, this
patch adds a new family of thread flag manipulators
update*_thread_flag([...,] flag, cond)
which do the equivalent of:
if (cond)
set*_thread_flag([...,] flag);
else
clear*_thread_flag([...,] flag);
Signed-off-by: Dave Martin <Dave.Martin@arm.com>
Acked-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Oleg Nesterov <oleg@redhat.com>
---
include/linux/sched.h | 6 ++++++
include/linux/thread_info.h | 11 +++++++++++
2 files changed, 17 insertions(+)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index b3d697f..c2c3051 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1578,6 +1578,12 @@ static inline void clear_tsk_thread_flag(struct task_struct *tsk, int flag)
clear_ti_thread_flag(task_thread_info(tsk), flag);
}
+static inline void update_tsk_thread_flag(struct task_struct *tsk, int flag,
+ bool value)
+{
+ update_ti_thread_flag(task_thread_info(tsk), flag, value);
+}
+
static inline int test_and_set_tsk_thread_flag(struct task_struct *tsk, int flag)
{
return test_and_set_ti_thread_flag(task_thread_info(tsk), flag);
diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h
index cf2862b..8d8821b 100644
--- a/include/linux/thread_info.h
+++ b/include/linux/thread_info.h
@@ -60,6 +60,15 @@ static inline void clear_ti_thread_flag(struct thread_info *ti, int flag)
clear_bit(flag, (unsigned long *)&ti->flags);
}
+static inline void update_ti_thread_flag(struct thread_info *ti, int flag,
+ bool value)
+{
+ if (value)
+ set_ti_thread_flag(ti, flag);
+ else
+ clear_ti_thread_flag(ti, flag);
+}
+
static inline int test_and_set_ti_thread_flag(struct thread_info *ti, int flag)
{
return test_and_set_bit(flag, (unsigned long *)&ti->flags);
@@ -79,6 +88,8 @@ static inline int test_ti_thread_flag(struct thread_info *ti, int flag)
set_ti_thread_flag(current_thread_info(), flag)
#define clear_thread_flag(flag) \
clear_ti_thread_flag(current_thread_info(), flag)
+#define update_thread_flag(flag, value) \
+ update_ti_thread_flag(current_thread_info(), flag, value)
#define test_and_set_thread_flag(flag) \
test_and_set_ti_thread_flag(current_thread_info(), flag)
#define test_and_clear_thread_flag(flag) \
--
2.1.4
^ permalink raw reply related
* [PATCH v10 03/18] arm64: Use update{,_tsk}_thread_flag()
From: Dave Martin @ 2018-05-22 16:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1527005119-6842-1-git-send-email-Dave.Martin@arm.com>
This patch uses the new update_thread_flag() helpers to simplify a
couple of if () set; else clear; constructs.
No functional change.
Signed-off-by: Dave Martin <Dave.Martin@arm.com>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
arch/arm64/kernel/fpsimd.c | 18 ++++++++----------
1 file changed, 8 insertions(+), 10 deletions(-)
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 12e1c96..9d85373 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -618,10 +618,8 @@ int sve_set_vector_length(struct task_struct *task,
task->thread.sve_vl = vl;
out:
- if (flags & PR_SVE_VL_INHERIT)
- set_tsk_thread_flag(task, TIF_SVE_VL_INHERIT);
- else
- clear_tsk_thread_flag(task, TIF_SVE_VL_INHERIT);
+ update_tsk_thread_flag(task, TIF_SVE_VL_INHERIT,
+ flags & PR_SVE_VL_INHERIT);
return 0;
}
@@ -910,12 +908,12 @@ void fpsimd_thread_switch(struct task_struct *next)
* the TIF_FOREIGN_FPSTATE flag so the state will be loaded
* upon the next return to userland.
*/
- if (__this_cpu_read(fpsimd_last_state.st) ==
- &next->thread.uw.fpsimd_state
- && next->thread.fpsimd_cpu == smp_processor_id())
- clear_tsk_thread_flag(next, TIF_FOREIGN_FPSTATE);
- else
- set_tsk_thread_flag(next, TIF_FOREIGN_FPSTATE);
+ bool wrong_task = __this_cpu_read(fpsimd_last_state.st) !=
+ &next->thread.uw.fpsimd_state;
+ bool wrong_cpu = next->thread.fpsimd_cpu != smp_processor_id();
+
+ update_tsk_thread_flag(next, TIF_FOREIGN_FPSTATE,
+ wrong_task || wrong_cpu);
}
}
--
2.1.4
^ 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