LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: Freeze on ppc32 MPC8248 board with 5.2 kernel
From: Christophe Leroy @ 2019-08-13  4:41 UTC (permalink / raw)
  To: Doug Crawford, linuxppc-dev
In-Reply-To: <CAESxVDiyXu+=6+YmLej3K=i55h3=Z9JLA8JgrDn3fEQGUuSq7Q@mail.gmail.com>

Hi Doug,

Le 26/07/2019 à 00:30, Doug Crawford a écrit :
> We have a ppc32 MPC8248 board that is working perfectly with the 4.19 
> kernel.
> We have noticed two issues with the 5.2 kernel:

  Have you tried 5.0 and 5.1 ?

> 
> 1) If the new CONFIG_PPC_KUAP (kernel userspace access protection) is 
> enabled the kernel freezes right after initializing all the drivers and 
> just before starting /sbin/init.

Can you provide your .config ?

Can you also provide the output of the boot console ?

> 
> 2) If CONFIG_PPC_KUAP is disabled the system starts up, but any user 
> space program will hang indefinitely after calling the GCC atomic 
> "__sync_bool_compare_and_swap".  This happens when nginx starts.  The 
> same nginx binary works fine on a 4.19 kernel.

Can you provide 'dmesg' ?

What version of GCC do you use ?

Have you tried a simple program doing nothing else than 
__sync_bool_compare_and_swap() ?

Can you provide a disassembly of the function that uses 
__sync_bool_compare_and_swap() ?

Thanks
Christophe

^ permalink raw reply

* Re: [PATCH v9 1/7] powerpc/mce: Schedule work from irq_work
From: Mahesh Jagannath Salgaonkar @ 2019-08-13  4:46 UTC (permalink / raw)
  To: Santosh Sivaraj, linuxppc-dev, Linux Kernel
  Cc: Aneesh Kumar K.V, Mahesh Salgaonkar, Nicholas Piggin,
	Chandan Rajendra, stable, Reza Arbab
In-Reply-To: <20190812092236.16648-2-santosh@fossix.org>

On 8/12/19 2:52 PM, Santosh Sivaraj wrote:
> schedule_work() cannot be called from MCE exception context as MCE can
> interrupt even in interrupt disabled context.
> 
> fixes: 733e4a4c ("powerpc/mce: hookup memory_failure for UE errors")
> Suggested-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
> Signed-off-by: Santosh Sivaraj <santosh@fossix.org>
> Cc: stable@vger.kernel.org # v4.15+
> ---
>  arch/powerpc/kernel/mce.c | 11 ++++++++++-
>  1 file changed, 10 insertions(+), 1 deletion(-)

Reviewed-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>

Thanks,
-Mahesh.

> 
> diff --git a/arch/powerpc/kernel/mce.c b/arch/powerpc/kernel/mce.c
> index b18df633eae9..cff31d4a501f 100644
> --- a/arch/powerpc/kernel/mce.c
> +++ b/arch/powerpc/kernel/mce.c
> @@ -33,6 +33,7 @@ static DEFINE_PER_CPU(struct machine_check_event[MAX_MC_EVT],
>  					mce_ue_event_queue);
>  
>  static void machine_check_process_queued_event(struct irq_work *work);
> +static void machine_check_ue_irq_work(struct irq_work *work);
>  void machine_check_ue_event(struct machine_check_event *evt);
>  static void machine_process_ue_event(struct work_struct *work);
>  
> @@ -40,6 +41,10 @@ static struct irq_work mce_event_process_work = {
>          .func = machine_check_process_queued_event,
>  };
>  
> +static struct irq_work mce_ue_event_irq_work = {
> +	.func = machine_check_ue_irq_work,
> +};
> +
>  DECLARE_WORK(mce_ue_event_work, machine_process_ue_event);
>  
>  static void mce_set_error_info(struct machine_check_event *mce,
> @@ -199,6 +204,10 @@ void release_mce_event(void)
>  	get_mce_event(NULL, true);
>  }
>  
> +static void machine_check_ue_irq_work(struct irq_work *work)
> +{
> +	schedule_work(&mce_ue_event_work);
> +}
>  
>  /*
>   * Queue up the MCE event which then can be handled later.
> @@ -216,7 +225,7 @@ void machine_check_ue_event(struct machine_check_event *evt)
>  	memcpy(this_cpu_ptr(&mce_ue_event_queue[index]), evt, sizeof(*evt));
>  
>  	/* Queue work to process this event later. */
> -	schedule_work(&mce_ue_event_work);
> +	irq_work_queue(&mce_ue_event_irq_work);
>  }
>  
>  /*
> 


^ permalink raw reply

* Re: [PATCHv4 1/2] PCI: layerscape: Add the bar_fixed_64bit property in EP driver.
From: Kishon Vijay Abraham I @ 2019-08-13  4:36 UTC (permalink / raw)
  To: Xiaowei Bao, lorenzo.pieralisi, bhelgaas, minghuan.Lian,
	mingkai.hu, roy.zang, l.stach, tpiepho, leonard.crestez,
	andrew.smirnov, yue.wang, hayashi.kunihiko, dwmw, jonnyc,
	linux-pci, linux-kernel, linuxppc-dev, linux-arm-kernel
In-Reply-To: <20190813025317.48290-1-xiaowei.bao@nxp.com>



On 13/08/19 8:23 AM, Xiaowei Bao wrote:
> The PCIe controller of layerscape just have 4 BARs, BAR0 and BAR1
> is 32bit, BAR3 and BAR4 is 64bit, this is determined by hardware,

Do you mean BAR2 instead of BAR3 here?

Thanks
Kishon

> so set the bar_fixed_64bit with 0x14.
> 
> Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
> ---
> v2:
>  - Replace value 0x14 with a macro.
> v3:
>  - No change.
> v4:
>  - send the patch again with '--to'.
> 
>  drivers/pci/controller/dwc/pci-layerscape-ep.c |    1 +
>  1 files changed, 1 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> index be61d96..227c33b 100644
> --- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
> +++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> @@ -44,6 +44,7 @@ static int ls_pcie_establish_link(struct dw_pcie *pci)
>  	.linkup_notifier = false,
>  	.msi_capable = true,
>  	.msix_capable = false,
> +	.bar_fixed_64bit = (1 << BAR_2) | (1 << BAR_4),
>  };
>  
>  static const struct pci_epc_features*
> 

^ permalink raw reply

* Re: [PATCH 2/2] powerpc/xive: Implement get_irqchip_state method for XIVE to fix shutdown race
From: Paul Mackerras @ 2019-08-13  4:56 UTC (permalink / raw)
  To: Lijun Pan; +Cc: linuxppc-dev, kvm-ppc, kvm, David Gibson
In-Reply-To: <E547965E-CC31-470F-8849-0F2A899A121F@linux.vnet.ibm.com>

On Mon, Aug 12, 2019 at 10:52:11PM -0500, Lijun Pan wrote:
> 
> 
> > On Aug 12, 2019, at 12:07 AM, Paul Mackerras <paulus@ozlabs.org> wrote:

[snip]

> > +static void cleanup_single_escalation(struct kvm_vcpu *vcpu,
> > +				      struct kvmppc_xive_vcpu *xc, int irq)
> > +{
> > +	struct irq_data *d = irq_get_irq_data(irq);
> > +	struct xive_irq_data *xd = irq_data_get_irq_handler_data(d);
> > +
> > +	/*
> > +	 * This slightly odd sequence gives the right result
> > +	 * (i.e. stale_p set if xive_esc_on is false) even if
> > +	 * we race with xive_esc_irq() and xive_irq_eoi().
> > +	 */
> 
> Hi Paul,
> 
> I don’t quite understand the logic here.
> Are you saying the code sequence is
> vcpu->arch.xive_esc_on = false; (xive_esc_irq)
> then
> xd->stale_p = true; (cleanup_single_escaltion)
> 
> > +	xd->stale_p = false;
> > +	smp_mb();		/* paired with smb_wmb in xive_esc_irq */
> > +	if (!vcpu->arch.xive_esc_on)
> > +		xd->stale_p = true;

The natural sequence would be just
	xd->stale_p = !vcpu->arch.xive_esc_on;

However, imagine that vcpu->arch.xive_esc_on is true, and the
escalation interrupt gets handled on another CPU between the load of
vcpu->arch.xive_esc_on and the store to xd->stale_p.  The interrupt
code calls xive_esc_irq(), which clears vcpu->arch.xive_esc_on, and
then xive_irq_eoi(), which sets xd->stale_p.  The natural sequence
could read vcpu->arch.xive_esc_on before the interrupt and see 1, then
write 0 to xd->stale_p after xive_irq_eoi() has set it.  That would
mean the final value of xd->stale_p was 0, which is wrong, since in
fact the queue entry has been removed.

