* Re: [PATCH 2/2] mm/sparse: add common helper to mark all memblocks present
From: Logan Gunthorpe @ 2018-12-06 17:40 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-arch, Albert Ou, Arnd Bergmann, linux-sh, Palmer Dabbelt,
linux-kernel, Stephen Bates, linux-mm, Michal Hocko,
Vlastimil Babka, linux-riscv, Christoph Hellwig, linux-arm-kernel,
Oscar Salvador
In-Reply-To: <20181107121207.62cb37cf58484b7cc80a8fd8@linux-foundation.org>
Hey Andrew,
On 2018-11-07 1:12 p.m., Andrew Morton wrote:
> Acked-by: Andrew Morton <akpm@linux-foundation.org>
>
> I can grab both patches and shall sneak them into 4.20-rcX, but feel
> free to merge them into some git tree if you'd prefer. If I see them
> turn up in linux-next I shall drop my copy.
Just wanted to check if you are still planning to get these patches into
4.20-rcX. It would really help us if you can do this seeing we then
won't have to delay a cycle and can target the riscv sparsemem code for
4.21.
Thanks,
Logan
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v3 6/8] arm64: KVM: Add synchronization on translation regime change for erratum 1165522
From: Marc Zyngier @ 2018-12-06 17:31 UTC (permalink / raw)
To: linux-arm-kernel, kvmarm, kvm
Cc: Mark Rutland, Suzuki K Poulose, Catalin Marinas, Will Deacon,
Christoffer Dall, James Morse
In-Reply-To: <20181206173126.139877-1-marc.zyngier@arm.com>
In order to ensure that slipping HCR_EL2.TGE is done at the right
time when switching translation regime, let insert the required ISBs
that will be patched in when erratum 1165522 is detected.
Take this opportunity to add the missing include of asm/alternative.h
which was getting there by pure luck.
Reviewed-by: James Morse <james.morse@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm64/include/asm/kvm_hyp.h | 8 ++++++++
arch/arm64/kvm/hyp/switch.c | 19 +++++++++++++++++++
2 files changed, 27 insertions(+)
diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h
index 23aca66767f9..a80a7ef57325 100644
--- a/arch/arm64/include/asm/kvm_hyp.h
+++ b/arch/arm64/include/asm/kvm_hyp.h
@@ -20,6 +20,7 @@
#include <linux/compiler.h>
#include <linux/kvm_host.h>
+#include <asm/alternative.h>
#include <asm/sysreg.h>
#define __hyp_text __section(.hyp.text) notrace
@@ -163,6 +164,13 @@ static __always_inline void __hyp_text __load_guest_stage2(struct kvm *kvm)
{
write_sysreg(kvm->arch.vtcr, vtcr_el2);
write_sysreg(kvm->arch.vttbr, vttbr_el2);
+
+ /*
+ * ARM erratum 1165522 requires the actual execution of the above
+ * before we can switch to the EL1/EL0 translation regime used by
+ * the guest.
+ */
+ asm(ALTERNATIVE("nop", "isb", ARM64_WORKAROUND_1165522));
}
#endif /* __ARM64_KVM_HYP_H__ */
diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
index a8fa61c68c32..31ee0bfc432f 100644
--- a/arch/arm64/kvm/hyp/switch.c
+++ b/arch/arm64/kvm/hyp/switch.c
@@ -143,6 +143,14 @@ static void deactivate_traps_vhe(void)
{
extern char vectors[]; /* kernel exception vectors */
write_sysreg(HCR_HOST_VHE_FLAGS, hcr_el2);
+
+ /*
+ * ARM erratum 1165522 requires the actual execution of the above
+ * before we can switch to the EL2/EL0 translation regime used by
+ * the host.
+ */
+ asm(ALTERNATIVE("nop", "isb", ARM64_WORKAROUND_1165522));
+
write_sysreg(CPACR_EL1_DEFAULT, cpacr_el1);
write_sysreg(vectors, vbar_el1);
}
@@ -499,6 +507,17 @@ int kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu)
sysreg_save_host_state_vhe(host_ctxt);
+ /*
+ * ARM erratum 1165522 requires us to configure both stage 1 and
+ * stage 2 translation for the guest context before we clear
+ * HCR_EL2.TGE.
+ *
+ * We have already configured the guest's stage 1 translation in
+ * kvm_vcpu_load_sysregs above. We must now call __activate_vm
+ * before __activate_traps, because __activate_vm configures
+ * stage 2 translation, and __activate_traps clear HCR_EL2.TGE
+ * (among other things).
+ */
__activate_vm(vcpu->kvm);
__activate_traps(vcpu);
--
2.19.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 1/8] arm64: KVM: Make VHE Stage-2 TLB invalidation operations non-interruptible
From: Marc Zyngier @ 2018-12-06 17:31 UTC (permalink / raw)
To: linux-arm-kernel, kvmarm, kvm
Cc: Mark Rutland, Suzuki K Poulose, Catalin Marinas, Will Deacon,
Christoffer Dall, James Morse
In-Reply-To: <20181206173126.139877-1-marc.zyngier@arm.com>
Contrary to the non-VHE version of the TLB invalidation helpers, the VHE
code has interrupts enabled, meaning that we can take an interrupt in
the middle of such a sequence, and start running something else with
HCR_EL2.TGE cleared.
That's really not a good idea.
Take the heavy-handed option and disable interrupts in
__tlb_switch_to_guest_vhe, restoring them in __tlb_switch_to_host_vhe.
The latter also gain an ISB in order to make sure that TGE really has
taken effect.
Cc: stable@vger.kernel.org
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm64/kvm/hyp/tlb.c | 35 +++++++++++++++++++++++++----------
1 file changed, 25 insertions(+), 10 deletions(-)
diff --git a/arch/arm64/kvm/hyp/tlb.c b/arch/arm64/kvm/hyp/tlb.c
index 4dbd9c69a96d..7fcc9c1a5f45 100644
--- a/arch/arm64/kvm/hyp/tlb.c
+++ b/arch/arm64/kvm/hyp/tlb.c
@@ -15,14 +15,19 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <linux/irqflags.h>
+
#include <asm/kvm_hyp.h>
#include <asm/kvm_mmu.h>
#include <asm/tlbflush.h>
-static void __hyp_text __tlb_switch_to_guest_vhe(struct kvm *kvm)
+static void __hyp_text __tlb_switch_to_guest_vhe(struct kvm *kvm,
+ unsigned long *flags)
{
u64 val;
+ local_irq_save(*flags);
+
/*
* With VHE enabled, we have HCR_EL2.{E2H,TGE} = {1,1}, and
* most TLB operations target EL2/EL0. In order to affect the
@@ -37,7 +42,8 @@ static void __hyp_text __tlb_switch_to_guest_vhe(struct kvm *kvm)
isb();
}
-static void __hyp_text __tlb_switch_to_guest_nvhe(struct kvm *kvm)
+static void __hyp_text __tlb_switch_to_guest_nvhe(struct kvm *kvm,
+ unsigned long *flags)
{
__load_guest_stage2(kvm);
isb();
@@ -48,7 +54,8 @@ static hyp_alternate_select(__tlb_switch_to_guest,
__tlb_switch_to_guest_vhe,
ARM64_HAS_VIRT_HOST_EXTN);
-static void __hyp_text __tlb_switch_to_host_vhe(struct kvm *kvm)
+static void __hyp_text __tlb_switch_to_host_vhe(struct kvm *kvm,
+ unsigned long flags)
{
/*
* We're done with the TLB operation, let's restore the host's
@@ -56,9 +63,12 @@ static void __hyp_text __tlb_switch_to_host_vhe(struct kvm *kvm)
*/
write_sysreg(0, vttbr_el2);
write_sysreg(HCR_HOST_VHE_FLAGS, hcr_el2);
+ isb();
+ local_irq_restore(flags);
}
-static void __hyp_text __tlb_switch_to_host_nvhe(struct kvm *kvm)
+static void __hyp_text __tlb_switch_to_host_nvhe(struct kvm *kvm,
+ unsigned long flags)
{
write_sysreg(0, vttbr_el2);
}
@@ -70,11 +80,13 @@ static hyp_alternate_select(__tlb_switch_to_host,
void __hyp_text __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
{
+ unsigned long flags;
+
dsb(ishst);
/* Switch to requested VMID */
kvm = kern_hyp_va(kvm);
- __tlb_switch_to_guest()(kvm);
+ __tlb_switch_to_guest()(kvm, &flags);
/*
* We could do so much better if we had the VA as well.
@@ -117,36 +129,39 @@ void __hyp_text __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
if (!has_vhe() && icache_is_vpipt())
__flush_icache_all();
- __tlb_switch_to_host()(kvm);
+ __tlb_switch_to_host()(kvm, flags);
}
void __hyp_text __kvm_tlb_flush_vmid(struct kvm *kvm)
{
+ unsigned long flags;
+
dsb(ishst);
/* Switch to requested VMID */
kvm = kern_hyp_va(kvm);
- __tlb_switch_to_guest()(kvm);
+ __tlb_switch_to_guest()(kvm, &flags);
__tlbi(vmalls12e1is);
dsb(ish);
isb();
- __tlb_switch_to_host()(kvm);
+ __tlb_switch_to_host()(kvm, flags);
}
void __hyp_text __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu)
{
struct kvm *kvm = kern_hyp_va(kern_hyp_va(vcpu)->kvm);
+ unsigned long flags;
/* Switch to requested VMID */
- __tlb_switch_to_guest()(kvm);
+ __tlb_switch_to_guest()(kvm, &flags);
__tlbi(vmalle1);
dsb(nsh);
isb();
- __tlb_switch_to_host()(kvm);
+ __tlb_switch_to_host()(kvm, flags);
}
void __hyp_text __kvm_flush_vm_context(void)
--
2.19.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 7/8] arm64: KVM: Handle ARM erratum 1165522 in TLB invalidation
From: Marc Zyngier @ 2018-12-06 17:31 UTC (permalink / raw)
To: linux-arm-kernel, kvmarm, kvm
Cc: Mark Rutland, Suzuki K Poulose, Catalin Marinas, Will Deacon,
Christoffer Dall, James Morse
In-Reply-To: <20181206173126.139877-1-marc.zyngier@arm.com>
In order to avoid TLB corruption whilst invalidating TLBs on CPUs
affected by erratum 1165522, we need to prevent S1 page tables
from being usable.
For this, we set the EL1 S1 MMU on, and also disable the page table
walker (by setting the TCR_EL1.EPD* bits to 1).
This ensures that once we switch to the EL1/EL0 translation regime,
speculated AT instructions won't be able to parse the page tables.
Reviewed-by: James Morse <james.morse@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm64/kvm/hyp/tlb.c | 66 +++++++++++++++++++++++++++++++---------
1 file changed, 51 insertions(+), 15 deletions(-)
diff --git a/arch/arm64/kvm/hyp/tlb.c b/arch/arm64/kvm/hyp/tlb.c
index 7fcc9c1a5f45..ec157543d5a9 100644
--- a/arch/arm64/kvm/hyp/tlb.c
+++ b/arch/arm64/kvm/hyp/tlb.c
@@ -21,12 +21,36 @@
#include <asm/kvm_mmu.h>
#include <asm/tlbflush.h>
+struct tlb_inv_context {
+ unsigned long flags;
+ u64 tcr;
+ u64 sctlr;
+};
+
static void __hyp_text __tlb_switch_to_guest_vhe(struct kvm *kvm,
- unsigned long *flags)
+ struct tlb_inv_context *cxt)
{
u64 val;
- local_irq_save(*flags);
+ local_irq_save(cxt->flags);
+
+ if (cpus_have_const_cap(ARM64_WORKAROUND_1165522)) {
+ /*
+ * For CPUs that are affected by ARM erratum 1165522, we
+ * cannot trust stage-1 to be in a correct state at that
+ * point. Since we do not want to force a full load of the
+ * vcpu state, we prevent the EL1 page-table walker to
+ * allocate new TLBs. This is done by setting the EPD bits
+ * in the TCR_EL1 register. We also need to prevent it to
+ * allocate IPA->PA walks, so we enable the S1 MMU...
+ */
+ val = cxt->tcr = read_sysreg_el1(tcr);
+ val |= TCR_EPD1_MASK | TCR_EPD0_MASK;
+ write_sysreg_el1(val, tcr);
+ val = cxt->sctlr = read_sysreg_el1(sctlr);
+ val |= SCTLR_ELx_M;
+ write_sysreg_el1(val, sctlr);
+ }
/*
* With VHE enabled, we have HCR_EL2.{E2H,TGE} = {1,1}, and
@@ -34,6 +58,11 @@ static void __hyp_text __tlb_switch_to_guest_vhe(struct kvm *kvm,
* guest TLBs (EL1/EL0), we need to change one of these two
* bits. Changing E2H is impossible (goodbye TTBR1_EL2), so
* let's flip TGE before executing the TLB operation.
+ *
+ * ARM erratum 1165522 requires some special handling (again),
+ * as we need to make sure both stages of translation are in
+ * place before clearing TGE. __load_guest_stage2() already
+ * has an ISB in order to deal with this.
*/
__load_guest_stage2(kvm);
val = read_sysreg(hcr_el2);
@@ -43,7 +72,7 @@ static void __hyp_text __tlb_switch_to_guest_vhe(struct kvm *kvm,
}
static void __hyp_text __tlb_switch_to_guest_nvhe(struct kvm *kvm,
- unsigned long *flags)
+ struct tlb_inv_context *cxt)
{
__load_guest_stage2(kvm);
isb();
@@ -55,7 +84,7 @@ static hyp_alternate_select(__tlb_switch_to_guest,
ARM64_HAS_VIRT_HOST_EXTN);
static void __hyp_text __tlb_switch_to_host_vhe(struct kvm *kvm,
- unsigned long flags)
+ struct tlb_inv_context *cxt)
{
/*
* We're done with the TLB operation, let's restore the host's
@@ -64,11 +93,18 @@ static void __hyp_text __tlb_switch_to_host_vhe(struct kvm *kvm,
write_sysreg(0, vttbr_el2);
write_sysreg(HCR_HOST_VHE_FLAGS, hcr_el2);
isb();
- local_irq_restore(flags);
+
+ if (cpus_have_const_cap(ARM64_WORKAROUND_1165522)) {
+ /* Restore the guest's registers to what they were */
+ write_sysreg_el1(cxt->tcr, tcr);
+ write_sysreg_el1(cxt->sctlr, sctlr);
+ }
+
+ local_irq_restore(cxt->flags);
}
static void __hyp_text __tlb_switch_to_host_nvhe(struct kvm *kvm,
- unsigned long flags)
+ struct tlb_inv_context *cxt)
{
write_sysreg(0, vttbr_el2);
}
@@ -80,13 +116,13 @@ static hyp_alternate_select(__tlb_switch_to_host,
void __hyp_text __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
{
- unsigned long flags;
+ struct tlb_inv_context cxt;
dsb(ishst);
/* Switch to requested VMID */
kvm = kern_hyp_va(kvm);
- __tlb_switch_to_guest()(kvm, &flags);
+ __tlb_switch_to_guest()(kvm, &cxt);
/*
* We could do so much better if we had the VA as well.
@@ -129,39 +165,39 @@ void __hyp_text __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
if (!has_vhe() && icache_is_vpipt())
__flush_icache_all();
- __tlb_switch_to_host()(kvm, flags);
+ __tlb_switch_to_host()(kvm, &cxt);
}
void __hyp_text __kvm_tlb_flush_vmid(struct kvm *kvm)
{
- unsigned long flags;
+ struct tlb_inv_context cxt;
dsb(ishst);
/* Switch to requested VMID */
kvm = kern_hyp_va(kvm);
- __tlb_switch_to_guest()(kvm, &flags);
+ __tlb_switch_to_guest()(kvm, &cxt);
__tlbi(vmalls12e1is);
dsb(ish);
isb();
- __tlb_switch_to_host()(kvm, flags);
+ __tlb_switch_to_host()(kvm, &cxt);
}
void __hyp_text __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu)
{
struct kvm *kvm = kern_hyp_va(kern_hyp_va(vcpu)->kvm);
- unsigned long flags;
+ struct tlb_inv_context cxt;
/* Switch to requested VMID */
- __tlb_switch_to_guest()(kvm, &flags);
+ __tlb_switch_to_guest()(kvm, &cxt);
__tlbi(vmalle1);
dsb(nsh);
isb();
- __tlb_switch_to_host()(kvm, flags);
+ __tlb_switch_to_host()(kvm, &cxt);
}
void __hyp_text __kvm_flush_vm_context(void)
--
2.19.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 8/8] arm64: Add configuration/documentation for Cortex-A76 erratum 1165522
From: Marc Zyngier @ 2018-12-06 17:31 UTC (permalink / raw)
To: linux-arm-kernel, kvmarm, kvm
Cc: Mark Rutland, Suzuki K Poulose, Catalin Marinas, Will Deacon,
Christoffer Dall, James Morse
In-Reply-To: <20181206173126.139877-1-marc.zyngier@arm.com>
Now that the infrastructure to handle erratum 1165522 is in place,
let's make it a selectable option and add the required documentation.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
Documentation/arm64/silicon-errata.txt | 1 +
arch/arm64/Kconfig | 12 ++++++++++++
2 files changed, 13 insertions(+)
diff --git a/Documentation/arm64/silicon-errata.txt b/Documentation/arm64/silicon-errata.txt
index 76ccded8b74c..04f0bc4690c6 100644
--- a/Documentation/arm64/silicon-errata.txt
+++ b/Documentation/arm64/silicon-errata.txt
@@ -57,6 +57,7 @@ stable kernels.
| ARM | Cortex-A73 | #858921 | ARM64_ERRATUM_858921 |
| ARM | Cortex-A55 | #1024718 | ARM64_ERRATUM_1024718 |
| ARM | Cortex-A76 | #1188873 | ARM64_ERRATUM_1188873 |
+| ARM | Cortex-A76 | #1165522 | ARM64_ERRATUM_1165522 |
| ARM | MMU-500 | #841119,#826419 | N/A |
| | | | |
| Cavium | ThunderX ITS | #22375, #24313 | CAVIUM_ERRATUM_22375 |
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 787d7850e064..a68bc6cc2167 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -497,6 +497,18 @@ config ARM64_ERRATUM_1188873
If unsure, say Y.
+config ARM64_ERRATUM_1165522
+ bool "Cortex-A76: Speculative AT instruction using out-of-context translation regime could cause subsequent request to generate an incorrect translation"
+ default y
+ help
+ This option adds work arounds for ARM Cortex-A76 erratum 1165522
+
+ Affected Cortex-A76 cores (r0p0, r1p0, r2p0) could end-up with
+ corrupted TLBs by speculating an AT instruction during a guest
+ context switch.
+
+ If unsure, say Y.
+
config CAVIUM_ERRATUM_22375
bool "Cavium erratum 22375, 24313"
default y
--
2.19.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 5/8] arm64: KVM: Force VHE for systems affected by erratum 1165522
From: Marc Zyngier @ 2018-12-06 17:31 UTC (permalink / raw)
To: linux-arm-kernel, kvmarm, kvm
Cc: Mark Rutland, Suzuki K Poulose, Catalin Marinas, Will Deacon,
Christoffer Dall, James Morse
In-Reply-To: <20181206173126.139877-1-marc.zyngier@arm.com>
In order to easily mitigate ARM erratum 1165522, we need to force
affected CPUs to run in VHE mode if using KVM.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm64/include/asm/cpucaps.h | 3 ++-
arch/arm64/include/asm/kvm_host.h | 4 ++++
arch/arm64/kernel/cpu_errata.c | 8 ++++++++
3 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h
index 6e2d254c09eb..62d8cd15fdf2 100644
--- a/arch/arm64/include/asm/cpucaps.h
+++ b/arch/arm64/include/asm/cpucaps.h
@@ -54,7 +54,8 @@
#define ARM64_HAS_CRC32 33
#define ARM64_SSBS 34
#define ARM64_WORKAROUND_1188873 35
+#define ARM64_WORKAROUND_1165522 36
-#define ARM64_NCAPS 36
+#define ARM64_NCAPS 37
#endif /* __ASM_CPUCAPS_H */
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index d6d9aa76a943..9217759afa6b 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -432,6 +432,10 @@ static inline bool kvm_arch_requires_vhe(void)
if (system_supports_sve())
return true;
+ /* Some implementations have defects that confine them to VHE */
+ if (cpus_have_cap(ARM64_WORKAROUND_1165522))
+ return true;
+
return false;
}
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index a509e35132d2..476e738e6c46 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -739,6 +739,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
.capability = ARM64_WORKAROUND_1188873,
ERRATA_MIDR_RANGE(MIDR_CORTEX_A76, 0, 0, 2, 0),
},
+#endif
+#ifdef CONFIG_ARM64_ERRATUM_1165522
+ {
+ /* Cortex-A76 r0p0 to r2p0 */
+ .desc = "ARM erratum 1165522",
+ .capability = ARM64_WORKAROUND_1165522,
+ ERRATA_MIDR_RANGE(MIDR_CORTEX_A76, 0, 0, 2, 0),
+ },
#endif
{
}
--
2.19.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 0/8] Workaround for Cortex-A76 erratum 1165522
From: Marc Zyngier @ 2018-12-06 17:31 UTC (permalink / raw)
To: linux-arm-kernel, kvmarm, kvm
Cc: Mark Rutland, Suzuki K Poulose, Catalin Marinas, Will Deacon,
Christoffer Dall, James Morse
Early Cortex-A76 suffer from an erratum that can result in invalid
TLBs when the CPU speculatively executes an AT instruction in the
middle of a guest world switch, while the guest virtual memory
configuration is in an inconsistent state.
We handle this issue by mandating the use of VHE and making sure that
the guest context is fully installed before switching HCR_EL2.TGE to
zero. This ensures that a speculated AT instruction is either executed
on the host context (TGE set) or the guest context (TGE clear), and
that there is no intermediate state.
There is some additional complexity in the TLB invalidation code,
where we most make sure that a speculated AT instruction cannot mess
the stage-1 TLBs.
* From v2:
- Dropped a bunch of spurious ISBs after James review
- Added James RBs.
* From v1:
- VHE TLB invalidation now atomic
- Avoid speculated AT during TLB invalidation
- Addressed most comments from Christoffer
- Resplit to ease reviewing
Marc Zyngier (8):
arm64: KVM: Make VHE Stage-2 TLB invalidation operations
non-interruptible
KVM: arm64: Rework detection of SVE, !VHE systems
arm64: KVM: Install stage-2 translation before enabling traps
arm64: Add TCR_EPD{0,1} definitions
arm64: KVM: Force VHE for systems affected by erratum 1165522
arm64: KVM: Add synchronization on translation regime change for
erratum 1165522
arm64: KVM: Handle ARM erratum 1165522 in TLB invalidation
arm64: Add configuration/documentation for Cortex-A76 erratum 1165522
Documentation/arm64/silicon-errata.txt | 1 +
arch/arm/include/asm/kvm_host.h | 2 +-
arch/arm64/Kconfig | 12 +++++
arch/arm64/include/asm/cpucaps.h | 3 +-
arch/arm64/include/asm/kvm_host.h | 10 ++--
arch/arm64/include/asm/kvm_hyp.h | 8 +++
arch/arm64/include/asm/pgtable-hwdef.h | 4 ++
arch/arm64/kernel/cpu_errata.c | 8 +++
arch/arm64/kvm/hyp/switch.c | 23 ++++++++-
arch/arm64/kvm/hyp/tlb.c | 71 ++++++++++++++++++++++----
virt/kvm/arm/arm.c | 8 +--
11 files changed, 129 insertions(+), 21 deletions(-)
--
2.19.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v3 3/8] arm64: KVM: Install stage-2 translation before enabling traps
From: Marc Zyngier @ 2018-12-06 17:31 UTC (permalink / raw)
To: linux-arm-kernel, kvmarm, kvm
Cc: Mark Rutland, Suzuki K Poulose, Catalin Marinas, Will Deacon,
Christoffer Dall, James Morse
In-Reply-To: <20181206173126.139877-1-marc.zyngier@arm.com>
It is a bit odd that we only install stage-2 translation after having
cleared HCR_EL2.TGE, which means that there is a window during which
AT requests could fail as stage-2 is not configured yet.
Let's move stage-2 configuration before we clear TGE, making the
guest entry sequence clearer: we first configure all the guest stuff,
then only switch to the guest translation regime.
While we're at it, do the same thing for !VHE. It doesn't hurt,
and keeps things symmetric.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm64/kvm/hyp/switch.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
index 7cc175c88a37..a8fa61c68c32 100644
--- a/arch/arm64/kvm/hyp/switch.c
+++ b/arch/arm64/kvm/hyp/switch.c
@@ -499,8 +499,8 @@ int kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu)
sysreg_save_host_state_vhe(host_ctxt);
- __activate_traps(vcpu);
__activate_vm(vcpu->kvm);
+ __activate_traps(vcpu);
sysreg_restore_guest_state_vhe(guest_ctxt);
__debug_switch_to_guest(vcpu);
@@ -545,8 +545,8 @@ int __hyp_text __kvm_vcpu_run_nvhe(struct kvm_vcpu *vcpu)
__sysreg_save_state_nvhe(host_ctxt);
- __activate_traps(vcpu);
__activate_vm(kern_hyp_va(vcpu->kvm));
+ __activate_traps(vcpu);
__hyp_vgic_restore_state(vcpu);
__timer_enable_traps(vcpu);
--
2.19.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 2/8] KVM: arm64: Rework detection of SVE, !VHE systems
From: Marc Zyngier @ 2018-12-06 17:31 UTC (permalink / raw)
To: linux-arm-kernel, kvmarm, kvm
Cc: Mark Rutland, Suzuki K Poulose, Catalin Marinas, Will Deacon,
Christoffer Dall, James Morse
In-Reply-To: <20181206173126.139877-1-marc.zyngier@arm.com>
An SVE system is so far the only case where we mandate VHE. As we're
starting to grow this requirements, let's slightly rework the way we
deal with that situation, allowing for easy extension of this check.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm/include/asm/kvm_host.h | 2 +-
arch/arm64/include/asm/kvm_host.h | 6 +++---
virt/kvm/arm/arm.c | 8 ++++----
3 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index 5ca5d9af0c26..2184d9ddb418 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -285,7 +285,7 @@ void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot);
struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr);
-static inline bool kvm_arch_check_sve_has_vhe(void) { return true; }
+static inline bool kvm_arch_requires_vhe(void) { return false; }
static inline void kvm_arch_hardware_unsetup(void) {}
static inline void kvm_arch_sync_events(struct kvm *kvm) {}
static inline void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {}
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 52fbc823ff8c..d6d9aa76a943 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -422,7 +422,7 @@ static inline void __cpu_init_hyp_mode(phys_addr_t pgd_ptr,
}
}
-static inline bool kvm_arch_check_sve_has_vhe(void)
+static inline bool kvm_arch_requires_vhe(void)
{
/*
* The Arm architecture specifies that implementation of SVE
@@ -430,9 +430,9 @@ static inline bool kvm_arch_check_sve_has_vhe(void)
* relies on this when SVE is present:
*/
if (system_supports_sve())
- return has_vhe();
- else
return true;
+
+ return false;
}
static inline void kvm_arch_hardware_unsetup(void) {}
diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
index 23774970c9df..1db4c15edcdd 100644
--- a/virt/kvm/arm/arm.c
+++ b/virt/kvm/arm/arm.c
@@ -1640,8 +1640,10 @@ int kvm_arch_init(void *opaque)
return -ENODEV;
}
- if (!kvm_arch_check_sve_has_vhe()) {
- kvm_pr_unimpl("SVE system without VHE unsupported. Broken cpu?");
+ in_hyp_mode = is_kernel_in_hyp_mode();
+
+ if (!in_hyp_mode && kvm_arch_requires_vhe()) {
+ kvm_pr_unimpl("CPU requiring VHE was booted in non-VHE mode");
return -ENODEV;
}
@@ -1657,8 +1659,6 @@ int kvm_arch_init(void *opaque)
if (err)
return err;
- in_hyp_mode = is_kernel_in_hyp_mode();
-
if (!in_hyp_mode) {
err = init_hyp_mode();
if (err)
--
2.19.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 4/8] arm64: Add TCR_EPD{0,1} definitions
From: Marc Zyngier @ 2018-12-06 17:31 UTC (permalink / raw)
To: linux-arm-kernel, kvmarm, kvm
Cc: Mark Rutland, Suzuki K Poulose, Catalin Marinas, Will Deacon,
Christoffer Dall, James Morse
In-Reply-To: <20181206173126.139877-1-marc.zyngier@arm.com>
We are soon going to play with TCR_EL1.EPD{0,1}, so let's add the
relevant definitions.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm64/include/asm/pgtable-hwdef.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
index 1d7d8da2ef9b..a7d5d6e459eb 100644
--- a/arch/arm64/include/asm/pgtable-hwdef.h
+++ b/arch/arm64/include/asm/pgtable-hwdef.h
@@ -224,6 +224,8 @@
#define TCR_TxSZ_WIDTH 6
#define TCR_T0SZ_MASK (((UL(1) << TCR_TxSZ_WIDTH) - 1) << TCR_T0SZ_OFFSET)
+#define TCR_EPD0_SHIFT 7
+#define TCR_EPD0_MASK (UL(1) << TCR_EPD0_SHIFT)
#define TCR_IRGN0_SHIFT 8
#define TCR_IRGN0_MASK (UL(3) << TCR_IRGN0_SHIFT)
#define TCR_IRGN0_NC (UL(0) << TCR_IRGN0_SHIFT)
@@ -231,6 +233,8 @@
#define TCR_IRGN0_WT (UL(2) << TCR_IRGN0_SHIFT)
#define TCR_IRGN0_WBnWA (UL(3) << TCR_IRGN0_SHIFT)
+#define TCR_EPD1_SHIFT 23
+#define TCR_EPD1_MASK (UL(1) << TCR_EPD1_SHIFT)
#define TCR_IRGN1_SHIFT 24
#define TCR_IRGN1_MASK (UL(3) << TCR_IRGN1_SHIFT)
#define TCR_IRGN1_NC (UL(0) << TCR_IRGN1_SHIFT)
--
2.19.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v2] power: reset: at91-poweroff: move shdwc related data to one structure
From: Claudiu.Beznea @ 2018-12-06 17:29 UTC (permalink / raw)
To: sre, Nicolas.Ferre, alexandre.belloni, Ludovic.Desroches
Cc: Claudiu.Beznea, linux-kernel, linux-arm-kernel, linux-pm
From: Claudiu Beznea <claudiu.beznea@microchip.com>
Move SHDWC realted data to only one structure to have them grouped.
Inspired from commit 9be74f0d39c1 ("power: reset: at91-poweroff: make
mpddrc_base part of struct shdwc").
Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
---
Changes in v2:
- avoid allocate at91_shdwc and keep it static instead
- avoid registering at91_shdwc as platform data and use static variable
instead
drivers/power/reset/at91-poweroff.c | 48 +++++++++++++++++++------------------
1 file changed, 25 insertions(+), 23 deletions(-)
diff --git a/drivers/power/reset/at91-poweroff.c b/drivers/power/reset/at91-poweroff.c
index d3d87af24e55..9e74e131c675 100644
--- a/drivers/power/reset/at91-poweroff.c
+++ b/drivers/power/reset/at91-poweroff.c
@@ -51,14 +51,16 @@ static const char *shdwc_wakeup_modes[] = {
[AT91_SHDW_WKMODE0_ANYLEVEL] = "any",
};
-static void __iomem *at91_shdwc_base;
-static struct clk *sclk;
-static void __iomem *mpddrc_base;
+static struct shdwc {
+ struct clk *sclk;
+ void __iomem *shdwc_base;
+ void __iomem *mpddrc_base;
+} at91_shdwc;
static void __init at91_wakeup_status(struct platform_device *pdev)
{
const char *reason;
- u32 reg = readl(at91_shdwc_base + AT91_SHDW_SR);
+ u32 reg = readl(at91_shdwc.shdwc_base + AT91_SHDW_SR);
/* Simple power-on, just bail out */
if (!reg)
@@ -92,9 +94,9 @@ static void at91_poweroff(void)
" b .\n\t"
:
- : "r" (mpddrc_base),
+ : "r" (at91_shdwc.mpddrc_base),
"r" cpu_to_le32(AT91_DDRSDRC_LPDDR2_PWOFF),
- "r" (at91_shdwc_base),
+ "r" (at91_shdwc.shdwc_base),
"r" cpu_to_le32(AT91_SHDW_KEY | AT91_SHDW_SHDW)
: "r6");
}
@@ -144,7 +146,7 @@ static void at91_poweroff_dt_set_wakeup_mode(struct platform_device *pdev)
if (of_property_read_bool(np, "atmel,wakeup-rtt-timer"))
mode |= AT91_SHDW_RTTWKEN;
- writel(wakeup_mode | mode, at91_shdwc_base + AT91_SHDW_MR);
+ writel(wakeup_mode | mode, at91_shdwc.shdwc_base + AT91_SHDW_MR);
}
static int __init at91_poweroff_probe(struct platform_device *pdev)
@@ -155,15 +157,15 @@ static int __init at91_poweroff_probe(struct platform_device *pdev)
int ret;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- at91_shdwc_base = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(at91_shdwc_base))
- return PTR_ERR(at91_shdwc_base);
+ at91_shdwc.shdwc_base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(at91_shdwc.shdwc_base))
+ return PTR_ERR(at91_shdwc.shdwc_base);
- sclk = devm_clk_get(&pdev->dev, NULL);
- if (IS_ERR(sclk))
- return PTR_ERR(sclk);
+ at91_shdwc.sclk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(at91_shdwc.sclk))
+ return PTR_ERR(at91_shdwc.sclk);
- ret = clk_prepare_enable(sclk);
+ ret = clk_prepare_enable(at91_shdwc.sclk);
if (ret) {
dev_err(&pdev->dev, "Could not enable slow clock\n");
return ret;
@@ -176,20 +178,20 @@ static int __init at91_poweroff_probe(struct platform_device *pdev)
np = of_find_compatible_node(NULL, NULL, "atmel,sama5d3-ddramc");
if (np) {
- mpddrc_base = of_iomap(np, 0);
+ at91_shdwc.mpddrc_base = of_iomap(np, 0);
of_node_put(np);
- if (!mpddrc_base) {
+ if (!at91_shdwc.mpddrc_base) {
ret = -ENOMEM;
goto clk_disable;
}
- ddr_type = readl(mpddrc_base + AT91_DDRSDRC_MDR) &
+ ddr_type = readl(at91_shdwc.mpddrc_base + AT91_DDRSDRC_MDR) &
AT91_DDRSDRC_MD;
if (ddr_type != AT91_DDRSDRC_MD_LPDDR2 &&
ddr_type != AT91_DDRSDRC_MD_LPDDR3) {
- iounmap(mpddrc_base);
- mpddrc_base = NULL;
+ iounmap(at91_shdwc.mpddrc_base);
+ at91_shdwc.mpddrc_base = NULL;
}
}
@@ -198,7 +200,7 @@ static int __init at91_poweroff_probe(struct platform_device *pdev)
return 0;
clk_disable:
- clk_disable_unprepare(sclk);
+ clk_disable_unprepare(at91_shdwc.sclk);
return ret;
}
@@ -207,10 +209,10 @@ static int __exit at91_poweroff_remove(struct platform_device *pdev)
if (pm_power_off == at91_poweroff)
pm_power_off = NULL;
- if (mpddrc_base)
- iounmap(mpddrc_base);
+ if (at91_shdwc.mpddrc_base)
+ iounmap(at91_shdwc.mpddrc_base);
- clk_disable_unprepare(sclk);
+ clk_disable_unprepare(at91_shdwc.sclk);
return 0;
}
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH v5 2/2] ARM: module: Fix function kallsyms on Thumb-2
From: Jessica Yu @ 2018-12-06 17:29 UTC (permalink / raw)
To: Vincent Whitchurch
Cc: linux-kernel, Vincent Whitchurch, linux, linux-arm-kernel,
dave.martin
In-Reply-To: <20181204141415.969-2-vincent.whitchurch@axis.com>
+++ Vincent Whitchurch [04/12/18 15:14 +0100]:
>Thumb-2 functions have the lowest bit set in the symbol value in the
>symtab. When kallsyms are generated for the vmlinux, the kallsyms are
>generated from the output of nm, and nm clears the lowest bit.
>
> $ arm-linux-gnueabihf-readelf -a vmlinux | grep show_interrupts
> 95947: 8015dc89 686 FUNC GLOBAL DEFAULT 2 show_interrupts
> $ arm-linux-gnueabihf-nm vmlinux | grep show_interrupts
> 8015dc88 T show_interrupts
> $ cat /proc/kallsyms | grep show_interrupts
> 8015dc88 T show_interrupts
>
>However, for modules, the kallsyms uses the values in the symbol table
>without modification, so for functions in modules, the lowest bit is set
>in kallsyms.
>
> $ arm-linux-gnueabihf-readelf -a drivers/net/tun.ko | grep tun_get_socket
> 333: 00002d4d 36 FUNC GLOBAL DEFAULT 1 tun_get_socket
> $ arm-linux-gnueabihf-nm drivers/net/tun.ko | grep tun_get_socket
> 00002d4c T tun_get_socket
> $ cat /proc/kallsyms | grep tun_get_socket
> 7f802d4d t tun_get_socket [tun]
>
>Because of this, the symbol+offset of the crashing instruction shown in
>oopses is incorrect when the crash is in a module. For example, given a
>tun_get_socket which starts like this,
>
> 00002d4c <tun_get_socket>:
> 2d4c: 6943 ldr r3, [r0, #20]
> 2d4e: 4a07 ldr r2, [pc, #28]
> 2d50: 4293 cmp r3, r2
>
>a crash when tun_get_socket is called with NULL results in:
>
> PC is at tun_xdp+0xa3/0xa4 [tun]
> pc : [<7f802d4c>]
>
>As can be seen, the "PC is at" line reports the wrong symbol name, and
>the symbol+offset will point to the wrong source line if it is passed to
>gdb.
>
>To solve this, add a way for archs to fixup the reading of these module
>kallsyms values, and use that to clear the lowest bit for function
>symbols on Thumb-2.
>
>After the fix:
>
> # cat /proc/kallsyms | grep tun_get_socket
> 7f802d4c t tun_get_socket [tun]
>
> PC is at tun_get_socket+0x0/0x24 [tun]
> pc : [<7f802d4c>]
>
>Signed-off-by: Vincent Whitchurch <vincent.whitchurch@axis.com>
Looks good, could I get an ACK from an ARM maintainer? (Russell?)
Also, do you mind if I drop the module_ prefix from
module_kallsyms_symbol_value()? I recently submitted some internal
module kallsyms cleanups [1] and there we have the newly renamed
kallsyms_symbol_name(), so I think it'd be nice if we kept the naming
scheme consistent with just kallsyms_symbol_value(). I could just do
this myself if you don't want to respin a v6.
Thanks!
Jessica
[1] https://git.kernel.org/pub/scm/linux/kernel/git/jeyu/linux.git/commit/?h=modules-next&id=2d25bc55235314d869459c574be14e8faa73aca3
>---
>v5: Use/move local variables to reduce calls and keep lines short. Use const arg.
>v4: Split out st_value overwrite change. Add HAVE* macro to avoid function call.
>v3: Do not overwrite st_value
>v2: Fix build warning with !MODULES
>
> arch/arm/include/asm/module.h | 11 +++++++++++
> include/linux/module.h | 7 +++++++
> kernel/module.c | 45 +++++++++++++++++++++++++++----------------
> 3 files changed, 46 insertions(+), 17 deletions(-)
>
>diff --git a/arch/arm/include/asm/module.h b/arch/arm/include/asm/module.h
>index 9e81b7c498d8..c7bcf0347801 100644
>--- a/arch/arm/include/asm/module.h
>+++ b/arch/arm/include/asm/module.h
>@@ -61,4 +61,15 @@ u32 get_module_plt(struct module *mod, unsigned long loc, Elf32_Addr val);
> MODULE_ARCH_VERMAGIC_ARMTHUMB \
> MODULE_ARCH_VERMAGIC_P2V
>
>+#ifdef CONFIG_THUMB2_KERNEL
>+#define HAVE_ARCH_MODULE_KALLSYMS_SYMBOL_VALUE
>+static inline unsigned long module_kallsyms_symbol_value(const Elf_Sym *sym)
>+{
>+ if (ELF_ST_TYPE(sym->st_info) == STT_FUNC)
>+ return sym->st_value & ~1;
>+
>+ return sym->st_value;
>+}
>+#endif
>+
> #endif /* _ASM_ARM_MODULE_H */
>diff --git a/include/linux/module.h b/include/linux/module.h
>index fce6b4335e36..12146257eb5d 100644
>--- a/include/linux/module.h
>+++ b/include/linux/module.h
>@@ -486,6 +486,13 @@ struct module {
> #define MODULE_ARCH_INIT {}
> #endif
>
>+#ifndef HAVE_ARCH_MODULE_KALLSYMS_SYMBOL_VALUE
>+static inline unsigned long module_kallsyms_symbol_value(const Elf_Sym *sym)
>+{
>+ return sym->st_value;
>+}
>+#endif
>+
> extern struct mutex module_mutex;
>
> /* FIXME: It'd be nice to isolate modules during init, too, so they
>diff --git a/kernel/module.c b/kernel/module.c
>index 3d86a38b580c..9364017fdc21 100644
>--- a/kernel/module.c
>+++ b/kernel/module.c
>@@ -3922,7 +3922,7 @@ static const char *get_ksymbol(struct module *mod,
> unsigned long *offset)
> {
> unsigned int i, best = 0;
>- unsigned long nextval;
>+ unsigned long nextval, bestval;
> struct mod_kallsyms *kallsyms = rcu_dereference_sched(mod->kallsyms);
>
> /* At worse, next value is at end of module */
>@@ -3931,10 +3931,15 @@ static const char *get_ksymbol(struct module *mod,
> else
> nextval = (unsigned long)mod->core_layout.base+mod->core_layout.text_size;
>
>+ bestval = module_kallsyms_symbol_value(&kallsyms->symtab[best]);
>+
> /* Scan for closest preceding symbol, and next symbol. (ELF
> starts real symbols at 1). */
> for (i = 1; i < kallsyms->num_symtab; i++) {
>- if (kallsyms->symtab[i].st_shndx == SHN_UNDEF)
>+ const Elf_Sym *sym = &kallsyms->symtab[i];
>+ unsigned long thisval = module_kallsyms_symbol_value(sym);
>+
>+ if (sym->st_shndx == SHN_UNDEF)
> continue;
>
> /* We ignore unnamed symbols: they're uninformative
>@@ -3943,21 +3948,21 @@ static const char *get_ksymbol(struct module *mod,
> || is_arm_mapping_symbol(symname(kallsyms, i)))
> continue;
>
>- if (kallsyms->symtab[i].st_value <= addr
>- && kallsyms->symtab[i].st_value > kallsyms->symtab[best].st_value)
>+ if (thisval <= addr && thisval > bestval) {
> best = i;
>- if (kallsyms->symtab[i].st_value > addr
>- && kallsyms->symtab[i].st_value < nextval)
>- nextval = kallsyms->symtab[i].st_value;
>+ bestval = thisval;
>+ }
>+ if (thisval > addr && thisval < nextval)
>+ nextval = thisval;
> }
>
> if (!best)
> return NULL;
>
> if (size)
>- *size = nextval - kallsyms->symtab[best].st_value;
>+ *size = nextval - bestval;
> if (offset)
>- *offset = addr - kallsyms->symtab[best].st_value;
>+ *offset = addr - bestval;
> return symname(kallsyms, best);
> }
>
>@@ -4060,8 +4065,10 @@ int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
> continue;
> kallsyms = rcu_dereference_sched(mod->kallsyms);
> if (symnum < kallsyms->num_symtab) {
>- *value = kallsyms->symtab[symnum].st_value;
>- *type = kallsyms->symtab[symnum].st_size;
>+ const Elf_Sym *sym = &kallsyms->symtab[symnum];
>+
>+ *value = module_kallsyms_symbol_value(sym);
>+ *type = sym->st_size;
> strlcpy(name, symname(kallsyms, symnum), KSYM_NAME_LEN);
> strlcpy(module_name, mod->name, MODULE_NAME_LEN);
> *exported = is_exported(name, *value, mod);
>@@ -4079,10 +4086,13 @@ static unsigned long mod_find_symname(struct module *mod, const char *name)
> unsigned int i;
> struct mod_kallsyms *kallsyms = rcu_dereference_sched(mod->kallsyms);
>
>- for (i = 0; i < kallsyms->num_symtab; i++)
>+ for (i = 0; i < kallsyms->num_symtab; i++) {
>+ const Elf_Sym *sym = &kallsyms->symtab[i];
>+
> if (strcmp(name, symname(kallsyms, i)) == 0 &&
>- kallsyms->symtab[i].st_shndx != SHN_UNDEF)
>- return kallsyms->symtab[i].st_value;
>+ sym->st_shndx != SHN_UNDEF)
>+ return module_kallsyms_symbol_value(sym);
>+ }
> return 0;
> }
>
>@@ -4127,12 +4137,13 @@ int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,
> if (mod->state == MODULE_STATE_UNFORMED)
> continue;
> for (i = 0; i < kallsyms->num_symtab; i++) {
>+ const Elf_Sym *sym = &kallsyms->symtab[i];
>
>- if (kallsyms->symtab[i].st_shndx == SHN_UNDEF)
>+ if (sym->st_shndx == SHN_UNDEF)
> continue;
>
>- ret = fn(data, symname(kallsyms, i),
>- mod, kallsyms->symtab[i].st_value);
>+ ret = fn(data, symname(kallsyms, i), mod,
>+ module_kallsyms_symbol_value(sym));
> if (ret != 0)
> return ret;
> }
>--
>2.11.0
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v2 7/8] arm64: KVM: Handle ARM erratum 1165522 in TLB invalidation
From: Marc Zyngier @ 2018-12-06 17:21 UTC (permalink / raw)
To: James Morse, linux-arm-kernel, kvmarm, kvm
Cc: Mark Rutland, Catalin Marinas, Will Deacon, Christoffer Dall,
Suzuki K Poulose
In-Reply-To: <b662ad23-68bc-e25d-2ce7-2499af4b358d@arm.com>
On 27/11/2018 09:50, James Morse wrote:
> Hi Marc,
>
> On 23/11/2018 18:41, Marc Zyngier wrote:
>> In order to avoid TLB corruption whilst invalidating TLBs on CPUs
>> affected by erratum 1165522, we need to prevent S1 page tables
>> from being usable.
>>
>> For this, we set the EL1 S1 MMU on, and also disable the page table
>> walker (by setting the TCR_EL1.EPD* bits to 1).
>>
>> This ensures that once we switch to the EL1/EL0 translation regime,
>> speculated AT instructions won't be able to parse the page tables.
>
> Reviewed-by: James Morse <james.morse@arm.com>
>
>
> I think we can ditch an isb or two:
>
>> diff --git a/arch/arm64/kvm/hyp/tlb.c b/arch/arm64/kvm/hyp/tlb.c
>> index 7fcc9c1a5f45..0506ced16afc 100644
>> --- a/arch/arm64/kvm/hyp/tlb.c
>> +++ b/arch/arm64/kvm/hyp/tlb.c
>> @@ -21,12 +21,37 @@
>> #include <asm/kvm_mmu.h>
>> #include <asm/tlbflush.h>
>>
>> +struct tlb_inv_context {
>> + unsigned long flags;
>> + u64 tcr;
>> + u64 sctlr;
>> +};
>> +
>> static void __hyp_text __tlb_switch_to_guest_vhe(struct kvm *kvm,
>> - unsigned long *flags)
>> + struct tlb_inv_context *cxt)
>> {
>> u64 val;
>>
>> - local_irq_save(*flags);
>> + local_irq_save(cxt->flags);
>> +
>> + if (cpus_have_const_cap(ARM64_WORKAROUND_1165522)) {
>> + /*
>> + * For CPUs that are affected by ARM erratum 1165522, we
>> + * cannot trust stage-1 to be in a correct state at that
>> + * point. Since we do not want to force a full load of the
>> + * vcpu state, we prevent the EL1 page-table walker to
>> + * allocate new TLBs. This is done by setting the EPD bits
>> + * in the TCR_EL1 register. We also need to prevent it to
>> + * allocate API->PA walks, so we enable the S1 MMU...
>
> typo: API => IPA
>
>
>> + */
>> + val = cxt->tcr = read_sysreg_el1(tcr);
>> + val |= TCR_EPD1_MASK | TCR_EPD0_MASK;
>> + write_sysreg_el1(val, tcr);
>> + val = cxt->sctlr = read_sysreg_el1(sctlr);
>> + val |= SCTLR_ELx_M;
>> + write_sysreg_el1(val, sctlr);
>
>> + isb();
>
> Could you leave these to be synchronised by the isb() in __load_guest_stage2()?
> An AT speculated here would see HCR_EL2.TGE set and use the EL2&EL0 regime.
Yes, you're right.
>
>> + }
>>
>> /*
>> * With VHE enabled, we have HCR_EL2.{E2H,TGE} = {1,1}, and
>> @@ -34,8 +59,13 @@ static void __hyp_text __tlb_switch_to_guest_vhe(struct kvm *kvm,
>> * guest TLBs (EL1/EL0), we need to change one of these two
>> * bits. Changing E2H is impossible (goodbye TTBR1_EL2), so
>> * let's flip TGE before executing the TLB operation.
>> + *
>> + * ARM erratum 1165522 requires some special handling (again),
>
>> + * as we need to make sure stage-2 is in place before clearing
>> + * TGE.
>
> Typo: stage-1?
>
> stage2 remains disabled here, we only call __load_guest_stage2() for the vmid.
> The problem was the EL1:stage-1 being usable and unknown when TGE is cleared.
>
>
>> */
>> __load_guest_stage2(kvm);
>> + asm(ALTERNATIVE("nop", "isb", ARM64_WORKAROUND_1165522));
>
> __load_guest_stage2() already has an isb for this workaround after it writes
> vtcr/vttbr. I think we can just refer to it in the comment and let it
> synchronise the stage1+2 config before we touch hcr_el2 below.
Well spotted, I've dropped that line and hopefully clarified the comment.
>
>
>> val = read_sysreg(hcr_el2);
>> val &= ~HCR_TGE;
>> write_sysreg(val, hcr_el2);
>
> [...]
>
>> @@ -64,11 +94,19 @@ static void __hyp_text __tlb_switch_to_host_vhe(struct kvm *kvm,
>> write_sysreg(0, vttbr_el2);
>> write_sysreg(HCR_HOST_VHE_FLAGS, hcr_el2);
>> isb();
>> - local_irq_restore(flags);
>> +
>> + if (cpus_have_const_cap(ARM64_WORKAROUND_1165522)) {
>> + /* Restore the guest's registers to what they were */
>> + write_sysreg_el1(cxt->tcr, tcr);
>> + write_sysreg_el1(cxt->sctlr, sctlr);
>
>> + isb();
>
> Hmm, why do we need this isb?
>
> We just set TGE, so these registers values no long matter. vcpu_put() would read
> the values we wrote, as would __tlb_switch_to_guest_vhe() above if we re-ran
> this sequence. If we're on our way into the guest, the extra isb in
> __load_guest_stage2() would synchronise them before clearing TGE during
> world-switch.
>
> I don't think there is a path where we depend on these values being isb'd before
> guest eret.
Absolutely right, I dropped that one to. Yeah, 3 ISB down, profit! ;-)
> (if its just to be robust, I'm all in favour of it!)
No, it was all about being paranoid, thanks for curing that for me!
M.
--
Jazz is not dead. It just smells funny...
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v5 2/4] arm64: KVM: add accessors to track guest/host only counters
From: Suzuki K Poulose @ 2018-12-06 17:21 UTC (permalink / raw)
To: Andrew Murray, Christoffer Dall, Marc Zyngier, Catalin Marinas,
Will Deacon, Mark Rutland
Cc: kvmarm, linux-arm-kernel, Julien Thierry
In-Reply-To: <1544023815-16958-3-git-send-email-andrew.murray@arm.com>
Hi Andrew,
On 05/12/2018 15:30, Andrew Murray wrote:
> In order to effeciently enable/disable guest/host only perf counters
> at guest entry/exit we add bitfields to kvm_cpu_context for guest and
> host events as well as accessors for updating them.
>
> Signed-off-by: Andrew Murray <andrew.murray@arm.com>
> ---
> arch/arm64/include/asm/kvm_host.h | 24 ++++++++++++++++++++++++
> 1 file changed, 24 insertions(+)
>
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 1550192..800c87b 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -203,6 +203,8 @@ struct kvm_cpu_context {
> };
>
> struct kvm_vcpu *__hyp_running_vcpu;
> + u32 events_host;
> + u32 events_guest;
> };
>
> typedef struct kvm_cpu_context kvm_cpu_context_t;
> @@ -467,11 +469,33 @@ void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu);
> void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu);
> void kvm_arch_vcpu_put_fp(struct kvm_vcpu *vcpu);
>
> +#define KVM_PMU_EVENTS_HOST 1
> +#define KVM_PMU_EVENTS_GUEST 2
> +
> #ifdef CONFIG_KVM /* Avoid conflicts with core headers if CONFIG_KVM=n */
> static inline int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)
> {
> return kvm_arch_vcpu_run_map_fp(vcpu);
> }
> +static inline void kvm_set_pmu_events(u32 set, int flags)
> +{
> + kvm_cpu_context_t *ctx = this_cpu_ptr(&kvm_host_cpu_state);
> +
> + if (flags & KVM_PMU_EVENTS_HOST)
> + ctx->events_host |= set;
> + if (flags & KVM_PMU_EVENTS_GUEST)
> + ctx->events_guest |= set;
You seem to be passing a single flag at a time ever, in the next patch.
Either we can batch the calls in the next patch, or make this a real number and
not a flag. g.g, enum { HOST, GUEST } or even a bool.
I think the former sounds better.
Cheers
Suzuki
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v2 5/5] arm64: dts: marvell: Add cpu clock node on Armada 7K/8K
From: Gregory CLEMENT @ 2018-12-06 17:15 UTC (permalink / raw)
To: Stephen Boyd, Mike Turquette, linux-clk, linux-kernel
Cc: devicetree, Jason Cooper, Andrew Lunn, Antoine Tenart,
Gregory CLEMENT, Maxime Chevallier, Rob Herring, Thomas Petazzoni,
Miquèl Raynal, linux-arm-kernel, Sebastian Hesselbarth
In-Reply-To: <20181206171516.15891-1-gregory.clement@bootlin.com>
Add cpu clock node on AP
Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
---
arch/arm64/boot/dts/marvell/armada-ap806-quad.dtsi | 4 ++++
arch/arm64/boot/dts/marvell/armada-ap806.dtsi | 6 ++++++
2 files changed, 10 insertions(+)
diff --git a/arch/arm64/boot/dts/marvell/armada-ap806-quad.dtsi b/arch/arm64/boot/dts/marvell/armada-ap806-quad.dtsi
index 01ea662afba8..c2c81d4e2d38 100644
--- a/arch/arm64/boot/dts/marvell/armada-ap806-quad.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-ap806-quad.dtsi
@@ -20,24 +20,28 @@
compatible = "arm,cortex-a72", "arm,armv8";
reg = <0x000>;
enable-method = "psci";
+ clocks = <&cpu_clk 0>;
};
cpu1: cpu@1 {
device_type = "cpu";
compatible = "arm,cortex-a72", "arm,armv8";
reg = <0x001>;
enable-method = "psci";
+ clocks = <&cpu_clk 0>;
};
cpu2: cpu@100 {
device_type = "cpu";
compatible = "arm,cortex-a72", "arm,armv8";
reg = <0x100>;
enable-method = "psci";
+ clocks = <&cpu_clk 1>;
};
cpu3: cpu@101 {
device_type = "cpu";
compatible = "arm,cortex-a72", "arm,armv8";
reg = <0x101>;
enable-method = "psci";
+ clocks = <&cpu_clk 1>;
};
};
};
diff --git a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
index 7d94c1fa592a..a430e884b1a3 100644
--- a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi
@@ -263,6 +263,12 @@
#address-cells = <1>;
#size-cells = <1>;
+ cpu_clk: clock-cpu {
+ compatible = "marvell,ap806-cpu-clock";
+ clocks = <&ap_clk 0>, <&ap_clk 1>;
+ #clock-cells = <1>;
+ };
+
ap_thermal: thermal-sensor@80 {
compatible = "marvell,armada-ap806-thermal";
reg = <0x80 0x10>;
--
2.19.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v2 2/5] clk: mvebu: add CPU clock driver for Armada 7K/8K
From: Gregory CLEMENT @ 2018-12-06 17:15 UTC (permalink / raw)
To: Stephen Boyd, Mike Turquette, linux-clk, linux-kernel
Cc: devicetree, Jason Cooper, Andrew Lunn, Antoine Tenart,
Gregory CLEMENT, Maxime Chevallier, Rob Herring, Thomas Petazzoni,
Miquèl Raynal, linux-arm-kernel, Sebastian Hesselbarth
In-Reply-To: <20181206171516.15891-1-gregory.clement@bootlin.com>
The CPU frequency is managed at the AP level for the Armada 7K/8K. The
CPU frequency is modified by cluster: the CPUs of the same cluster have
the same frequency.
This patch adds the clock driver that will be used by CPUFreq, it is
based on the work of Omri Itach <omrii@marvell.com>.
Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
---
drivers/clk/mvebu/Kconfig | 3 +
drivers/clk/mvebu/Makefile | 1 +
drivers/clk/mvebu/ap-cpu-clk.c | 259 +++++++++++++++++++++++++++++++++
3 files changed, 263 insertions(+)
create mode 100644 drivers/clk/mvebu/ap-cpu-clk.c
diff --git a/drivers/clk/mvebu/Kconfig b/drivers/clk/mvebu/Kconfig
index 5492fae3f0ab..9d0b2f7cee21 100644
--- a/drivers/clk/mvebu/Kconfig
+++ b/drivers/clk/mvebu/Kconfig
@@ -39,6 +39,9 @@ config ARMADA_AP806_SYSCON
bool
select ARMADA_AP_CP_HELPER
+config ARMADA_AP_CPU_CLK
+ bool
+
config ARMADA_CP110_SYSCON
bool
select ARMADA_AP_CP_HELPER
diff --git a/drivers/clk/mvebu/Makefile b/drivers/clk/mvebu/Makefile
index 6638ad962ec1..04464cef0f06 100644
--- a/drivers/clk/mvebu/Makefile
+++ b/drivers/clk/mvebu/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_ARMADA_37XX_CLK) += armada-37xx-tbg.o
obj-$(CONFIG_ARMADA_37XX_CLK) += armada-37xx-periph.o
obj-$(CONFIG_ARMADA_XP_CLK) += armada-xp.o mv98dx3236.o
obj-$(CONFIG_ARMADA_AP806_SYSCON) += ap806-system-controller.o
+obj-$(CONFIG_ARMADA_AP_CPU_CLK) += ap-cpu-clk.o
obj-$(CONFIG_ARMADA_CP110_SYSCON) += cp110-system-controller.o
obj-$(CONFIG_DOVE_CLK) += dove.o dove-divider.o
obj-$(CONFIG_KIRKWOOD_CLK) += kirkwood.o
diff --git a/drivers/clk/mvebu/ap-cpu-clk.c b/drivers/clk/mvebu/ap-cpu-clk.c
new file mode 100644
index 000000000000..e4cecb456884
--- /dev/null
+++ b/drivers/clk/mvebu/ap-cpu-clk.c
@@ -0,0 +1,259 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Marvell Armada AP CPU Clock Controller
+ *
+ * Copyright (C) 2018 Marvell
+ *
+ * Omri Itach <omrii@marvell.com>
+ * Gregory Clement <gregory.clement@bootlin.com>
+ */
+
+#define pr_fmt(fmt) "ap-cpu-clk: " fmt
+
+#include <linux/clk-provider.h>
+#include <linux/clk.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include "armada_ap_cp_helper.h"
+
+#define AP806_CPU_CLUSTER0 0
+#define AP806_CPU_CLUSTER1 1
+#define AP806_CPUS_PER_CLUSTER 2
+#define APN806_CPU1_MASK 0x1
+
+#define APN806_CLUSTER_NUM_OFFSET 8
+#define APN806_CLUSTER_NUM_MASK BIT(APN806_CLUSTER_NUM_OFFSET)
+
+#define APN806_MAX_DIVIDER 32
+
+/* AP806 CPU DFS register mapping*/
+#define AP806_CA72MP2_0_PLL_CR_0_REG_OFFSET 0x278
+#define AP806_CA72MP2_0_PLL_CR_1_REG_OFFSET 0x280
+#define AP806_CA72MP2_0_PLL_CR_2_REG_OFFSET 0x284
+#define AP806_CA72MP2_0_PLL_SR_REG_OFFSET 0xC94
+
+#define AP806_CA72MP2_0_PLL_CR_CLUSTER_OFFSET 0x14
+#define AP806_PLL_CR_0_CPU_CLK_DIV_RATIO_OFFSET 0
+#define AP806_PLL_CR_0_CPU_CLK_DIV_RATIO_MASK \
+ (0x3f << AP806_PLL_CR_0_CPU_CLK_DIV_RATIO_OFFSET)
+#define AP806_PLL_CR_0_CPU_CLK_RELOAD_FORCE_OFFSET 24
+#define AP806_PLL_CR_0_CPU_CLK_RELOAD_FORCE_MASK \
+ (0x1 << AP806_PLL_CR_0_CPU_CLK_RELOAD_FORCE_OFFSET)
+#define AP806_PLL_CR_0_CPU_CLK_RELOAD_RATIO_OFFSET 16
+#define AP806_CA72MP2_0_PLL_RATIO_STATE 11
+
+#define STATUS_POLL_PERIOD_US 1
+#define STATUS_POLL_TIMEOUT_US 1000000
+
+#define to_ap_cpu_clk(_hw) container_of(_hw, struct ap_cpu_clk, hw)
+
+/*
+ * struct ap806_clk: CPU cluster clock controller instance
+ * @cluster: Cluster clock controller index
+ * @clk_name: Cluster clock controller name
+ * @dev : Cluster clock device
+ * @hw: HW specific structure of Cluster clock controller
+ * @pll_cr_base: CA72MP2 Register base (Device Sample at Reset register)
+ */
+struct ap_cpu_clk {
+ unsigned int cluster;
+ const char *clk_name;
+ struct device *dev;
+ struct clk_hw hw;
+ struct regmap *pll_cr_base;
+};
+
+static unsigned long ap_cpu_clk_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct ap_cpu_clk *clk = to_ap_cpu_clk(hw);
+ unsigned int cpu_clkdiv_reg;
+ int cpu_clkdiv_ratio;
+
+ cpu_clkdiv_reg = AP806_CA72MP2_0_PLL_CR_0_REG_OFFSET +
+ (clk->cluster * AP806_CA72MP2_0_PLL_CR_CLUSTER_OFFSET);
+ regmap_read(clk->pll_cr_base, cpu_clkdiv_reg, &cpu_clkdiv_ratio);
+ cpu_clkdiv_ratio &= AP806_PLL_CR_0_CPU_CLK_DIV_RATIO_MASK;
+ cpu_clkdiv_ratio >>= AP806_PLL_CR_0_CPU_CLK_DIV_RATIO_OFFSET;
+
+ return parent_rate / cpu_clkdiv_ratio;
+}
+
+static int ap_cpu_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct ap_cpu_clk *clk = to_ap_cpu_clk(hw);
+ int ret, reg, divider = parent_rate / rate;
+ unsigned int cpu_clkdiv_reg, cpu_force_reg, cpu_ratio_reg, stable_bit;
+
+ cpu_clkdiv_reg = AP806_CA72MP2_0_PLL_CR_0_REG_OFFSET +
+ (clk->cluster * AP806_CA72MP2_0_PLL_CR_CLUSTER_OFFSET);
+ cpu_force_reg = AP806_CA72MP2_0_PLL_CR_1_REG_OFFSET +
+ (clk->cluster * AP806_CA72MP2_0_PLL_CR_CLUSTER_OFFSET);
+ cpu_ratio_reg = AP806_CA72MP2_0_PLL_CR_2_REG_OFFSET +
+ (clk->cluster * AP806_CA72MP2_0_PLL_CR_CLUSTER_OFFSET);
+
+ regmap_update_bits(clk->pll_cr_base, cpu_clkdiv_reg,
+ AP806_PLL_CR_0_CPU_CLK_DIV_RATIO_MASK, divider);
+
+ regmap_update_bits(clk->pll_cr_base, cpu_force_reg,
+ AP806_PLL_CR_0_CPU_CLK_RELOAD_FORCE_MASK,
+ AP806_PLL_CR_0_CPU_CLK_RELOAD_FORCE_MASK);
+
+ regmap_update_bits(clk->pll_cr_base, cpu_ratio_reg,
+ BIT(AP806_PLL_CR_0_CPU_CLK_RELOAD_RATIO_OFFSET),
+ BIT(AP806_PLL_CR_0_CPU_CLK_RELOAD_RATIO_OFFSET));
+
+ stable_bit = BIT(clk->cluster * AP806_CA72MP2_0_PLL_RATIO_STATE),
+
+ ret = regmap_read_poll_timeout(clk->pll_cr_base,
+ AP806_CA72MP2_0_PLL_SR_REG_OFFSET, reg,
+ reg & stable_bit, STATUS_POLL_PERIOD_US,
+ STATUS_POLL_TIMEOUT_US);
+ if (ret)
+ return ret;
+
+ regmap_update_bits(clk->pll_cr_base, cpu_ratio_reg,
+ BIT(AP806_PLL_CR_0_CPU_CLK_RELOAD_RATIO_OFFSET), 0);
+
+ return 0;
+}
+
+static long ap_cpu_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *parent_rate)
+{
+ int divider = *parent_rate / rate;
+
+ divider = min(divider, APN806_MAX_DIVIDER);
+
+ return *parent_rate / divider;
+}
+
+static const struct clk_ops ap_cpu_clk_ops = {
+ .recalc_rate = ap_cpu_clk_recalc_rate,
+ .round_rate = ap_cpu_clk_round_rate,
+ .set_rate = ap_cpu_clk_set_rate,
+};
+
+static int ap_cpu_clock_probe(struct platform_device *pdev)
+{
+ int ret, nclusters = 0, cluster_index = 0;
+ struct device *dev = &pdev->dev;
+ struct device_node *dn, *np = dev->of_node;
+ struct clk_hw_onecell_data *ap_cpu_data;
+ struct ap_cpu_clk *ap_cpu_clk;
+ struct regmap *regmap;
+
+ regmap = syscon_node_to_regmap(np->parent);
+ if (IS_ERR(regmap)) {
+ pr_err("cannot get pll_cr_base regmap\n");
+ return PTR_ERR(regmap);
+ }
+
+ /*
+ * AP806 has 4 cpus and DFS for AP806 is controlled per
+ * cluster (2 CPUs per cluster), cpu0 and cpu1 are fixed to
+ * cluster0 while cpu2 and cpu3 are fixed to cluster1 whether
+ * they are enabled or not. Since cpu0 is the boot cpu, then
+ * cluster0 must exist. If cpu2 or cpu3 is enabled, cluster1
+ * will exist and the cluster number is 2; otherwise the
+ * cluster number is 1.
+ */
+ nclusters = 1;
+ for_each_of_cpu_node(dn) {
+ int cpu, err;
+
+ err = of_property_read_u32(dn, "reg", &cpu);
+ if (WARN_ON(err))
+ return err;
+
+ /* If cpu2 or cpu3 is enabled */
+ if (cpu & APN806_CLUSTER_NUM_MASK) {
+ nclusters = 2;
+ break;
+ }
+ }
+ /*
+ * DFS for AP806 is controlled per cluster (2 CPUs per cluster),
+ * so allocate structs per cluster
+ */
+ ap_cpu_clk = devm_kcalloc(dev, nclusters, sizeof(*ap_cpu_clk),
+ GFP_KERNEL);
+ if (!ap_cpu_clk)
+ return -ENOMEM;
+
+ ap_cpu_data = devm_kzalloc(dev, sizeof(*ap_cpu_data) +
+ sizeof(struct clk_hw *) * nclusters,
+ GFP_KERNEL);
+ if (!ap_cpu_data)
+ return -ENOMEM;
+
+ for_each_of_cpu_node(dn) {
+ char *clk_name = "cpu-cluster-0";
+ struct clk_init_data init;
+ const char *parent_name;
+ struct clk *parent;
+ int cpu, err;
+
+ err = of_property_read_u32(dn, "reg", &cpu);
+ if (WARN_ON(err))
+ return err;
+
+ cluster_index = cpu & APN806_CLUSTER_NUM_MASK;
+ cluster_index >>= APN806_CLUSTER_NUM_OFFSET;
+
+ /* Initialize once for one cluster */
+ if (ap_cpu_data->hws[cluster_index])
+ continue;
+
+ parent = of_clk_get(np, cluster_index);
+ if (IS_ERR(parent)) {
+ dev_err(dev, "Could not get the clock parent\n");
+ return -EINVAL;
+ }
+ parent_name = __clk_get_name(parent);
+ clk_name[12] += cluster_index;
+ ap_cpu_clk[cluster_index].clk_name =
+ ap_cp_unique_name(dev, np->parent, clk_name);
+ ap_cpu_clk[cluster_index].cluster = cluster_index;
+ ap_cpu_clk[cluster_index].pll_cr_base = regmap;
+ ap_cpu_clk[cluster_index].hw.init = &init;
+ ap_cpu_clk[cluster_index].dev = dev;
+
+ init.name = ap_cpu_clk[cluster_index].clk_name;
+ init.ops = &ap_cpu_clk_ops;
+ init.num_parents = 1;
+ init.parent_names = &parent_name;
+
+ ret = devm_clk_hw_register(dev, &ap_cpu_clk[cluster_index].hw);
+ if (ret)
+ return ret;
+ ap_cpu_data->hws[cluster_index] = &ap_cpu_clk[cluster_index].hw;
+ }
+
+ ap_cpu_data->num = cluster_index + 1;
+
+ ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, ap_cpu_data);
+ if (ret)
+ dev_err(dev, "failed to register OF clock provider\n");
+
+ return ret;
+}
+
+static const struct of_device_id ap_cpu_clock_of_match[] = {
+ { .compatible = "marvell,ap806-cpu-clock", },
+ { }
+};
+
+static struct platform_driver ap_cpu_clock_driver = {
+ .probe = ap_cpu_clock_probe,
+ .driver = {
+ .name = "marvell-ap-cpu-clock",
+ .of_match_table = ap_cpu_clock_of_match,
+ .suppress_bind_attrs = true,
+ },
+};
+builtin_platform_driver(ap_cpu_clock_driver);
--
2.19.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v2 4/5] arm64: marvell: enable the Armada 7K/8K CPU clk driver
From: Gregory CLEMENT @ 2018-12-06 17:15 UTC (permalink / raw)
To: Stephen Boyd, Mike Turquette, linux-clk, linux-kernel
Cc: devicetree, Jason Cooper, Andrew Lunn, Antoine Tenart,
Gregory CLEMENT, Maxime Chevallier, Rob Herring, Thomas Petazzoni,
Miquèl Raynal, linux-arm-kernel, Sebastian Hesselbarth
In-Reply-To: <20181206171516.15891-1-gregory.clement@bootlin.com>
This commit makes sure the driver for the Armada 7K/8K CPU clock is
enabled.
Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
---
arch/arm64/Kconfig.platforms | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 51bc479334a4..8a05870b1ba8 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -121,6 +121,7 @@ config ARCH_MESON
config ARCH_MVEBU
bool "Marvell EBU SoC Family"
+ select ARMADA_AP_CPU_CLK
select ARMADA_AP806_SYSCON
select ARMADA_CP110_SYSCON
select ARMADA_37XX_CLK
--
2.19.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v2 1/5] clk: mvebu: add helper file for Armada AP and CP clocks
From: Gregory CLEMENT @ 2018-12-06 17:15 UTC (permalink / raw)
To: Stephen Boyd, Mike Turquette, linux-clk, linux-kernel
Cc: devicetree, Jason Cooper, Andrew Lunn, Antoine Tenart,
Gregory CLEMENT, Maxime Chevallier, Rob Herring, Thomas Petazzoni,
Miquèl Raynal, linux-arm-kernel, Sebastian Hesselbarth
In-Reply-To: <20181206171516.15891-1-gregory.clement@bootlin.com>
Clock drivers for Armada AP and Armada CP use the same function to
generate unique clock name. A third drivers is coming with the same
need, so it's time to move this function in a common file.
Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
---
drivers/clk/mvebu/Kconfig | 5 ++++
drivers/clk/mvebu/Makefile | 1 +
drivers/clk/mvebu/ap806-system-controller.c | 24 ++++------------
drivers/clk/mvebu/armada_ap_cp_helper.c | 30 +++++++++++++++++++
drivers/clk/mvebu/armada_ap_cp_helper.h | 11 +++++++
drivers/clk/mvebu/cp110-system-controller.c | 32 ++++++---------------
6 files changed, 61 insertions(+), 42 deletions(-)
create mode 100644 drivers/clk/mvebu/armada_ap_cp_helper.c
create mode 100644 drivers/clk/mvebu/armada_ap_cp_helper.h
diff --git a/drivers/clk/mvebu/Kconfig b/drivers/clk/mvebu/Kconfig
index fddc8ac5faff..5492fae3f0ab 100644
--- a/drivers/clk/mvebu/Kconfig
+++ b/drivers/clk/mvebu/Kconfig
@@ -7,6 +7,9 @@ config MVEBU_CLK_CPU
config MVEBU_CLK_COREDIV
bool
+config ARMADA_AP_CP_HELPER
+ bool
+
config ARMADA_370_CLK
bool
select MVEBU_CLK_COMMON
@@ -34,9 +37,11 @@ config ARMADA_XP_CLK
config ARMADA_AP806_SYSCON
bool
+ select ARMADA_AP_CP_HELPER
config ARMADA_CP110_SYSCON
bool
+ select ARMADA_AP_CP_HELPER
config DOVE_CLK
bool
diff --git a/drivers/clk/mvebu/Makefile b/drivers/clk/mvebu/Makefile
index 93ac3685271f..6638ad962ec1 100644
--- a/drivers/clk/mvebu/Makefile
+++ b/drivers/clk/mvebu/Makefile
@@ -2,6 +2,7 @@
obj-$(CONFIG_MVEBU_CLK_COMMON) += common.o
obj-$(CONFIG_MVEBU_CLK_CPU) += clk-cpu.o
obj-$(CONFIG_MVEBU_CLK_COREDIV) += clk-corediv.o
+obj-$(CONFIG_ARMADA_AP_CP_HELPER) += armada_ap_cp_helper.o
obj-$(CONFIG_ARMADA_370_CLK) += armada-370.o
obj-$(CONFIG_ARMADA_375_CLK) += armada-375.o
diff --git a/drivers/clk/mvebu/ap806-system-controller.c b/drivers/clk/mvebu/ap806-system-controller.c
index ea54a874bbda..0a58824ff053 100644
--- a/drivers/clk/mvebu/ap806-system-controller.c
+++ b/drivers/clk/mvebu/ap806-system-controller.c
@@ -10,11 +10,11 @@
#define pr_fmt(fmt) "ap806-system-controller: " fmt
+#include "armada_ap_cp_helper.h"
#include <linux/clk-provider.h>
#include <linux/mfd/syscon.h>
#include <linux/init.h>
#include <linux/of.h>
-#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
@@ -30,18 +30,6 @@ static struct clk_onecell_data ap806_clk_data = {
.clk_num = AP806_CLK_NUM,
};
-static char *ap806_unique_name(struct device *dev, struct device_node *np,
- char *name)
-{
- const __be32 *reg;
- u64 addr;
-
- reg = of_get_property(np, "reg", NULL);
- addr = of_translate_address(np, reg);
- return devm_kasprintf(dev, GFP_KERNEL, "%llx-%s",
- (unsigned long long)addr, name);
-}
-
static int ap806_syscon_common_probe(struct platform_device *pdev,
struct device_node *syscon_node)
{
@@ -109,7 +97,7 @@ static int ap806_syscon_common_probe(struct platform_device *pdev,
cpuclk_freq *= 1000 * 1000;
/* CPU clocks depend on the Sample At Reset configuration */
- name = ap806_unique_name(dev, syscon_node, "cpu-cluster-0");
+ name = ap_cp_unique_name(dev, syscon_node, "cpu-cluster-0");
ap806_clks[0] = clk_register_fixed_rate(dev, name, NULL,
0, cpuclk_freq);
if (IS_ERR(ap806_clks[0])) {
@@ -117,7 +105,7 @@ static int ap806_syscon_common_probe(struct platform_device *pdev,
goto fail0;
}
- name = ap806_unique_name(dev, syscon_node, "cpu-cluster-1");
+ name = ap_cp_unique_name(dev, syscon_node, "cpu-cluster-1");
ap806_clks[1] = clk_register_fixed_rate(dev, name, NULL, 0,
cpuclk_freq);
if (IS_ERR(ap806_clks[1])) {
@@ -126,7 +114,7 @@ static int ap806_syscon_common_probe(struct platform_device *pdev,
}
/* Fixed clock is always 1200 Mhz */
- fixedclk_name = ap806_unique_name(dev, syscon_node, "fixed");
+ fixedclk_name = ap_cp_unique_name(dev, syscon_node, "fixed");
ap806_clks[2] = clk_register_fixed_rate(dev, fixedclk_name, NULL,
0, 1200 * 1000 * 1000);
if (IS_ERR(ap806_clks[2])) {
@@ -135,7 +123,7 @@ static int ap806_syscon_common_probe(struct platform_device *pdev,
}
/* MSS Clock is fixed clock divided by 6 */
- name = ap806_unique_name(dev, syscon_node, "mss");
+ name = ap_cp_unique_name(dev, syscon_node, "mss");
ap806_clks[3] = clk_register_fixed_factor(NULL, name, fixedclk_name,
0, 1, 6);
if (IS_ERR(ap806_clks[3])) {
@@ -144,7 +132,7 @@ static int ap806_syscon_common_probe(struct platform_device *pdev,
}
/* SDIO(/eMMC) Clock is fixed clock divided by 3 */
- name = ap806_unique_name(dev, syscon_node, "sdio");
+ name = ap_cp_unique_name(dev, syscon_node, "sdio");
ap806_clks[4] = clk_register_fixed_factor(NULL, name,
fixedclk_name,
0, 1, 3);
diff --git a/drivers/clk/mvebu/armada_ap_cp_helper.c b/drivers/clk/mvebu/armada_ap_cp_helper.c
new file mode 100644
index 000000000000..6a930f697ee5
--- /dev/null
+++ b/drivers/clk/mvebu/armada_ap_cp_helper.c
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Marvell Armada AP and CP110 helper
+ *
+ * Copyright (C) 2018 Marvell
+ *
+ * Gregory Clement <gregory.clement@bootlin.com>
+ *
+ */
+
+#include "armada_ap_cp_helper.h"
+#include <linux/device.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+char *ap_cp_unique_name(struct device *dev, struct device_node *np,
+ const char *name)
+{
+ const __be32 *reg;
+ u64 addr;
+
+ /* Do not create a name if there is no clock */
+ if (!name)
+ return NULL;
+
+ reg = of_get_property(np, "reg", NULL);
+ addr = of_translate_address(np, reg);
+ return devm_kasprintf(dev, GFP_KERNEL, "%llx-%s",
+ (unsigned long long)addr, name);
+}
diff --git a/drivers/clk/mvebu/armada_ap_cp_helper.h b/drivers/clk/mvebu/armada_ap_cp_helper.h
new file mode 100644
index 000000000000..810af1e5dfa4
--- /dev/null
+++ b/drivers/clk/mvebu/armada_ap_cp_helper.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#ifndef __ARMADA_AP_CP_HELPER_H
+#define __ARMADA_AP_CP_HELPER_H
+
+struct device;
+struct device_node;
+
+char *ap_cp_unique_name(struct device *dev, struct device_node *np,
+ const char *name);
+#endif
diff --git a/drivers/clk/mvebu/cp110-system-controller.c b/drivers/clk/mvebu/cp110-system-controller.c
index 9781b1bf5998..e5f6c4b114b0 100644
--- a/drivers/clk/mvebu/cp110-system-controller.c
+++ b/drivers/clk/mvebu/cp110-system-controller.c
@@ -26,11 +26,11 @@
#define pr_fmt(fmt) "cp110-system-controller: " fmt
+#include "armada_ap_cp_helper.h"
#include <linux/clk-provider.h>
#include <linux/mfd/syscon.h>
#include <linux/init.h>
#include <linux/of.h>
-#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/slab.h>
@@ -212,22 +212,6 @@ static struct clk_hw *cp110_of_clk_get(struct of_phandle_args *clkspec,
return ERR_PTR(-EINVAL);
}
-static char *cp110_unique_name(struct device *dev, struct device_node *np,
- const char *name)
-{
- const __be32 *reg;
- u64 addr;
-
- /* Do not create a name if there is no clock */
- if (!name)
- return NULL;
-
- reg = of_get_property(np, "reg", NULL);
- addr = of_translate_address(np, reg);
- return devm_kasprintf(dev, GFP_KERNEL, "%llx-%s",
- (unsigned long long)addr, name);
-}
-
static int cp110_syscon_common_probe(struct platform_device *pdev,
struct device_node *syscon_node)
{
@@ -261,7 +245,7 @@ static int cp110_syscon_common_probe(struct platform_device *pdev,
cp110_clk_data->num = CP110_CLK_NUM;
/* Register the PLL0 which is the root of the hw tree */
- pll0_name = cp110_unique_name(dev, syscon_node, "pll0");
+ pll0_name = ap_cp_unique_name(dev, syscon_node, "pll0");
hw = clk_hw_register_fixed_rate(NULL, pll0_name, NULL, 0,
1000 * 1000 * 1000);
if (IS_ERR(hw)) {
@@ -272,7 +256,7 @@ static int cp110_syscon_common_probe(struct platform_device *pdev,
cp110_clks[CP110_CORE_PLL0] = hw;
/* PPv2 is PLL0/3 */
- ppv2_name = cp110_unique_name(dev, syscon_node, "ppv2-core");
+ ppv2_name = ap_cp_unique_name(dev, syscon_node, "ppv2-core");
hw = clk_hw_register_fixed_factor(NULL, ppv2_name, pll0_name, 0, 1, 3);
if (IS_ERR(hw)) {
ret = PTR_ERR(hw);
@@ -282,7 +266,7 @@ static int cp110_syscon_common_probe(struct platform_device *pdev,
cp110_clks[CP110_CORE_PPV2] = hw;
/* X2CORE clock is PLL0/2 */
- x2core_name = cp110_unique_name(dev, syscon_node, "x2core");
+ x2core_name = ap_cp_unique_name(dev, syscon_node, "x2core");
hw = clk_hw_register_fixed_factor(NULL, x2core_name, pll0_name,
0, 1, 2);
if (IS_ERR(hw)) {
@@ -293,7 +277,7 @@ static int cp110_syscon_common_probe(struct platform_device *pdev,
cp110_clks[CP110_CORE_X2CORE] = hw;
/* Core clock is X2CORE/2 */
- core_name = cp110_unique_name(dev, syscon_node, "core");
+ core_name = ap_cp_unique_name(dev, syscon_node, "core");
hw = clk_hw_register_fixed_factor(NULL, core_name, x2core_name,
0, 1, 2);
if (IS_ERR(hw)) {
@@ -303,7 +287,7 @@ static int cp110_syscon_common_probe(struct platform_device *pdev,
cp110_clks[CP110_CORE_CORE] = hw;
/* NAND can be either PLL0/2.5 or core clock */
- nand_name = cp110_unique_name(dev, syscon_node, "nand-core");
+ nand_name = ap_cp_unique_name(dev, syscon_node, "nand-core");
if (nand_clk_ctrl & NF_CLOCK_SEL_400_MASK)
hw = clk_hw_register_fixed_factor(NULL, nand_name,
pll0_name, 0, 2, 5);
@@ -318,7 +302,7 @@ static int cp110_syscon_common_probe(struct platform_device *pdev,
cp110_clks[CP110_CORE_NAND] = hw;
/* SDIO clock is PLL0/2.5 */
- sdio_name = cp110_unique_name(dev, syscon_node, "sdio-core");
+ sdio_name = ap_cp_unique_name(dev, syscon_node, "sdio-core");
hw = clk_hw_register_fixed_factor(NULL, sdio_name,
pll0_name, 0, 2, 5);
if (IS_ERR(hw)) {
@@ -330,7 +314,7 @@ static int cp110_syscon_common_probe(struct platform_device *pdev,
/* create the unique name for all the gate clocks */
for (i = 0; i < ARRAY_SIZE(gate_base_names); i++)
- gate_name[i] = cp110_unique_name(dev, syscon_node,
+ gate_name[i] = ap_cp_unique_name(dev, syscon_node,
gate_base_names[i]);
for (i = 0; i < ARRAY_SIZE(gate_base_names); i++) {
--
2.19.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v2 0/5] Add CPU clock support for Armada 7K/8K
From: Gregory CLEMENT @ 2018-12-06 17:15 UTC (permalink / raw)
To: Stephen Boyd, Mike Turquette, linux-clk, linux-kernel
Cc: devicetree, Jason Cooper, Andrew Lunn, Antoine Tenart,
Gregory CLEMENT, Maxime Chevallier, Rob Herring, Thomas Petazzoni,
Miquèl Raynal, linux-arm-kernel, Sebastian Hesselbarth
Hello,
This is the second version of a series allowing to manage the cpu
clock for Armada 7K/8K. For these SoCs, the CPUs share the same clock
by cluster, so actually the clock management is done at cluster level.
As for the other Armada 7K/8K clocks it is possible to have multiple
AP so here again we need to have unique name: the purpose of the second
patch is to share a common code which will be used in 3 drivers.
The last 2 patch enable the driver at dt and platform level and will
be applied through the mvebu subsystem.
Changelog v1->v2:
- Header cleanup
- Use unsigned int instead of it for cluster member of the ap_cpu_clk struct
- Use clk_hw instead of clk
- Use regmap_read_poll_timeout
- Use for_each_of_cpu_node
- Remove unnecessary WARN_ON()
- Remove headers from armada_ap_cp_helper.h
- Few other minor cleanup
Gregory CLEMENT (5):
clk: mvebu: add helper file for Armada AP and CP clocks
clk: mvebu: add CPU clock driver for Armada 7K/8K
clk: mvebu: ap806: Fix clock name for the cluster
arm64: marvell: enable the Armada 7K/8K CPU clk driver
arm64: dts: marvell: Add cpu clock node on Armada 7K/8K
arch/arm64/Kconfig.platforms | 1 +
.../boot/dts/marvell/armada-ap806-quad.dtsi | 4 +
arch/arm64/boot/dts/marvell/armada-ap806.dtsi | 6 +
drivers/clk/mvebu/Kconfig | 8 +
drivers/clk/mvebu/Makefile | 2 +
drivers/clk/mvebu/ap-cpu-clk.c | 259 ++++++++++++++++++
drivers/clk/mvebu/ap806-system-controller.c | 24 +-
drivers/clk/mvebu/armada_ap_cp_helper.c | 30 ++
drivers/clk/mvebu/armada_ap_cp_helper.h | 11 +
drivers/clk/mvebu/cp110-system-controller.c | 32 +--
10 files changed, 335 insertions(+), 42 deletions(-)
create mode 100644 drivers/clk/mvebu/ap-cpu-clk.c
create mode 100644 drivers/clk/mvebu/armada_ap_cp_helper.c
create mode 100644 drivers/clk/mvebu/armada_ap_cp_helper.h
--
2.19.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v2 3/5] clk: mvebu: ap806: Fix clock name for the cluster
From: Gregory CLEMENT @ 2018-12-06 17:15 UTC (permalink / raw)
To: Stephen Boyd, Mike Turquette, linux-clk, linux-kernel
Cc: devicetree, Jason Cooper, Andrew Lunn, Antoine Tenart,
Gregory CLEMENT, Maxime Chevallier, Rob Herring, Thomas Petazzoni,
Miquèl Raynal, linux-arm-kernel, Sebastian Hesselbarth
In-Reply-To: <20181206171516.15891-1-gregory.clement@bootlin.com>
Actually, the clocks exposed for the cluster are not the CPU clocks, but
the PLL clock used as entry clock for the CPU clocks. The CPU clock will
be managed by a driver submitting in the following patches.
Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
---
drivers/clk/mvebu/ap806-system-controller.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/clk/mvebu/ap806-system-controller.c b/drivers/clk/mvebu/ap806-system-controller.c
index 0a58824ff053..73ba8fd7860f 100644
--- a/drivers/clk/mvebu/ap806-system-controller.c
+++ b/drivers/clk/mvebu/ap806-system-controller.c
@@ -97,7 +97,7 @@ static int ap806_syscon_common_probe(struct platform_device *pdev,
cpuclk_freq *= 1000 * 1000;
/* CPU clocks depend on the Sample At Reset configuration */
- name = ap_cp_unique_name(dev, syscon_node, "cpu-cluster-0");
+ name = ap_cp_unique_name(dev, syscon_node, "pll-cluster-0");
ap806_clks[0] = clk_register_fixed_rate(dev, name, NULL,
0, cpuclk_freq);
if (IS_ERR(ap806_clks[0])) {
@@ -105,7 +105,7 @@ static int ap806_syscon_common_probe(struct platform_device *pdev,
goto fail0;
}
- name = ap_cp_unique_name(dev, syscon_node, "cpu-cluster-1");
+ name = ap_cp_unique_name(dev, syscon_node, "pll-cluster-1");
ap806_clks[1] = clk_register_fixed_rate(dev, name, NULL, 0,
cpuclk_freq);
if (IS_ERR(ap806_clks[1])) {
--
2.19.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH v2 2/3] arm64: dts: allwinner: a64: Add A64 CSI controller
From: Michael Nazzareno Trimarchi @ 2018-12-06 17:07 UTC (permalink / raw)
To: Maxime Ripard
Cc: Mark Rutland, devicetree, LKML, Chen-Yu Tsai, Rob Herring,
Jagan Teki, linux-amarula, linux-arm-kernel
In-Reply-To: <20181206153445.kqu2pep5orktr6yv@flea>
Hi Maxime
On Thu, Dec 6, 2018 at 4:34 PM Maxime Ripard <maxime.ripard@bootlin.com> wrote:
>
> On Thu, Dec 06, 2018 at 06:53:05PM +0530, Jagan Teki wrote:
> > Allwinner A64 CSI controller has similar features as like in
> > H3, So add support for A64 via H3 fallback.
> >
> > Also updated CSI_SCLK to use 300MHz via assigned-clocks, since
> > the default clock 600MHz seems unable to drive the sensor(ov5640)
> > to capture the image.
> >
> > Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
> > ---
> > Changes for v2:
> > - Use CSI_SCLK to 300MHz
> >
> > arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 23 +++++++++++++++++++
> > 1 file changed, 23 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> > index 384c417cb7a2..d7ab0006ebce 100644
> > --- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> > +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> > @@ -532,6 +532,12 @@
> > interrupt-controller;
> > #interrupt-cells = <3>;
> >
> > + csi_pins: csi-pins {
> > + pins = "PE0", "PE2", "PE3", "PE4", "PE5", "PE6",
> > + "PE7", "PE8", "PE9", "PE10", "PE11";
> > + function = "csi0";
> > + };
> > +
> > i2c0_pins: i2c0_pins {
> > pins = "PH0", "PH1";
> > function = "i2c0";
> > @@ -899,6 +905,23 @@
> > status = "disabled";
> > };
> >
> > + csi: csi@1cb0000 {
> > + compatible = "allwinner,sun50i-a64-csi",
> > + "allwinner,sun8i-h3-csi";
> > + reg = <0x01cb0000 0x1000>;
> > + interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
> > + clocks = <&ccu CLK_BUS_CSI>,
> > + <&ccu CLK_CSI_SCLK>,
> > + <&ccu CLK_DRAM_CSI>;
> > + clock-names = "bus", "mod", "ram";
> > + resets = <&ccu RST_BUS_CSI>;
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&csi_pins>;
> > + assigned-clocks = <&ccu CLK_CSI_SCLK>;
> > + assigned-clock-rates = <300000000>;
>
> That should be enforced in the driver.
>
We are not really sure what is the best here. Our first idea was to
put in the board file and then Jagan
decide to put in dtsi. We don't have enough coverage of camera on this
CPU and I prefer to stay with this
minimal change that does not impact the driver.
Michael
> Maxime
>
> --
> Maxime Ripard, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com
--
| Michael Nazzareno Trimarchi Amarula Solutions BV |
| COO - Founder Cruquiuskade 47 |
| +31(0)851119172 Amsterdam 1018 AM NL |
| [`as] http://www.amarulasolutions.com |
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v3 12/12] perf/core: remove unused perf_flags
From: Andrew Murray @ 2018-12-06 16:47 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Richard Henderson, Ivan Kokshaysky, Matt Turner, Will Deacon,
Mark Rutland, Shawn Guo, Sascha Hauer, Benjamin Herrenschmidt,
Paul Mackerras, Thomas Gleixner, Borislav Petkov, Russell King,
suzuki.poulose, robin.murphy, Michael Ellerman
Cc: x86, linuxppc-dev, linux-kernel, linux-arm-kernel, linux-alpha
In-Reply-To: <1544114849-47266-1-git-send-email-andrew.murray@arm.com>
Now that perf_flags is not used we remove it.
Signed-off-by: Andrew Murray <andrew.murray@arm.com>
---
include/uapi/linux/perf_event.h | 2 --
tools/include/uapi/linux/perf_event.h | 2 --
2 files changed, 4 deletions(-)
diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
index f35eb72..ba89bd3 100644
--- a/include/uapi/linux/perf_event.h
+++ b/include/uapi/linux/perf_event.h
@@ -445,8 +445,6 @@ struct perf_event_query_bpf {
__u32 ids[0];
};
-#define perf_flags(attr) (*(&(attr)->read_format + 1))
-
/*
* Ioctls that can be done on a perf event fd:
*/
diff --git a/tools/include/uapi/linux/perf_event.h b/tools/include/uapi/linux/perf_event.h
index f35eb72..ba89bd3 100644
--- a/tools/include/uapi/linux/perf_event.h
+++ b/tools/include/uapi/linux/perf_event.h
@@ -445,8 +445,6 @@ struct perf_event_query_bpf {
__u32 ids[0];
};
-#define perf_flags(attr) (*(&(attr)->read_format + 1))
-
/*
* Ioctls that can be done on a perf event fd:
*/
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 2/7] arm64: tegra: Enable HDA on Jetson TX2
From: Thierry Reding @ 2018-12-06 16:50 UTC (permalink / raw)
To: Thierry Reding; +Cc: linux-tegra, Sameer Pujar, linux-arm-kernel, Jon Hunter
In-Reply-To: <20181206165022.23845-1-thierry.reding@gmail.com>
From: Thierry Reding <treding@nvidia.com>
Enable the HDA controller on Jetson TX2 so that it can be used for audio
playback over HDMI.
Signed-off-by: Thierry Reding <treding@nvidia.com>
---
arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts b/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts
index bfcc00a65af6..0f3c6cebb049 100644
--- a/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts
+++ b/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts
@@ -53,6 +53,10 @@
vmmc-supply = <&vdd_sd>;
};
+ hda@3510000 {
+ status = "okay";
+ };
+
pcie@10003000 {
status = "okay";
--
2.19.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 4/7] arm64: tegra: Add HDA controller on Tegra194
From: Thierry Reding @ 2018-12-06 16:50 UTC (permalink / raw)
To: Thierry Reding; +Cc: linux-tegra, Sameer Pujar, linux-arm-kernel, Jon Hunter
In-Reply-To: <20181206165022.23845-1-thierry.reding@gmail.com>
From: Thierry Reding <treding@nvidia.com>
The HDA controller found on Tegra194 can be used for audio playback over
HDMI.
Signed-off-by: Thierry Reding <treding@nvidia.com>
---
arch/arm64/boot/dts/nvidia/tegra194.dtsi | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
index 439ffe86a823..59baa631b422 100644
--- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
@@ -328,6 +328,22 @@
status = "disabled";
};
+ hda@3510000 {
+ compatible = "nvidia,tegra194-hda", "nvidia,tegra30-hda";
+ reg = <0x03510000 0x10000>;
+ interrupts = <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&bpmp TEGRA194_CLK_HDA>,
+ <&bpmp TEGRA194_CLK_HDA2HDMICODEC>,
+ <&bpmp TEGRA194_CLK_HDA2CODEC_2X>;
+ clock-names = "hda", "hda2hdmi", "hda2codec_2x";
+ resets = <&bpmp TEGRA194_RESET_HDA>,
+ <&bpmp TEGRA194_RESET_HDA2HDMICODEC>,
+ <&bpmp TEGRA194_RESET_HDA2CODEC_2X>;
+ reset-names = "hda", "hda2hdmi", "hda2codec_2x";
+ power-domains = <&bpmp TEGRA194_POWER_DOMAIN_DISP>;
+ status = "disabled";
+ };
+
gic: interrupt-controller@3881000 {
compatible = "arm,gic-400";
#interrupt-cells = <3>;
--
2.19.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH 7/7] arm64: tegra: Enable HDA controller on Jetson TX1
From: Thierry Reding @ 2018-12-06 16:50 UTC (permalink / raw)
To: Thierry Reding; +Cc: linux-tegra, Sameer Pujar, linux-arm-kernel, Jon Hunter
In-Reply-To: <20181206165022.23845-1-thierry.reding@gmail.com>
From: Thierry Reding <treding@nvidia.com>
The HDA controller can be used for audio playback over HDMI.
Signed-off-by: Thierry Reding <treding@nvidia.com>
---
arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi b/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi
index 365726ddd418..a96e6ee70c21 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi
@@ -1330,6 +1330,10 @@
phys = <&{/padctl@7009f000/pads/sata/lanes/sata-0}>;
};
+ hda@70030000 {
+ status = "okay";
+ };
+
padctl@7009f000 {
status = "okay";
--
2.19.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox