Skip to content

Commit 6fcc8ce

Browse files
committed
Merge tag 'powerpc-4.9-4' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux
Pull powerpc fixes from Michael Ellerman: "Fixes marked for stable: - Convert cmp to cmpd in idle enter sequence (Segher Boessenkool) - cxl: Fix leaking pid refs in some error paths (Vaibhav Jain) - Re-fix race condition between going idle and entering guest (Paul Mackerras) - Fix race condition in setting lock bit in idle/wakeup code (Paul Mackerras) - radix: Use tlbiel only if we ever ran on the current cpu (Aneesh Kumar K.V) - relocation, register save fixes for system reset interrupt (Nicholas Piggin) Fixes for code merged this cycle: - Fix CONFIG_ALIVEC typo in restore_tm_state() (Valentin Rothberg) - KVM: PPC: Book3S HV: Fix build error when SMP=n (Michael Ellerman)" * tag 'powerpc-4.9-4' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: powerpc/64s: relocation, register save fixes for system reset interrupt powerpc/mm/radix: Use tlbiel only if we ever ran on the current cpu powerpc/process: Fix CONFIG_ALIVEC typo in restore_tm_state() powerpc/64: Fix race condition in setting lock bit in idle/wakeup code powerpc/64: Re-fix race condition between going idle and entering guest cxl: Fix leaking pid refs in some error paths powerpc: Convert cmp to cmpd in idle enter sequence KVM: PPC: Book3S HV: Fix build error when SMP=n
2 parents b49c317 + fb479e4 commit 6fcc8ce

File tree

10 files changed

+108
-42
lines changed

10 files changed

+108
-42
lines changed

arch/powerpc/include/asm/cpuidle.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ extern u64 pnv_first_deep_stop_state;
2626
std r0,0(r1); \
2727
ptesync; \
2828
ld r0,0(r1); \
29-
1: cmp cr0,r0,r0; \
29+
1: cmpd cr0,r0,r0; \
3030
bne 1b; \
3131
IDLE_INST; \
3232
b .

arch/powerpc/include/asm/exception-64s.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@
9393
ld reg,PACAKBASE(r13); /* get high part of &label */ \
9494
ori reg,reg,(FIXED_SYMBOL_ABS_ADDR(label))@l;
9595

96+
#define __LOAD_HANDLER(reg, label) \
97+
ld reg,PACAKBASE(r13); \
98+
ori reg,reg,(ABS_ADDR(label))@l;
99+
96100
/* Exception register prefixes */
97101
#define EXC_HV H
98102
#define EXC_STD
@@ -208,6 +212,18 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
208212
#define kvmppc_interrupt kvmppc_interrupt_pr
209213
#endif
210214

215+
#ifdef CONFIG_RELOCATABLE
216+
#define BRANCH_TO_COMMON(reg, label) \
217+
__LOAD_HANDLER(reg, label); \
218+
mtctr reg; \
219+
bctr
220+
221+
#else
222+
#define BRANCH_TO_COMMON(reg, label) \
223+
b label
224+
225+
#endif
226+
211227
#define __KVM_HANDLER_PROLOG(area, n) \
212228
BEGIN_FTR_SECTION_NESTED(947) \
213229
ld r10,area+EX_CFAR(r13); \

arch/powerpc/include/asm/tlb.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,23 @@ static inline int mm_is_core_local(struct mm_struct *mm)
5252
return cpumask_subset(mm_cpumask(mm),
5353
topology_sibling_cpumask(smp_processor_id()));
5454
}
55+
56+
static inline int mm_is_thread_local(struct mm_struct *mm)
57+
{
58+
return cpumask_equal(mm_cpumask(mm),
59+
cpumask_of(smp_processor_id()));
60+
}
61+
5562
#else
5663
static inline int mm_is_core_local(struct mm_struct *mm)
5764
{
5865
return 1;
5966
}
67+
68+
static inline int mm_is_thread_local(struct mm_struct *mm)
69+
{
70+
return 1;
71+
}
6072
#endif
6173