With the code I wrote, because the clearing of xd->stale_p comes
before the load from vcpu->arch.xive_esc_on (with a barrier to make
sure they don't get reordered), then if a racing escalation interrupt
on another CPU stores 1 to xd->stale_p before we clear it, then we
must see vcpu->arch.xive_esc_on as 0, and we will set xd->stale_p
again, giving the correct final state (xd->stale_p == 1).  If the
racing interrupt clears vcpu->arch.xive_esc_on after we load it and
see 1, then its store to set xd->stale_p must come after our store to
clear it because of the barrier that I added to xive_esc_irq, so the
final result is once again correct.

[snip]

> > @@ -397,11 +411,16 @@ static void xive_do_source_set_mask(struct xive_irq_data *xd,
> > 	 */
> > 	if (mask) {
> > 		val = xive_esb_read(xd, XIVE_ESB_SET_PQ_01);
> > -		xd->saved_p = !!(val & XIVE_ESB_VAL_P);
> > -	} else if (xd->saved_p)
> > +		if (!xd->stale_p && !!(val & XIVE_ESB_VAL_P))
> > +			xd->saved_p = true;
> > +		xd->stale_p = false;
> > +	} else if (xd->saved_p) {
> > 		xive_esb_read(xd, XIVE_ESB_SET_PQ_10);
> > -	else
> > +		xd->saved_p = false;
> 
> Should we also explicitly set xd->stale_p = true; here?

We don't need to because xd->saved_p and xd->stale_p can never be both
set, and we just saw that xd->saved_p was set.

> > +	} else {
> > 		xive_esb_read(xd, XIVE_ESB_SET_PQ_00);
> > +		xd->stale_p = false;
> 
> Should we also explicitly set xd->saved_p = true; here?

No, that would be incorrect.  This is the case where we are unmasking
the interrupt and there is no queue entry currently.  Setting saved_p
would imply that there is a queue entry, which there isn't.

Paul.

^ permalink raw reply

* Re: [PATCH 1/2] KVM: PPC: Book3S HV: Fix race in re-enabling XIVE escalation interrupts
From: Paul Mackerras @ 2019-08-13  4:59 UTC (permalink / raw)
  To: linuxppc-dev, kvm; +Cc: kvm-ppc, David Gibson
In-Reply-To: <20190812050705.mlszjkatxa635pzh@oak.ozlabs.ibm.com>

On Mon, Aug 12, 2019 at 03:07:05PM +1000, Paul Mackerras wrote:

>  	lbz	r5, VCPU_XIVE_ESC_ON(r9)
>  	cmpwi	r5, 0
> -	beq	1f
> +	beq	4f
>  	li	r0, 0
>  	stb	r0, VCPU_CEDED(r9)
> +	li	r6, XIVE_ESB_SET_PQ_10
> +	b	1f
> +4:	li	r0, 1
> +	stb	r0, VCPU_XIVE_ESC_ON(r9)

This ends up setting vcpu->arch.xive_esc_on even on platforms without
XIVE, which is wrong.  I'll send a v2.

Paul.

^ permalink raw reply

* [PATCH] powerpc: Remove empty comment
From: Jordan Niethe @ 2019-08-13  5:12 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Jordan Niethe

Commit 2874c5fd2842 ("treewide: Replace GPLv2 boilerplate/reference with
SPDX - rule 152") left an empty comment in machdep.h, as the boilerplate
was the only text in the comment. Remove the empty comment.

Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
 arch/powerpc/include/asm/machdep.h | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
index c43d6eca9edd..ab6c94c650e7 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -3,9 +3,6 @@
 #define _ASM_POWERPC_MACHDEP_H
 #ifdef __KERNEL__
 
-/*
- */
-
 #include <linux/seq_file.h>
 #include <linux/init.h>
 #include <linux/dma-mapping.h>
-- 
2.20.1


^ permalink raw reply related

* Re: [PATCH v4 07/25] pseries/fadump: move out platform specific support from generic code
From: Mahesh J Salgaonkar @ 2019-08-13  5:16 UTC (permalink / raw)
  To: Hari Bathini
  Cc: Ananth N Mavinakayanahalli, Mahesh J Salgaonkar, Nicholas Piggin,
	linuxppc-dev, Oliver, Vasant Hegde, Stewart Smith, Daniel Axtens
In-Reply-To: <156327676575.27462.15697361502635226365.stgit@hbathini.in.ibm.com>

On 2019-07-16 17:02:45 Tue, Hari Bathini wrote:
> Move code that supports processing the crash'ed kernel's memory
> preserved by firmware to platform specific callback functions.
> 
> Signed-off-by: Hari Bathini <hbathini@linux.ibm.com>
> ---
>  arch/powerpc/kernel/fadump-common.h          |    6 
>  arch/powerpc/kernel/fadump.c                 |  340 +-------------------------
>  arch/powerpc/platforms/pseries/rtas-fadump.c |  278 +++++++++++++++++++++
>  3 files changed, 299 insertions(+), 325 deletions(-)
> 

Reviewed-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>

Thanks,
-Mahesh.

> diff --git a/arch/powerpc/kernel/fadump-common.h b/arch/powerpc/kernel/fadump-common.h
> index 273247d..0231a0b 100644
> --- a/arch/powerpc/kernel/fadump-common.h
> +++ b/arch/powerpc/kernel/fadump-common.h
> @@ -100,6 +100,12 @@ struct fw_dump {
>  	/* cmd line option during boot */
>  	unsigned long	reserve_bootvar;
>  
> +	/*
> +	 * Start address of preserve area. This memory is reserved
> +	 * permanently (production or capture kernel) for FADump.
> +	 */
> +	unsigned long	preserv_area_start;
> +
>  	unsigned long	cpu_state_data_size;
>  	unsigned long	hpte_region_size;
>  	unsigned long	boot_memory_size;
> diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c
> index 650ebf8..e995db1 100644
> --- a/arch/powerpc/kernel/fadump.c
> +++ b/arch/powerpc/kernel/fadump.c
> @@ -28,15 +28,12 @@
>  #include <asm/debugfs.h>
>  #include <asm/page.h>
>  #include <asm/prom.h>
> -#include <asm/rtas.h>
>  #include <asm/fadump.h>
>  #include <asm/setup.h>
>  
>  #include "fadump-common.h"
> -#include "../platforms/pseries/rtas-fadump.h"
>  
>  static struct fw_dump fw_dump;
> -static const struct rtas_fadump_mem_struct *fdm_active;
>  
>  static DEFINE_MUTEX(fadump_mutex);
>  struct fad_crash_memory_ranges *crash_memory_ranges;
> @@ -111,22 +108,13 @@ static int __init fadump_cma_init(void) { return 1; }
>  int __init early_init_dt_scan_fw_dump(unsigned long node, const char *uname,
>  				      int depth, void *data)
>  {
> -	int ret;
> -
> -	if (depth != 1 || strcmp(uname, "rtas") != 0)
> +	if (depth != 1)
>  		return 0;
>  
> -	ret = rtas_fadump_dt_scan(&fw_dump, node);
> +	if (strcmp(uname, "rtas") == 0)
> +		return rtas_fadump_dt_scan(&fw_dump, node);
>  
> -	/*
> -	 * The 'ibm,kernel-dump' rtas node is present only if there is
> -	 * dump data waiting for us.
> -	 */
> -	fdm_active = of_get_flat_dt_prop(node, "ibm,kernel-dump", NULL);
> -	if (fdm_active)
> -		fw_dump.dump_active = 1;
> -
> -	return ret;
> +	return 0;
>  }
>  
>  /*
> @@ -308,9 +296,7 @@ int __init fadump_reserve_mem(void)
>  	 * If dump is active then we have already calculated the size during
>  	 * first kernel.
>  	 */
> -	if (fdm_active)
> -		fw_dump.boot_memory_size = be64_to_cpu(fdm_active->rmr_region.source_len);
> -	else {
> +	if (!fw_dump.dump_active) {
>  		fw_dump.boot_memory_size = fadump_calculate_reserve_size();
>  #ifdef CONFIG_CMA
>  		if (!fw_dump.nocma)
> @@ -320,6 +306,7 @@ int __init fadump_reserve_mem(void)
>  #endif
>  	}
>  
> +	size = get_fadump_area_size();
>  	if (memory_limit)
>  		memory_boundary = memory_limit;
>  	else
> @@ -346,15 +333,10 @@ int __init fadump_reserve_mem(void)
>  		size = memory_boundary - base;
>  		fadump_reserve_crash_area(base, size);
>  
> -		fw_dump.fadumphdr_addr =
> -				be64_to_cpu(fdm_active->rmr_region.destination_address) +
> -				be64_to_cpu(fdm_active->rmr_region.source_len);
> -		pr_debug("fadumphdr_addr = %pa\n", &fw_dump.fadumphdr_addr);
> +		pr_debug("fadumphdr_addr = %#016lx\n", fw_dump.fadumphdr_addr);
>  		fw_dump.reserve_dump_area_start = base;
>  		fw_dump.reserve_dump_area_size = size;
>  	} else {
> -		size = get_fadump_area_size();
> -
>  		/*
>  		 * Reserve memory at an offset closer to bottom of the RAM to
>  		 * minimize the impact of memory hot-remove operation. We can't
> @@ -469,218 +451,6 @@ void crash_fadump(struct pt_regs *regs, const char *str)
>  	fw_dump.ops->fadump_trigger(fdh, str);
>  }
>  
> -#define GPR_MASK	0xffffff0000000000
> -static inline int fadump_gpr_index(u64 id)
> -{
> -	int i = -1;
> -	char str[3];
> -
> -	if ((id & GPR_MASK) == fadump_str_to_u64("GPR")) {
> -		/* get the digits at the end */
> -		id &= ~GPR_MASK;
> -		id >>= 24;
> -		str[2] = '\0';
> -		str[1] = id & 0xff;
> -		str[0] = (id >> 8) & 0xff;
> -		sscanf(str, "%d", &i);
> -		if (i > 31)
> -			i = -1;
> -	}
> -	return i;
> -}
> -
> -static inline void fadump_set_regval(struct pt_regs *regs, u64 reg_id,
> -								u64 reg_val)
> -{
> -	int i;
> -
> -	i = fadump_gpr_index(reg_id);
> -	if (i >= 0)
> -		regs->gpr[i] = (unsigned long)reg_val;
> -	else if (reg_id == fadump_str_to_u64("NIA"))
> -		regs->nip = (unsigned long)reg_val;
> -	else if (reg_id == fadump_str_to_u64("MSR"))
> -		regs->msr = (unsigned long)reg_val;
> -	else if (reg_id == fadump_str_to_u64("CTR"))
> -		regs->ctr = (unsigned long)reg_val;
> -	else if (reg_id == fadump_str_to_u64("LR"))
> -		regs->link = (unsigned long)reg_val;
> -	else if (reg_id == fadump_str_to_u64("XER"))
> -		regs->xer = (unsigned long)reg_val;
> -	else if (reg_id == fadump_str_to_u64("CR"))
> -		regs->ccr = (unsigned long)reg_val;
> -	else if (reg_id == fadump_str_to_u64("DAR"))
> -		regs->dar = (unsigned long)reg_val;
> -	else if (reg_id == fadump_str_to_u64("DSISR"))
> -		regs->dsisr = (unsigned long)reg_val;
> -}
> -
> -static struct rtas_fadump_reg_entry*
> -fadump_read_registers(struct rtas_fadump_reg_entry *reg_entry, struct pt_regs *regs)
> -{
> -	memset(regs, 0, sizeof(struct pt_regs));
> -
> -	while (be64_to_cpu(reg_entry->reg_id) != fadump_str_to_u64("CPUEND")) {
> -		fadump_set_regval(regs, be64_to_cpu(reg_entry->reg_id),
> -					be64_to_cpu(reg_entry->reg_value));
> -		reg_entry++;
> -	}
> -	reg_entry++;
> -	return reg_entry;
> -}
> -
> -/*
> - * Read CPU state dump data and convert it into ELF notes.
> - * The CPU dump starts with magic number "REGSAVE". NumCpusOffset should be
> - * used to access the data to allow for additional fields to be added without
> - * affecting compatibility. Each list of registers for a CPU starts with
> - * "CPUSTRT" and ends with "CPUEND". Each register entry is of 16 bytes,
> - * 8 Byte ASCII identifier and 8 Byte register value. The register entry
> - * with identifier "CPUSTRT" and "CPUEND" contains 4 byte cpu id as part
> - * of register value. For more details refer to PAPR document.
> - *
> - * Only for the crashing cpu we ignore the CPU dump data and get exact
> - * state from fadump crash info structure populated by first kernel at the
> - * time of crash.
> - */
> -static int __init fadump_build_cpu_notes(const struct rtas_fadump_mem_struct *fdm)
> -{
> -	struct rtas_fadump_reg_save_area_header *reg_header;
> -	struct rtas_fadump_reg_entry *reg_entry;
> -	struct fadump_crash_info_header *fdh = NULL;
> -	void *vaddr;
> -	unsigned long addr;
> -	u32 num_cpus, *note_buf;
> -	struct pt_regs regs;
> -	int i, rc = 0, cpu = 0;
> -
> -	if (!fdm->cpu_state_data.bytes_dumped)
> -		return -EINVAL;
> -
> -	addr = be64_to_cpu(fdm->cpu_state_data.destination_address);
> -	vaddr = __va(addr);
> -
> -	reg_header = vaddr;
> -	if (be64_to_cpu(reg_header->magic_number) !=
> -	    fadump_str_to_u64("REGSAVE")) {
> -		printk(KERN_ERR "Unable to read register save area.\n");
> -		return -ENOENT;
> -	}
> -	pr_debug("--------CPU State Data------------\n");
> -	pr_debug("Magic Number: %llx\n", be64_to_cpu(reg_header->magic_number));
> -	pr_debug("NumCpuOffset: %x\n", be32_to_cpu(reg_header->num_cpu_offset));
> -
> -	vaddr += be32_to_cpu(reg_header->num_cpu_offset);
> -	num_cpus = be32_to_cpu(*((__be32 *)(vaddr)));
> -	pr_debug("NumCpus     : %u\n", num_cpus);
> -	vaddr += sizeof(u32);
> -	reg_entry = (struct rtas_fadump_reg_entry *)vaddr;
> -
> -	/* Allocate buffer to hold cpu crash notes. */
> -	fw_dump.cpu_notes_buf_size = num_cpus * sizeof(note_buf_t);
> -	fw_dump.cpu_notes_buf_size = PAGE_ALIGN(fw_dump.cpu_notes_buf_size);
> -	note_buf = fadump_cpu_notes_buf_alloc(fw_dump.cpu_notes_buf_size);
> -	if (!note_buf) {
> -		printk(KERN_ERR "Failed to allocate 0x%lx bytes for "
> -			"cpu notes buffer\n", fw_dump.cpu_notes_buf_size);
> -		return -ENOMEM;
> -	}
> -	fw_dump.cpu_notes_buf = __pa(note_buf);
> -
> -	pr_debug("Allocated buffer for cpu notes of size %ld at %p\n",
> -			(num_cpus * sizeof(note_buf_t)), note_buf);
> -
> -	if (fw_dump.fadumphdr_addr)
> -		fdh = __va(fw_dump.fadumphdr_addr);
> -
> -	for (i = 0; i < num_cpus; i++) {
> -		if (be64_to_cpu(reg_entry->reg_id) != fadump_str_to_u64("CPUSTRT")) {
> -			printk(KERN_ERR "Unable to read CPU state data\n");
> -			rc = -ENOENT;
> -			goto error_out;
> -		}
> -		/* Lower 4 bytes of reg_value contains logical cpu id */
> -		cpu = be64_to_cpu(reg_entry->reg_value) & RTAS_FADUMP_CPU_ID_MASK;
> -		if (fdh && !cpumask_test_cpu(cpu, &fdh->online_mask)) {
> -			RTAS_FADUMP_SKIP_TO_NEXT_CPU(reg_entry);
> -			continue;
> -		}
> -		pr_debug("Reading register data for cpu %d...\n", cpu);
> -		if (fdh && fdh->crashing_cpu == cpu) {
> -			regs = fdh->regs;
> -			note_buf = fadump_regs_to_elf_notes(note_buf, &regs);
> -			RTAS_FADUMP_SKIP_TO_NEXT_CPU(reg_entry);
> -		} else {
> -			reg_entry++;
> -			reg_entry = fadump_read_registers(reg_entry, &regs);
> -			note_buf = fadump_regs_to_elf_notes(note_buf, &regs);
> -		}
> -	}
> -	final_note(note_buf);
> -
> -	if (fdh) {
> -		addr = fdh->elfcorehdr_addr;
> -		pr_debug("Updating elfcore header(%lx) with cpu notes\n", addr);
> -		fadump_update_elfcore_header(&fw_dump, (char *)__va(addr));
> -	}
> -	return 0;
> -
> -error_out:
> -	fadump_cpu_notes_buf_free((unsigned long)__va(fw_dump.cpu_notes_buf),
> -					fw_dump.cpu_notes_buf_size);
> -	fw_dump.cpu_notes_buf = 0;
> -	fw_dump.cpu_notes_buf_size = 0;
> -	return rc;
> -
> -}
> -
> -/*
> - * Validate and process the dump data stored by firmware before exporting
> - * it through '/proc/vmcore'.
> - */
> -static int __init process_fadump(const struct rtas_fadump_mem_struct *fdm_active)
> -{
> -	struct fadump_crash_info_header *fdh;
> -	int rc = 0;
> -
> -	if (!fdm_active || !fw_dump.fadumphdr_addr)
> -		return -EINVAL;
> -
> -	/* Check if the dump data is valid. */
> -	if ((be16_to_cpu(fdm_active->header.dump_status_flag) == RTAS_FADUMP_ERROR_FLAG) ||
> -			(fdm_active->cpu_state_data.error_flags != 0) ||
> -			(fdm_active->rmr_region.error_flags != 0)) {
> -		printk(KERN_ERR "Dump taken by platform is not valid\n");
> -		return -EINVAL;
> -	}
> -	if ((fdm_active->rmr_region.bytes_dumped !=
> -			fdm_active->rmr_region.source_len) ||
> -			!fdm_active->cpu_state_data.bytes_dumped) {
> -		printk(KERN_ERR "Dump taken by platform is incomplete\n");
> -		return -EINVAL;
> -	}
> -
> -	/* Validate the fadump crash info header */
> -	fdh = __va(fw_dump.fadumphdr_addr);
> -	if (fdh->magic_number != FADUMP_CRASH_INFO_MAGIC) {
> -		printk(KERN_ERR "Crash info header is not valid.\n");
> -		return -EINVAL;
> -	}
> -
> -	rc = fadump_build_cpu_notes(fdm_active);
> -	if (rc)
> -		return rc;
> -
> -	/*
> -	 * We are done validating dump info and elfcore header is now ready
> -	 * to be exported. set elfcorehdr_addr so that vmcore module will
> -	 * export the elfcore header through '/proc/vmcore'.
> -	 */
> -	elfcorehdr_addr = fdh->elfcorehdr_addr;
> -
> -	return 0;
> -}
> -
>  static void free_crash_memory_ranges(void)
>  {
>  	kfree(crash_memory_ranges);
> @@ -970,7 +740,6 @@ static unsigned long init_fadump_header(unsigned long addr)
>  	if (!addr)
>  		return 0;
>  
> -	fw_dump.fadumphdr_addr = addr;
>  	fdh = __va(addr);
>  	addr += sizeof(struct fadump_crash_info_header);
>  
> @@ -1014,39 +783,12 @@ static int register_fadump(void)
>  	return fw_dump.ops->register_fadump(&fw_dump);
>  }
>  
> -static int fadump_invalidate_dump(const struct rtas_fadump_mem_struct *fdm)
> -{
> -	int rc = 0;
> -	unsigned int wait_time;
> -
> -	pr_debug("Invalidating firmware-assisted dump registration\n");
> -
> -	/* TODO: Add upper time limit for the delay */
> -	do {
> -		rc = rtas_call(fw_dump.ibm_configure_kernel_dump, 3, 1, NULL,
> -			FADUMP_INVALIDATE, fdm,
> -			sizeof(struct rtas_fadump_mem_struct));
> -
> -		wait_time = rtas_busy_delay_time(rc);
> -		if (wait_time)
> -			mdelay(wait_time);
> -	} while (wait_time);
> -
> -	if (rc) {
> -		pr_err("Failed to invalidate firmware-assisted dump registration. Unexpected error (%d).\n", rc);
> -		return rc;
> -	}
> -	fw_dump.dump_active = 0;
> -	fdm_active = NULL;
> -	return 0;
> -}
> -
>  void fadump_cleanup(void)
>  {
>  	/* Invalidate the registration only if dump is active. */
>  	if (fw_dump.dump_active) {
> -		/* pass the same memory dump structure provided by platform */
> -		fadump_invalidate_dump(fdm_active);
> +		pr_debug("Invalidating firmware-assisted dump registration\n");
> +		fw_dump.ops->invalidate_fadump(&fw_dump);
>  	} else if (fw_dump.dump_registered) {
>  		/* Un-register Firmware-assisted dump if it was registered. */
>  		fw_dump.ops->unregister_fadump(&fw_dump);
> @@ -1132,7 +874,7 @@ static void fadump_invalidate_release_mem(void)
>  		return;
>  	}
>  
> -	destination_address = be64_to_cpu(fdm_active->cpu_state_data.destination_address);
> +	destination_address = fw_dump.preserv_area_start;
>  	fadump_cleanup();
>  	mutex_unlock(&fadump_mutex);
>  
> @@ -1158,6 +900,7 @@ static void fadump_invalidate_release_mem(void)
>  		fw_dump.cpu_notes_buf = 0;
>  		fw_dump.cpu_notes_buf_size = 0;
>  	}
> +
>  	/* Initialize the kernel dump memory structure for FAD registration. */
>  	fw_dump.ops->init_fadump_mem_struct(&fw_dump);
>  }
> @@ -1210,7 +953,7 @@ static ssize_t fadump_register_store(struct kobject *kobj,
>  	int ret = 0;
>  	int input = -1;
>  
> -	if (!fw_dump.fadump_enabled || fdm_active)
> +	if (!fw_dump.fadump_enabled || fw_dump.dump_active)
>  		return -EPERM;
>  
>  	if (kstrtoint(buf, 0, &input))
> @@ -1223,7 +966,9 @@ static ssize_t fadump_register_store(struct kobject *kobj,
>  		if (fw_dump.dump_registered == 0) {
>  			goto unlock_out;
>  		}
> +
>  		/* Un-register Firmware-assisted dump */
> +		pr_debug("Un-register firmware-assisted dump\n");
>  		fw_dump.ops->unregister_fadump(&fw_dump);
>  		break;
>  	case 1:
> @@ -1246,63 +991,13 @@ static ssize_t fadump_register_store(struct kobject *kobj,
>  
>  static int fadump_region_show(struct seq_file *m, void *private)
>  {
> -	const struct rtas_fadump_mem_struct *fdm_ptr;
> -
>  	if (!fw_dump.fadump_enabled)
>  		return 0;
>  
>  	mutex_lock(&fadump_mutex);
> -	if (fdm_active)
> -		fdm_ptr = fdm_active;
> -	else {
> -		mutex_unlock(&fadump_mutex);
> -		fw_dump.ops->fadump_region_show(&fw_dump, m);
> -		return 0;
> -	}
> +	fw_dump.ops->fadump_region_show(&fw_dump, m);
> +	mutex_unlock(&fadump_mutex);
>  
> -	seq_printf(m,
> -			"CPU : [%#016llx-%#016llx] %#llx bytes, "
> -			"Dumped: %#llx\n",
> -			be64_to_cpu(fdm_ptr->cpu_state_data.destination_address),
> -			be64_to_cpu(fdm_ptr->cpu_state_data.destination_address) +
> -			be64_to_cpu(fdm_ptr->cpu_state_data.source_len) - 1,
> -			be64_to_cpu(fdm_ptr->cpu_state_data.source_len),
> -			be64_to_cpu(fdm_ptr->cpu_state_data.bytes_dumped));
> -	seq_printf(m,
> -			"HPTE: [%#016llx-%#016llx] %#llx bytes, "
> -			"Dumped: %#llx\n",
> -			be64_to_cpu(fdm_ptr->hpte_region.destination_address),
> -			be64_to_cpu(fdm_ptr->hpte_region.destination_address) +
> -			be64_to_cpu(fdm_ptr->hpte_region.source_len) - 1,
> -			be64_to_cpu(fdm_ptr->hpte_region.source_len),
> -			be64_to_cpu(fdm_ptr->hpte_region.bytes_dumped));
> -	seq_printf(m,
> -			"DUMP: [%#016llx-%#016llx] %#llx bytes, "
> -			"Dumped: %#llx\n",
> -			be64_to_cpu(fdm_ptr->rmr_region.destination_address),
> -			be64_to_cpu(fdm_ptr->rmr_region.destination_address) +
> -			be64_to_cpu(fdm_ptr->rmr_region.source_len) - 1,
> -			be64_to_cpu(fdm_ptr->rmr_region.source_len),
> -			be64_to_cpu(fdm_ptr->rmr_region.bytes_dumped));
> -
> -	if (!fdm_active ||
> -		(fw_dump.reserve_dump_area_start ==
> -		be64_to_cpu(fdm_ptr->cpu_state_data.destination_address)))
> -		goto out;
> -
> -	/* Dump is active. Show reserved memory region. */
> -	seq_printf(m,
> -			"    : [%#016llx-%#016llx] %#llx bytes, "
> -			"Dumped: %#llx\n",
> -			(unsigned long long)fw_dump.reserve_dump_area_start,
> -			be64_to_cpu(fdm_ptr->cpu_state_data.destination_address) - 1,
> -			be64_to_cpu(fdm_ptr->cpu_state_data.destination_address) -
> -			fw_dump.reserve_dump_area_start,
> -			be64_to_cpu(fdm_ptr->cpu_state_data.destination_address) -
> -			fw_dump.reserve_dump_area_start);
> -out:
> -	if (fdm_active)
> -		mutex_unlock(&fadump_mutex);
>  	return 0;
>  }
>  
> @@ -1373,12 +1068,13 @@ int __init setup_fadump(void)
>  		 * if dump process fails then invalidate the registration
>  		 * and release memory before proceeding for re-registration.
>  		 */
> -		if (process_fadump(fdm_active) < 0)
> +		if (fw_dump.ops->process_fadump(&fw_dump) < 0)
>  			fadump_invalidate_release_mem();
>  	}
>  	/* Initialize the kernel dump memory structure for FAD registration. */
>  	else if (fw_dump.reserve_dump_area_size)
>  		fw_dump.ops->init_fadump_mem_struct(&fw_dump);
> +
>  	fadump_init_files();
>  
>  	return 1;
> diff --git a/arch/powerpc/platforms/pseries/rtas-fadump.c b/arch/powerpc/platforms/pseries/rtas-fadump.c
> index 790a37d..7ce84f8 100644
> --- a/arch/powerpc/platforms/pseries/rtas-fadump.c
> +++ b/arch/powerpc/platforms/pseries/rtas-fadump.c
> @@ -31,6 +31,7 @@
>  #include "rtas-fadump.h"
>  
>  static struct rtas_fadump_mem_struct fdm;
> +static const struct rtas_fadump_mem_struct *fdm_active;
>  
>  static void rtas_fadump_update_config(struct fw_dump *fadump_conf,
>  				      const struct rtas_fadump_mem_struct *fdm)
> @@ -40,6 +41,23 @@ static void rtas_fadump_update_config(struct fw_dump *fadump_conf,
>  
>  	fadump_conf->fadumphdr_addr = (fadump_conf->boot_mem_dest_addr +
>  				       fadump_conf->boot_memory_size);
> +
> +	/* Start address of preserve area (permanent reservation) */
> +	fadump_conf->preserv_area_start =
> +		be64_to_cpu(fdm->cpu_state_data.destination_address);
> +	pr_debug("Preserve area start address: 0x%lx\n",
> +		 fadump_conf->preserv_area_start);
> +}
> +
> +/*
> + * This function is called in the capture kernel to get configuration details
> + * setup in the first kernel and passed to the f/w.
> + */
> +static void rtas_fadump_get_config(struct fw_dump *fadump_conf,
> +				   const struct rtas_fadump_mem_struct *fdm)
> +{
> +	fadump_conf->boot_memory_size = be64_to_cpu(fdm->rmr_region.source_len);
> +	rtas_fadump_update_config(fadump_conf, fdm);
>  }
>  
>  static ulong rtas_fadump_init_mem_struct(struct fw_dump *fadump_conf)
> @@ -180,7 +198,196 @@ static int rtas_fadump_unregister_fadump(struct fw_dump *fadump_conf)
>  
>  static int rtas_fadump_invalidate_fadump(struct fw_dump *fadump_conf)
>  {
> -	return -EIO;
> +	int rc;
> +	unsigned int wait_time;
> +
> +	/* TODO: Add upper time limit for the delay */
> +	do {
> +		rc =  rtas_call(fadump_conf->ibm_configure_kernel_dump, 3, 1,
> +				NULL, FADUMP_INVALIDATE, fdm_active,
> +				sizeof(struct rtas_fadump_mem_struct));
> +
> +		wait_time = rtas_busy_delay_time(rc);
> +		if (wait_time)
> +			mdelay(wait_time);
> +	} while (wait_time);
> +
> +	if (rc) {
> +		pr_err("Failed to invalidate - unexpected error (%d).\n", rc);
> +		return -EIO;
> +	}
> +
> +	fadump_conf->dump_active = 0;
> +	fdm_active = NULL;
> +	return 0;
> +}
> +
> +#define RTAS_FADUMP_GPR_MASK			0xffffff0000000000
> +static inline int rtas_fadump_gpr_index(u64 id)
> +{
> +	int i = -1;
> +	char str[3];
> +
> +	if ((id & RTAS_FADUMP_GPR_MASK) == fadump_str_to_u64("GPR")) {
> +		/* get the digits at the end */
> +		id &= ~RTAS_FADUMP_GPR_MASK;
> +		id >>= 24;
> +		str[2] = '\0';
> +		str[1] = id & 0xff;
> +		str[0] = (id >> 8) & 0xff;
> +		if (kstrtoint(str, 10, &i))
> +			i = -EINVAL;
> +		if (i > 31)
> +			i = -1;
> +	}
> +	return i;
> +}
> +
> +void rtas_fadump_set_regval(struct pt_regs *regs, u64 reg_id, u64 reg_val)
> +{
> +	int i;
> +
> +	i = rtas_fadump_gpr_index(reg_id);
> +	if (i >= 0)
> +		regs->gpr[i] = (unsigned long)reg_val;
> +	else if (reg_id == fadump_str_to_u64("NIA"))
> +		regs->nip = (unsigned long)reg_val;
> +	else if (reg_id == fadump_str_to_u64("MSR"))
> +		regs->msr = (unsigned long)reg_val;
> +	else if (reg_id == fadump_str_to_u64("CTR"))
> +		regs->ctr = (unsigned long)reg_val;
> +	else if (reg_id == fadump_str_to_u64("LR"))
> +		regs->link = (unsigned long)reg_val;
> +	else if (reg_id == fadump_str_to_u64("XER"))
> +		regs->xer = (unsigned long)reg_val;
> +	else if (reg_id == fadump_str_to_u64("CR"))
> +		regs->ccr = (unsigned long)reg_val;
> +	else if (reg_id == fadump_str_to_u64("DAR"))
> +		regs->dar = (unsigned long)reg_val;
> +	else if (reg_id == fadump_str_to_u64("DSISR"))
> +		regs->dsisr = (unsigned long)reg_val;
> +}
> +
> +static struct rtas_fadump_reg_entry*
> +rtas_fadump_read_regs(struct rtas_fadump_reg_entry *reg_entry,
> +		      struct pt_regs *regs)
> +{
> +	memset(regs, 0, sizeof(struct pt_regs));
> +
> +	while (be64_to_cpu(reg_entry->reg_id) != fadump_str_to_u64("CPUEND")) {
> +		rtas_fadump_set_regval(regs, be64_to_cpu(reg_entry->reg_id),
> +				       be64_to_cpu(reg_entry->reg_value));
> +		reg_entry++;
> +	}
> +	reg_entry++;
> +	return reg_entry;
> +}
> +
> +/*
> + * Read CPU state dump data and convert it into ELF notes.
> + * The CPU dump starts with magic number "REGSAVE". NumCpusOffset should be
> + * used to access the data to allow for additional fields to be added without
> + * affecting compatibility. Each list of registers for a CPU starts with
> + * "CPUSTRT" and ends with "CPUEND". Each register entry is of 16 bytes,
> + * 8 Byte ASCII identifier and 8 Byte register value. The register entry
> + * with identifier "CPUSTRT" and "CPUEND" contains 4 byte cpu id as part
> + * of register value. For more details refer to PAPR document.
> + *
> + * Only for the crashing cpu we ignore the CPU dump data and get exact
> + * state from fadump crash info structure populated by first kernel at the
> + * time of crash.
> + */
> +static int __init rtas_fadump_build_cpu_notes(struct fw_dump *fadump_conf)
> +{
> +	struct rtas_fadump_reg_save_area_header *reg_header;
> +	struct rtas_fadump_reg_entry *reg_entry;
> +	struct fadump_crash_info_header *fdh = NULL;
> +	void *vaddr;
> +	unsigned long addr;
> +	u32 num_cpus, *note_buf;
> +	struct pt_regs regs;
> +	int i, rc = 0, cpu = 0;
> +
> +	addr = be64_to_cpu(fdm_active->cpu_state_data.destination_address);
> +	vaddr = __va(addr);
> +
> +	reg_header = vaddr;
> +	if (be64_to_cpu(reg_header->magic_number) !=
> +	    fadump_str_to_u64("REGSAVE")) {
> +		pr_err("Unable to read register save area.\n");
> +		return -ENOENT;
> +	}
> +
> +	pr_debug("--------CPU State Data------------\n");
> +	pr_debug("Magic Number: %llx\n", be64_to_cpu(reg_header->magic_number));
> +	pr_debug("NumCpuOffset: %x\n", be32_to_cpu(reg_header->num_cpu_offset));
> +
> +	vaddr += be32_to_cpu(reg_header->num_cpu_offset);
> +	num_cpus = be32_to_cpu(*((__be32 *)(vaddr)));
> +	pr_debug("NumCpus     : %u\n", num_cpus);
> +	vaddr += sizeof(u32);
> +	reg_entry = (struct rtas_fadump_reg_entry *)vaddr;
> +
> +	/* Allocate buffer to hold cpu crash notes. */
> +	fadump_conf->cpu_notes_buf_size = num_cpus * sizeof(note_buf_t);
> +	fadump_conf->cpu_notes_buf_size =
> +		PAGE_ALIGN(fadump_conf->cpu_notes_buf_size);
> +	note_buf = fadump_cpu_notes_buf_alloc(fadump_conf->cpu_notes_buf_size);
> +	if (!note_buf) {
> +		pr_err("Failed to allocate 0x%lx bytes for cpu notes buffer\n",
> +		       fadump_conf->cpu_notes_buf_size);
> +		return -ENOMEM;
> +	}
> +	fadump_conf->cpu_notes_buf = __pa(note_buf);
> +
> +	pr_debug("Allocated buffer for cpu notes of size %ld at %p\n",
> +			(num_cpus * sizeof(note_buf_t)), note_buf);
> +
> +	if (fadump_conf->fadumphdr_addr)
> +		fdh = __va(fadump_conf->fadumphdr_addr);
> +
> +	for (i = 0; i < num_cpus; i++) {
> +		if (be64_to_cpu(reg_entry->reg_id) !=
> +		    fadump_str_to_u64("CPUSTRT")) {
> +			pr_err("Unable to read CPU state data\n");
> +			rc = -ENOENT;
> +			goto error_out;
> +		}
> +		/* Lower 4 bytes of reg_value contains logical cpu id */
> +		cpu = (be64_to_cpu(reg_entry->reg_value) &
> +		       RTAS_FADUMP_CPU_ID_MASK);
> +		if (fdh && !cpumask_test_cpu(cpu, &fdh->online_mask)) {
> +			RTAS_FADUMP_SKIP_TO_NEXT_CPU(reg_entry);
> +			continue;
> +		}
> +		pr_debug("Reading register data for cpu %d...\n", cpu);
> +		if (fdh && fdh->crashing_cpu == cpu) {
> +			regs = fdh->regs;
> +			note_buf = fadump_regs_to_elf_notes(note_buf, &regs);
> +			RTAS_FADUMP_SKIP_TO_NEXT_CPU(reg_entry);
> +		} else {
> +			reg_entry++;
> +			reg_entry = rtas_fadump_read_regs(reg_entry, &regs);
> +			note_buf = fadump_regs_to_elf_notes(note_buf, &regs);
> +		}
> +	}
> +	final_note(note_buf);
> +
> +	if (fdh) {
> +		pr_debug("Updating elfcore header (%llx) with cpu notes\n",
> +			 fdh->elfcorehdr_addr);
> +		fadump_update_elfcore_header(fadump_conf,
> +					     __va(fdh->elfcorehdr_addr));
> +	}
> +	return 0;
> +
> +error_out:
> +	fadump_cpu_notes_buf_free((ulong)__va(fadump_conf->cpu_notes_buf),
> +				  fadump_conf->cpu_notes_buf_size);
> +	fadump_conf->cpu_notes_buf = 0;
> +	fadump_conf->cpu_notes_buf_size = 0;
> +	return rc;
> +
>  }
>  
>  /*
> @@ -189,15 +396,62 @@ static int rtas_fadump_invalidate_fadump(struct fw_dump *fadump_conf)
>   */
>  static int __init rtas_fadump_process_fadump(struct fw_dump *fadump_conf)
>  {
> -	return -EINVAL;
> +	struct fadump_crash_info_header *fdh;
> +	int rc = 0;
> +
> +	if (!fdm_active || !fadump_conf->fadumphdr_addr)
> +		return -EINVAL;
> +
> +	/* Check if the dump data is valid. */
> +	if ((be16_to_cpu(fdm_active->header.dump_status_flag) ==
> +			RTAS_FADUMP_ERROR_FLAG) ||
> +			(fdm_active->cpu_state_data.error_flags != 0) ||
> +			(fdm_active->rmr_region.error_flags != 0)) {
> +		pr_err("Dump taken by platform is not valid\n");
> +		return -EINVAL;
> +	}
> +	if ((fdm_active->rmr_region.bytes_dumped !=
> +			fdm_active->rmr_region.source_len) ||
> +			!fdm_active->cpu_state_data.bytes_dumped) {
> +		pr_err("Dump taken by platform is incomplete\n");
> +		return -EINVAL;
> +	}
> +
> +	/* Validate the fadump crash info header */
> +	fdh = __va(fadump_conf->fadumphdr_addr);
> +	if (fdh->magic_number != FADUMP_CRASH_INFO_MAGIC) {
> +		pr_err("Crash info header is not valid.\n");
> +		return -EINVAL;
> +	}
> +
> +	if (!fdm_active->cpu_state_data.bytes_dumped)
> +		return -EINVAL;
> +
> +	rc = rtas_fadump_build_cpu_notes(fadump_conf);
> +	if (rc)
> +		return rc;
> +
> +	/*
> +	 * We are done validating dump info and elfcore header is now ready
> +	 * to be exported. set elfcorehdr_addr so that vmcore module will
> +	 * export the elfcore header through '/proc/vmcore'.
> +	 */
> +	elfcorehdr_addr = fdh->elfcorehdr_addr;
> +
> +	return 0;
>  }
>  
>  static void rtas_fadump_region_show(struct fw_dump *fadump_conf,
>  				    struct seq_file *m)
>  {
> -	const struct rtas_fadump_mem_struct *fdm_ptr = &fdm;
> +	const struct rtas_fadump_mem_struct *fdm_ptr;
>  	const struct rtas_fadump_section *cpu_data_section;
>  
> +	if (fdm_active)
> +		fdm_ptr = fdm_active;
> +	else
> +		fdm_ptr = &fdm;
> +
>  	cpu_data_section = &(fdm_ptr->cpu_state_data);
>  	seq_printf(m, "CPU :[%#016llx-%#016llx] %#llx bytes, Dumped: %#llx\n",
>  		   be64_to_cpu(cpu_data_section->destination_address),
> @@ -219,6 +473,12 @@ static void rtas_fadump_region_show(struct fw_dump *fadump_conf,
>  	seq_printf(m, "Size: %#llx, Dumped: %#llx bytes\n",
>  		   be64_to_cpu(fdm_ptr->rmr_region.source_len),
>  		   be64_to_cpu(fdm_ptr->rmr_region.bytes_dumped));
> +
> +	/* Dump is active. Show reserved area start address. */
> +	if (fdm_active) {
> +		seq_printf(m, "\nMemory above %#016lx is reserved for saving crash dump\n",
> +			   fadump_conf->reserve_dump_area_start);
> +	}
>  }
>  
>  static void rtas_fadump_trigger(struct fadump_crash_info_header *fdh,
> @@ -228,6 +488,7 @@ static void rtas_fadump_trigger(struct fadump_crash_info_header *fdh,
>  	rtas_os_term((char *)msg);
>  }
>  
> +
>  static struct fadump_ops rtas_fadump_ops = {
>  	.init_fadump_mem_struct	= rtas_fadump_init_mem_struct,
>  	.register_fadump	= rtas_fadump_register_fadump,
> @@ -258,6 +519,17 @@ int __init rtas_fadump_dt_scan(struct fw_dump *fadump_conf, ulong node)
>  	fadump_conf->fadump_platform	= FADUMP_PLATFORM_PSERIES;
>  	fadump_conf->fadump_supported	= 1;
>  
> +	/*
> +	 * The 'ibm,kernel-dump' rtas node is present only if there is
> +	 * dump data waiting for us.
> +	 */
> +	fdm_active = of_get_flat_dt_prop(node, "ibm,kernel-dump", NULL);
> +	if (fdm_active) {
> +		pr_info("Firmware-assisted dump is active.\n");
> +		fadump_conf->dump_active = 1;
> +		rtas_fadump_get_config(fadump_conf, (void *)__pa(fdm_active));
> +	}
> +
>  	/* Get the sizes required to store dump data for the firmware provided
>  	 * dump sections.
>  	 * For each dump section type supported, a 32bit cell which defines
> 

-- 
Mahesh J Salgaonkar


^ permalink raw reply

* RE: [EXT] Re: [PATCHv4 1/2] PCI: layerscape: Add the bar_fixed_64bit property in EP driver.
From: Xiaowei Bao @ 2019-08-13  6:29 UTC (permalink / raw)
  To: Kishon Vijay Abraham I, lorenzo.pieralisi@arm.com,
	bhelgaas@google.com, M.h. Lian, Mingkai Hu, Roy Zang,
	l.stach@pengutronix.de, tpiepho@impinj.com, Leonard Crestez,
	andrew.smirnov@gmail.com, yue.wang@amlogic.com,
	hayashi.kunihiko@socionext.com, dwmw@amazon.co.uk,
	jonnyc@amazon.com, linux-pci@vger.kernel.org,
	linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <4a456d72-f5b5-e860-0215-dd215e2edf09@ti.com>



> -----Original Message-----
> From: Kishon Vijay Abraham I <kishon@ti.com>
> Sent: 2019年8月13日 12:36
> To: Xiaowei Bao <xiaowei.bao@nxp.com>; lorenzo.pieralisi@arm.com;
> bhelgaas@google.com; M.h. Lian <minghuan.lian@nxp.com>; Mingkai Hu
> <mingkai.hu@nxp.com>; Roy Zang <roy.zang@nxp.com>;
> l.stach@pengutronix.de; tpiepho@impinj.com; Leonard Crestez
> <leonard.crestez@nxp.com>; andrew.smirnov@gmail.com;
> yue.wang@amlogic.com; hayashi.kunihiko@socionext.com;
> dwmw@amazon.co.uk; jonnyc@amazon.com; linux-pci@vger.kernel.org;
> linux-kernel@vger.kernel.org; linuxppc-dev@lists.ozlabs.org;
> linux-arm-kernel@lists.infradead.org
> Subject: [EXT] Re: [PATCHv4 1/2] PCI: layerscape: Add the bar_fixed_64bit
> property in EP driver.
> 
> Caution: EXT Email
> 
> On 13/08/19 8:23 AM, Xiaowei Bao wrote:
> > The PCIe controller of layerscape just have 4 BARs, BAR0 and BAR1 is
> > 32bit, BAR3 and BAR4 is 64bit, this is determined by hardware,
> 
> Do you mean BAR2 instead of BAR3 here?
Yes.
> 
> Thanks
> Kishon
> 
> > so set the bar_fixed_64bit with 0x14.
> >
> > Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
> > ---
> > v2:
> >  - Replace value 0x14 with a macro.
> > v3:
> >  - No change.
> > v4:
> >  - send the patch again with '--to'.
> >
> >  drivers/pci/controller/dwc/pci-layerscape-ep.c |    1 +
> >  1 files changed, 1 insertions(+), 0 deletions(-)
> >
> > diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > index be61d96..227c33b 100644
> > --- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > +++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > @@ -44,6 +44,7 @@ static int ls_pcie_establish_link(struct dw_pcie *pci)
> >       .linkup_notifier = false,
> >       .msi_capable = true,
> >       .msix_capable = false,
> > +     .bar_fixed_64bit = (1 << BAR_2) | (1 << BAR_4),
> >  };
> >
> >  static const struct pci_epc_features*
> >

^ permalink raw reply

* [PATCHv5 1/2] PCI: layerscape: Add the bar_fixed_64bit property in EP driver.
From: Xiaowei Bao @ 2019-08-13  6:28 UTC (permalink / raw)
  To: lorenzo.pieralisi, bhelgaas, minghuan.Lian, mingkai.hu, roy.zang,
	l.stach, kishon, tpiepho, leonard.crestez, andrew.smirnov,
	yue.wang, hayashi.kunihiko, dwmw, jonnyc, linux-pci, linux-kernel,
	linuxppc-dev, linux-arm-kernel
  Cc: Xiaowei Bao

The PCIe controller of layerscape just have 4 BARs, BAR0 and BAR1
is 32bit, BAR2 and BAR4 is 64bit, this is determined by hardware,
so set the bar_fixed_64bit with 0x14.

Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
---
v2:
 - Replace value 0x14 with a macro.
v3:
 - No change.
v4:
 - send the patch again with '--to'.
v5:
 - fix the commit message.

 drivers/pci/controller/dwc/pci-layerscape-ep.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c b/drivers/pci/controller/dwc/pci-layerscape-ep.c
index be61d96..ca9aa45 100644
--- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
+++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
@@ -44,6 +44,7 @@ static const struct pci_epc_features ls_pcie_epc_features = {
 	.linkup_notifier = false,
 	.msi_capable = true,
 	.msix_capable = false,
+	.bar_fixed_64bit = (1 << BAR_2) | (1 << BAR_4),
 };
 
 static const struct pci_epc_features*
-- 
2.9.5


^ permalink raw reply related

* [PATCHv5 2/2] PCI: layerscape: Add CONFIG_PCI_LAYERSCAPE_EP to build EP/RC separately
From: Xiaowei Bao @ 2019-08-13  6:28 UTC (permalink / raw)
  To: lorenzo.pieralisi, bhelgaas, minghuan.Lian, mingkai.hu, roy.zang,
	l.stach, kishon, tpiepho, leonard.crestez, andrew.smirnov,
	yue.wang, hayashi.kunihiko, dwmw, jonnyc, linux-pci, linux-kernel,
	linuxppc-dev, linux-arm-kernel
  Cc: Xiaowei Bao
In-Reply-To: <20190813062840.2733-1-xiaowei.bao@nxp.com>

Add CONFIG_PCI_LAYERSCAPE_EP to build EP/RC separately.

Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
---
v2:
 - No change.
v3:
 - modify the commit message.
v4:
 - send the patch again with '--to'.
v5:
 - No change.

 drivers/pci/controller/dwc/Kconfig  | 20 ++++++++++++++++++--
 drivers/pci/controller/dwc/Makefile |  3 ++-
 2 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig
index 6ea778a..869c645 100644
--- a/drivers/pci/controller/dwc/Kconfig
+++ b/drivers/pci/controller/dwc/Kconfig
@@ -131,13 +131,29 @@ config PCI_KEYSTONE_EP
 	  DesignWare core functions to implement the driver.
 
 config PCI_LAYERSCAPE
-	bool "Freescale Layerscape PCIe controller"
+	bool "Freescale Layerscape PCIe controller - Host mode"
 	depends on OF && (ARM || ARCH_LAYERSCAPE || COMPILE_TEST)
 	depends on PCI_MSI_IRQ_DOMAIN
 	select MFD_SYSCON
 	select PCIE_DW_HOST
 	help
-	  Say Y here if you want PCIe controller support on Layerscape SoCs.
+	  Say Y here if you want to enable PCIe controller support on Layerscape
+	  SoCs to work in Host mode.
+	  This controller can work either as EP or RC. The RCW[HOST_AGT_PEX]
+	  determines which PCIe controller works in EP mode and which PCIe
+	  controller works in RC mode.
+
+config PCI_LAYERSCAPE_EP
+	bool "Freescale Layerscape PCIe controller - Endpoint mode"
+	depends on OF && (ARM || ARCH_LAYERSCAPE || COMPILE_TEST)
+	depends on PCI_ENDPOINT
+	select PCIE_DW_EP
+	help
+	  Say Y here if you want to enable PCIe controller support on Layerscape
+	  SoCs to work in Endpoint mode.
+	  This controller can work either as EP or RC. The RCW[HOST_AGT_PEX]
+	  determines which PCIe controller works in EP mode and which PCIe
+	  controller works in RC mode.
 
 config PCI_HISI
 	depends on OF && (ARM64 || COMPILE_TEST)
diff --git a/drivers/pci/controller/dwc/Makefile b/drivers/pci/controller/dwc/Makefile
index b085dfd..824fde7 100644
--- a/drivers/pci/controller/dwc/Makefile
+++ b/drivers/pci/controller/dwc/Makefile
@@ -8,7 +8,8 @@ obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
 obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
 obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o
 obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone.o
-obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o pci-layerscape-ep.o
+obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o
+obj-$(CONFIG_PCI_LAYERSCAPE_EP) += pci-layerscape-ep.o
 obj-$(CONFIG_PCIE_QCOM) += pcie-qcom.o
 obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o
 obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o
-- 
2.9.5


^ permalink raw reply related

* RE: [EXT] Re: [PATCHv5 1/2] PCI: layerscape: Add the bar_fixed_64bit property in EP driver.
From: Xiaowei Bao @ 2019-08-13  7:39 UTC (permalink / raw)
  To: Kishon Vijay Abraham I, lorenzo.pieralisi@arm.com,
	bhelgaas@google.com, M.h. Lian, Mingkai Hu, Roy Zang,
	l.stach@pengutronix.de, tpiepho@impinj.com, Leonard Crestez,
	andrew.smirnov@gmail.com, yue.wang@amlogic.com,
	hayashi.kunihiko@socionext.com, dwmw@amazon.co.uk,
	jonnyc@amazon.com, linux-pci@vger.kernel.org,
	linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <61e6df1c-a0dc-8f05-f74a-85a3cac9823f@ti.com>



> -----Original Message-----
> From: Kishon Vijay Abraham I <kishon@ti.com>
> Sent: 2019年8月13日 15:30
> To: Xiaowei Bao <xiaowei.bao@nxp.com>; lorenzo.pieralisi@arm.com;
> bhelgaas@google.com; M.h. Lian <minghuan.lian@nxp.com>; Mingkai Hu
> <mingkai.hu@nxp.com>; Roy Zang <roy.zang@nxp.com>;
> l.stach@pengutronix.de; tpiepho@impinj.com; Leonard Crestez
> <leonard.crestez@nxp.com>; andrew.smirnov@gmail.com;
> yue.wang@amlogic.com; hayashi.kunihiko@socionext.com;
> dwmw@amazon.co.uk; jonnyc@amazon.com; linux-pci@vger.kernel.org;
> linux-kernel@vger.kernel.org; linuxppc-dev@lists.ozlabs.org;
> linux-arm-kernel@lists.infradead.org
> Subject: [EXT] Re: [PATCHv5 1/2] PCI: layerscape: Add the bar_fixed_64bit
> property in EP driver.
> 
> Caution: EXT Email
> 
> On 13/08/19 11:58 AM, Xiaowei Bao wrote:
> > The PCIe controller of layerscape just have 4 BARs, BAR0 and BAR1 is
> > 32bit, BAR2 and BAR4 is 64bit, this is determined by hardware, so set
> > the bar_fixed_64bit with 0x14.
> >
> > Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
> 
> Acked-by: Kishon Vijay Abraham I <kishon@ti.com>
> > ---
> > v2:
> >  - Replace value 0x14 with a macro.
> > v3:
> >  - No change.
> > v4:
> >  - send the patch again with '--to'.
> > v5:
> >  - fix the commit message.
> >
> >  drivers/pci/controller/dwc/pci-layerscape-ep.c | 1 +
> >  1 file changed, 1 insertion(+)
> >
> > diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > index be61d96..ca9aa45 100644
> > --- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > +++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > @@ -44,6 +44,7 @@ static const struct pci_epc_features
> ls_pcie_epc_features = {
> >       .linkup_notifier = false,
> >       .msi_capable = true,
> >       .msix_capable = false,
> > +     .bar_fixed_64bit = (1 << BAR_2) | (1 << BAR_4),
> >  };
> >
> >  static const struct pci_epc_features*
I check other platforms, it is 'static const struct pci_epc_features', I can get the correct 
Value use this define way in pci-epf-test.c file.
> >

^ permalink raw reply

* Re: [PATCHv5 1/2] PCI: layerscape: Add the bar_fixed_64bit property in EP driver.
From: Kishon Vijay Abraham I @ 2019-08-13  7:30 UTC (permalink / raw)
  To: Xiaowei Bao, lorenzo.pieralisi, bhelgaas, minghuan.Lian,
	mingkai.hu, roy.zang, l.stach, tpiepho, leonard.crestez,
	andrew.smirnov, yue.wang, hayashi.kunihiko, dwmw, jonnyc,
	linux-pci, linux-kernel, linuxppc-dev, linux-arm-kernel
In-Reply-To: <20190813062840.2733-1-xiaowei.bao@nxp.com>



On 13/08/19 11:58 AM, Xiaowei Bao wrote:
> The PCIe controller of layerscape just have 4 BARs, BAR0 and BAR1
> is 32bit, BAR2 and BAR4 is 64bit, this is determined by hardware,
> so set the bar_fixed_64bit with 0x14.
> 
> Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>

Acked-by: Kishon Vijay Abraham I <kishon@ti.com>
> ---
> v2:
>  - Replace value 0x14 with a macro.
> v3:
>  - No change.
> v4:
>  - send the patch again with '--to'.
> v5:
>  - fix the commit message.
> 
>  drivers/pci/controller/dwc/pci-layerscape-ep.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> index be61d96..ca9aa45 100644
> --- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
> +++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> @@ -44,6 +44,7 @@ static const struct pci_epc_features ls_pcie_epc_features = {
>  	.linkup_notifier = false,
>  	.msi_capable = true,
>  	.msix_capable = false,
> +	.bar_fixed_64bit = (1 << BAR_2) | (1 << BAR_4),
>  };
>  
>  static const struct pci_epc_features*
> 

^ permalink raw reply

* [Bug 204371] BUG kmalloc-4k (Tainted: G        W        ): Object padding overwritten
From: bugzilla-daemon @ 2019-08-13  9:19 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <bug-204371-206035@https.bugzilla.kernel.org/>

https://bugzilla.kernel.org/show_bug.cgi?id=204371

Erhard F. (erhard_f@mailbox.org) changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
 Attachment #284035|0                           |1
        is obsolete|                            |

--- Comment #14 from Erhard F. (erhard_f@mailbox.org) ---
Created attachment 284353
  --> https://bugzilla.kernel.org/attachment.cgi?id=284353&action=edit
kernel .config (PowerMac G4 DP, kernel 4.18.0-rc8+, final bisect)

-- 
You are receiving this mail because:
You are on the CC list for the bug.

^ permalink raw reply

* [Bug 204371] BUG kmalloc-4k (Tainted: G        W        ): Object padding overwritten
From: bugzilla-daemon @ 2019-08-13  9:20 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <bug-204371-206035@https.bugzilla.kernel.org/>

https://bugzilla.kernel.org/show_bug.cgi?id=204371

--- Comment #15 from Erhard F. (erhard_f@mailbox.org) ---
On Fri, 09 Aug 2019 12:31:26 +0000
bugzilla-daemon@bugzilla.kernel.org wrote:

> https://bugzilla.kernel.org/show_bug.cgi?id=204371
# cat ~/bisect01.log 
binäre Suche: danach noch 37903 Commits zum Testen übrig (ungefähr 15 Schritte)
[9abf8acea297b4c65f5fa3206e2b8e468e730e84] Merge tag 'tty-4.17-rc1' of
git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
binäre Suche: danach noch 19051 Commits zum Testen übrig (ungefähr 14 Schritte)
[7c00e8ae041b349992047769af741b67379ce19a] Merge tag 'armsoc-soc' of
git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
binäre Suche: danach noch 9762 Commits zum Testen übrig (ungefähr 13 Schritte)
[dafa5f6577a9eecd2941add553d1672c30b02364] Merge branch 'linus' of
git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
binäre Suche: danach noch 4644 Commits zum Testen übrig (ungefähr 12 Schritte)
[2ed9db3074fcd8d12709fe40ff0e691d74229818] net: sched: cls_api: fix dead code
in switch
binäre Suche: danach noch 2319 Commits zum Testen übrig (ungefähr 11 Schritte)
[b219a1d2de0c025318475e3bbf8e3215cf49d083] Merge branch 'for-next' of
git://git.kernel.org/pub/scm/linux/kernel/git/shli/md
binäre Suche: danach noch 1153 Commits zum Testen übrig (ungefähr 10 Schritte)
[85a0b791bc17f7a49280b33e2905d109c062a47b] Merge branch 'for-linus' of
git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
binäre Suche: danach noch 629 Commits zum Testen übrig (ungefähr 9 Schritte)
[10f3e23f07cb0c20f9bcb77a5b5a7eb2a1b2a2fe] Merge tag 'ext4_for_linus' of
git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
binäre Suche: danach noch 273 Commits zum Testen übrig (ungefähr 8 Schritte)
[575b94386bd539a7d803aee9fd4a8d275844c40f] Merge tag 'locks-v4.19-1' of
git://git.kernel.org/pub/scm/linux/kernel/git/jlayton/linux
binäre Suche: danach noch 136 Commits zum Testen übrig (ungefähr 7 Schritte)
[d7e8555b1dd493c809e56e359974eecabe7d3fde] btrfs: remove unused member
async_submit_bio::fs_info
binäre Suche: danach noch 68 Commits zum Testen übrig (ungefähr 6 Schritte)
[389305b2aa68723c754f88d9dbd268a400e10664] btrfs: relocation: Only remove reloc
rb_trees if reloc control has been initialized
binäre Suche: danach noch 34 Commits zum Testen übrig (ungefähr 5 Schritte)
[d814a49198eafa6163698bdd93961302f3a877a4] btrfs: use correct compare function
of dirty_metadata_bytes
binäre Suche: danach noch 16 Commits zum Testen übrig (ungefähr 4 Schritte)
[c7b562c5480322ffaf591f45a4ff7ee089340ab4] btrfs: raid56: catch errors from
full_stripe_write
binäre Suche: danach noch 8 Commits zum Testen übrig (ungefähr 3 Schritte)
[65ad010488a5cc0f123a9924f7ad26a1b3f6a4f6] btrfs: pass only eb to
num_extent_pages
binäre Suche: danach noch 3 Commits zum Testen übrig (ungefähr 2 Schritte)
[37508515621551538addaf826ab4b8a9aaf0a382] btrfs: simplify some assignments of
inode numbers
binäre Suche: danach noch 1 Commit zum Testen übrig (ungefähr 1 Schritt)
[69d2480456d1baf027a86e530989d7bedd698d5f] btrfs: use copy_page for copying
pages instead of memcpy
binäre Suche: danach noch 0 Commits zum Testen übrig (ungefähr 0 Schritte)
[3ffbd68c48320730ef64ebfb5e639220f1f65483] btrfs: simplify pointer chasing of
local fs_info variables
69d2480456d1baf027a86e530989d7bedd698d5f is the first bad commit
commit 69d2480456d1baf027a86e530989d7bedd698d5f
Author: David Sterba <dsterba@suse.com>
Date:   Fri Jun 29 10:56:44 2018 +0200

    btrfs: use copy_page for copying pages instead of memcpy

    Use the helper that's possibly optimized for full page copies.

    Signed-off-by: David Sterba <dsterba@suse.com>

:040000 040000 87de10a38618c1655c3266ff5a31358068fa1ca6
d0a2612d260215acaff66adaa5183ebd29a4b710 M      fs

-- 
You are receiving this mail because:
You are on the CC list for the bug.

^ permalink raw reply

* Re: [EXT] Re: [PATCHv5 1/2] PCI: layerscape: Add the bar_fixed_64bit property in EP driver.
From: Lorenzo Pieralisi @ 2019-08-13  9:51 UTC (permalink / raw)
  To: Xiaowei Bao
  Cc: linux-arm-kernel@lists.infradead.org, Roy Zang, Leonard Crestez,
	hayashi.kunihiko@socionext.com, andrew.smirnov@gmail.com,
	linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org,
	yue.wang@amlogic.com, Kishon Vijay Abraham I, M.h. Lian,
	dwmw@amazon.co.uk, jonnyc@amazon.com, bhelgaas@google.com,
	tpiepho@impinj.com, linuxppc-dev@lists.ozlabs.org, Mingkai Hu,
	l.stach@pengutronix.de
In-Reply-To: <AM5PR04MB32993CC1344DD660A298C7E1F5D20@AM5PR04MB3299.eurprd04.prod.outlook.com>

You should fix your email client set-up to avoid sticking an [EXT]
tag to your emails $SUBJECT.

On Tue, Aug 13, 2019 at 07:39:48AM +0000, Xiaowei Bao wrote:
> 
> 
> > -----Original Message-----
> > From: Kishon Vijay Abraham I <kishon@ti.com>
> > Sent: 2019年8月13日 15:30
> > To: Xiaowei Bao <xiaowei.bao@nxp.com>; lorenzo.pieralisi@arm.com;
> > bhelgaas@google.com; M.h. Lian <minghuan.lian@nxp.com>; Mingkai Hu
> > <mingkai.hu@nxp.com>; Roy Zang <roy.zang@nxp.com>;
> > l.stach@pengutronix.de; tpiepho@impinj.com; Leonard Crestez
> > <leonard.crestez@nxp.com>; andrew.smirnov@gmail.com;
> > yue.wang@amlogic.com; hayashi.kunihiko@socionext.com;
> > dwmw@amazon.co.uk; jonnyc@amazon.com; linux-pci@vger.kernel.org;
> > linux-kernel@vger.kernel.org; linuxppc-dev@lists.ozlabs.org;
> > linux-arm-kernel@lists.infradead.org
> > Subject: [EXT] Re: [PATCHv5 1/2] PCI: layerscape: Add the bar_fixed_64bit
> > property in EP driver.
> > 
> > Caution: EXT Email

See above, this "Caution" stuff should disappear.

Also, quoting the email header is useless, please configure your email
client to remove it.

Thanks,
Lorenzo

> > On 13/08/19 11:58 AM, Xiaowei Bao wrote:
> > > The PCIe controller of layerscape just have 4 BARs, BAR0 and BAR1 is
> > > 32bit, BAR2 and BAR4 is 64bit, this is determined by hardware, so set
> > > the bar_fixed_64bit with 0x14.
> > >
> > > Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
> > 
> > Acked-by: Kishon Vijay Abraham I <kishon@ti.com>
> > > ---
> > > v2:
> > >  - Replace value 0x14 with a macro.
> > > v3:
> > >  - No change.
> > > v4:
> > >  - send the patch again with '--to'.
> > > v5:
> > >  - fix the commit message.
> > >
> > >  drivers/pci/controller/dwc/pci-layerscape-ep.c | 1 +
> > >  1 file changed, 1 insertion(+)
> > >
> > > diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > > b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > > index be61d96..ca9aa45 100644
> > > --- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > > +++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > > @@ -44,6 +44,7 @@ static const struct pci_epc_features
> > ls_pcie_epc_features = {
> > >       .linkup_notifier = false,
> > >       .msi_capable = true,
> > >       .msix_capable = false,
> > > +     .bar_fixed_64bit = (1 << BAR_2) | (1 << BAR_4),
> > >  };
> > >
> > >  static const struct pci_epc_features*
> I check other platforms, it is 'static const struct pci_epc_features', I can get the correct 
> Value use this define way in pci-epf-test.c file.
> > >

^ permalink raw reply

* [PATCH 1/2] powerpc: rewrite LOAD_REG_IMMEDIATE() as an intelligent macro
From: Christophe Leroy @ 2019-08-13  9:59 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, segher
  Cc: linuxppc-dev, linux-kernel

Today LOAD_REG_IMMEDIATE() is a basic #define which loads all
parts on a value into a register, including the parts that are NUL.

This means always 2 instructions on PPC32 and always 5 instructions
on PPC64. And those instructions cannot run in parallele as they are
updating the same register.

Ex: LOAD_REG_IMMEDIATE(r1,THREAD_SIZE) in head_64.S results in:

3c 20 00 00     lis     r1,0
60 21 00 00     ori     r1,r1,0
78 21 07 c6     rldicr  r1,r1,32,31
64 21 00 00     oris    r1,r1,0
60 21 40 00     ori     r1,r1,16384

Rewrite LOAD_REG_IMMEDIATE() with GAS macro in order to skip
the parts that are NUL.

Rename existing LOAD_REG_IMMEDIATE() as LOAD_REG_IMMEDIATE_SYM()
and use that one for loading value of symbols which are not known
at compile time.

Now LOAD_REG_IMMEDIATE(r1,THREAD_SIZE) in head_64.S results in:

38 20 40 00     li      r1,16384

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
 arch/powerpc/include/asm/ppc_asm.h   | 42 +++++++++++++++++++++++++++++++-----
 arch/powerpc/kernel/exceptions-64e.S | 10 ++++-----
 arch/powerpc/kernel/head_64.S        |  2 +-
 3 files changed, 43 insertions(+), 11 deletions(-)

diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h
index e0637730a8e7..9a7c2ca9b714 100644
--- a/arch/powerpc/include/asm/ppc_asm.h
+++ b/arch/powerpc/include/asm/ppc_asm.h
@@ -311,13 +311,43 @@ GLUE(.,name):
 	addis	reg,reg,(name - 0b)@ha;		\
 	addi	reg,reg,(name - 0b)@l;
 
-#ifdef __powerpc64__
-#ifdef HAVE_AS_ATHIGH
+#if defined(__powerpc64__) && defined(HAVE_AS_ATHIGH)
 #define __AS_ATHIGH high
 #else
 #define __AS_ATHIGH h
 #endif
-#define LOAD_REG_IMMEDIATE(reg,expr)		\
+
+.macro __LOAD_REG_IMMEDIATE_32 r, x
+	.if (\x) >= 0x8000 || (\x) < -0x8000
+		lis \r, (\x)@__AS_ATHIGH
+		.if (\x) & 0xffff != 0
+			ori \r, \r, (\x)@l
+		.endif
+	.else
+		li \r, (\x)@l
+	.endif
+.endm
+
+.macro __LOAD_REG_IMMEDIATE r, x
+	.if \x & ~0xffffffff != 0
+		__LOAD_REG_IMMEDIATE_32 \r, (\x) >> 32
+		rldicr	\r, \r, 32, 31
+		.if (\x) & 0xffff0000 != 0
+			oris \r, \r, (\x)@__AS_ATHIGH
+		.endif
+		.if (\x) & 0xffff != 0
+			oris \r, \r, (\x)@l
+		.endif
+	.else
+		__LOAD_REG_IMMEDIATE_32 \r, \x
+	.endif
+.endm
+
+#ifdef __powerpc64__
+
+#define LOAD_REG_IMMEDIATE(reg, expr) __LOAD_REG_IMMEDIATE reg, expr
+
+#define LOAD_REG_IMMEDIATE_SYM(reg,expr)	\
 	lis     reg,(expr)@highest;		\
 	ori     reg,reg,(expr)@higher;	\
 	rldicr  reg,reg,32,31;		\
@@ -335,11 +365,13 @@ GLUE(.,name):
 
 #else /* 32-bit */
 
-#define LOAD_REG_IMMEDIATE(reg,expr)		\
+#define LOAD_REG_IMMEDIATE(reg, expr) __LOAD_REG_IMMEDIATE_32 reg, expr
+
+#define LOAD_REG_IMMEDIATE_SYM(reg,expr)		\
 	lis	reg,(expr)@ha;		\
 	addi	reg,reg,(expr)@l;
 
-#define LOAD_REG_ADDR(reg,name)		LOAD_REG_IMMEDIATE(reg, name)
+#define LOAD_REG_ADDR(reg,name)		LOAD_REG_IMMEDIATE_SYM(reg, name)
 
 #define LOAD_REG_ADDRBASE(reg, name)	lis	reg,name@ha
 #define ADDROFF(name)			name@l
diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S
index 1cfb3da4a84a..898aae6da167 100644
--- a/arch/powerpc/kernel/exceptions-64e.S
+++ b/arch/powerpc/kernel/exceptions-64e.S
@@ -751,8 +751,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
 	ld	r14,interrupt_base_book3e@got(r15)
 	ld	r15,__end_interrupts@got(r15)
 #else
-	LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e)
-	LOAD_REG_IMMEDIATE(r15,__end_interrupts)
+	LOAD_REG_IMMEDIATE_SYM(r14,interrupt_base_book3e)
+	LOAD_REG_IMMEDIATE_SYM(r15,__end_interrupts)
 #endif
 	cmpld	cr0,r10,r14
 	cmpld	cr1,r10,r15
@@ -821,8 +821,8 @@ kernel_dbg_exc:
 	ld	r14,interrupt_base_book3e@got(r15)
 	ld	r15,__end_interrupts@got(r15)
 #else
-	LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e)
-	LOAD_REG_IMMEDIATE(r15,__end_interrupts)
+	LOAD_REG_IMMEDIATE_SYM(r14,interrupt_base_book3e)
+	LOAD_REG_IMMEDIATE_SYM(r15,__end_interrupts)
 #endif
 	cmpld	cr0,r10,r14
 	cmpld	cr1,r10,r15
@@ -1449,7 +1449,7 @@ a2_tlbinit_code_start:
 a2_tlbinit_after_linear_map:
 
 	/* Now we branch the new virtual address mapped by this entry */
-	LOAD_REG_IMMEDIATE(r3,1f)
+	LOAD_REG_IMMEDIATE_SYM(r3,1f)
 	mtctr	r3
 	bctr
 
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 91d297e696dd..1fd44761e997 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -635,7 +635,7 @@ __after_prom_start:
 	sub	r5,r5,r11
 #else
 	/* just copy interrupts */
-	LOAD_REG_IMMEDIATE(r5, FIXED_SYMBOL_ABS_ADDR(__end_interrupts))
+	LOAD_REG_IMMEDIATE_SYM(r5, FIXED_SYMBOL_ABS_ADDR(__end_interrupts))
 #endif
 	b	5f
 3:
-- 
2.13.3


^ permalink raw reply related

* [PATCH 2/2] powerpc/32: replace LOAD_MSR_KERNEL() by LOAD_REG_IMMEDIATE()
From: Christophe Leroy @ 2019-08-13  9:59 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, segher
  Cc: linuxppc-dev, linux-kernel
In-Reply-To: <61d2a0b6f0c89b1ee546851ce9b6bd345e5ec968.1565690241.git.christophe.leroy@c-s.fr>

LOAD_MSR_KERNEL() and LOAD_REG_IMMEDIATE() are doing the same thing
in the same way. Drop LOAD_MSR_KERNEL()

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
 arch/powerpc/kernel/entry_32.S | 18 +++++++++---------
 arch/powerpc/kernel/head_32.h  | 21 ++++-----------------
 2 files changed, 13 insertions(+), 26 deletions(-)

diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 54fab22c9a43..972b05504a0a 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -230,7 +230,7 @@ transfer_to_handler_cont:
 	 */
 	lis	r12,reenable_mmu@h
 	ori	r12,r12,reenable_mmu@l
-	LOAD_MSR_KERNEL(r0, MSR_KERNEL)
+	LOAD_REG_IMMEDIATE(r0, MSR_KERNEL)
 	mtspr	SPRN_SRR0,r12
 	mtspr	SPRN_SRR1,r0
 	SYNC
@@ -304,7 +304,7 @@ stack_ovf:
 	addi	r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
 	lis	r9,StackOverflow@ha
 	addi	r9,r9,StackOverflow@l
-	LOAD_MSR_KERNEL(r10,MSR_KERNEL)
+	LOAD_REG_IMMEDIATE(r10,MSR_KERNEL)
 #if defined(CONFIG_PPC_8xx) && defined(CONFIG_PERF_EVENTS)
 	mtspr	SPRN_NRI, r0
 #endif
@@ -324,7 +324,7 @@ trace_syscall_entry_irq_off:
 	bl	trace_hardirqs_on
 
 	/* Now enable for real */
-	LOAD_MSR_KERNEL(r10, MSR_KERNEL | MSR_EE)
+	LOAD_REG_IMMEDIATE(r10, MSR_KERNEL | MSR_EE)
 	mtmsr	r10
 
 	REST_GPR(0, r1)
@@ -394,7 +394,7 @@ ret_from_syscall:
 #endif
 	mr	r6,r3
 	/* disable interrupts so current_thread_info()->flags can't change */
-	LOAD_MSR_KERNEL(r10,MSR_KERNEL)	/* doesn't include MSR_EE */
+	LOAD_REG_IMMEDIATE(r10,MSR_KERNEL)	/* doesn't include MSR_EE */
 	/* Note: We don't bother telling lockdep about it */
 	SYNC
 	MTMSRD(r10)
@@ -824,7 +824,7 @@ ret_from_except:
 	 * can't change between when we test it and when we return
 	 * from the interrupt. */
 	/* Note: We don't bother telling lockdep about it */
-	LOAD_MSR_KERNEL(r10,MSR_KERNEL)
+	LOAD_REG_IMMEDIATE(r10,MSR_KERNEL)
 	SYNC			/* Some chip revs have problems here... */
 	MTMSRD(r10)		/* disable interrupts */
 
@@ -991,7 +991,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX)
 	 * can restart the exception exit path at the label
 	 * exc_exit_restart below.  -- paulus
 	 */
-	LOAD_MSR_KERNEL(r10,MSR_KERNEL & ~MSR_RI)
+	LOAD_REG_IMMEDIATE(r10,MSR_KERNEL & ~MSR_RI)
 	SYNC
 	MTMSRD(r10)		/* clear the RI bit */
 	.globl exc_exit_restart
@@ -1066,7 +1066,7 @@ exc_exit_restart_end:
 	REST_NVGPRS(r1);						\
 	lwz	r3,_MSR(r1);						\
 	andi.	r3,r3,MSR_PR;						\
-	LOAD_MSR_KERNEL(r10,MSR_KERNEL);				\
+	LOAD_REG_IMMEDIATE(r10,MSR_KERNEL);				\
 	bne	user_exc_return;					\
 	lwz	r0,GPR0(r1);						\
 	lwz	r2,GPR2(r1);						\
@@ -1236,7 +1236,7 @@ recheck:
 	 * neither. Those disable/enable cycles used to peek at
 	 * TI_FLAGS aren't advertised.
 	 */
-	LOAD_MSR_KERNEL(r10,MSR_KERNEL)
+	LOAD_REG_IMMEDIATE(r10,MSR_KERNEL)
 	SYNC
 	MTMSRD(r10)		/* disable interrupts */
 	lwz	r9,TI_FLAGS(r2)
@@ -1329,7 +1329,7 @@ _GLOBAL(enter_rtas)
 	lwz	r4,RTASBASE(r4)
 	mfmsr	r9
 	stw	r9,8(r1)
-	LOAD_MSR_KERNEL(r0,MSR_KERNEL)
+	LOAD_REG_IMMEDIATE(r0,MSR_KERNEL)
 	SYNC			/* disable interrupts so SRR0/1 */
 	MTMSRD(r0)		/* don't get trashed */
 	li	r9,MSR_KERNEL & ~(MSR_IR|MSR_DR)
diff --git a/arch/powerpc/kernel/head_32.h b/arch/powerpc/kernel/head_32.h
index 4a692553651f..8abc7783dbe5 100644
--- a/arch/powerpc/kernel/head_32.h
+++ b/arch/powerpc/kernel/head_32.h
@@ -5,19 +5,6 @@
 #include <asm/ptrace.h>	/* for STACK_FRAME_REGS_MARKER */
 
 /*
- * MSR_KERNEL is > 0x8000 on 4xx/Book-E since it include MSR_CE.
- */
-.macro __LOAD_MSR_KERNEL r, x
-.if \x >= 0x8000
-	lis \r, (\x)@h
-	ori \r, \r, (\x)@l
-.else
-	li \r, (\x)
-.endif
-.endm
-#define LOAD_MSR_KERNEL(r, x) __LOAD_MSR_KERNEL r, x
-
-/*
  * Exception entry code.  This code runs with address translation
  * turned off, i.e. using physical addresses.
  * We assume sprg3 has the physical address of the current
@@ -92,7 +79,7 @@
 #ifdef CONFIG_40x
 	rlwinm	r9,r9,0,14,12		/* clear MSR_WE (necessary?) */
 #else
-	LOAD_MSR_KERNEL(r10, MSR_KERNEL & ~(MSR_IR|MSR_DR)) /* can take exceptions */
+	LOAD_REG_IMMEDIATE(r10, MSR_KERNEL & ~(MSR_IR|MSR_DR)) /* can take exceptions */
 	MTMSRD(r10)			/* (except for mach check in rtas) */
 #endif
 	lis	r10,STACK_FRAME_REGS_MARKER@ha /* exception frame marker */
@@ -140,10 +127,10 @@
 	 * otherwise we might risk taking an interrupt before we tell lockdep
 	 * they are enabled.
 	 */
-	LOAD_MSR_KERNEL(r10, MSR_KERNEL)
+	LOAD_REG_IMMEDIATE(r10, MSR_KERNEL)
 	rlwimi	r10, r9, 0, MSR_EE
 #else
-	LOAD_MSR_KERNEL(r10, MSR_KERNEL | MSR_EE)
+	LOAD_REG_IMMEDIATE(r10, MSR_KERNEL | MSR_EE)
 #endif
 #if defined(CONFIG_PPC_8xx) && defined(CONFIG_PERF_EVENTS)
 	mtspr	SPRN_NRI, r0
@@ -187,7 +174,7 @@
 #define EXC_XFER_TEMPLATE(hdlr, trap, msr, tfer, ret)		\
 	li	r10,trap;					\
 	stw	r10,_TRAP(r11);					\
-	LOAD_MSR_KERNEL(r10, msr);				\
+	LOAD_REG_IMMEDIATE(r10, msr);				\
 	bl	tfer;						\
 	.long	hdlr;						\
 	.long	ret
-- 
2.13.3


^ permalink raw reply related

* Re: [PATCHv5 1/2] PCI: layerscape: Add the bar_fixed_64bit property in EP driver.
From: Lorenzo Pieralisi @ 2019-08-13 10:04 UTC (permalink / raw)
  To: Xiaowei Bao
  Cc: linux-arm-kernel, roy.zang, leonard.crestez, hayashi.kunihiko,
	andrew.smirnov, linux-pci, linux-kernel, yue.wang, kishon,
	minghuan.Lian, dwmw, jonnyc, bhelgaas, tpiepho, linuxppc-dev,
	mingkai.hu, l.stach
In-Reply-To: <20190813062840.2733-1-xiaowei.bao@nxp.com>

git log --oneline --follow drivers/pci/controller/dwc/pci-layerscape.c

Do you see any commit with a $SUBJECT ending with a period ?

There is not. So remove it from yours too.

On Tue, Aug 13, 2019 at 02:28:39PM +0800, Xiaowei Bao wrote:
> The PCIe controller of layerscape just have 4 BARs, BAR0 and BAR1
> is 32bit, BAR2 and BAR4 is 64bit, this is determined by hardware,
> so set the bar_fixed_64bit with 0x14.
> 
> Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
> ---
> v2:
>  - Replace value 0x14 with a macro.
> v3:
>  - No change.
> v4:
>  - send the patch again with '--to'.
> v5:
>  - fix the commit message.
> 
>  drivers/pci/controller/dwc/pci-layerscape-ep.c | 1 +
>  1 file changed, 1 insertion(+)

scripts/get_maintainer.pl -f drivers/pci/controller/dwc/pci-layerscape-ep.c
Now, with the output you get justify all the people you send this email
to.

So, again, trim the CC list and it is the last time I tell you.

Before sending patches on mailing lists use git --dry-run to check
the emails you are sending.

Thanks,
Lorenzo

> diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> index be61d96..ca9aa45 100644
> --- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
> +++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> @@ -44,6 +44,7 @@ static const struct pci_epc_features ls_pcie_epc_features = {
>  	.linkup_notifier = false,
>  	.msi_capable = true,
>  	.msix_capable = false,
> +	.bar_fixed_64bit = (1 << BAR_2) | (1 << BAR_4),
>  };
>  
>  static const struct pci_epc_features*
> -- 
> 2.9.5
> 

^ permalink raw reply

* [PATCH v2 3/3] powerpc/xive: Implement get_irqchip_state method for XIVE to fix shutdown race
From: Paul Mackerras @ 2019-08-13 10:06 UTC (permalink / raw)
  To: linuxppc-dev, kvm; +Cc: kvm-ppc, David Gibson
In-Reply-To: <20190813095845.GA9567@blackberry>

Testing has revealed the existence of a race condition where a XIVE
interrupt being shut down can be in one of the XIVE interrupt queues
(of which there are up to 8 per CPU, one for each priority) at the
point where free_irq() is called.  If this happens, can return an
interrupt number which has been shut down.  This can lead to various
symptoms:

- irq_to_desc(irq) can be NULL.  In this case, no end-of-interrupt
  function gets called, resulting in the CPU's elevated interrupt
  priority (numerically lowered CPPR) never gets reset.  That then
  means that the CPU stops processing interrupts, causing device
  timeouts and other errors in various device drivers.

- The irq descriptor or related data structures can be in the process
  of being freed as the interrupt code is using them.  This typically
  leads to crashes due to bad pointer dereferences.

This race is basically what commit 62e0468650c3 ("genirq: Add optional
hardware synchronization for shutdown", 2019-06-28) is intended to
fix, given a get_irqchip_state() method for the interrupt controller
being used.  It works by polling the interrupt controller when an
interrupt is being freed until the controller says it is not pending.

With XIVE, the PQ bits of the interrupt source indicate the state of
the interrupt source, and in particular the P bit goes from 0 to 1 at
the point where the hardware writes an entry into the interrupt queue
that this interrupt is directed towards.  Normally, the code will then
process the interrupt and do an end-of-interrupt (EOI) operation which
will reset PQ to 00 (assuming another interrupt hasn't been generated
in the meantime).  However, there are situations where the code resets
P even though a queue entry exists (for example, by setting PQ to 01,
which disables the interrupt source), and also situations where the
code leaves P at 1 after removing the queue entry (for example, this
is done for escalation interrupts so they cannot fire again until
they are explicitly re-enabled).

The code already has a 'saved_p' flag for the interrupt source which
indicates that a queue entry exists, although it isn't maintained
consistently.  This patch adds a 'stale_p' flag to indicate that
P has been left at 1 after processing a queue entry, and adds code
to set and clear saved_p and stale_p as necessary to maintain a
consistent indication of whether a queue entry may or may not exist.

With this, we can implement xive_get_irqchip_state() by looking at
stale_p, saved_p and the ESB PQ bits for the interrupt.

There is some additional code to handle escalation interrupts
properly; because they are enabled and disabled in KVM assembly code,
which does not have access to the xive_irq_data struct for the
escalation interrupt.  Hence, stale_p may be incorrect when the
escalation interrupt is freed in kvmppc_xive_{,native_}cleanup_vcpu().
Fortunately, we can fix it up by looking at vcpu->arch.xive_esc_on,
with some careful attention to barriers in order to ensure the correct
result if xive_esc_irq() races with kvmppc_xive_cleanup_vcpu().

Finally, this adds code to make noise on the console (pr_crit and
WARN_ON(1)) if we find an interrupt queue entry for an interrupt
which does not have a descriptor.  While this won't catch the race
reliably, if it does get triggered it will be an indication that
the race is occurring and needs to be debugged.

Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
---
v2: call xive_cleanup_single_escalation
from kvmppc_xive_native_cleanup_vcpu() too.

 arch/powerpc/include/asm/xive.h       |  8 ++++
 arch/powerpc/kvm/book3s_xive.c        | 31 +++++++++++++
 arch/powerpc/kvm/book3s_xive.h        |  2 +
 arch/powerpc/kvm/book3s_xive_native.c |  3 ++
 arch/powerpc/sysdev/xive/common.c     | 87 ++++++++++++++++++++++++++---------
 5 files changed, 108 insertions(+), 23 deletions(-)

diff --git a/arch/powerpc/include/asm/xive.h b/arch/powerpc/include/asm/xive.h
index e401698..efb0e59 100644
--- a/arch/powerpc/include/asm/xive.h
+++ b/arch/powerpc/include/asm/xive.h
@@ -46,7 +46,15 @@ struct xive_irq_data {
 
 	/* Setup/used by frontend */
 	int target;
+	/*
+	 * saved_p means that there is a queue entry for this interrupt
+	 * in some CPU's queue (not including guest vcpu queues), even
+	 * if P is not set in the source ESB.
+	 * stale_p means that there is no queue entry for this interrupt
+	 * in some CPU's queue, even if P is set in the source ESB.
+	 */
 	bool saved_p;
+	bool stale_p;
 };
 #define XIVE_IRQ_FLAG_STORE_EOI	0x01
 #define XIVE_IRQ_FLAG_LSI	0x02
diff --git a/arch/powerpc/kvm/book3s_xive.c b/arch/powerpc/kvm/book3s_xive.c
index 586867e..591bfb4 100644
--- a/arch/powerpc/kvm/book3s_xive.c
+++ b/arch/powerpc/kvm/book3s_xive.c
@@ -166,6 +166,9 @@ static irqreturn_t xive_esc_irq(int irq, void *data)
 	 */
 	vcpu->arch.xive_esc_on = false;
 
+	/* This orders xive_esc_on = false vs. subsequent stale_p = true */
+	smp_wmb();	/* goes with smp_mb() in cleanup_single_escalation */
+
 	return IRQ_HANDLED;
 }
 
@@ -1119,6 +1122,31 @@ void kvmppc_xive_disable_vcpu_interrupts(struct kvm_vcpu *vcpu)
 	vcpu->arch.xive_esc_raddr = 0;
 }
 
+/*
+ * In single escalation mode, the escalation interrupt is marked so
+ * that EOI doesn't re-enable it, but just sets the stale_p flag to
+ * indicate that the P bit has already been dealt with.  However, the
+ * assembly code that enters the guest sets PQ to 00 without clearing
+ * stale_p (because it has no easy way to address it).  Hence we have
+ * to adjust stale_p before shutting down the interrupt.
+ */
+void xive_cleanup_single_escalation(struct kvm_vcpu *vcpu,
+				    struct kvmppc_xive_vcpu *xc, int irq)
+{
+	struct irq_data *d = irq_get_irq_data(irq);
+	struct xive_irq_data *xd = irq_data_get_irq_handler_data(d);
+
+	/*
+	 * This slightly odd sequence gives the right result
+	 * (i.e. stale_p set if xive_esc_on is false) even if
+	 * we race with xive_esc_irq() and xive_irq_eoi().
+	 */
+	xd->stale_p = false;
+	smp_mb();		/* paired with smb_wmb in xive_esc_irq */
+	if (!vcpu->arch.xive_esc_on)
+		xd->stale_p = true;
+}
+
 void kvmppc_xive_cleanup_vcpu(struct kvm_vcpu *vcpu)
 {
 	struct kvmppc_xive_vcpu *xc = vcpu->arch.xive_vcpu;
@@ -1143,6 +1171,9 @@ void kvmppc_xive_cleanup_vcpu(struct kvm_vcpu *vcpu)
 	/* Free escalations */
 	for (i = 0; i < KVMPPC_XIVE_Q_COUNT; i++) {
 		if (xc->esc_virq[i]) {
+			if (xc->xive->single_escalation)
+				xive_cleanup_single_escalation(vcpu, xc,
+							xc->esc_virq[i]);
 			free_irq(xc->esc_virq[i], vcpu);
 			irq_dispose_mapping(xc->esc_virq[i]);
 			kfree(xc->esc_virq_names[i]);
diff --git a/arch/powerpc/kvm/book3s_xive.h b/arch/powerpc/kvm/book3s_xive.h
index 50494d0..955b820 100644
--- a/arch/powerpc/kvm/book3s_xive.h
+++ b/arch/powerpc/kvm/book3s_xive.h
@@ -282,6 +282,8 @@ int kvmppc_xive_select_target(struct kvm *kvm, u32 *server, u8 prio);
 int kvmppc_xive_attach_escalation(struct kvm_vcpu *vcpu, u8 prio,
 				  bool single_escalation);
 struct kvmppc_xive *kvmppc_xive_get_device(struct kvm *kvm, u32 type);
+void xive_cleanup_single_escalation(struct kvm_vcpu *vcpu,
+				    struct kvmppc_xive_vcpu *xc, int irq);
 
 #endif /* CONFIG_KVM_XICS */
 #endif /* _KVM_PPC_BOOK3S_XICS_H */
diff --git a/arch/powerpc/kvm/book3s_xive_native.c b/arch/powerpc/kvm/book3s_xive_native.c
index 11b91b4..f0cab43 100644
--- a/arch/powerpc/kvm/book3s_xive_native.c
+++ b/arch/powerpc/kvm/book3s_xive_native.c
@@ -71,6 +71,9 @@ void kvmppc_xive_native_cleanup_vcpu(struct kvm_vcpu *vcpu)
 	for (i = 0; i < KVMPPC_XIVE_Q_COUNT; i++) {
 		/* Free the escalation irq */
 		if (xc->esc_virq[i]) {
+			if (xc->xive->single_escalation)
+				xive_cleanup_single_escalation(vcpu, xc,
+							xc->esc_virq[i]);
 			free_irq(xc->esc_virq[i], vcpu);
 			irq_dispose_mapping(xc->esc_virq[i]);
 			kfree(xc->esc_virq_names[i]);
diff --git a/arch/powerpc/sysdev/xive/common.c b/arch/powerpc/sysdev/xive/common.c
index 1cdb395..be86fce 100644
--- a/arch/powerpc/sysdev/xive/common.c
+++ b/arch/powerpc/sysdev/xive/common.c
@@ -135,7 +135,7 @@ static u32 xive_read_eq(struct xive_q *q, bool just_peek)
 static u32 xive_scan_interrupts(struct xive_cpu *xc, bool just_peek)
 {
 	u32 irq = 0;
-	u8 prio;
+	u8 prio = 0;
 
 	/* Find highest pending priority */
 	while (xc->pending_prio != 0) {
@@ -148,8 +148,19 @@ static u32 xive_scan_interrupts(struct xive_cpu *xc, bool just_peek)
 		irq = xive_read_eq(&xc->queue[prio], just_peek);
 
 		/* Found something ? That's it */
-		if (irq)
-			break;
+		if (irq) {
+			if (just_peek || irq_to_desc(irq))
+				break;
+			/*
+			 * We should never get here; if we do then we must
+			 * have failed to synchronize the interrupt properly
+			 * when shutting it down.
+			 */
+			pr_crit("xive: got interrupt %d without descriptor, dropping\n",
+				irq);
+			WARN_ON(1);
+			continue;
+		}
 
 		/* Clear pending bits */
 		xc->pending_prio &= ~(1 << prio);
@@ -307,6 +318,7 @@ static void xive_do_queue_eoi(struct xive_cpu *xc)
  */
 static void xive_do_source_eoi(u32 hw_irq, struct xive_irq_data *xd)
 {
+	xd->stale_p = false;
 	/* If the XIVE supports the new "store EOI facility, use it */
 	if (xd->flags & XIVE_IRQ_FLAG_STORE_EOI)
 		xive_esb_write(xd, XIVE_ESB_STORE_EOI, 0);
@@ -350,7 +362,7 @@ static void xive_do_source_eoi(u32 hw_irq, struct xive_irq_data *xd)
 	}
 }
 
-/* irq_chip eoi callback */
+/* irq_chip eoi callback, called with irq descriptor lock held */
 static void xive_irq_eoi(struct irq_data *d)
 {
 	struct xive_irq_data *xd = irq_data_get_irq_handler_data(d);
@@ -366,6 +378,8 @@ static void xive_irq_eoi(struct irq_data *d)
 	if (!irqd_irq_disabled(d) && !irqd_is_forwarded_to_vcpu(d) &&
 	    !(xd->flags & XIVE_IRQ_NO_EOI))
 		xive_do_source_eoi(irqd_to_hwirq(d), xd);
+	else
+		xd->stale_p = true;
 
 	/*
 	 * Clear saved_p to indicate that it's no longer occupying
@@ -397,11 +411,16 @@ static void xive_do_source_set_mask(struct xive_irq_data *xd,
 	 */
 	if (mask) {
 		val = xive_esb_read(xd, XIVE_ESB_SET_PQ_01);
-		xd->saved_p = !!(val & XIVE_ESB_VAL_P);
-	} else if (xd->saved_p)
+		if (!xd->stale_p && !!(val & XIVE_ESB_VAL_P))
+			xd->saved_p = true;
+		xd->stale_p = false;
+	} else if (xd->saved_p) {
 		xive_esb_read(xd, XIVE_ESB_SET_PQ_10);
-	else
+		xd->saved_p = false;
+	} else {
 		xive_esb_read(xd, XIVE_ESB_SET_PQ_00);
+		xd->stale_p = false;
+	}
 }
 
 /*
@@ -541,6 +560,8 @@ static unsigned int xive_irq_startup(struct irq_data *d)
 	unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d);
 	int target, rc;
 
+	xd->saved_p = false;
+	xd->stale_p = false;
 	pr_devel("xive_irq_startup: irq %d [0x%x] data @%p\n",
 		 d->irq, hw_irq, d);
 
@@ -587,6 +608,7 @@ static unsigned int xive_irq_startup(struct irq_data *d)
 	return 0;
 }
 
+/* called with irq descriptor lock held */
 static void xive_irq_shutdown(struct irq_data *d)
 {
 	struct xive_irq_data *xd = irq_data_get_irq_handler_data(d);
@@ -602,16 +624,6 @@ static void xive_irq_shutdown(struct irq_data *d)
 	xive_do_source_set_mask(xd, true);
 
 	/*
-	 * The above may have set saved_p. We clear it otherwise it
-	 * will prevent re-enabling later on. It is ok to forget the
-	 * fact that the interrupt might be in a queue because we are
-	 * accounting that already in xive_dec_target_count() and will
-	 * be re-routing it to a new queue with proper accounting when
-	 * it's started up again
-	 */
-	xd->saved_p = false;
-
-	/*
 	 * Mask the interrupt in HW in the IVT/EAS and set the number
 	 * to be the "bad" IRQ number
 	 */
@@ -797,6 +809,10 @@ static int xive_irq_retrigger(struct irq_data *d)
 	return 1;
 }
 
+/*
+ * Caller holds the irq descriptor lock, so this won't be called
+ * concurrently with xive_get_irqchip_state on the same interrupt.
+ */
 static int xive_irq_set_vcpu_affinity(struct irq_data *d, void *state)
 {
 	struct xive_irq_data *xd = irq_data_get_irq_handler_data(d);
@@ -820,6 +836,10 @@ static int xive_irq_set_vcpu_affinity(struct irq_data *d, void *state)
 
 		/* Set it to PQ=10 state to prevent further sends */
 		pq = xive_esb_read(xd, XIVE_ESB_SET_PQ_10);
+		if (!xd->stale_p) {
+			xd->saved_p = !!(pq & XIVE_ESB_VAL_P);
+			xd->stale_p = !xd->saved_p;
+		}
 
 		/* No target ? nothing to do */
 		if (xd->target == XIVE_INVALID_TARGET) {
@@ -827,7 +847,7 @@ static int xive_irq_set_vcpu_affinity(struct irq_data *d, void *state)
 			 * An untargetted interrupt should have been
 			 * also masked at the source
 			 */
-			WARN_ON(pq & 2);
+			WARN_ON(xd->saved_p);
 
 			return 0;
 		}
@@ -847,9 +867,8 @@ static int xive_irq_set_vcpu_affinity(struct irq_data *d, void *state)
 		 * This saved_p is cleared by the host EOI, when we know
 		 * for sure the queue slot is no longer in use.
 		 */
-		if (pq & 2) {
-			pq = xive_esb_read(xd, XIVE_ESB_SET_PQ_11);
-			xd->saved_p = true;
+		if (xd->saved_p) {
+			xive_esb_read(xd, XIVE_ESB_SET_PQ_11);
 
 			/*
 			 * Sync the XIVE source HW to ensure the interrupt
@@ -862,8 +881,7 @@ static int xive_irq_set_vcpu_affinity(struct irq_data *d, void *state)
 			 */
 			if (xive_ops->sync_source)
 				xive_ops->sync_source(hw_irq);
-		} else
-			xd->saved_p = false;
+		}
 	} else {
 		irqd_clr_forwarded_to_vcpu(d);
 
@@ -914,6 +932,23 @@ static int xive_irq_set_vcpu_affinity(struct irq_data *d, void *state)
 	return 0;
 }
 
+/* Called with irq descriptor lock held. */
+static int xive_get_irqchip_state(struct irq_data *data,
+				  enum irqchip_irq_state which, bool *state)
+{
+	struct xive_irq_data *xd = irq_data_get_irq_handler_data(data);
+
+	switch (which) {
+	case IRQCHIP_STATE_ACTIVE:
+		*state = !xd->stale_p &&
+			 (xd->saved_p ||
+			  !!(xive_esb_read(xd, XIVE_ESB_GET) & XIVE_ESB_VAL_P));
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
 static struct irq_chip xive_irq_chip = {
 	.name = "XIVE-IRQ",
 	.irq_startup = xive_irq_startup,
@@ -925,6 +960,7 @@ static struct irq_chip xive_irq_chip = {
 	.irq_set_type = xive_irq_set_type,
 	.irq_retrigger = xive_irq_retrigger,
 	.irq_set_vcpu_affinity = xive_irq_set_vcpu_affinity,
+	.irq_get_irqchip_state = xive_get_irqchip_state,
 };
 
 bool is_xive_irq(struct irq_chip *chip)
@@ -1338,6 +1374,11 @@ static void xive_flush_cpu_queue(unsigned int cpu, struct xive_cpu *xc)
 		xd = irq_desc_get_handler_data(desc);
 
 		/*
+		 * Clear saved_p to indicate that it's no longer pending
+		 */
+		xd->saved_p = false;
+
+		/*
 		 * For LSIs, we EOI, this will cause a resend if it's
 		 * still asserted. Otherwise do an MSI retrigger.
 		 */
-- 
2.7.4


^ permalink raw reply related

* [PATCH v2 2/3] KVM: PPC: Book3S HV: Don't push XIVE context when not using XIVE device
From: Paul Mackerras @ 2019-08-13 10:01 UTC (permalink / raw)
  To: linuxppc-dev, kvm; +Cc: kvm-ppc, David Gibson
In-Reply-To: <20190813095845.GA9567@blackberry>

At present, when running a guest on POWER9 using HV KVM but not using
an in-kernel interrupt controller (XICS or XIVE), for example if QEMU
is run with the kernel_irqchip=off option, the guest entry code goes
ahead and tries to load the guest context into the XIVE hardware, even
though no context has been set up.

To fix this, we check that the "CAM word" is non-zero before pushing
it to the hardware.  The CAM word is initialized to a non-zero value
in kvmppc_xive_connect_vcpu() and kvmppc_xive_native_connect_vcpu(),
and is now cleared in kvmppc_xive_{,native_}cleanup_vcpu.

Cc: stable@vger.kernel.org # v4.11+
Reported-by: Cédric Le Goater <clg@kaod.org>
Fixes: 5af50993850a ("KVM: PPC: Book3S HV: Native usage of the XIVE interrupt controller")
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
---
 arch/powerpc/kvm/book3s_hv_rmhandlers.S |  2 ++
 arch/powerpc/kvm/book3s_xive.c          | 11 ++++++++++-
 arch/powerpc/kvm/book3s_xive_native.c   |  3 +++
 3 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index 2e7e788..07181d0 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -942,6 +942,8 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_300)
 	ld	r11, VCPU_XIVE_SAVED_STATE(r4)
 	li	r9, TM_QW1_OS
 	lwz	r8, VCPU_XIVE_CAM_WORD(r4)
+	cmpwi	r8, 0
+	beq	no_xive
 	li	r7, TM_QW1_OS + TM_WORD2
 	mfmsr	r0
 	andi.	r0, r0, MSR_DR		/* in real mode? */
diff --git a/arch/powerpc/kvm/book3s_xive.c b/arch/powerpc/kvm/book3s_xive.c
index 09f838a..586867e 100644
--- a/arch/powerpc/kvm/book3s_xive.c
+++ b/arch/powerpc/kvm/book3s_xive.c
@@ -67,8 +67,14 @@ void kvmppc_xive_push_vcpu(struct kvm_vcpu *vcpu)
 	void __iomem *tima = local_paca->kvm_hstate.xive_tima_virt;
 	u64 pq;
 
-	if (!tima)
+	/*
+	 * Nothing to do if the platform doesn't have a XIVE
+	 * or this vCPU doesn't have its own XIVE context
+	 * (e.g. because it's not using an in-kernel interrupt controller).
+	 */
+	if (!tima || !vcpu->arch.xive_cam_word)
 		return;
+
 	eieio();
 	__raw_writeq(vcpu->arch.xive_saved_state.w01, tima + TM_QW1_OS);
 	__raw_writel(vcpu->arch.xive_cam_word, tima + TM_QW1_OS + TM_WORD2);
@@ -1146,6 +1152,9 @@ void kvmppc_xive_cleanup_vcpu(struct kvm_vcpu *vcpu)
 	/* Disable the VP */
 	xive_native_disable_vp(xc->vp_id);
 
+	/* Clear the cam word so guest entry won't try to push context */
+	vcpu->arch.xive_cam_word = 0;
+
 	/* Free the queues */
 	for (i = 0; i < KVMPPC_XIVE_Q_COUNT; i++) {
 		struct xive_q *q = &xc->queues[i];
diff --git a/arch/powerpc/kvm/book3s_xive_native.c b/arch/powerpc/kvm/book3s_xive_native.c
index 368427f..11b91b4 100644
--- a/arch/powerpc/kvm/book3s_xive_native.c
+++ b/arch/powerpc/kvm/book3s_xive_native.c
@@ -81,6 +81,9 @@ void kvmppc_xive_native_cleanup_vcpu(struct kvm_vcpu *vcpu)
 	/* Disable the VP */
 	xive_native_disable_vp(xc->vp_id);
 
+	/* Clear the cam word so guest entry won't try to push context */
+	vcpu->arch.xive_cam_word = 0;
+
 	/* Free the queues */
 	for (i = 0; i < KVMPPC_XIVE_Q_COUNT; i++) {
 		kvmppc_xive_native_cleanup_queue(vcpu, i);
-- 
2.7.4


^ permalink raw reply related

* [PATCH v2 0/3] powerpc/xive: Fix race condition leading to host crashes and hangs
From: Paul Mackerras @ 2019-08-13  9:58 UTC (permalink / raw)
  To: linuxppc-dev, kvm; +Cc: kvm-ppc, David Gibson

This series fixes a race condition that has been observed in testing
on POWER9 machines running KVM guests.  An interrupt being freed by
free_irq() can have an instance present in a XIVE interrupt queue,
which can then be presented to the generic interrupt code after the
data structures for it have been freed, leading to a variety of
crashes and hangs.

This series is based on current upstream kernel source plus Cédric Le
Goater's patch "KVM: PPC: Book3S HV: XIVE: Free escalation interrupts
before disabling the VP", which is a pre-requisite for this series.
As it touches both KVM and generic PPC code, this series will probably
go in via Michael Ellerman's powerpc tree.

V2 of this patch series adds a patch fixing a bug noticed by Cédric,
and also fixes a bug in patch 1/2 of the v1 series.

Paul.

 arch/powerpc/include/asm/xive.h         |  8 +++
 arch/powerpc/kvm/book3s_hv_rmhandlers.S | 38 +++++++++-----
 arch/powerpc/kvm/book3s_xive.c          | 42 +++++++++++++++-
 arch/powerpc/kvm/book3s_xive.h          |  2 +
 arch/powerpc/kvm/book3s_xive_native.c   |  6 +++
 arch/powerpc/sysdev/xive/common.c       | 87 ++++++++++++++++++++++++---------
 6 files changed, 146 insertions(+), 37 deletions(-)

^ permalink raw reply

* [PATCH v2 1/3] KVM: PPC: Book3S HV: Fix race in re-enabling XIVE escalation interrupts
From: Paul Mackerras @ 2019-08-13 10:03 UTC (permalink / raw)
  To: linuxppc-dev, kvm; +Cc: kvm-ppc, David Gibson
In-Reply-To: <20190813095845.GA9567@blackberry>

Escalation interrupts are interrupts sent to the host by the XIVE
hardware when it has an interrupt to deliver to a guest VCPU but that
VCPU is not running anywhere in the system.  Hence we disable the
escalation interrupt for the VCPU being run when we enter the guest
and re-enable it when the guest does an H_CEDE hypercall indicating
it is idle.

It is possible that an escalation interrupt gets generated just as we
are entering the guest.  In that case the escalation interrupt may be
using a queue entry in one of the interrupt queues, and that queue
entry may not have been processed when the guest exits with an H_CEDE.
The existing entry code detects this situation and does not clear the
vcpu->arch.xive_esc_on flag as an indication that there is a pending
queue entry (if the queue entry gets processed, xive_esc_irq() will
clear the flag).  There is a comment in the code saying that if the
flag is still set on H_CEDE, we have to abort the cede rather than
re-enabling the escalation interrupt, lest we end up with two
occurrences of the escalation interrupt in the interrupt queue.

However, the exit code doesn't do that; it aborts the cede in the sense
that vcpu->arch.ceded gets cleared, but it still enables the escalation
interrupt by setting the source's PQ bits to 00.  Instead we need to
set the PQ bits to 10, indicating that an interrupt has been triggered.
We also need to avoid setting vcpu->arch.xive_esc_on in this case
(i.e. vcpu->arch.xive_esc_on seen to be set on H_CEDE) because
xive_esc_irq() will run at some point and clear it, and if we race with
that we may end up with an incorrect result (i.e. xive_esc_on set when
the escalation interrupt has just been handled).

It is extremely unlikely that having two queue entries would cause
observable problems; theoretically it could cause queue overflow, but
the CPU would have to have thousands of interrupts targetted to it for
that to be possible.  However, this fix will also make it possible to
determine accurately whether there is an unhandled escalation
interrupt in the queue, which will be needed by the following patch.

Cc: stable@vger.kernel.org # v4.16+
Fixes: 9b9b13a6d153 ("KVM: PPC: Book3S HV: Keep XIVE escalation interrupt masked unless ceded")
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
---
v2: don't set xive_esc_on if we're not using a XIVE escalation
interrupt.

 arch/powerpc/kvm/book3s_hv_rmhandlers.S | 36 +++++++++++++++++++++------------
 1 file changed, 23 insertions(+), 13 deletions(-)

diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index 337e644..2e7e788 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -2831,29 +2831,39 @@ kvm_cede_prodded:
 kvm_cede_exit:
 	ld	r9, HSTATE_KVM_VCPU(r13)
 #ifdef CONFIG_KVM_XICS
-	/* Abort if we still have a pending escalation */
+	/* are we using XIVE with single escalation? */
+	ld	r10, VCPU_XIVE_ESC_VADDR(r9)
+	cmpdi	r10, 0
+	beq	3f
+	li	r6, XIVE_ESB_SET_PQ_00
+	/*
+	 * If we still have a pending escalation, abort the cede,
+	 * and we must set PQ to 10 rather than 00 so that we don't
+	 * potentially end up with two entries for the escalation
+	 * interrupt in the XIVE interrupt queue.  In that case
+	 * we also don't want to set xive_esc_on to 1 here in
+	 * case we race with xive_esc_irq().
+	 */
 	lbz	r5, VCPU_XIVE_ESC_ON(r9)
 	cmpwi	r5, 0
-	beq	1f
+	beq	4f
 	li	r0, 0
 	stb	r0, VCPU_CEDED(r9)
-1:	/* Enable XIVE escalation */
-	li	r5, XIVE_ESB_SET_PQ_00
+	li	r6, XIVE_ESB_SET_PQ_10
+	b	5f
+4:	li	r0, 1
+	stb	r0, VCPU_XIVE_ESC_ON(r9)
+	/* make sure store to xive_esc_on is seen before xive_esc_irq runs */
+	sync
+5:	/* Enable XIVE escalation */
 	mfmsr	r0
 	andi.	r0, r0, MSR_DR		/* in real mode? */
 	beq	1f
-	ld	r10, VCPU_XIVE_ESC_VADDR(r9)
-	cmpdi	r10, 0
-	beq	3f
-	ldx	r0, r10, r5
+	ldx	r0, r10, r6
 	b	2f
 1:	ld	r10, VCPU_XIVE_ESC_RADDR(r9)
-	cmpdi	r10, 0
-	beq	3f
-	ldcix	r0, r10, r5
+	ldcix	r0, r10, r6
 2:	sync
-	li	r0, 1
-	stb	r0, VCPU_XIVE_ESC_ON(r9)
 #endif /* CONFIG_KVM_XICS */
 3:	b	guest_exit_cont
 
-- 
2.7.4


^ permalink raw reply related

* Re: [PATCH v4 11/25] powernv/fadump: register kernel metadata address with opal
From: Mahesh J Salgaonkar @ 2019-08-13 10:41 UTC (permalink / raw)
  To: Hari Bathini
  Cc: Ananth N Mavinakayanahalli, Mahesh J Salgaonkar, Nicholas Piggin,
	linuxppc-dev, Oliver, Vasant Hegde, Stewart Smith, Daniel Axtens
In-Reply-To: <156327679568.27462.14864917663459855788.stgit@hbathini.in.ibm.com>

On 2019-07-16 17:03:15 Tue, Hari Bathini wrote:
> OPAL allows registering address with it in the first kernel and
> retrieving it after MPIPL. Setup kernel metadata and register its
> address with OPAL to use it for processing the crash dump.
> 
> Signed-off-by: Hari Bathini <hbathini@linux.ibm.com>
> ---
>  arch/powerpc/kernel/fadump-common.h          |    4 +
>  arch/powerpc/kernel/fadump.c                 |   65 ++++++++++++++---------
>  arch/powerpc/platforms/powernv/opal-fadump.c |   73 ++++++++++++++++++++++++++
>  arch/powerpc/platforms/powernv/opal-fadump.h |   37 +++++++++++++
>  arch/powerpc/platforms/pseries/rtas-fadump.c |   32 +++++++++--
>  5 files changed, 177 insertions(+), 34 deletions(-)
>  create mode 100644 arch/powerpc/platforms/powernv/opal-fadump.h
> 
[...]
> @@ -346,30 +349,42 @@ int __init fadump_reserve_mem(void)
>  		 * use memblock_find_in_range() here since it doesn't allocate
>  		 * from bottom to top.
>  		 */
> -		for (base = fw_dump.boot_memory_size;
> -		     base <= (memory_boundary - size);
> -		     base += size) {
> +		while (base <= (memory_boundary - size)) {
>  			if (memblock_is_region_memory(base, size) &&
>  			    !memblock_is_region_reserved(base, size))
>  				break;
> +
> +			base += size;
>  		}
> -		if ((base > (memory_boundary - size)) ||
> -		    memblock_reserve(base, size)) {
> +
> +		if (base > (memory_boundary - size)) {
> +			pr_err("Failed to find memory chunk for reservation\n");
> +			goto error_out;
> +		}
> +		fw_dump.reserve_dump_area_start = base;
> +
> +		/*
> +		 * Calculate the kernel metadata address and register it with
> +		 * f/w if the platform supports.
> +		 */
> +		if (fw_dump.ops->setup_kernel_metadata(&fw_dump) < 0)
> +			goto error_out;

I see setup_kernel_metadata() registers the metadata address with opal without
having any minimum data initialized in it. Secondaly, why can't this wait until
registration ? I think we should defer this until fadump registration.
What if kernel crashes before metadata area is initialized ?

> +
> +		if (memblock_reserve(base, size)) {
>  			pr_err("Failed to reserve memory\n");
> -			return 0;
> +			goto error_out;
>  		}
[...]
> -
>  static struct fadump_ops rtas_fadump_ops = {
> -	.init_fadump_mem_struct	= rtas_fadump_init_mem_struct,
> -	.register_fadump	= rtas_fadump_register_fadump,
> -	.unregister_fadump	= rtas_fadump_unregister_fadump,
> -	.invalidate_fadump	= rtas_fadump_invalidate_fadump,
> -	.process_fadump		= rtas_fadump_process_fadump,
> -	.fadump_region_show	= rtas_fadump_region_show,
> -	.fadump_trigger		= rtas_fadump_trigger,
> +	.init_fadump_mem_struct		= rtas_fadump_init_mem_struct,
> +	.get_kernel_metadata_size	= rtas_fadump_get_kernel_metadata_size,
> +	.setup_kernel_metadata		= rtas_fadump_setup_kernel_metadata,
> +	.register_fadump		= rtas_fadump_register_fadump,
> +	.unregister_fadump		= rtas_fadump_unregister_fadump,
> +	.invalidate_fadump		= rtas_fadump_invalidate_fadump,
> +	.process_fadump			= rtas_fadump_process_fadump,
> +	.fadump_region_show		= rtas_fadump_region_show,
> +	.fadump_trigger			= rtas_fadump_trigger,

Can you make the tab space changes in your previous patch where these
were initially introduced ? So that this patch can only show new members
that are added.

Thanks,
-Mahesh.


^ permalink raw reply

* RE: [EXT] Re: [PATCHv5 1/2] PCI: layerscape: Add the bar_fixed_64bit property in EP driver.
From: Xiaowei Bao @ 2019-08-13 11:02 UTC (permalink / raw)
  To: Lorenzo Pieralisi
  Cc: linux-arm-kernel@lists.infradead.org, Roy Zang, Leonard Crestez,
	hayashi.kunihiko@socionext.com, andrew.smirnov@gmail.com,
	linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org,
	yue.wang@amlogic.com, kishon@ti.com, M.h. Lian, dwmw@amazon.co.uk,
	jonnyc@amazon.com, bhelgaas@google.com, tpiepho@impinj.com,
	linuxppc-dev@lists.ozlabs.org, Mingkai Hu, l.stach@pengutronix.de
In-Reply-To: <20190813100409.GB10070@red-moon>



> -----Original Message-----
> From: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Sent: 2019年8月13日 18:04
> To: Xiaowei Bao <xiaowei.bao@nxp.com>
> Cc: bhelgaas@google.com; M.h. Lian <minghuan.lian@nxp.com>; Mingkai Hu
> <mingkai.hu@nxp.com>; Roy Zang <roy.zang@nxp.com>;
> l.stach@pengutronix.de; kishon@ti.com; tpiepho@impinj.com; Leonard
> Crestez <leonard.crestez@nxp.com>; andrew.smirnov@gmail.com;
> yue.wang@amlogic.com; hayashi.kunihiko@socionext.com;
> dwmw@amazon.co.uk; jonnyc@amazon.com; linux-pci@vger.kernel.org;
> linux-kernel@vger.kernel.org; linuxppc-dev@lists.ozlabs.org;
> linux-arm-kernel@lists.infradead.org
> Subject: [EXT] Re: [PATCHv5 1/2] PCI: layerscape: Add the bar_fixed_64bit
> property in EP driver.
> 
> Caution: EXT Email
> 
> git log --oneline --follow drivers/pci/controller/dwc/pci-layerscape.c
> 
> Do you see any commit with a $SUBJECT ending with a period ?
> 
> There is not. So remove it from yours too.
OK, thanks a lot, I will remove it in the next version patch, I have to get the approved
Form IT team of our company. 
> 
> On Tue, Aug 13, 2019 at 02:28:39PM +0800, Xiaowei Bao wrote:
> > The PCIe controller of layerscape just have 4 BARs, BAR0 and BAR1 is
> > 32bit, BAR2 and BAR4 is 64bit, this is determined by hardware, so set
> > the bar_fixed_64bit with 0x14.
> >
> > Signed-off-by: Xiaowei Bao <xiaowei.bao@nxp.com>
> > ---
> > v2:
> >  - Replace value 0x14 with a macro.
> > v3:
> >  - No change.
> > v4:
> >  - send the patch again with '--to'.
> > v5:
> >  - fix the commit message.
> >
> >  drivers/pci/controller/dwc/pci-layerscape-ep.c | 1 +
> >  1 file changed, 1 insertion(+)
> 
> scripts/get_maintainer.pl -f drivers/pci/controller/dwc/pci-layerscape-ep.c
> Now, with the output you get justify all the people you send this email to.
> 
> So, again, trim the CC list and it is the last time I tell you.
Do you mean that I use scripts/get_maintainer.pl -f drivers/pci/controller/
dwc/pci-layerscape-ep.c to get the mail list who I need to send? I use the
command of ' scripts/get_maintainer.pl *.patch' to get the mail list before.
If yes, I will use the command that you provided. Thanks a lot.
> 
> Before sending patches on mailing lists use git --dry-run to check the emails
> you are sending.
> 
> Thanks,
> Lorenzo
> 
> > diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > index be61d96..ca9aa45 100644
> > --- a/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > +++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
> > @@ -44,6 +44,7 @@ static const struct pci_epc_features
> ls_pcie_epc_features = {
> >       .linkup_notifier = false,
> >       .msi_capable = true,
> >       .msix_capable = false,
> > +     .bar_fixed_64bit = (1 << BAR_2) | (1 << BAR_4),
> >  };
> >
> >  static const struct pci_epc_features*
> > --
> > 2.9.5
> >

^ permalink raw reply

* [Bug 204479] KASAN hit at modprobe zram
From: bugzilla-daemon @ 2019-08-13 11:12 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <bug-204479-206035@https.bugzilla.kernel.org/>

https://bugzilla.kernel.org/show_bug.cgi?id=204479

--- Comment #19 from Erhard F. (erhard_f@mailbox.org) ---
Created attachment 284355
  --> https://bugzilla.kernel.org/attachment.cgi?id=284355&action=edit
dmesg (kernel 5.3-rc4 + shadow patch + parallel patch, PowerMac G4 DP)

-- 
You are receiving this mail because:
You are on the CC list for the bug.

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox