Skip to content

Commit 32f741b

Browse files
committed
Merge tag 'powerpc-5.10-5' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux
Pull powerpc fixes from Michael Ellerman: "Some more powerpc fixes for 5.10: - Three commits fixing possible missed TLB invalidations for multi-threaded processes when CPUs are hotplugged in and out. - A fix for a host crash triggerable by host userspace (qemu) in KVM on Power9. - A fix for a host crash in machine check handling when running HPT guests on a HPT host. - One commit fixing potential missed TLB invalidations when using the hash MMU on Power9 or later. - A regression fix for machines with CPUs on node 0 but no memory. Thanks to Aneesh Kumar K.V, Cédric Le Goater, Greg Kurz, Milan Mohanty, Milton Miller, Nicholas Piggin, Paul Mackerras, and Srikar Dronamraju" * tag 'powerpc-5.10-5' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: powerpc/64s/powernv: Fix memory corruption when saving SLB entries on MCE KVM: PPC: Book3S HV: XIVE: Fix vCPU id sanity check powerpc/numa: Fix a regression on memoryless node 0 powerpc/64s: Trim offlined CPUs from mm_cpumasks kernel/cpu: add arch override for clear_tasks_mm_cpumask() mm handling powerpc/64s/pseries: Fix hash tlbiel_all_isa300 for guest kernels powerpc/64s: Fix hash ISA v3.0 TLBIEL instruction generation
2 parents d4e9041 + a1ee281 commit 32f741b

10 files changed

Lines changed: 70 additions & 18 deletions

File tree

arch/powerpc/include/asm/book3s/64/mmu.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,18 @@ extern void radix_init_pseries(void);
242242
static inline void radix_init_pseries(void) { };
243243
#endif
244244

245+
#ifdef CONFIG_HOTPLUG_CPU
246+
#define arch_clear_mm_cpumask_cpu(cpu, mm) \
247+
do { \
248+
if (cpumask_test_cpu(cpu, mm_cpumask(mm))) { \
249+
atomic_dec(&(mm)->context.active_cpus); \
250+
cpumask_clear_cpu(cpu, mm_cpumask(mm)); \
251+
} \
252+
} while (0)
253+
254+
void cleanup_cpu_mmu_context(void);
255+
#endif
256+
245257
static inline int get_user_context(mm_context_t *ctx, unsigned long ea)
246258
{
247259
int index = ea >> MAX_EA_BITS_PER_CONTEXT;

arch/powerpc/kvm/book3s_xive.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,12 +1214,9 @@ void kvmppc_xive_cleanup_vcpu(struct kvm_vcpu *vcpu)
12141214
static bool kvmppc_xive_vcpu_id_valid(struct kvmppc_xive *xive, u32 cpu)
12151215
{
12161216
/* We have a block of xive->nr_servers VPs. We just need to check
1217-
* raw vCPU ids are below the expected limit for this guest's
1218-
* core stride ; kvmppc_pack_vcpu_id() will pack them down to an
1219-
* index that can be safely used to compute a VP id that belongs
1220-
* to the VP block.
1217+
* packed vCPU ids are below that.
12211218
*/
1222-
return cpu < xive->nr_servers * xive->kvm->arch.emul_smt_mode;
1219+
return kvmppc_pack_vcpu_id(xive->kvm, cpu) < xive->nr_servers;
12231220
}
12241221

12251222
int kvmppc_xive_compute_vp_id(struct kvmppc_xive *xive, u32 cpu, u32 *vp)

arch/powerpc/mm/book3s64/hash_native.c

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ static __always_inline void tlbiel_hash_set_isa300(unsigned int set, unsigned in
6868
rs = ((unsigned long)pid << PPC_BITLSHIFT(31));
6969

7070
asm volatile(PPC_TLBIEL(%0, %1, %2, %3, %4)
71-
: : "r"(rb), "r"(rs), "i"(ric), "i"(prs), "r"(r)
71+
: : "r"(rb), "r"(rs), "i"(ric), "i"(prs), "i"(r)
7272
: "memory");
7373
}
7474

@@ -92,16 +92,15 @@ static void tlbiel_all_isa300(unsigned int num_sets, unsigned int is)
9292
asm volatile("ptesync": : :"memory");
9393

9494
/*
95-
* Flush the first set of the TLB, and any caching of partition table
96-
* entries. Then flush the remaining sets of the TLB. Hash mode uses
97-
* partition scoped TLB translations.
95+
* Flush the partition table cache if this is HV mode.
9896
*/
99-
tlbiel_hash_set_isa300(0, is, 0, 2, 0);
100-
for (set = 1; set < num_sets; set++)
101-
tlbiel_hash_set_isa300(set, is, 0, 0, 0);
97+
if (early_cpu_has_feature(CPU_FTR_HVMODE))
98+
tlbiel_hash_set_isa300(0, is, 0, 2, 0);
10299

103100
/*
104-
* Now invalidate the process table cache.
101+
* Now invalidate the process table cache. UPRT=0 HPT modes (what
102+
* current hardware implements) do not use the process table, but
103+
* add the flushes anyway.
105104
*
106105
* From ISA v3.0B p. 1078:
107106
* The following forms are invalid.
@@ -110,6 +109,14 @@ static void tlbiel_all_isa300(unsigned int num_sets, unsigned int is)
110109
*/
111110
tlbiel_hash_set_isa300(0, is, 0, 2, 1);
112111

112+
/*
113+
* Then flush the sets of the TLB proper. Hash mode uses
114+
* partition scoped TLB translations, which may be flushed
115+
* in !HV mode.
116+
*/
117+
for (set = 0; set < num_sets; set++)
118+
tlbiel_hash_set_isa300(set, is, 0, 0, 0);
119+
113120
ppc_after_tlbiel_barrier();
114121

115122
asm volatile(PPC_ISA_3_0_INVALIDATE_ERAT "; isync" : : :"memory");

arch/powerpc/mm/book3s64/mmu_context.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <linux/export.h>
1818
#include <linux/gfp.h>
1919
#include <linux/slab.h>
20+
#include <linux/cpu.h>
2021

2122
#include <asm/mmu_context.h>
2223
#include <asm/pgalloc.h>
@@ -307,3 +308,22 @@ void radix__switch_mmu_context(struct mm_struct *prev, struct mm_struct *next)
307308
isync();
308309
}
309310
#endif
311+
312+
/**
313+
* cleanup_cpu_mmu_context - Clean up MMU details for this CPU (newly offlined)
314+
*
315+
* This clears the CPU from mm_cpumask for all processes, and then flushes the
316+
* local TLB to ensure TLB coherency in case the CPU is onlined again.
317+
*
318+
* KVM guest translations are not necessarily flushed here. If KVM started
319+
* using mm_cpumask or the Linux APIs which do, this would have to be resolved.
320+
*/
321+
#ifdef CONFIG_HOTPLUG_CPU
322+
void cleanup_cpu_mmu_context(void)
323+
{
324+
int cpu = smp_processor_id();
325+
326+
clear_tasks_mm_cpumask(cpu);
327+
tlbiel_all();
328+
}
329+
#endif