6274
#endif /* __KERNEL__ */

arch/powerpc/kernel/exceptions-64s.S

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -95,19 +95,35 @@ __start_interrupts:
9595
/* No virt vectors corresponding with 0x0..0x100 */
9696
EXC_VIRT_NONE(0x4000, 0x4100)
9797

98-
EXC_REAL_BEGIN(system_reset, 0x100, 0x200)
99-
SET_SCRATCH0(r13)
98+
10099
#ifdef CONFIG_PPC_P7_NAP
101-
BEGIN_FTR_SECTION
102-
/* Running native on arch 2.06 or later, check if we are
103-
* waking up from nap/sleep/winkle.
100+
/*
101+
* If running native on arch 2.06 or later, check if we are waking up
102+
* from nap/sleep/winkle, and branch to idle handler.
104103
*/
105-
mfspr r13,SPRN_SRR1
106-
rlwinm. r13,r13,47-31,30,31
107-
beq 9f
104+
#define IDLETEST(n) \
105+
BEGIN_FTR_SECTION ; \
106+
mfspr r10,SPRN_SRR1 ; \
107+
rlwinm. r10,r10,47-31,30,31 ; \
108+
beq- 1f ; \
109+
cmpwi cr3,r10,2 ; \
110+
BRANCH_TO_COMMON(r10, system_reset_idle_common) ; \
111+
1: \
112+
END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
113+
#else
114+
#define IDLETEST NOTEST
115+
#endif
108116

109-
cmpwi cr3,r13,2
110-
GET_PACA(r13)
117+
EXC_REAL_BEGIN(system_reset, 0x100, 0x200)
118+
SET_SCRATCH0(r13)
119+
EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common, EXC_STD,
120+
IDLETEST, 0x100)
121+
122+
EXC_REAL_END(system_reset, 0x100, 0x200)
123+
EXC_VIRT_NONE(0x4100, 0x4200)
124+
125+
#ifdef CONFIG_PPC_P7_NAP
126+
EXC_COMMON_BEGIN(system_reset_idle_common)
111127
bl pnv_restore_hyp_resource
112128

113129
li r0,PNV_THREAD_RUNNING
@@ -130,14 +146,8 @@ BEGIN_FTR_SECTION
130146
blt cr3,2f
131147
b pnv_wakeup_loss
132148
2: b pnv_wakeup_noloss
149+
#endif
133150

134-
9:
135-
END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
136-
#endif /* CONFIG_PPC_P7_NAP */
137-
EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common, EXC_STD,
138-
NOTEST, 0x100)
139-
EXC_REAL_END(system_reset, 0x100, 0x200)
140-
EXC_VIRT_NONE(0x4100, 0x4200)
141151
EXC_COMMON(system_reset_common, 0x100, system_reset_exception)
142152

143153
#ifdef CONFIG_PPC_PSERIES
@@ -817,10 +827,8 @@ EXC_VIRT(trap_0b, 0x4b00, 0x4c00, 0xb00)
817827
TRAMP_KVM(PACA_EXGEN, 0xb00)
818828
EXC_COMMON(trap_0b_common, 0xb00, unknown_exception)
819829

820-
821-
#define LOAD_SYSCALL_HANDLER(reg) \
822-
ld reg,PACAKBASE(r13); \
823-
ori reg,reg,(ABS_ADDR(system_call_common))@l;
830+
#define LOAD_SYSCALL_HANDLER(reg) \
831+
__LOAD_HANDLER(reg, system_call_common)
824832

825833
/* Syscall routine is used twice, in reloc-off and reloc-on paths */
826834
#define SYSCALL_PSERIES_1 \

arch/powerpc/kernel/idle_book3s.S

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_ARCH_300)
9090
* Threads will spin in HMT_LOW until the lock bit is cleared.
9191
* r14 - pointer to core_idle_state
9292
* r15 - used to load contents of core_idle_state
93+
* r9 - used as a temporary variable
9394
*/
9495

