* [PATCH 1/2] arm64: avoid alloc memory on offline node
From: Xie XiuQi @ 2018-06-19 12:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <87bmce60y3.fsf@e105922-lin.cambridge.arm.com>
Hi Punit,
On 2018/6/14 1:39, Punit Agrawal wrote:
> Punit Agrawal <punit.agrawal@arm.com> writes:
>
>
> [...]
>
>>
>> CONFIG_HAVE_MEMORYLESS node is not enabled on arm64 which means we end
>> up returning the original node in the fallback path.
>>
>> Xie, does the below patch help? I can submit a proper patch if this
>> fixes the issue for you.
>>
>> -- >8 --
>> Subject: [PATCH] arm64/numa: Enable memoryless numa nodes
>>
>> Signed-off-by: Punit Agrawal <punit.agrawal@arm.com>
>> ---
>> arch/arm64/Kconfig | 4 ++++
>> arch/arm64/mm/numa.c | 2 ++
>> 2 files changed, 6 insertions(+)
>>
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>> index eb2cf4938f6d..5317e9aa93ab 100644
>> --- a/arch/arm64/Kconfig
>> +++ b/arch/arm64/Kconfig
>> @@ -756,6 +756,10 @@ config USE_PERCPU_NUMA_NODE_ID
>> def_bool y
>> depends on NUMA
>>
>> +config HAVE_MEMORYLESS_NODES
>> + def_bool y
>> + depends on NUMA
>> +
>> config HAVE_SETUP_PER_CPU_AREA
>> def_bool y
>> depends on NUMA
>> diff --git a/arch/arm64/mm/numa.c b/arch/arm64/mm/numa.c
>> index dad128ba98bf..c699dcfe93de 100644
>> --- a/arch/arm64/mm/numa.c
>> +++ b/arch/arm64/mm/numa.c
>> @@ -73,6 +73,8 @@ EXPORT_SYMBOL(cpumask_of_node);
>> static void map_cpu_to_node(unsigned int cpu, int nid)
>> {
>> set_cpu_numa_node(cpu, nid);
>> + set_numa_mem(local_memory_node(nid));
>
> Argh, this should be
>
> set_cpu_numa_mem(cpu, local_memory_node(nid));
>
> There is not guarantee that map_cpu_to_node() will be called on the
> local cpu.
>
> Hanjun, Xie - can you try with the update please?
I've tested this patch, but it does not help.
The boot message is attached.
I tested on a arm board with 128 cores 4 numa nodes, but I set CONFIG_NR_CPUS=72.
Then node 3 is not be created, because node 3 has no memory, and no cpu.
But some pci device may related to node 3, which be set in ACPI table.
165 /* Interface called from ACPI code to setup PCI host controller */
166 struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
167 {
168 int node = acpi_get_node(root->device->handle);
169 struct acpi_pci_generic_root_info *ri;
170 struct pci_bus *bus, *child;
171 struct acpi_pci_root_ops *root_ops;
172
// this node may be not created.
177 ri = kzalloc_node(sizeof(*ri), GFP_KERNEL, node);
178 if (!ri)
179 return NULL;
180
181 root_ops = kzalloc_node(sizeof(*root_ops), GFP_KERNEL, node);
182 if (!root_ops) {
183 kfree(ri);
184 return NULL;
185 }
186
187 ri->cfg = pci_acpi_setup_ecam_mapping(root);
188 if (!ri->cfg) {
189 kfree(ri);
190 kfree(root_ops);
191 return NULL;
192 }
>
> Thanks,
> Punit
>
>> +
>> if (nid >= 0)
>> cpumask_set_cpu(cpu, node_to_cpumask_map[nid]);
>> }
>
> .
>
--
Thanks,
Xie XiuQi
-------------- next part --------------
[ 0.000000] Booting Linux on physical CPU 0x0000030000 [0x480fd010]
[ 0.000000] Linux version 4.16.0-rc1-00491-g204a6cc-dirty (xiexiuqi at localhost.localdomain) (gcc version 6.3.1 20170404 (Linaro GCC 6.3-2017.05)) #17 SMP PREEMPT Tue Jun 19 16:33:32 CST 2018
[ 0.000000] earlycon: pl11 at MMIO32 0x0000000094080000 (options '')
[ 0.000000] bootconsole [pl11] enabled
[ 0.000000] efi: Getting EFI parameters from FDT:
[ 0.000000] efi: EFI v2.60 by EDK II
[ 0.000000] efi: SMBIOS 3.0=0x3eb60000 ACPI 2.0=0x39710000 MEMATTR=0x3b106418
[ 0.000000] ACPI: Early table checksum verification disabled
[ 0.000000] ACPI: RSDP 0x0000000039710000 000024 (v02 HISI )
[ 0.000000] ACPI: XSDT 0x0000000039700000 000074 (v01 HISI HIP08 00000000 01000013)
[ 0.000000] ACPI: FACP 0x0000000039630000 000114 (v06 HISI HIP08 00000000 INTL 20151124)
[ 0.000000] ACPI: DSDT 0x00000000395C0000 006A1A (v02 HISI HIP08 00000000 INTL 20170929)
[ 0.000000] ACPI: GTDT 0x0000000039620000 000060 (v02 HISI HIP08 00000000 INTL 20151124)
[ 0.000000] ACPI: DBG2 0x0000000039610000 00005A (v00 HISI HIP08 00000000 INTL 20151124)
[ 0.000000] ACPI: MCFG 0x0000000039600000 00003C (v01 HISI HIP08 00000000 INTL 20151124)
[ 0.000000] ACPI: SLIT 0x00000000395F0000 00003C (v01 HISI HIP07 00000000 INTL 20151124)
[ 0.000000] ACPI: SRAT 0x00000000395E0000 0009C0 (v03 HISI HIP08 00000000 INTL 20151124)
[ 0.000000] ACPI: APIC 0x00000000395D0000 00286C (v04 HISI HIP08 00000000 INTL 20151124)
[ 0.000000] ACPI: IORT 0x00000000395B0000 00110C (v00 HISI HIP08 00000000 INTL 20170929)
[ 0.000000] ACPI: PPTT 0x00000000311F0000 0037D0 (v01 HISI HIP08 00000000 INTL 20151124)
[ 0.000000] ACPI: SPMI 0x00000000311E0000 000041 (v05 HISI HIP08 00000000 INTL 20151124)
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30000 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30001 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30002 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30003 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30100 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30101 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30102 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30103 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30200 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30201 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30202 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30203 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30300 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30301 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30302 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30303 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30400 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30401 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30402 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30403 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30500 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30501 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30502 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30503 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30600 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30601 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30602 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30603 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30700 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30701 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30702 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30703 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10000 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10001 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10002 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10003 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10100 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10101 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10102 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10103 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10200 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10201 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10202 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10203 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10300 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10301 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10302 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10303 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10400 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10401 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10402 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10403 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10500 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10501 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10502 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10503 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10600 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10601 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10602 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10603 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10700 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10701 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10702 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10703 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 2 -> MPIDR 0x70000 -> Node 2
[ 0.000000] ACPI: NUMA: SRAT: PXM 2 -> MPIDR 0x70001 -> Node 2
[ 0.000000] ACPI: NUMA: SRAT: PXM 2 -> MPIDR 0x70002 -> Node 2
[ 0.000000] ACPI: NUMA: SRAT: PXM 2 -> MPIDR 0x70003 -> Node 2
[ 0.000000] ACPI: NUMA: SRAT: PXM 2 -> MPIDR 0x70100 -> Node 2
[ 0.000000] ACPI: NUMA: SRAT: PXM 2 -> MPIDR 0x70101 -> Node 2
[ 0.000000] ACPI: NUMA: SRAT: PXM 2 -> MPIDR 0x70102 -> Node 2
[ 0.000000] ACPI: NUMA: SRAT: PXM 2 -> MPIDR 0x70103 -> Node 2
[ 0.000000] ACPI: NUMA: SRAT: cpu_to_node_map[72] is too small, may not be able to use all cpus
[ 0.000000] ACPI: SRAT: Node 0 PXM 0 [mem 0x2080000000-0x23ffffffff]
[ 0.000000] ACPI: SRAT: Node 0 PXM 0 [mem 0x00000000-0x7fffffff]
[ 0.000000] ACPI: SRAT: Node 2 PXM 2 [mem 0x402000000000-0x4023ffffffff]
[ 0.000000] NUMA: NODE_DATA [mem 0x23ffffe780-0x23ffffffff]
[ 0.000000] NUMA: Initmem setup node 1 [<memory-less node>]
[ 0.000000] NUMA: NODE_DATA [mem 0x4023fffed780-0x4023fffeefff]
[ 0.000000] NUMA: NODE_DATA(1) on node 2
[ 0.000000] NUMA: NODE_DATA [mem 0x4023fffebf00-0x4023fffed77f]
[ 0.000000] Zone ranges:
[ 0.000000] DMA32 [mem 0x0000000000000000-0x00000000ffffffff]
[ 0.000000] Normal [mem 0x0000000100000000-0x00004023ffffffff]
[ 0.000000] Movable zone start for each node
[ 0.000000] Early memory node ranges
[ 0.000000] node 0: [mem 0x0000000000000000-0x000000003942ffff]
[ 0.000000] node 0: [mem 0x0000000039430000-0x000000003956ffff]
[ 0.000000] node 0: [mem 0x0000000039570000-0x000000003963ffff]
[ 0.000000] node 0: [mem 0x0000000039640000-0x00000000396fffff]
[ 0.000000] node 0: [mem 0x0000000039700000-0x000000003971ffff]
[ 0.000000] node 0: [mem 0x0000000039720000-0x0000000039b6ffff]
[ 0.000000] node 0: [mem 0x0000000039b70000-0x000000003eb5ffff]
[ 0.000000] node 0: [mem 0x000000003eb60000-0x000000003eb8ffff]
[ 0.000000] node 0: [mem 0x000000003eb90000-0x000000003fbfffff]
[ 0.000000] node 0: [mem 0x0000002080000000-0x00000023ffffffff]
[ 0.000000] node 2: [mem 0x0000402000000000-0x00004023ffffffff]
[ 0.000000] Initmem setup node 0 [mem 0x0000000000000000-0x00000023ffffffff]
[ 0.000000] Could not find start_pfn for node 1
[ 0.000000] Initmem setup node 1 [mem 0x0000000000000000-0x0000000000000000]
[ 0.000000] Initmem setup node 2 [mem 0x0000402000000000-0x00004023ffffffff]
[ 0.000000] psci: probing for conduit method from ACPI.
[ 0.000000] psci: PSCIv1.0 detected in firmware.
[ 0.000000] psci: Using standard PSCI v0.2 function IDs
[ 0.000000] psci: MIGRATE_INFO_TYPE not supported.
[ 0.000000] psci: SMC Calling Convention v1.0
[ 0.000000] random: fast init done
[ 0.000000] percpu: Embedded 24 pages/cpu @ (ptrval) s59432 r8192 d30680 u98304
[ 0.000000] Detected VIPT I-cache on CPU0
[ 0.000000] Built 3 zonelists, mobility grouping on. Total pages: 7998480
[ 0.000000] Policy zone: Normal
[ 0.000000] Kernel command line: earlycon=pl011,mmio32,0x94080000 console=ttyAMA0,115200 initrd=minifs.cpio.gz acpi=force
[ 0.000000] log_buf_len individual max cpu contribution: 4096 bytes
[ 0.000000] log_buf_len total cpu_extra contributions: 290816 bytes
...
[ 0.141182] Platform MSI: ITS at 0x400202100000 domain created
[ 0.146793] PCI/MSI: ITS at 0x202100000 domain created
[ 0.151690] PCI/MSI: ITS at 0x400202100000 domain created
[ 0.156906] Remapping and enabling EFI services.
[ 0.161562] EFI remap 0x0000000039430000 => (ptrval)
[ 0.167431] EFI remap 0x0000000039480000 => (ptrval)
[ 0.173299] EFI remap 0x00000000394d0000 => (ptrval)
[ 0.179167] EFI remap 0x0000000039520000 => (ptrval)
[ 0.185037] EFI remap 0x0000000039650000 => (ptrval)
[ 0.190905] EFI remap 0x00000000396b0000 => (ptrval)
[ 0.196773] EFI remap 0x0000000039720000 => (ptrval)
[ 0.202639] EFI remap 0x0000000039770000 => (ptrval)
[ 0.208505] EFI remap 0x00000000397c0000 => (ptrval)
[ 0.214371] EFI remap 0x0000000039810000 => (ptrval)
[ 0.220236] EFI remap 0x0000000039860000 => (ptrval)
[ 0.226103] EFI remap 0x00000000398b0000 => (ptrval)
[ 0.231973] EFI remap 0x0000000039900000 => (ptrval)
[ 0.237840] EFI remap 0x0000000039970000 => (ptrval)
[ 0.243710] EFI remap 0x00000000399c0000 => (ptrval)
[ 0.249577] EFI remap 0x0000000039a10000 => (ptrval)
[ 0.255445] EFI remap 0x0000000039a60000 => (ptrval)
[ 0.261313] EFI remap 0x0000000039ab0000 => (ptrval)
[ 0.267184] EFI remap 0x0000000039b00000 => (ptrval)
[ 0.273047] EFI remap 0x000000003eb60000 => (ptrval)
[ 0.278907] EFI remap 0x0000000080000000 => (ptrval)
[ 0.284766] EFI remap 0x0000000202020000 => (ptrval)
[ 0.290626] EFI remap 0x0000000204000000 => (ptrval)
[ 0.296487] EFI remap 0x0000000206200000 => (ptrval)
[ 0.318359] smp: Bringing up secondary CPUs ...
[ 0.422473] Detected VIPT I-cache on CPU1
[ 0.422481] GICv3: CPU1: found redistributor 30001 region 1:0x00000000aa140000
[ 0.422502] CPU1: using LPI pending table @0x00000023ee480000
[ 0.422543] CPU1: Booted secondary processor 0x0000030001 [0x480fd010]
[ 0.522109] Detected VIPT I-cache on CPU2
[ 0.522115] GICv3: CPU2: found redistributor 30002 region 2:0x00000000aa180000
[ 0.522135] CPU2: using LPI pending table @0x00000023ee4b0000
[ 0.522175] CPU2: Booted secondary processor 0x0000030002 [0x480fd010]
[ 0.621751] Detected VIPT I-cache on CPU3
...
[ 7.328992] CPU70: Booted secondary processor 0x0000070102 [0x480fd010]
[ 7.435880] Detected VIPT I-cache on CPU71
[ 7.435931] GICv3: CPU71: found redistributor 70103 region 71:0x00004000aa2c0000
[ 7.435958] CPU71: using LPI pending table @0x00000023ed340000
[ 7.436037] CPU71: Booted secondary processor 0x0000070103 [0x480fd010]
[ 7.436131] smp: Brought up 3 nodes, 72 CPUs
[ 9.146250] SMP: Total of 72 processors activated.
[ 9.151067] CPU features: detected feature: GIC system register CPU interface
[ 9.158247] CPU features: detected feature: Privileged Access Never
...
[ 11.535050] pci 0000:74:02.0: BAR 5: assigned [mem 0xa2000000-0xa2007fff]
[ 11.541829] pci 0000:74:03.0: BAR 5: assigned [mem 0xa2008000-0xa2008fff]
[ 11.548610] pci 0000:75:00.0: BAR 2: assigned [mem 0x144000000-0x1443fffff 64bit pref]
[ 11.556518] pci 0000:75:00.0: BAR 9: assigned [mem 0x144400000-0x1447effff 64bit pref]
[ 11.564426] pci 0000:74:00.0: PCI bridge to [bus 75]
[ 11.569382] pci 0000:74:00.0: bridge window [mem 0x144000000-0x1447fffff 64bit pref]
[ 11.577332] ACPI: PCI Root Bridge [PCI6] (domain 0000 [bus 80-9f])
[ 11.583505] acpi PNP0A08:06: _OSC: OS supports [ExtendedConfig ASPM ClockPM Segments MSI]
[ 11.591850] acpi PNP0A08:06: _OSC: OS now controls [PCIeHotplug PME AER PCIeCapability]
[ 11.599851] CPU002: pci_acpi_scan_root: 175 node 3, online 0
[ 11.605503] Unable to handle kernel paging request at virtual address 00001530
[ 11.612712] Mem abort info:
[ 11.615492] ESR = 0x96000004
[ 11.618534] Exception class = DABT (current EL), IL = 32 bits
[ 11.624440] SET = 0, FnV = 0
[ 11.627481] EA = 0, S1PTW = 0
[ 11.630608] Data abort info:
[ 11.633476] ISV = 0, ISS = 0x00000004
[ 11.637299] CM = 0, WnR = 0
[ 11.640254] [0000000000001530] user address but active_mm is swapper
[ 11.646594] Internal error: Oops: 96000004 [#1] PREEMPT SMP
[ 11.652154] Modules linked in:
[ 11.655198] CPU: 2 PID: 1 Comm: swapper/0 Not tainted 4.16.0-rc1-00491-g204a6cc-dirty #17
[ 11.663361] Hardware name: Huawei, 06/02/2018
[ 11.673174] pstate: 20c00089 (nzCv daIf +PAN +UAO)
[ 11.677955] pc : ___slab_alloc+0x60/0x590
[ 11.681952] lr : __slab_alloc.isra.24+0x58/0x70
[ 11.686469] sp : ffff00000981b870
[ 11.689771] x29: ffff00000981b870 x28: ffffc023eb8d8000
[ 11.695071] x27: ffff7e008fafd600 x26: ffff8023f0407c00
[ 11.700372] x25: ffff8023f0407c00 x24: ffff000008098da0
[ 11.705671] x23: 0000000000000003 x22: 00000000014080c0
[ 11.710971] x21: 0000000000000000 x20: 0000000000000003
[ 11.716271] x19: ffff8023f0b40870 x18: ffffffffffffffff
[ 11.721571] x17: 0000000000000000 x16: 000000000001c200
[ 11.726871] x15: ffff000009423b88 x14: ffff00008958c94f
[ 11.732171] x13: ffff00000958c95d x12: ffff00000943e858
[ 11.737471] x11: ffff00000943e000 x10: 0000000005f5e0ff
[ 11.742771] x9 : 00000000ffffffd0 x8 : 65646f6e20353731
[ 11.748071] x7 : 203a746f6f725f6e x6 : 00000000000002e8
[ 11.753371] x5 : 000000000000000a x4 : ffff8023f0b40870
[ 11.758670] x3 : ffff000008098da0 x2 : 0000000000000003
[ 11.763970] x1 : 0000000000000000 x0 : 0000000000000000
[ 11.769271] Process swapper/0 (pid: 1, stack limit = 0x00000000b21a776c)
[ 11.775958] Call trace:
[ 11.778392] ___slab_alloc+0x60/0x590
[ 11.782041] __slab_alloc.isra.24+0x58/0x70
[ 11.786212] kmem_cache_alloc_node+0xe0/0x240
[ 11.790556] pci_acpi_scan_root+0xb0/0x270
[ 11.794642] acpi_pci_root_add+0x29c/0x498
[ 11.798726] acpi_bus_attach+0x104/0x210
[ 11.802635] acpi_bus_attach+0xa4/0x210
[ 11.806458] acpi_bus_attach+0xa4/0x210
[ 11.810282] acpi_bus_scan+0x4c/0xb0
[ 11.813846] acpi_scan_init+0xec/0x24c
[ 11.817582] acpi_init+0x300/0x36c
[ 11.820972] do_one_initcall+0x50/0x158
[ 11.824797] kernel_init_freeable+0x188/0x228
[ 11.829141] kernel_init+0x10/0x100
[ 11.832617] ret_from_fork+0x10/0x18
[ 11.836181] Code: 90009081 93407e82 912ec021 f8627821 (f94a9821)
[ 11.842316] ---[ end trace 6b7476446f4b95ab ]---
[ 11.846936] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
[ 11.846936]
[ 11.856079] SMP: stopping secondary CPUs
[ 11.860027] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
[ 11.860027]
^ permalink raw reply
* [PATCH 1/2] arm64: avoid alloc memory on offline node
From: Michal Hocko @ 2018-06-19 12:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <8b715082-14d4-f10b-d2d6-b23be7e4bf7e@huawei.com>
On Tue 19-06-18 20:03:07, Xie XiuQi wrote:
[...]
> I tested on a arm board with 128 cores 4 numa nodes, but I set CONFIG_NR_CPUS=72.
> Then node 3 is not be created, because node 3 has no memory, and no cpu.
> But some pci device may related to node 3, which be set in ACPI table.
Could you double check that zonelists for node 3 are generated
correctly?
--
Michal Hocko
SUSE Labs
^ permalink raw reply
* [PATCHv3 10/19] arm64: convert native/compat syscall entry to C
From: Dave Martin @ 2018-06-19 12:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180618120310.39527-11-mark.rutland@arm.com>
On Mon, Jun 18, 2018 at 01:03:01PM +0100, Mark Rutland wrote:
> Now that the syscall invocation logic is in C, we can migrate the rest
> of the syscall entry logic over, so that the entry assembly needn't look
> at the register values at all.
>
> The SVE reset across syscall logic now unconditionally clears TIF_SVE,
> but sve_user_disable() will only write back to CPACR_EL1 when SVE is
> actually enabled.
>
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> ---
> arch/arm64/kernel/entry.S | 42 ++++--------------------------------------
> arch/arm64/kernel/syscall.c | 40 ++++++++++++++++++++++++++++++++++++++--
> 2 files changed, 42 insertions(+), 40 deletions(-)
>
> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
> index 05b9f03f3e00..156c4e3fd1a4 100644
> --- a/arch/arm64/kernel/entry.S
> +++ b/arch/arm64/kernel/entry.S
> @@ -720,14 +720,9 @@ el0_sync_compat:
> b.ge el0_dbg
> b el0_inv
> el0_svc_compat:
> - /*
> - * AArch32 syscall handling
> - */
> - ldr x16, [tsk, #TSK_TI_FLAGS] // load thread flags
> - adrp stbl, compat_sys_call_table // load compat syscall table pointer
> - mov wscno, w7 // syscall number in w7 (r7)
> - mov wsc_nr, #__NR_compat_syscalls
> - b el0_svc_naked
> + mov x0, sp
> + bl el0_svc_compat_handler
> + b ret_to_user
>
> .align 6
> el0_irq_compat:
> @@ -925,37 +920,8 @@ ENDPROC(ret_to_user)
> */
> .align 6
> el0_svc:
> - ldr x16, [tsk, #TSK_TI_FLAGS] // load thread flags
> - adrp stbl, sys_call_table // load syscall table pointer
> - mov wscno, w8 // syscall number in w8
> - mov wsc_nr, #__NR_syscalls
> -
> -#ifdef CONFIG_ARM64_SVE
> -alternative_if_not ARM64_SVE
> - b el0_svc_naked
> -alternative_else_nop_endif
> - tbz x16, #TIF_SVE, el0_svc_naked // Skip unless TIF_SVE set:
> - bic x16, x16, #_TIF_SVE // discard SVE state
> - str x16, [tsk, #TSK_TI_FLAGS]
> -
> - /*
> - * task_fpsimd_load() won't be called to update CPACR_EL1 in
> - * ret_to_user unless TIF_FOREIGN_FPSTATE is still set, which only
> - * happens if a context switch or kernel_neon_begin() or context
> - * modification (sigreturn, ptrace) intervenes.
> - * So, ensure that CPACR_EL1 is already correct for the fast-path case:
> - */
> - mrs x9, cpacr_el1
> - bic x9, x9, #CPACR_EL1_ZEN_EL0EN // disable SVE for el0
> - msr cpacr_el1, x9 // synchronised by eret to el0
> -#endif
> -
> -el0_svc_naked: // compat entry point
> mov x0, sp
> - mov w1, wscno
> - mov w2, wsc_nr
> - mov x3, stbl
> - bl el0_svc_common
> + bl el0_svc_handler
> b ret_to_user
> ENDPROC(el0_svc)
>
> diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
> index 2adf1a073398..6a31bb2a382b 100644
> --- a/arch/arm64/kernel/syscall.c
> +++ b/arch/arm64/kernel/syscall.c
> @@ -6,7 +6,9 @@
> #include <linux/ptrace.h>
>
> #include <asm/daifflags.h>
> +#include <asm/fpsimd.h>
> #include <asm/thread_info.h>
> +#include <asm/unistd.h>
>
> long do_ni_syscall(struct pt_regs *regs);
>
> @@ -42,8 +44,8 @@ static inline bool has_syscall_work(unsigned long flags)
> int syscall_trace_enter(struct pt_regs *regs);
> void syscall_trace_exit(struct pt_regs *regs);
>
> -asmlinkage void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
> - syscall_fn_t syscall_table[])
> +static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
> + syscall_fn_t syscall_table[])
> {
> unsigned long flags = current_thread_info()->flags;
>
> @@ -80,3 +82,37 @@ asmlinkage void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
> trace_exit:
> syscall_trace_exit(regs);
> }
> +
> +static inline void sve_user_reset(void)
> +{
Can we call this "sve_user_discard" please?
"Reset" is a reasonable name for the concept, but the "discard"
terminology has been used elsewhere.
> + if (!system_supports_sve())
> + return;
> +
> + /*
> + * task_fpsimd_load() won't be called to update CPACR_EL1 in
> + * ret_to_user unless TIF_FOREIGN_FPSTATE is still set, which only
> + * happens if a context switch or kernel_neon_begin() or context
> + * modification (sigreturn, ptrace) intervenes.
> + * So, ensure that CPACR_EL1 is already correct for the fast-path case.
> + */
This comment should go after clear_thead_flag(), since it describes not
the purpose of this function but the presence of sve_user_disable().
> + clear_thread_flag(TIF_SVE);
> + sve_user_disable();
> +}
> +
> +extern syscall_fn_t sys_call_table[];
> +
> +asmlinkage void el0_svc_handler(struct pt_regs *regs)
> +{
> + sve_user_reset();
> + el0_svc_common(regs, regs->regs[8], __NR_syscalls, sys_call_table);
> +}
> +
> +#ifdef CONFIG_COMPAT
> +extern syscall_fn_t compat_sys_call_table[];
> +
> +asmlinkage void el0_svc_compat_handler(struct pt_regs *regs)
> +{
> + el0_svc_common(regs, regs->regs[7], __NR_compat_syscalls,
> + compat_sys_call_table);
> +}
> +#endif
> --
> 2.11.0
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCHv3 06/19] arm64: move sve_user_{enable, disable} to <asm/fpsimd.h>
From: Dave Martin @ 2018-06-19 12:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180618120310.39527-7-mark.rutland@arm.com>
On Mon, Jun 18, 2018 at 01:02:57PM +0100, Mark Rutland wrote:
> In subsequent patches, we'll want to make use of sve_user_enable() and
> sve_user_disable() outside of kernel/fpsimd.c. Let's move these to
> <asm/fpsimd.h> where we can make use of them.
>
> To avoid ifdeffery in sequences like:
>
> if (system_supports_sve() && some_condition
> sve_user_disable();
>
> ... empty stubs are provided when support for SVE is not enabled. Note
> that system_supports_sve() contains as IS_ENABLED(CONFIG_ARM64_SVE), so
> the sve_user_disable() call should be optimized away entirely when
> CONFIG_ARM64_SVE is not selected.
>
> To ensure that this is the case, the stub definitions contain a
> BUILD_BUG(), as we do for other stubs for which calls should always be
> optimized away when the relevant config option is not selected.
>
> At the same time, the include list of <asm/fpsimd.h> is sorted while
> adding <asm/sysreg.h>.
>
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Dave Martin <dave.martin@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
Reviewed-by: Dave Martin <Dave.Martin@arm.com>
> ---
> arch/arm64/include/asm/fpsimd.h | 17 ++++++++++++++++-
> arch/arm64/kernel/fpsimd.c | 10 ----------
> 2 files changed, 16 insertions(+), 11 deletions(-)
>
> diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
> index fa92747a49c8..dd1ad3950ef5 100644
> --- a/arch/arm64/include/asm/fpsimd.h
> +++ b/arch/arm64/include/asm/fpsimd.h
> @@ -16,13 +16,15 @@
> #ifndef __ASM_FP_H
> #define __ASM_FP_H
>
> -#include <asm/ptrace.h>
> #include <asm/errno.h>
> +#include <asm/ptrace.h>
> #include <asm/processor.h>
> #include <asm/sigcontext.h>
> +#include <asm/sysreg.h>
>
> #ifndef __ASSEMBLY__
>
> +#include <linux/build_bug.h>
> #include <linux/cache.h>
> #include <linux/init.h>
> #include <linux/stddef.h>
> @@ -102,6 +104,16 @@ extern int sve_set_vector_length(struct task_struct *task,
> extern int sve_set_current_vl(unsigned long arg);
> extern int sve_get_current_vl(void);
>
> +static inline void sve_user_disable(void)
> +{
> + sysreg_clear_set(cpacr_el1, CPACR_EL1_ZEN_EL0EN, 0);
> +}
> +
> +static inline void sve_user_enable(void)
> +{
> + sysreg_clear_set(cpacr_el1, 0, CPACR_EL1_ZEN_EL0EN);
> +}
> +
> /*
> * Probing and setup functions.
> * Calls to these functions must be serialised with one another.
> @@ -128,6 +140,9 @@ static inline int sve_get_current_vl(void)
> return -EINVAL;
> }
>
> +static inline void sve_user_disable(void) { BUILD_BUG(); }
> +static inline void sve_user_enable(void) { BUILD_BUG(); }
> +
> static inline void sve_init_vq_map(void) { }
> static inline void sve_update_vq_map(void) { }
> static inline int sve_verify_vq_map(void) { return 0; }
> diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
> index a98a7f96aff1..58c53bc96928 100644
> --- a/arch/arm64/kernel/fpsimd.c
> +++ b/arch/arm64/kernel/fpsimd.c
> @@ -159,16 +159,6 @@ static void sve_free(struct task_struct *task)
> __sve_free(task);
> }
>
> -static void sve_user_disable(void)
> -{
> - sysreg_clear_set(cpacr_el1, CPACR_EL1_ZEN_EL0EN, 0);
> -}
> -
> -static void sve_user_enable(void)
> -{
> - sysreg_clear_set(cpacr_el1, 0, CPACR_EL1_ZEN_EL0EN);
> -}
> -
> /*
> * TIF_SVE controls whether a task can use SVE without trapping while
> * in userspace, and also the way a task's FPSIMD/SVE state is stored
> --
> 2.11.0
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH] arm: Hook up SYNC_CORE functionality for sys_membarrier()
From: Will Deacon @ 2018-06-19 12:22 UTC (permalink / raw)
To: linux-arm-kernel
Exception return implies context synchronization, so we can hook up the
SYNC_CORE option to sys_membarrier() simply by selecting the Kconfig option,
just like we've done for arm64 already.
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Orion Hodson <oth@google.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
arch/arm/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 54eeb8d00bc6..b0ac18547370 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -9,6 +9,7 @@ config ARM
select ARCH_HAS_ELF_RANDOMIZE
select ARCH_HAS_FORTIFY_SOURCE
select ARCH_HAS_KCOV
+ select ARCH_HAS_MEMBARRIER_SYNC_CORE
select ARCH_HAS_PTE_SPECIAL if ARM_LPAE
select ARCH_HAS_PHYS_TO_DMA
select ARCH_HAS_SET_MEMORY
--
2.1.4
^ permalink raw reply related
* [PATCH 0/2] clk: Fix switching CPU rate from 300Mhz to 1.2GHz on Armada 3700
From: Gregory CLEMENT @ 2018-06-19 12:34 UTC (permalink / raw)
To: linux-arm-kernel
Hello,
in this series the first patch is the main patch which fixes the case
when switching CPU rate from 300Mhz (or 200M MHz) to 1.2GH. See the
commit log for the details. As this one is a fix, it should be applied
on v4.18-rc.
While I was on this file, I also switch to SPDX license identifier,
this one is fine for 4.19*;
Thanks,
Gregory
Gregory CLEMENT (2):
clk: mvebu: armada-37xx-periph: Fix switching CPU rate from 300Mhz to
1.2GHz
clk: mvebu: armada-37xx-periph: switch to SPDX license identifier
drivers/clk/mvebu/armada-37xx-periph.c | 43 +++++++++++++++++++++++---
1 file changed, 39 insertions(+), 4 deletions(-)
--
2.17.1
^ permalink raw reply
* [PATCH 1/2] clk: mvebu: armada-37xx-periph: Fix switching CPU rate from 300Mhz to 1.2GHz
From: Gregory CLEMENT @ 2018-06-19 12:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180619123446.694-1-gregory.clement@bootlin.com>
Switching the CPU from the L2 or L3 frequencies (300 and 200 Mhz
respectively) to L0 frequency (1.2 Ghz) requires a significant amount
of time to let VDD stabilize to the appropriate voltage. This amount of
time is large enough that it cannot be covered by the hardware
countdown register. Due to this, the CPU might start operating at L0
before the voltage is stabilized, leading to CPU stalls.
To work around this problem, we prevent switching directly from the
L2/L3 frequencies to the L0 frequency, and instead switch to the L1
frequency in-between. The sequence therefore becomes:
1. First switch from L2/L3(200/300MHz) to L1(600MHZ)
2. Sleep 20ms for stabling VDD voltage
3. Then switch from L1(600MHZ) to L0(1200Mhz).
It is based on the work done by Ken Ma <make@marvell.com>
Cc: stable at vger.kernel.org
Fixes: 2089dc33ea0e ("clk: mvebu: armada-37xx-periph: add DVFS support for cpu clocks")
Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
---
drivers/clk/mvebu/armada-37xx-periph.c | 38 ++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/drivers/clk/mvebu/armada-37xx-periph.c b/drivers/clk/mvebu/armada-37xx-periph.c
index 6860bd5a37c5..44e4e27eddad 100644
--- a/drivers/clk/mvebu/armada-37xx-periph.c
+++ b/drivers/clk/mvebu/armada-37xx-periph.c
@@ -35,6 +35,7 @@
#define CLK_SEL 0x10
#define CLK_DIS 0x14
+#define ARMADA_37XX_DVFS_LOAD_1 1
#define LOAD_LEVEL_NR 4
#define ARMADA_37XX_NB_L0L1 0x18
@@ -507,6 +508,40 @@ static long clk_pm_cpu_round_rate(struct clk_hw *hw, unsigned long rate,
return -EINVAL;
}
+/*
+ * Switching the CPU from the L2 or L3 frequencies (300 and 200 Mhz
+ * respectively) to L0 frequency (1.2 Ghz) requires a significant
+ * amount of time to let VDD stabilize to the appropriate
+ * voltage. This amount of time is large enough that it cannot be
+ * covered by the hardware countdown register. Due to this, the CPU
+ * might start operating at L0 before the voltage is stabilized,
+ * leading to CPU stalls.
+ *
+ * To work around this problem, we prevent switching directly from the
+ * L2/L3 frequencies to the L0 frequency, and instead switch to the L1
+ * frequency in-between. The sequence therefore becomes:
+ * 1. First switch from L2/L3(200/300MHz) to L1(600MHZ)
+ * 2. Sleep 20ms for stabling VDD voltage
+ * 3. Then switch from L1(600MHZ) to L0(1200Mhz).
+ */
+static void clk_pm_cpu_set_rate_wa(unsigned long rate, struct regmap *base)
+{
+ unsigned int cur_level;
+
+ if (rate != 1200 * 1000 * 1000)
+ return;
+
+ regmap_read(base, ARMADA_37XX_NB_CPU_LOAD, &cur_level);
+ cur_level &= ARMADA_37XX_NB_CPU_LOAD_MASK;
+ if (cur_level <= ARMADA_37XX_DVFS_LOAD_1)
+ return;
+
+ regmap_update_bits(base, ARMADA_37XX_NB_CPU_LOAD,
+ ARMADA_37XX_NB_CPU_LOAD_MASK,
+ ARMADA_37XX_DVFS_LOAD_1);
+ msleep(20);
+}
+
static int clk_pm_cpu_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
@@ -537,6 +572,9 @@ static int clk_pm_cpu_set_rate(struct clk_hw *hw, unsigned long rate,
*/
reg = ARMADA_37XX_NB_CPU_LOAD;
mask = ARMADA_37XX_NB_CPU_LOAD_MASK;
+
+ clk_pm_cpu_set_rate_wa(rate, base);
+
regmap_update_bits(base, reg, mask, load_level);
return rate;
--
2.17.1
^ permalink raw reply related
* [PATCH 2/2] clk: mvebu: armada-37xx-periph: switch to SPDX license identifier
From: Gregory CLEMENT @ 2018-06-19 12:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180619123446.694-1-gregory.clement@bootlin.com>
Adopt the SPDX license identifier headers to ease license compliance
management.
Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
---
drivers/clk/mvebu/armada-37xx-periph.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/drivers/clk/mvebu/armada-37xx-periph.c b/drivers/clk/mvebu/armada-37xx-periph.c
index 44e4e27eddad..a51edaab0c5c 100644
--- a/drivers/clk/mvebu/armada-37xx-periph.c
+++ b/drivers/clk/mvebu/armada-37xx-periph.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* Marvell Armada 37xx SoC Peripheral clocks
*
@@ -5,10 +6,6 @@
*
* Gregory CLEMENT <gregory.clement@free-electrons.com>
*
- * This file is licensed under the terms of the GNU General Public
- * License version 2 or later. This program is licensed "as is"
- * without any warranty of any kind, whether express or implied.
- *
* Most of the peripheral clocks can be modelled like this:
* _____ _______ _______
* TBG-A-P --| | | | | | ______
--
2.17.1
^ permalink raw reply related
* [PATCH 1/2] arm64: avoid alloc memory on offline node
From: Xie XiuQi @ 2018-06-19 12:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180619120714.GE13685@dhcp22.suse.cz>
Hi Michal,
On 2018/6/19 20:07, Michal Hocko wrote:
> On Tue 19-06-18 20:03:07, Xie XiuQi wrote:
> [...]
>> I tested on a arm board with 128 cores 4 numa nodes, but I set CONFIG_NR_CPUS=72.
>> Then node 3 is not be created, because node 3 has no memory, and no cpu.
>> But some pci device may related to node 3, which be set in ACPI table.
>
> Could you double check that zonelists for node 3 are generated
> correctly?
>
zonelists for node 3 is not created at all.
Kernel parse SRAT table to create node info, but in this case,
SRAT table is parsed not completed. Only the first 72 items are parsed.
In SRAT table, we haven't seen node 3 information yet, because cpu_to_node_map[72] is too small.
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30000 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30001 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30002 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30003 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30100 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30101 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30102 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30103 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30200 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30201 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30202 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30203 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30300 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30301 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30302 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30303 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30400 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30401 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30402 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30403 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30500 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30501 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30502 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30503 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30600 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30601 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30602 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30603 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30700 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30701 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30702 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 0 -> MPIDR 0x30703 -> Node 0
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10000 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10001 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10002 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10003 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10100 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10101 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10102 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10103 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10200 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10201 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10202 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10203 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10300 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10301 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10302 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10303 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10400 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10401 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10402 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10403 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10500 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10501 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10502 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10503 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10600 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10601 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10602 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10603 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10700 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10701 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10702 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 1 -> MPIDR 0x10703 -> Node 1
[ 0.000000] ACPI: NUMA: SRAT: PXM 2 -> MPIDR 0x70000 -> Node 2
[ 0.000000] ACPI: NUMA: SRAT: PXM 2 -> MPIDR 0x70001 -> Node 2
[ 0.000000] ACPI: NUMA: SRAT: PXM 2 -> MPIDR 0x70002 -> Node 2
[ 0.000000] ACPI: NUMA: SRAT: PXM 2 -> MPIDR 0x70003 -> Node 2
[ 0.000000] ACPI: NUMA: SRAT: PXM 2 -> MPIDR 0x70100 -> Node 2
[ 0.000000] ACPI: NUMA: SRAT: PXM 2 -> MPIDR 0x70101 -> Node 2
[ 0.000000] ACPI: NUMA: SRAT: PXM 2 -> MPIDR 0x70102 -> Node 2
[ 0.000000] ACPI: NUMA: SRAT: PXM 2 -> MPIDR 0x70103 -> Node 2
[ 0.000000] ACPI: NUMA: SRAT: cpu_to_node_map[72] is too small, may not be able to use all cpus
[ 0.000000] ACPI: SRAT: Node 0 PXM 0 [mem 0x2080000000-0x23ffffffff]
[ 0.000000] ACPI: SRAT: Node 0 PXM 0 [mem 0x00000000-0x7fffffff]
[ 0.000000] ACPI: SRAT: Node 2 PXM 2 [mem 0x402000000000-0x4023ffffffff]
[ 0.000000] NUMA: NODE_DATA [mem 0x23ffffe780-0x23ffffffff]
[ 0.000000] NUMA: Initmem setup node 1 [<memory-less node>]
[ 0.000000] NUMA: NODE_DATA [mem 0x4023fffed780-0x4023fffeefff]
[ 0.000000] NUMA: NODE_DATA(1) on node 2
[ 0.000000] NUMA: NODE_DATA [mem 0x4023fffebf00-0x4023fffed77f]
[ 0.000000] Zone ranges:
[ 0.000000] DMA32 [mem 0x0000000000000000-0x00000000ffffffff]
[ 0.000000] Normal [mem 0x0000000100000000-0x00004023ffffffff]
[ 0.000000] Movable zone start for each node
[ 0.000000] Early memory node ranges
[ 0.000000] node 0: [mem 0x0000000000000000-0x000000003942ffff]
[ 0.000000] node 0: [mem 0x0000000039430000-0x000000003956ffff]
[ 0.000000] node 0: [mem 0x0000000039570000-0x000000003963ffff]
[ 0.000000] node 0: [mem 0x0000000039640000-0x00000000396fffff]
[ 0.000000] node 0: [mem 0x0000000039700000-0x000000003971ffff]
[ 0.000000] node 0: [mem 0x0000000039720000-0x0000000039b6ffff]
[ 0.000000] node 0: [mem 0x0000000039b70000-0x000000003eb5ffff]
[ 0.000000] node 0: [mem 0x000000003eb60000-0x000000003eb8ffff]
[ 0.000000] node 0: [mem 0x000000003eb90000-0x000000003fbfffff]
[ 0.000000] node 0: [mem 0x0000002080000000-0x00000023ffffffff]
[ 0.000000] node 2: [mem 0x0000402000000000-0x00004023ffffffff]
[ 0.000000] Initmem setup node 0 [mem 0x0000000000000000-0x00000023ffffffff]
[ 0.000000] Could not find start_pfn for node 1
[ 0.000000] Initmem setup node 1 [mem 0x0000000000000000-0x0000000000000000]
[ 0.000000] Initmem setup node 2 [mem 0x0000402000000000-0x00004023ffffffff]
--
Thanks,
Xie XiuQi
^ permalink raw reply
* [PATCH 1/8] dt-bindings: tegra186-hsp: Add shared interrupts
From: Mikko Perttunen @ 2018-06-19 12:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <2bed23e6-19d5-66f8-774e-d613a91b1607@nvidia.com>
On 22.05.2018 18:15, Jon Hunter wrote:
>
> 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.
Thanks, I changed the text slightly to account for this.
>
>> 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?
Currently the driver always uses shared0 for mailbox-full interrupt, and
nothing else, which is what downstream does as well. It's difficult to
do anything else as we can trample on some other driver's configuration..
>
> Cheers
> Jon
>
Thanks,
Mikko
^ permalink raw reply
* [PATCH 0/3] cpufreq: add AVS support for Armada 3700
From: Gregory CLEMENT @ 2018-06-19 12:43 UTC (permalink / raw)
To: linux-arm-kernel
Hello,
Armada 37xx supports also Adaptive Voltage Scaling and this series
allow to us it.
In order to configure it, the drives needs to access a new set of
register which is documented in patch 1 and added in the dts in patch
3.
the first 2 patches should be merged through the cpufreq subsystem,
and I will take care of the 3rd patch once the binding will have been
validated.
Thanks,
Gregory CLEMENT (3):
dt-bindings: marvell: Add documentation for the Armada 3700 AVS
binding
cpufreq: armada-37xx: Add AVS support
arm64: dts: marvell: armada-37xx: add the node allowing AVS support
.../bindings/arm/marvell/armada-37xx.txt | 16 ++
arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 6 +
drivers/cpufreq/armada-37xx-cpufreq.c | 163 +++++++++++++++++-
3 files changed, 182 insertions(+), 3 deletions(-)
--
2.17.1
^ permalink raw reply
* [PATCH 1/3] dt-bindings: marvell: Add documentation for the Armada 3700 AVS binding
From: Gregory CLEMENT @ 2018-06-19 12:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180619124402.902-1-gregory.clement@bootlin.com>
Extend the documentation of the Armada 37xx SoC with the Adaptive Voltage
Scaling (AVS) registers.
Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
---
.../bindings/arm/marvell/armada-37xx.txt | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/Documentation/devicetree/bindings/arm/marvell/armada-37xx.txt b/Documentation/devicetree/bindings/arm/marvell/armada-37xx.txt
index 35c3c3460d17..22438f659d1e 100644
--- a/Documentation/devicetree/bindings/arm/marvell/armada-37xx.txt
+++ b/Documentation/devicetree/bindings/arm/marvell/armada-37xx.txt
@@ -33,3 +33,19 @@ nb_pm: syscon at 14000 {
compatible = "marvell,armada-3700-nb-pm", "syscon";
reg = <0x14000 0x60>;
}
+
+AVS
+---
+
+For AVS an other component is needed:
+
+Required properties:
+- compatible : should contain "marvell,armada-3700-avs", "syscon";
+- reg : the register start and length for the AVS
+
+Example:
+avs: avs at 11500 {
+ compatible = "marvell,armada-3700-avs", "syscon";
+ reg = <0x11500 0x40>;
+}
+
--
2.17.1
^ permalink raw reply related
* [PATCH 2/3] cpufreq: armada-37xx: Add AVS support
From: Gregory CLEMENT @ 2018-06-19 12:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180619124402.902-1-gregory.clement@bootlin.com>
Armada 37xx supports Adaptive Voltage Scaling and thanks to this patch a
voltage is associated to each load level.
Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
---
drivers/cpufreq/armada-37xx-cpufreq.c | 163 +++++++++++++++++++++++++-
1 file changed, 160 insertions(+), 3 deletions(-)
diff --git a/drivers/cpufreq/armada-37xx-cpufreq.c b/drivers/cpufreq/armada-37xx-cpufreq.c
index 739da90ff3f6..75491fc841a6 100644
--- a/drivers/cpufreq/armada-37xx-cpufreq.c
+++ b/drivers/cpufreq/armada-37xx-cpufreq.c
@@ -51,6 +51,16 @@
#define ARMADA_37XX_DVFS_LOAD_2 2
#define ARMADA_37XX_DVFS_LOAD_3 3
+/* AVS register set */
+#define ARMADA_37XX_AVS_CTL0 0x0
+#define ARMADA_37XX_AVS_ENABLE BIT(30)
+#define ARMADA_37XX_AVS_HIGH_VDD_LIMIT 16
+#define ARMADA_37XX_AVS_LOW_VDD_LIMIT 22
+#define ARMADA_37XX_AVS_VDD_MASK 0x3F
+#define ARMADA_37XX_AVS_CTL2 0x8
+#define ARMADA_37XX_AVS_LOW_VDD_EN BIT(6)
+#define ARMADA_37XX_AVS_VSET(x) (0x1C + 4 * (x))
+
/*
* On Armada 37xx the Power management manages 4 level of CPU load,
* each level can be associated with a CPU clock source, a CPU
@@ -58,6 +68,17 @@
*/
#define LOAD_LEVEL_NR 4
+#define MIN_VOLT_MV 1000
+
+/* AVS value for the corresponding voltage (in mV) */
+static int avs_map[] = {
+ 747, 758, 770, 782, 793, 805, 817, 828, 840, 852, 863, 875, 887, 898,
+ 910, 922, 933, 945, 957, 968, 980, 992, 1003, 1015, 1027, 1038, 1050,
+ 1062, 1073, 1085, 1097, 1108, 1120, 1132, 1143, 1155, 1167, 1178, 1190,
+ 1202, 1213, 1225, 1237, 1248, 1260, 1272, 1283, 1295, 1307, 1318, 1330,
+ 1342
+};
+
struct armada37xx_cpufreq_state {
struct regmap *regmap;
u32 nb_l0l1;
@@ -71,6 +92,7 @@ static struct armada37xx_cpufreq_state *armada37xx_cpufreq_state;
struct armada_37xx_dvfs {
u32 cpu_freq_max;
u8 divider[LOAD_LEVEL_NR];
+ u32 avs[LOAD_LEVEL_NR];
};
static struct armada_37xx_dvfs armada_37xx_dvfs[] = {
@@ -148,6 +170,128 @@ static void __init armada37xx_cpufreq_dvfs_setup(struct regmap *base,
clk_set_parent(clk, parent);
}
+/*
+ * Find out the armada 37x supported AVS value whose voltage value is
+ * the round-up closest to the target voltage value.
+ */
+static u32 armada_37xx_avs_val_match(int target_vm)
+{
+ u32 avs;
+
+ /* Find out the round-up closest supported voltage value */
+ for (avs = 0; avs < ARRAY_SIZE(avs_map); avs++)
+ if (avs_map[avs] >= target_vm)
+ break;
+
+ /*
+ * If all supported voltages are smaller than target one,
+ * choose the largest supported voltage
+ */
+ if (avs == ARRAY_SIZE(avs_map))
+ avs = ARRAY_SIZE(avs_map) - 1;
+
+ return avs;
+}
+
+/*
+ * For Armada 37xx soc, L0(VSET0) VDD AVS value is set to SVC revision
+ * value or a default value when SVC is not supported.
+ * - L0 can be read out from the register of AVS_CTRL_0 and L0 voltage
+ * can be got from the mapping table of avs_map.
+ * - L1 voltage should be about 100mv smaller than L0 voltage
+ * - L2 & L3 voltage should be about 150mv smaller than L0 voltage.
+ * This function calculates L1 & L2 & L3 AVS values dynamically based
+ * on L0 voltage and fill all AVS values to the AVS value table.
+ */
+static void __init armada37xx_cpufreq_avs_configure(struct regmap *base,
+ struct armada_37xx_dvfs *dvfs)
+{
+ unsigned int target_vm;
+ int load_level = 0;
+ u32 l0_vdd_min;
+
+ if (base == NULL)
+ return;
+
+ /* Get L0 VDD min value */
+ regmap_read(base, ARMADA_37XX_AVS_CTL0, &l0_vdd_min);
+ l0_vdd_min = (l0_vdd_min >> ARMADA_37XX_AVS_LOW_VDD_LIMIT) &
+ ARMADA_37XX_AVS_VDD_MASK;
+ if (l0_vdd_min >= ARRAY_SIZE(avs_map)) {
+ pr_err("L0 VDD MIN %d is not correct.\n", l0_vdd_min);
+ return;
+ }
+ dvfs->avs[0] = l0_vdd_min;
+
+ if (avs_map[l0_vdd_min] <= MIN_VOLT_MV) {
+ /*
+ * If L0 voltage is smaller than 1000mv, then all VDD sets
+ * use L0 voltage;
+ */
+ u32 avs_min = armada_37xx_avs_val_match(MIN_VOLT_MV);
+
+ for (load_level = 1; load_level < LOAD_LEVEL_NR; load_level++)
+ dvfs->avs[load_level] = avs_min;
+
+ return;
+ }
+
+ /*
+ * L1 voltage is equal to L0 voltage - 100mv and it must be
+ * larger than 1000mv
+ */
+
+ target_vm = avs_map[l0_vdd_min] - 100;
+ target_vm = target_vm > MIN_VOLT_MV ? target_vm : MIN_VOLT_MV;
+ dvfs->avs[1] = armada_37xx_avs_val_match(target_vm);
+
+ /*
+ * L2 & L3 voltage is equal to L0 voltage - 150mv and it must
+ * be larger than 1000mv
+ */
+ target_vm = avs_map[l0_vdd_min] - 150;
+ target_vm = target_vm > MIN_VOLT_MV ? target_vm : MIN_VOLT_MV;
+ dvfs->avs[2] = dvfs->avs[3] = armada_37xx_avs_val_match(target_vm);
+}
+
+static void __init armada37xx_cpufreq_avs_setup(struct regmap *base,
+ struct armada_37xx_dvfs *dvfs)
+{
+ unsigned int avs_val = 0, freq;
+ int load_level = 0;
+
+ if (base == NULL)
+ return;
+
+ /* Disable AVS before the configuration */
+ regmap_update_bits(base, ARMADA_37XX_AVS_CTL0,
+ ARMADA_37XX_AVS_ENABLE, 0);
+
+
+ /* Enable low voltage mode */
+ regmap_update_bits(base, ARMADA_37XX_AVS_CTL2,
+ ARMADA_37XX_AVS_LOW_VDD_EN,
+ ARMADA_37XX_AVS_LOW_VDD_EN);
+
+
+ for (load_level = 1; load_level < LOAD_LEVEL_NR; load_level++) {
+ freq = dvfs->cpu_freq_max / dvfs->divider[load_level];
+
+ avs_val = dvfs->avs[load_level];
+ regmap_update_bits(base, ARMADA_37XX_AVS_VSET(load_level-1),
+ ARMADA_37XX_AVS_VDD_MASK << ARMADA_37XX_AVS_HIGH_VDD_LIMIT |
+ ARMADA_37XX_AVS_VDD_MASK << ARMADA_37XX_AVS_LOW_VDD_LIMIT,
+ avs_val << ARMADA_37XX_AVS_HIGH_VDD_LIMIT |
+ avs_val << ARMADA_37XX_AVS_LOW_VDD_LIMIT);
+ }
+
+ /* Enable AVS after the configuration */
+ regmap_update_bits(base, ARMADA_37XX_AVS_CTL0,
+ ARMADA_37XX_AVS_ENABLE,
+ ARMADA_37XX_AVS_ENABLE);
+
+}
+
static void armada37xx_cpufreq_disable_dvfs(struct regmap *base)
{
unsigned int reg = ARMADA_37XX_NB_DYN_MOD,
@@ -216,7 +360,7 @@ static int __init armada37xx_cpufreq_driver_init(void)
struct platform_device *pdev;
unsigned long freq;
unsigned int cur_frequency;
- struct regmap *nb_pm_base;
+ struct regmap *nb_pm_base, *avs_base;
struct device *cpu_dev;
int load_lvl, ret;
struct clk *clk;
@@ -227,6 +371,14 @@ static int __init armada37xx_cpufreq_driver_init(void)
if (IS_ERR(nb_pm_base))
return -ENODEV;
+ avs_base =
+ syscon_regmap_lookup_by_compatible("marvell,armada-3700-avs");
+
+ /* if AVS is not present don't use it but still try to setup dvfs */
+ if (IS_ERR(avs_base)) {
+ pr_info("Syscon failed for Adapting Voltage Scaling: skip it\n");
+ avs_base = NULL;
+ }
/* Before doing any configuration on the DVFS first, disable it */
armada37xx_cpufreq_disable_dvfs(nb_pm_base);
@@ -270,16 +422,21 @@ static int __init armada37xx_cpufreq_driver_init(void)
armada37xx_cpufreq_state->regmap = nb_pm_base;
+ armada37xx_cpufreq_avs_configure(avs_base, dvfs);
+ armada37xx_cpufreq_avs_setup(avs_base, dvfs);
+
armada37xx_cpufreq_dvfs_setup(nb_pm_base, clk, dvfs->divider);
clk_put(clk);
for (load_lvl = ARMADA_37XX_DVFS_LOAD_0; load_lvl < LOAD_LEVEL_NR;
load_lvl++) {
+ unsigned long u_volt = avs_map[dvfs->avs[load_lvl]] * 1000;
freq = cur_frequency / dvfs->divider[load_lvl];
-
- ret = dev_pm_opp_add(cpu_dev, freq, 0);
+ ret = dev_pm_opp_add(cpu_dev, freq, u_volt);
if (ret)
goto remove_opp;
+
+
}
/* Now that everything is setup, enable the DVFS at hardware level */
--
2.17.1
^ permalink raw reply related
* [PATCH 3/3] arm64: dts: marvell: armada-37xx: add the node allowing AVS support
From: Gregory CLEMENT @ 2018-06-19 12:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180619124402.902-1-gregory.clement@bootlin.com>
In order to be able to use Adaptive Voltage Scaling, we need to add a
reference to these registers.
Signed-off-by: Gregory CLEMENT <gregory.clement@bootlin.com>
---
arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
index 3353252d78a0..15eb9e5e4370 100644
--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
@@ -98,6 +98,12 @@
status = "disabled";
};
+ avs: avs at 11500 {
+ compatible = "marvell,armada-3700-avs",
+ "syscon";
+ reg = <0x11500 0x40>;
+ };
+
uart0: serial at 12000 {
compatible = "marvell,armada-3700-uart";
reg = <0x12000 0x200>;
--
2.17.1
^ permalink raw reply related
* [PATCHv3 07/19] arm64: remove sigreturn wrappers
From: Catalin Marinas @ 2018-06-19 12:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180618120310.39527-8-mark.rutland@arm.com>
On Mon, Jun 18, 2018 at 01:02:58PM +0100, Mark Rutland wrote:
> The arm64 sigreturn* syscall handlers are non-standard. Rather than
> taking a number of user parameters in registers as per the AAPCS,
> they expect the pt_regs as their sole argument.
>
> To make this work, we override the syscall definitions to invoke
> wrappers written in assembly, which mov the SP into x0, and branch to
> their respective C functions.
>
> On other architectures (such as x86), the sigreturn* functions take no
> argument and instead use current_pt_regs() to acquire the user
> registers. This requires less boilerplate code, and allows for other
> features such as interposing C code in this path.
>
> This patch takes the same approach for arm64.
>
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Tentatively-reviewed-by: Dave Martin <dave.martin@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
^ permalink raw reply
* [PATCH 0/3] I-side fixes
From: Will Deacon @ 2018-06-19 12:48 UTC (permalink / raw)
To: linux-arm-kernel
Hi all,
These three patches attempt to address some issues with ISBs and I-cache
maintenance. Specifically:
- Ensure we don't invoke dynamically modified I-cache maintenance code
as part of the instruction patching routines
- Remove ISBs from pte/pmd/pud setter functions
- IPI other CPUs when invalidating the I-cache for kernel mappings
Whilst the IPI is a bit nasty, I couldn't figure out a better way to
ensure that CPUs don't retain instructions from freed pages in their
pipelines. I initially hoped to deal with this by hooking into RCU, but
that would rely on RCU being the only mechanism used to defer reclaim of
executable pages and this doesn't appear to be the case for e.g. modules.
Feedback welcome,
Will
--->8
Will Deacon (3):
arm64: Avoid flush_icache_range() in alternatives patching code
arm64: Remove unnecessary ISBs from set_{pte,pmd,pud}
arm64: IPI each CPU after invalidating the I-cache for kernel mappings
arch/arm64/include/asm/alternative.h | 7 +++++-
arch/arm64/include/asm/cacheflush.h | 13 +++++++++-
arch/arm64/include/asm/pgtable.h | 6 +----
arch/arm64/kernel/alternative.c | 47 ++++++++++++++++++++++++++++++------
arch/arm64/kernel/cpu_errata.c | 2 +-
arch/arm64/kernel/insn.c | 15 ++----------
arch/arm64/kernel/module.c | 5 ++--
arch/arm64/mm/cache.S | 4 +--
8 files changed, 65 insertions(+), 34 deletions(-)
--
2.1.4
^ permalink raw reply
* [PATCH 1/3] arm64: Avoid flush_icache_range() in alternatives patching code
From: Will Deacon @ 2018-06-19 12:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1529412495-17525-1-git-send-email-will.deacon@arm.com>
The implementation of flush_icache_range() includes instruction sequences
which are themselves patched at runtime, so it is not safe to call from
the patching framework.
This patch reworks the alternatives cache-flushing code so that it rolls
its own internal D-cache maintenance using DC CIVAC before invalidating
the entire I-cache after all alternatives have been applied at boot.
Modules don't cause any issues, since flush_icache_range() is safe to
call by the time they are loaded.
Reported-by: Rohit Khanna <rokhanna@nvidia.com>
Cc: Alexander Van Brunt <avanbrunt@nvidia.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
arch/arm64/include/asm/alternative.h | 7 +++++-
arch/arm64/kernel/alternative.c | 46 ++++++++++++++++++++++++++++++------
arch/arm64/kernel/module.c | 5 ++--
3 files changed, 47 insertions(+), 11 deletions(-)
diff --git a/arch/arm64/include/asm/alternative.h b/arch/arm64/include/asm/alternative.h
index a91933b1e2e6..4b650ec1d7dd 100644
--- a/arch/arm64/include/asm/alternative.h
+++ b/arch/arm64/include/asm/alternative.h
@@ -28,7 +28,12 @@ typedef void (*alternative_cb_t)(struct alt_instr *alt,
__le32 *origptr, __le32 *updptr, int nr_inst);
void __init apply_alternatives_all(void);
-void apply_alternatives(void *start, size_t length);
+
+#ifdef CONFIG_MODULES
+void apply_alternatives_module(void *start, size_t length);
+#else
+static inline void apply_alternatives_module(void *start, size_t length) { }
+#endif
#define ALTINSTR_ENTRY(feature,cb) \
" .word 661b - .\n" /* label */ \
diff --git a/arch/arm64/kernel/alternative.c b/arch/arm64/kernel/alternative.c
index 5c4bce4ac381..4f3dcc15a5b2 100644
--- a/arch/arm64/kernel/alternative.c
+++ b/arch/arm64/kernel/alternative.c
@@ -122,7 +122,25 @@ static void patch_alternative(struct alt_instr *alt,
}
}
-static void __apply_alternatives(void *alt_region, bool use_linear_alias)
+static void clean_dcache_range_nopatch(u64 start, u64 end)
+{
+ u64 cur, d_size, ctr_el0;
+
+ ctr_el0 = read_sanitised_ftr_reg(SYS_CTR_EL0);
+ d_size = 4 << cpuid_feature_extract_unsigned_field(ctr_el0,
+ CTR_DMINLINE_SHIFT);
+ cur = start & ~(d_size - 1);
+ do {
+ /*
+ * We must clean+invalidate to the PoC in order to avoid
+ * Cortex-A53 errata 826319, 827319, 824069 and 819472
+ * (this corresponds to ARM64_WORKAROUND_CLEAN_CACHE)
+ */
+ asm volatile("dc civac, %0" : : "r" (cur) : "memory");
+ } while (cur += d_size, cur < end);
+}
+
+static void __apply_alternatives(void *alt_region, bool is_module)
{
struct alt_instr *alt;
struct alt_region *region = alt_region;
@@ -145,7 +163,7 @@ static void __apply_alternatives(void *alt_region, bool use_linear_alias)
pr_info_once("patching kernel code\n");
origptr = ALT_ORIG_PTR(alt);
- updptr = use_linear_alias ? lm_alias(origptr) : origptr;
+ updptr = is_module ? origptr : lm_alias(origptr);
nr_inst = alt->orig_len / AARCH64_INSN_SIZE;
if (alt->cpufeature < ARM64_CB_PATCH)
@@ -155,8 +173,20 @@ static void __apply_alternatives(void *alt_region, bool use_linear_alias)
alt_cb(alt, origptr, updptr, nr_inst);
- flush_icache_range((uintptr_t)origptr,
- (uintptr_t)(origptr + nr_inst));
+ if (!is_module) {
+ clean_dcache_range_nopatch((u64)origptr,
+ (u64)(origptr + nr_inst));
+ }
+ }
+
+ /*
+ * The core module code takes care of cache maintenance in
+ * flush_module_icache().
+ */
+ if (!is_module) {
+ dsb(ish);
+ __flush_icache_all();
+ isb();
}
}
@@ -178,7 +208,7 @@ static int __apply_alternatives_multi_stop(void *unused)
isb();
} else {
BUG_ON(alternatives_applied);
- __apply_alternatives(®ion, true);
+ __apply_alternatives(®ion, false);
/* Barriers provided by the cache flushing */
WRITE_ONCE(alternatives_applied, 1);
}
@@ -192,12 +222,14 @@ void __init apply_alternatives_all(void)
stop_machine(__apply_alternatives_multi_stop, NULL, cpu_online_mask);
}
-void apply_alternatives(void *start, size_t length)
+#ifdef CONFIG_MODULES
+void apply_alternatives_module(void *start, size_t length)
{
struct alt_region region = {
.begin = start,
.end = start + length,
};
- __apply_alternatives(®ion, false);
+ __apply_alternatives(®ion, true);
}
+#endif
diff --git a/arch/arm64/kernel/module.c b/arch/arm64/kernel/module.c
index 155fd91e78f4..f0f27aeefb73 100644
--- a/arch/arm64/kernel/module.c
+++ b/arch/arm64/kernel/module.c
@@ -448,9 +448,8 @@ int module_finalize(const Elf_Ehdr *hdr,
const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
for (s = sechdrs, se = sechdrs + hdr->e_shnum; s < se; s++) {
- if (strcmp(".altinstructions", secstrs + s->sh_name) == 0) {
- apply_alternatives((void *)s->sh_addr, s->sh_size);
- }
+ if (strcmp(".altinstructions", secstrs + s->sh_name) == 0)
+ apply_alternatives_module((void *)s->sh_addr, s->sh_size);
#ifdef CONFIG_ARM64_MODULE_PLTS
if (IS_ENABLED(CONFIG_DYNAMIC_FTRACE) &&
!strcmp(".text.ftrace_trampoline", secstrs + s->sh_name))
--
2.1.4
^ permalink raw reply related
* [PATCH 2/3] arm64: Remove unnecessary ISBs from set_{pte,pmd,pud}
From: Will Deacon @ 2018-06-19 12:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1529412495-17525-1-git-send-email-will.deacon@arm.com>
Commit 7f0b1bf04511 ("arm64: Fix barriers used for page table modifications")
fixed a reported issue with fixmap page-table entries not being visible
to the walker due to a missing DSB instruction. At the same time, it added
ISB instructions to the arm64 set_{pte,pmd,pud} functions, which are not
required by the architecture and make little sense in isolation.
Remove the redundant ISBs.
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Steve Capper <steve.capper@linaro.org>
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
arch/arm64/include/asm/pgtable.h | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 9f82d6b53851..1bdeca8918a6 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -224,10 +224,8 @@ static inline void set_pte(pte_t *ptep, pte_t pte)
* Only if the new pte is valid and kernel, otherwise TLB maintenance
* or update_mmu_cache() have the necessary barriers.
*/
- if (pte_valid_not_user(pte)) {
+ if (pte_valid_not_user(pte))
dsb(ishst);
- isb();
- }
}
extern void __sync_icache_dcache(pte_t pteval);
@@ -434,7 +432,6 @@ static inline void set_pmd(pmd_t *pmdp, pmd_t pmd)
{
WRITE_ONCE(*pmdp, pmd);
dsb(ishst);
- isb();
}
static inline void pmd_clear(pmd_t *pmdp)
@@ -485,7 +482,6 @@ static inline void set_pud(pud_t *pudp, pud_t pud)
{
WRITE_ONCE(*pudp, pud);
dsb(ishst);
- isb();
}
static inline void pud_clear(pud_t *pudp)
--
2.1.4
^ permalink raw reply related
* [PATCH 3/3] arm64: IPI each CPU after invalidating the I-cache for kernel mappings
From: Will Deacon @ 2018-06-19 12:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1529412495-17525-1-git-send-email-will.deacon@arm.com>
When invalidating the instruction cache for a kernel mapping via
flush_icache_range(), it is also necessary to flush the pipeline for
other CPUs so that instructions fetched into the pipeline before the
I-cache invalidation are discarded. For example, if module 'foo' is
unloaded and then module 'bar' is loaded into the same area of memory,
a CPU could end up executing instructions from 'foo' when branching into
'bar' if these instructions were fetched into the pipeline before 'foo'
was unloaded.
Whilst this is highly unlikely to occur in practice, particularly as
any exception acts as a context-synchronizing operation, following the
letter of the architecture requires us to execute an ISB on each CPU
in order for the new instruction stream to be visible.
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
arch/arm64/include/asm/cacheflush.h | 13 ++++++++++++-
arch/arm64/kernel/alternative.c | 1 -
arch/arm64/kernel/cpu_errata.c | 2 +-
arch/arm64/kernel/insn.c | 15 ++-------------
arch/arm64/mm/cache.S | 4 ++--
5 files changed, 17 insertions(+), 18 deletions(-)
diff --git a/arch/arm64/include/asm/cacheflush.h b/arch/arm64/include/asm/cacheflush.h
index d264a7274811..a0ec27066e6f 100644
--- a/arch/arm64/include/asm/cacheflush.h
+++ b/arch/arm64/include/asm/cacheflush.h
@@ -71,7 +71,7 @@
* - kaddr - page address
* - size - region size
*/
-extern void flush_icache_range(unsigned long start, unsigned long end);
+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_dcache_area(void *addr, size_t len);
extern void __inval_dcache_area(void *addr, size_t len);
@@ -81,6 +81,17 @@ extern void __clean_dcache_area_pou(void *addr, size_t len);
extern long __flush_cache_user_range(unsigned long start, unsigned long end);
extern void sync_icache_aliases(void *kaddr, unsigned long len);
+static inline void flush_icache_range(unsigned long start, unsigned long end)
+{
+ __flush_icache_range(start, end);
+
+ /*
+ * IPI all online CPUs so that they undergo a context synchronization
+ * event and are forced to refetch the new instructions.
+ */
+ kick_all_cpus_sync();
+}
+
static inline void flush_cache_mm(struct mm_struct *mm)
{
}
diff --git a/arch/arm64/kernel/alternative.c b/arch/arm64/kernel/alternative.c
index 4f3dcc15a5b2..0ac06560c166 100644
--- a/arch/arm64/kernel/alternative.c
+++ b/arch/arm64/kernel/alternative.c
@@ -205,7 +205,6 @@ static int __apply_alternatives_multi_stop(void *unused)
if (smp_processor_id()) {
while (!READ_ONCE(alternatives_applied))
cpu_relax();
- isb();
} else {
BUG_ON(alternatives_applied);
__apply_alternatives(®ion, false);
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 1d2b6d768efe..0a338a1cd2d7 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -101,7 +101,7 @@ static void __copy_hyp_vect_bpi(int slot, const char *hyp_vecs_start,
for (i = 0; i < SZ_2K; i += 0x80)
memcpy(dst + i, hyp_vecs_start, hyp_vecs_end - hyp_vecs_start);
- flush_icache_range((uintptr_t)dst, (uintptr_t)dst + SZ_2K);
+ __flush_icache_range((uintptr_t)dst, (uintptr_t)dst + SZ_2K);
}
static void __install_bp_hardening_cb(bp_hardening_cb_t fn,
diff --git a/arch/arm64/kernel/insn.c b/arch/arm64/kernel/insn.c
index 816d03c4c913..4cc41864f277 100644
--- a/arch/arm64/kernel/insn.c
+++ b/arch/arm64/kernel/insn.c
@@ -249,7 +249,6 @@ static int __kprobes aarch64_insn_patch_text_cb(void *arg)
} else {
while (atomic_read(&pp->cpu_count) <= num_online_cpus())
cpu_relax();
- isb();
}
return ret;
@@ -283,18 +282,8 @@ int __kprobes aarch64_insn_patch_text(void *addrs[], u32 insns[], int cnt)
if (ret)
return ret;
- if (aarch64_insn_hotpatch_safe(insn, insns[0])) {
- /*
- * ARMv8 architecture doesn't guarantee all CPUs see
- * the new instruction after returning from function
- * aarch64_insn_patch_text_nosync(). So send IPIs to
- * all other CPUs to achieve instruction
- * synchronization.
- */
- ret = aarch64_insn_patch_text_nosync(addrs[0], insns[0]);
- kick_all_cpus_sync();
- return ret;
- }
+ if (aarch64_insn_hotpatch_safe(insn, insns[0]))
+ return aarch64_insn_patch_text_nosync(addrs[0], insns[0]);
}
return aarch64_insn_patch_text_sync(addrs, insns, cnt);
diff --git a/arch/arm64/mm/cache.S b/arch/arm64/mm/cache.S
index 30334d81b021..0c22ede52f90 100644
--- a/arch/arm64/mm/cache.S
+++ b/arch/arm64/mm/cache.S
@@ -35,7 +35,7 @@
* - start - virtual start address of region
* - end - virtual end address of region
*/
-ENTRY(flush_icache_range)
+ENTRY(__flush_icache_range)
/* FALLTHROUGH */
/*
@@ -77,7 +77,7 @@ alternative_else_nop_endif
9:
mov x0, #-EFAULT
b 1b
-ENDPROC(flush_icache_range)
+ENDPROC(__flush_icache_range)
ENDPROC(__flush_cache_user_range)
/*
--
2.1.4
^ permalink raw reply related
* [PATCH] arm: Hook up SYNC_CORE functionality for sys_membarrier()
From: Mathieu Desnoyers @ 2018-06-19 12:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1529410974-18929-1-git-send-email-will.deacon@arm.com>
----- On Jun 19, 2018, at 8:22 AM, Will Deacon will.deacon at arm.com wrote:
> Exception return implies context synchronization, so we can hook up the
> SYNC_CORE option to sys_membarrier() simply by selecting the Kconfig option,
> just like we've done for arm64 already.
>
> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
> Cc: Orion Hodson <oth@google.com>
> Signed-off-by: Will Deacon <will.deacon@arm.com>
> ---
> arch/arm/Kconfig | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 54eeb8d00bc6..b0ac18547370 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -9,6 +9,7 @@ config ARM
> select ARCH_HAS_ELF_RANDOMIZE
> select ARCH_HAS_FORTIFY_SOURCE
> select ARCH_HAS_KCOV
> + select ARCH_HAS_MEMBARRIER_SYNC_CORE
In addition to this, we added this comment in arch/arm64/kernel/entry.S:
+ /*
+ * ARCH_HAS_MEMBARRIER_SYNC_CORE rely on eret context synchronization
+ * when returning from IPI handler, and when returning to user-space.
+ */
So I would expect a similar comment in arch/arm/kernel/entry-header.S, within
svc_exit and svc_exit_via_fiq:
/*
* ARCH_HAS_MEMBARRIER_SYNC_CORE rely on [insn] context synchronization
* when returning from IPI handler, and when returning to user-space.
*/
Which instruction exactly is responsible for context synchronization on
arm32 ?
Thanks,
Mathieu
> select ARCH_HAS_PTE_SPECIAL if ARM_LPAE
> select ARCH_HAS_PHYS_TO_DMA
> select ARCH_HAS_SET_MEMORY
> --
> 2.1.4
--
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com
^ permalink raw reply
* [PATCH 1/2] arm64: avoid alloc memory on offline node
From: Punit Agrawal @ 2018-06-19 12:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180619120714.GE13685@dhcp22.suse.cz>
Michal Hocko <mhocko@kernel.org> writes:
> On Tue 19-06-18 20:03:07, Xie XiuQi wrote:
> [...]
>> I tested on a arm board with 128 cores 4 numa nodes, but I set CONFIG_NR_CPUS=72.
>> Then node 3 is not be created, because node 3 has no memory, and no cpu.
>> But some pci device may related to node 3, which be set in ACPI table.
>
> Could you double check that zonelists for node 3 are generated
> correctly?
The cpus in node 3 aren't onlined and there's no memory attached - I
suspect that no zonelists are built for this node.
We skip creating a node, if the number of SRAT entries parsed exceeds
NR_CPUS[0]. This in turn prevents onlining the numa node and so no
zonelists will be created for it.
I think the problem will go away if the cpus are restricted via the
kernel command line by setting nr_cpus.
Xie, can you try the below patch on top of the one enabling memoryless
nodes? I'm not sure this is the right solution but at least it'll
confirm the problem.
Thanks,
Punit
[0] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/kernel/acpi_numa.c?h=v4.18-rc1#n73
-- >8 --
diff --git a/arch/arm64/kernel/acpi_numa.c b/arch/arm64/kernel/acpi_numa.c
index d190a7b231bf..fea0f7164f1a 100644
--- a/arch/arm64/kernel/acpi_numa.c
+++ b/arch/arm64/kernel/acpi_numa.c
@@ -70,11 +70,9 @@ void __init acpi_numa_gicc_affinity_init(struct acpi_srat_gicc_affinity *pa)
if (!(pa->flags & ACPI_SRAT_GICC_ENABLED))
return;
- if (cpus_in_srat >= NR_CPUS) {
+ if (cpus_in_srat >= NR_CPUS)
pr_warn_once("SRAT: cpu_to_node_map[%d] is too small, may not be able to use all cpus\n",
NR_CPUS);
- return;
- }
pxm = pa->proximity_domain;
node = acpi_map_pxm_to_node(pxm);
^ permalink raw reply related
* [PATCH 4/8] mailbox: tegra-hsp: Refactor in preparation of mailboxes
From: Mikko Perttunen @ 2018-06-19 12:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <8306b033-e7f5-748c-6e6a-131dfd6a26b8@nvidia.com>
On 22.05.2018 18:36, Jon Hunter wrote:
>
> 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?
Fixed.
>
>> +??? }
>> +
>> +??? return -EINVAL;
>
> Does this function always return -EINVAL?
Fixed.
>
>> +}
>> +
>> +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?
That's done elsewhere in the next patch that actually adds the shared
mailbox support.
>
> Cheers
> Jon
>
Thanks,
Mikko
^ permalink raw reply
* [PATCH] iommu/io-pgtable-arm-v7s: Abort allocation when table address overflows the PTE
From: Jean-Philippe Brucker @ 2018-06-19 12:52 UTC (permalink / raw)
To: linux-arm-kernel
When run on a 64-bit system in selftest, the v7s driver may obtain page
table with physical addresses larger than 32-bit. Level-2 tables are 1KB
and are are allocated with slab, which doesn't accept the GFP_DMA32
flag. Currently map() truncates the address written in the PTE, causing
iova_to_phys() or unmap() to access invalid memory. Kasan reports it as
a use-after-free. To avoid any nasty surprise, test if the physical
address fits in a PTE before returning a new table. 32-bit systems,
which are the main users of this page table format, shouldn't see any
difference.
Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
---
drivers/iommu/io-pgtable-arm-v7s.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/io-pgtable-arm-v7s.c b/drivers/iommu/io-pgtable-arm-v7s.c
index 50e3a9fcf43e..b5948ba6b3b3 100644
--- a/drivers/iommu/io-pgtable-arm-v7s.c
+++ b/drivers/iommu/io-pgtable-arm-v7s.c
@@ -192,6 +192,7 @@ static void *__arm_v7s_alloc_table(int lvl, gfp_t gfp,
{
struct io_pgtable_cfg *cfg = &data->iop.cfg;
struct device *dev = cfg->iommu_dev;
+ phys_addr_t phys;
dma_addr_t dma;
size_t size = ARM_V7S_TABLE_SIZE(lvl);
void *table = NULL;
@@ -200,6 +201,10 @@ static void *__arm_v7s_alloc_table(int lvl, gfp_t gfp,
table = (void *)__get_dma_pages(__GFP_ZERO, get_order(size));
else if (lvl == 2)
table = kmem_cache_zalloc(data->l2_tables, gfp | GFP_DMA);
+ phys = virt_to_phys(table);
+ if (phys != (arm_v7s_iopte)phys)
+ /* Doesn't fit in PTE */
+ goto out_free;
if (table && !(cfg->quirks & IO_PGTABLE_QUIRK_NO_DMA)) {
dma = dma_map_single(dev, table, size, DMA_TO_DEVICE);
if (dma_mapping_error(dev, dma))
@@ -209,7 +214,7 @@ static void *__arm_v7s_alloc_table(int lvl, gfp_t gfp,
* address directly, so if the DMA layer suggests otherwise by
* translating or truncating them, that bodes very badly...
*/
- if (dma != virt_to_phys(table))
+ if (dma != phys)
goto out_unmap;
}
kmemleak_ignore(table);
--
2.17.0
^ permalink raw reply related
* [RESEND PATCH v2 0/9] Rewrite asm-generic/bitops/{atomic, lock}.h and use on arm64
From: Will Deacon @ 2018-06-19 12:53 UTC (permalink / raw)
To: linux-arm-kernel
Hi all,
This is a resend of the patches I previously sent here:
RFCv1: https://www.spinics.net/lists/arm-kernel/msg634719.html
RFCv2: https://www.spinics.net/lists/arm-kernel/msg636875.html
v1: https://www.spinics.net/lists/arm-kernel/msg655262.html
v2: https://lkml.org/lkml/2018/6/1/619
The only change is that I have rebased onto v4.18-rc1.
Ingo -- please can you queue this via -tip when you start picking up
patches for 4.19? It doesn't conflict with Mark's atomic API rework.
Thanks,
Will
--->8
Will Deacon (9):
h8300: Don't include linux/kernel.h in asm/atomic.h
m68k: Don't use asm-generic/bitops/lock.h
asm-generic: Move some macros from linux/bitops.h to a new bits.h file
openrisc: Don't pull in all of linux/bitops.h in asm/cmpxchg.h
sh: Don't pull in all of linux/bitops.h in asm/cmpxchg-xchg.h
asm-generic/bitops/atomic.h: Rewrite using atomic_*
asm-generic/bitops/lock.h: Rewrite using atomic_fetch_*
arm64: Replace our atomic/lock bitop implementations with asm-generic
arm64: bitops: Include <asm-generic/bitops/ext2-atomic-setbit.h>
arch/arm64/include/asm/bitops.h | 21 +---
arch/arm64/lib/Makefile | 2 +-
arch/arm64/lib/bitops.S | 76 ---------------
arch/h8300/include/asm/atomic.h | 4 +-
arch/m68k/include/asm/bitops.h | 6 +-
arch/openrisc/include/asm/cmpxchg.h | 3 +-
arch/sh/include/asm/cmpxchg-xchg.h | 3 +-
include/asm-generic/bitops/atomic.h | 188 +++++++-----------------------------
include/asm-generic/bitops/lock.h | 68 ++++++++++---
include/linux/bitops.h | 22 +----
include/linux/bits.h | 26 +++++
11 files changed, 131 insertions(+), 288 deletions(-)
delete mode 100644 arch/arm64/lib/bitops.S
create mode 100644 include/linux/bits.h
--
2.1.4
^ permalink raw reply
* [RESEND PATCH v2 1/9] h8300: Don't include linux/kernel.h in asm/atomic.h
From: Will Deacon @ 2018-06-19 12:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1529412794-17720-1-git-send-email-will.deacon@arm.com>
linux/kernel.h isn't needed by asm/atomic.h and will result in circular
dependencies when the asm-generic atomic bitops are built around the
tomic_long_t interface.
Remove the broad include and replace it with linux/compiler.h for
READ_ONCE() etc and asm/irqflags.h for arch_local_irq_save() etc.
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
arch/h8300/include/asm/atomic.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/h8300/include/asm/atomic.h b/arch/h8300/include/asm/atomic.h
index 941e7554e886..b174dec099bf 100644
--- a/arch/h8300/include/asm/atomic.h
+++ b/arch/h8300/include/asm/atomic.h
@@ -2,8 +2,10 @@
#ifndef __ARCH_H8300_ATOMIC__
#define __ARCH_H8300_ATOMIC__
+#include <linux/compiler.h>
#include <linux/types.h>
#include <asm/cmpxchg.h>
+#include <asm/irqflags.h>
/*
* Atomic operations that C can't guarantee us. Useful for
@@ -15,8 +17,6 @@
#define atomic_read(v) READ_ONCE((v)->counter)
#define atomic_set(v, i) WRITE_ONCE(((v)->counter), (i))
-#include <linux/kernel.h>
-
#define ATOMIC_OP_RETURN(op, c_op) \
static inline int atomic_##op##_return(int i, atomic_t *v) \
{ \
--
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