arch/powerpc/mm/numa.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -742,8 +742,7 @@ static int __init parse_numa_properties(void)
742742
of_node_put(cpu);
743743
}
744744

745-
if (likely(nid > 0))
746-
node_set_online(nid);
745+
node_set_online(nid);
747746
}
748747

749748
get_n_mem_cells(&n_mem_addr_cells, &n_mem_size_cells);

arch/powerpc/platforms/powermac/smp.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -911,6 +911,8 @@ static int smp_core99_cpu_disable(void)
911911

912912
mpic_cpu_set_priority(0xf);
913913

914+
cleanup_cpu_mmu_context();
915+
914916
return 0;
915917
}
916918

arch/powerpc/platforms/powernv/setup.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,11 +211,16 @@ static void __init pnv_init(void)
211211
add_preferred_console("hvc", 0, NULL);
212212

213213
if (!radix_enabled()) {
214+
size_t size = sizeof(struct slb_entry) * mmu_slb_size;
214215
int i;
215216

216217
/* Allocate per cpu area to save old slb contents during MCE */
217-
for_each_possible_cpu(i)
218-
paca_ptrs[i]->mce_faulty_slbs = memblock_alloc_node(mmu_slb_size, __alignof__(*paca_ptrs[i]->mce_faulty_slbs), cpu_to_node(i));
218+
for_each_possible_cpu(i) {
219+
paca_ptrs[i]->mce_faulty_slbs =
220+
memblock_alloc_node(size,
221+
__alignof__(struct slb_entry),
222+
cpu_to_node(i));
223+
}
219224
}
220225
}
221226

arch/powerpc/platforms/powernv/smp.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,9 @@ static int pnv_smp_cpu_disable(void)
143143
xive_smp_disable_cpu();
144144
else
145145
xics_migrate_irqs_away();
146+
147+
cleanup_cpu_mmu_context();
148+
146149
return 0;
147150
}
148151

arch/powerpc/platforms/pseries/hotplug-cpu.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ static int pseries_cpu_disable(void)
9090
xive_smp_disable_cpu();
9191
else
9292
xics_migrate_irqs_away();
93+
94+
cleanup_cpu_mmu_context();
95+
9396
return 0;
9497
}
9598

kernel/cpu.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -815,6 +815,10 @@ void __init cpuhp_threads_init(void)
815815
}
816816

817817
#ifdef CONFIG_HOTPLUG_CPU
818+
#ifndef arch_clear_mm_cpumask_cpu
819+
#define arch_clear_mm_cpumask_cpu(cpu, mm) cpumask_clear_cpu(cpu, mm_cpumask(mm))
820+
#endif
821+
818822
/**
819823
* clear_tasks_mm_cpumask - Safely clear tasks' mm_cpumask for a CPU
820824
* @cpu: a CPU id
@@ -850,7 +854,7 @@ void clear_tasks_mm_cpumask(int cpu)
850854
t = find_lock_task_mm(p);
851855
if (!t)
852856
continue;
853-
cpumask_clear_cpu(cpu, mm_cpumask(t->mm));
857+
arch_clear_mm_cpumask_cpu(cpu, t->mm);
854858
task_unlock(t);
855859
}
856860
rcu_read_unlock();

0 commit comments

Comments
 (0)