9596
core_idle_lock_held:
@@ -99,6 +100,8 @@ core_idle_lock_held:
99100
bne 3b
100101
HMT_MEDIUM
101102
lwarx r15,0,r14
103+
andi. r9,r15,PNV_CORE_IDLE_LOCK_BIT
104+
bne core_idle_lock_held
102105
blr
103106

104107
/*
@@ -163,12 +166,6 @@ _GLOBAL(pnv_powersave_common)
163166
std r9,_MSR(r1)
164167
std r1,PACAR1(r13)
165168

166-
#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
167-
/* Tell KVM we're entering idle */
168-
li r4,KVM_HWTHREAD_IN_IDLE
169-
stb r4,HSTATE_HWTHREAD_STATE(r13)
170-
#endif
171-
172169
/*
173170
* Go to real mode to do the nap, as required by the architecture.
174171
* Also, we need to be in real mode before setting hwthread_state,
@@ -185,6 +182,26 @@ _GLOBAL(pnv_powersave_common)
185182

186183
.globl pnv_enter_arch207_idle_mode
187184
pnv_enter_arch207_idle_mode:
185+
#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
186+
/* Tell KVM we're entering idle */
187+
li r4,KVM_HWTHREAD_IN_IDLE
188+
/******************************************************/
189+
/* N O T E W E L L ! ! ! N O T E W E L L */
190+
/* The following store to HSTATE_HWTHREAD_STATE(r13) */
191+
/* MUST occur in real mode, i.e. with the MMU off, */
192+
/* and the MMU must stay off until we clear this flag */
193+
/* and test HSTATE_HWTHREAD_REQ(r13) in the system */
194+
/* reset interrupt vector in exceptions-64s.S. */
195+
/* The reason is that another thread can switch the */
196+
/* MMU to a guest context whenever this flag is set */
197+
/* to KVM_HWTHREAD_IN_IDLE, and if the MMU was on, */
198+
/* that would potentially cause this thread to start */
199+
/* executing instructions from guest memory in */
200+
/* hypervisor mode, leading to a host crash or data */
201+
/* corruption, or worse. */
202+
/******************************************************/
203+
stb r4,HSTATE_HWTHREAD_STATE(r13)
204+
#endif
188205
stb r3,PACA_THREAD_IDLE_STATE(r13)
189206
cmpwi cr3,r3,PNV_THREAD_SLEEP
190207
bge cr3,2f
@@ -250,6 +267,12 @@ enter_winkle:
250267
* r3 - requested stop state
251268
*/
252269
power_enter_stop:
270+
#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
271+
/* Tell KVM we're entering idle */
272+
li r4,KVM_HWTHREAD_IN_IDLE
273+
/* DO THIS IN REAL MODE! See comment above. */
274+
stb r4,HSTATE_HWTHREAD_STATE(r13)
275+
#endif
253276
/*
254277
* Check if the requested state is a deep idle state.
255278
*/

arch/powerpc/kernel/process.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1012,7 +1012,7 @@ void restore_tm_state(struct pt_regs *regs)
10121012
/* Ensure that restore_math() will restore */
10131013
if (msr_diff & MSR_FP)
10141014
current->thread.load_fp = 1;
1015-
#ifdef CONFIG_ALIVEC
1015+
#ifdef CONFIG_ALTIVEC
10161016
if (cpu_has_feature(CPU_FTR_ALTIVEC) && msr_diff & MSR_VEC)
10171017
current->thread.load_vec = 1;
10181018
#endif

arch/powerpc/kvm/book3s_hv_rm_xics.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <asm/ppc-opcode.h>
2424
#include <asm/pnv-pci.h>
2525
#include <asm/opal.h>
26+
#include <asm/smp.h>
2627

2728
#include "book3s_xics.h"
2829

arch/powerpc/mm/tlb-radix.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ void radix__flush_tlb_mm(struct mm_struct *mm)
175175
if (unlikely(pid == MMU_NO_CONTEXT))
176176
goto no_context;
177177

