Skip to content

Commit

Permalink
Merge tag 'powerpc-4.15-5' of git://git.kernel.org/pub/scm/linux/kern…
Browse files Browse the repository at this point in the history
…el/git/powerpc/linux

Pull powerpc fixes from Michael Ellerman:
 "This is all fairly boring, except that there's two KVM fixes that
  you'd normally get via Paul's kvm-ppc tree. He's away so I picked them
  up. I was waiting to see if he would apply them, which is why they
  have only been in my tree since today. But they were on the list for a
  while and have been tested on the relevant hardware.

  Of note is two fixes for KVM XIVE (Power9 interrupt controller). These
  would normally go via the KVM tree but Paul is away so I've picked
  them up.

  Other than that, two fixes for error handling in the IMC driver, and
  one for a potential oops in the BHRB code if the hardware records a
  branch address that has subsequently been unmapped, and finally a
  s/%p/%px/ in our oops code.

  Thanks to: Anju T Sudhakar, Cédric Le Goater, Laurent Vivier, Madhavan
  Srinivasan, Naveen N. Rao, Ravi Bangoria"

* tag 'powerpc-4.15-5' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux:
  KVM: PPC: Book3S HV: Fix pending_pri value in kvmppc_xive_get_icp()
  KVM: PPC: Book3S: fix XIVE migration of pending interrupts
  powerpc/kernel: Print actual address of regs when oopsing
  powerpc/perf: Fix kfree memory allocated for nest pmus
  powerpc/perf/imc: Fix nest-imc cpuhotplug callback failure
  powerpc/perf: Dereference BHRB entries safely
  • Loading branch information
Linus Torvalds committed Dec 22, 2017
2 parents 9ad95bd + 7333b5a commit 9c294ec
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 7 deletions.
2 changes: 1 addition & 1 deletion arch/powerpc/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -1403,7 +1403,7 @@ void show_regs(struct pt_regs * regs)

printk("NIP: "REG" LR: "REG" CTR: "REG"\n",
regs->nip, regs->link, regs->ctr);
printk("REGS: %p TRAP: %04lx %s (%s)\n",
printk("REGS: %px TRAP: %04lx %s (%s)\n",
regs, regs->trap, print_tainted(), init_utsname()->release);
printk("MSR: "REG" ", regs->msr);
print_msr_bits(regs->msr);
Expand Down
7 changes: 4 additions & 3 deletions arch/powerpc/kvm/book3s_xive.c
Original file line number Diff line number Diff line change
Expand Up @@ -725,7 +725,8 @@ u64 kvmppc_xive_get_icp(struct kvm_vcpu *vcpu)

/* Return the per-cpu state for state saving/migration */
return (u64)xc->cppr << KVM_REG_PPC_ICP_CPPR_SHIFT |
(u64)xc->mfrr << KVM_REG_PPC_ICP_MFRR_SHIFT;
(u64)xc->mfrr << KVM_REG_PPC_ICP_MFRR_SHIFT |
(u64)0xff << KVM_REG_PPC_ICP_PPRI_SHIFT;
}

int kvmppc_xive_set_icp(struct kvm_vcpu *vcpu, u64 icpval)
Expand Down Expand Up @@ -1558,15 +1559,15 @@ static int xive_set_source(struct kvmppc_xive *xive, long irq, u64 addr)

/*
* Restore P and Q. If the interrupt was pending, we
* force both P and Q, which will trigger a resend.
* force Q and !P, which will trigger a resend.
*
* That means that a guest that had both an interrupt
* pending (queued) and Q set will restore with only
* one instance of that interrupt instead of 2, but that
* is perfectly fine as coalescing interrupts that haven't
* been presented yet is always allowed.
*/
if (val & KVM_XICS_PRESENTED || val & KVM_XICS_PENDING)
if (val & KVM_XICS_PRESENTED && !(val & KVM_XICS_PENDING))
state->old_p = true;
if (val & KVM_XICS_QUEUED || val & KVM_XICS_PENDING)
state->old_q = true;
Expand Down
8 changes: 6 additions & 2 deletions arch/powerpc/perf/core-book3s.c
Original file line number Diff line number Diff line change
Expand Up @@ -410,8 +410,12 @@ static __u64 power_pmu_bhrb_to(u64 addr)
int ret;
__u64 target;

if (is_kernel_addr(addr))
return branch_target((unsigned int *)addr);
if (is_kernel_addr(addr)) {
if (probe_kernel_read(&instr, (void *)addr, sizeof(instr)))
return 0;

return branch_target(&instr);
}

/* Userspace: need copy instruction here then translate it */
pagefault_disable();
Expand Down
17 changes: 16 additions & 1 deletion arch/powerpc/perf/imc-pmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,19 @@ static int ppc_nest_imc_cpu_offline(unsigned int cpu)
if (!cpumask_test_and_clear_cpu(cpu, &nest_imc_cpumask))
return 0;

/*
* Check whether nest_imc is registered. We could end up here if the
* cpuhotplug callback registration fails. i.e, callback invokes the
* offline path for all successfully registered nodes. At this stage,
* nest_imc pmu will not be registered and we should return here.
*
* We return with a zero since this is not an offline failure. And
* cpuhp_setup_state() returns the actual failure reason to the caller,
* which in turn will call the cleanup routine.
*/
if (!nest_pmus)
return 0;

/*
* Now that this cpu is one of the designated,
* find a next cpu a) which is online and b) in same chip.
Expand Down Expand Up @@ -1171,6 +1184,7 @@ static void imc_common_cpuhp_mem_free(struct imc_pmu *pmu_ptr)
if (nest_pmus == 1) {
cpuhp_remove_state(CPUHP_AP_PERF_POWERPC_NEST_IMC_ONLINE);
kfree(nest_imc_refc);
kfree(per_nest_pmu_arr);
}

if (nest_pmus > 0)
Expand All @@ -1195,7 +1209,6 @@ static void imc_common_cpuhp_mem_free(struct imc_pmu *pmu_ptr)
kfree(pmu_ptr->attr_groups[IMC_EVENT_ATTR]->attrs);
kfree(pmu_ptr->attr_groups[IMC_EVENT_ATTR]);
kfree(pmu_ptr);
kfree(per_nest_pmu_arr);
return;
}

Expand Down Expand Up @@ -1309,6 +1322,8 @@ int init_imc_pmu(struct device_node *parent, struct imc_pmu *pmu_ptr, int pmu_id
ret = nest_pmu_cpumask_init();
if (ret) {
mutex_unlock(&nest_init_lock);
kfree(nest_imc_refc);
kfree(per_nest_pmu_arr);
goto err_free;
}
}
Expand Down

0 comments on commit 9c294ec

Please sign in to comment.