178-
if (!mm_is_core_local(mm)) {
178+
if (!mm_is_thread_local(mm)) {
179179
int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
180180

181181
if (lock_tlbie)
@@ -201,7 +201,7 @@ void radix__flush_tlb_pwc(struct mmu_gather *tlb, unsigned long addr)
201201
if (unlikely(pid == MMU_NO_CONTEXT))
202202
goto no_context;
203203

204-
if (!mm_is_core_local(mm)) {
204+
if (!mm_is_thread_local(mm)) {
205205
int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
206206

207207
if (lock_tlbie)
@@ -226,7 +226,7 @@ void radix__flush_tlb_page_psize(struct mm_struct *mm, unsigned long vmaddr,
226226
pid = mm ? mm->context.id : 0;
227227
if (unlikely(pid == MMU_NO_CONTEXT))
228228
goto bail;
229-
if (!mm_is_core_local(mm)) {
229+
if (!mm_is_thread_local(mm)) {
230230
int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
231231

232232
if (lock_tlbie)
@@ -321,7 +321,7 @@ void radix__flush_tlb_range_psize(struct mm_struct *mm, unsigned long start,
321321
{
322322
unsigned long pid;
323323
unsigned long addr;
324-
int local = mm_is_core_local(mm);
324+
int local = mm_is_thread_local(mm);
325325
unsigned long ap = mmu_get_ap(psize);
326326
int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
327327
unsigned long page_size = 1UL << mmu_psize_defs[psize].shift;

drivers/misc/cxl/api.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,9 @@ int cxl_start_context(struct cxl_context *ctx, u64 wed,
247247
cxl_ctx_get();
248248

249249
if ((rc = cxl_ops->attach_process(ctx, kernel, wed, 0))) {
250+
put_pid(ctx->glpid);
250251
put_pid(ctx->pid);
252+
ctx->glpid = ctx->pid = NULL;
251253
cxl_adapter_context_put(ctx->afu->adapter);
252254
cxl_ctx_put();
253255
goto out;

drivers/misc/cxl/file.c

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,16 @@ static long afu_ioctl_start_work(struct cxl_context *ctx,
193193

194194
ctx->mmio_err_ff = !!(work.flags & CXL_START_WORK_ERR_FF);
195195

196+
/*
197+
* Increment the mapped context count for adapter. This also checks
198+
* if adapter_context_lock is taken.
199+
*/
200+
rc = cxl_adapter_context_get(ctx->afu->adapter);
201+
if (rc) {
202+
afu_release_irqs(ctx, ctx);
203+
goto out;
204+
}
205+
196206
/*
197207
* We grab the PID here and not in the file open to allow for the case
198208
* where a process (master, some daemon, etc) has opened the chardev on
@@ -205,22 +215,16 @@ static long afu_ioctl_start_work(struct cxl_context *ctx,
205215
ctx->pid = get_task_pid(current, PIDTYPE_PID);
206216
ctx->glpid = get_task_pid(current->group_leader, PIDTYPE_PID);
207217

208-
/*
209-
* Increment the mapped context count for adapter. This also checks
210-
* if adapter_context_lock is taken.
211-
*/
212-
rc = cxl_adapter_context_get(ctx->afu->adapter);
213-
if (rc) {
214-
afu_release_irqs(ctx, ctx);
215-
goto out;
216-
}
217218

218219
trace_cxl_attach(ctx, work.work_element_descriptor, work.num_interrupts, amr);
219220

220221
if ((rc = cxl_ops->attach_process(ctx, false, work.work_element_descriptor,
221222
amr))) {
222223
afu_release_irqs(ctx, ctx);
223224
cxl_adapter_context_put(ctx->afu->adapter);
225+
put_pid(ctx->glpid);
226+
put_pid(ctx->pid);
227+
ctx->glpid = ctx->pid = NULL;
224228
goto out;
225229
}
226230

0 commit comments

Comments
 (0)