LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH 03/10] KVM: PPC: reserve a capability and ioctl numbers for realmode VFIO
From: Alexey Kardashevskiy @ 2013-08-15  7:22 UTC (permalink / raw)
  To: Alexander Graf
  Cc: kvm, linux-doc, linux-kernel, kvm-ppc, Paul Mackerras,
	linuxppc-dev
In-Reply-To: <ED8250FB-B0A8-4C32-A960-20ADB5742D2B@suse.de>

On 08/15/2013 05:16 PM, Alexander Graf wrote:
> 
> On 01.08.2013, at 06:44, Alexey Kardashevskiy wrote:
> 
>> This is to reserve a capablity number for upcoming support
>> of VFIO-IOMMU DMA operations in real mode.
>>
>> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
>>
>> ---
>> Changes:
>> 2013/07/16:
>> * changed the number
>>
>> 2013/07/11:
>> * changed order in a file, added comment about a gap in ioctl number
>>
>> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
>> ---
>> include/uapi/linux/kvm.h | 4 ++++
>> 1 file changed, 4 insertions(+)
>>
>> diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
>> index 99c2533..53c3f1f 100644
>> --- a/include/uapi/linux/kvm.h
>> +++ b/include/uapi/linux/kvm.h
>> @@ -668,6 +668,7 @@ struct kvm_ppc_smmu_info {
>> #define KVM_CAP_IRQ_XICS 92
>> #define KVM_CAP_ARM_EL1_32BIT 93
>> #define KVM_CAP_SPAPR_MULTITCE 94
>> +#define KVM_CAP_SPAPR_TCE_IOMMU 95
>>
>> #ifdef KVM_CAP_IRQ_ROUTING
>>
>> @@ -933,6 +934,9 @@ struct kvm_s390_ucas_mapping {
>> #define KVM_ARM_SET_DEVICE_ADDR	  _IOW(KVMIO,  0xab, struct kvm_arm_device_addr)
>> /* Available with KVM_CAP_PPC_RTAS */
>> #define KVM_PPC_RTAS_DEFINE_TOKEN _IOW(KVMIO,  0xac, struct kvm_rtas_token_args)
>> +/* 0xad and 0xaf are already taken */
> 
> so 0xad and 0xaf are already taken? where?

Mistype :( s/af/ae/

They are taken in this file:

1016 /* VM is being stopped by host */
1017 #define KVM_KVMCLOCK_CTRL         _IO(KVMIO,   0xad)
1018 #define KVM_ARM_VCPU_INIT         _IOW(KVMIO,  0xae, struct kvm_vcpu_init)

> 
>> +/* Available with KVM_CAP_SPAPR_TCE_IOMMU */
>> +#define KVM_CREATE_SPAPR_TCE_IOMMU _IOW(KVMIO,  0xaf, struct kvm_create_spapr_tce_iommu)
> 
> and why is this one 0xaf then?

Sorry, mistype. My bad. Sorry again.


> 
> Alex
> 
>>
>> /* ioctl for vm fd */
>> #define KVM_CREATE_DEVICE	  _IOWR(KVMIO,  0xe0, struct kvm_create_device)
>> -- 
>> 1.8.3.2
>>
> 


-- 
Alexey

^ permalink raw reply

* Re: [PATCH 03/10] KVM: PPC: reserve a capability and ioctl numbers for realmode VFIO
From: Alexander Graf @ 2013-08-15  7:16 UTC (permalink / raw)
  To: Alexey Kardashevskiy
  Cc: kvm, linux-doc, linux-kernel, kvm-ppc, Paul Mackerras,
	linuxppc-dev
In-Reply-To: <1375332272-22176-4-git-send-email-aik@ozlabs.ru>


On 01.08.2013, at 06:44, Alexey Kardashevskiy wrote:

> This is to reserve a capablity number for upcoming support
> of VFIO-IOMMU DMA operations in real mode.
>=20
> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
>=20
> ---
> Changes:
> 2013/07/16:
> * changed the number
>=20
> 2013/07/11:
> * changed order in a file, added comment about a gap in ioctl number
>=20
> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
> ---
> include/uapi/linux/kvm.h | 4 ++++
> 1 file changed, 4 insertions(+)
>=20
> diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
> index 99c2533..53c3f1f 100644
> --- a/include/uapi/linux/kvm.h
> +++ b/include/uapi/linux/kvm.h
> @@ -668,6 +668,7 @@ struct kvm_ppc_smmu_info {
> #define KVM_CAP_IRQ_XICS 92
> #define KVM_CAP_ARM_EL1_32BIT 93
> #define KVM_CAP_SPAPR_MULTITCE 94
> +#define KVM_CAP_SPAPR_TCE_IOMMU 95
>=20
> #ifdef KVM_CAP_IRQ_ROUTING
>=20
> @@ -933,6 +934,9 @@ struct kvm_s390_ucas_mapping {
> #define KVM_ARM_SET_DEVICE_ADDR	  _IOW(KVMIO,  0xab, struct =
kvm_arm_device_addr)
> /* Available with KVM_CAP_PPC_RTAS */
> #define KVM_PPC_RTAS_DEFINE_TOKEN _IOW(KVMIO,  0xac, struct =
kvm_rtas_token_args)
> +/* 0xad and 0xaf are already taken */

so 0xad and 0xaf are already taken? where?

> +/* Available with KVM_CAP_SPAPR_TCE_IOMMU */
> +#define KVM_CREATE_SPAPR_TCE_IOMMU _IOW(KVMIO,  0xaf, struct =
kvm_create_spapr_tce_iommu)

and why is this one 0xaf then?


Alex

>=20
> /* ioctl for vm fd */
> #define KVM_CREATE_DEVICE	  _IOWR(KVMIO,  0xe0, struct =
kvm_create_device)
> --=20
> 1.8.3.2
>=20

^ permalink raw reply

* Re: [PATCH v2] KVM: PPC: move iommu_add_device earlier
From: Wei Yang @ 2013-08-15  5:55 UTC (permalink / raw)
  To: Alexey Kardashevskiy
  Cc: Paul Mackerras, alex.williamson, linuxppc-dev, linux-kernel, joro
In-Reply-To: <1376535439-12838-1-git-send-email-aik@ozlabs.ru>

Alexey,

On Thu, Aug 15, 2013 at 12:57:19PM +1000, Alexey Kardashevskiy wrote:
>The current implementation of IOMMU on sPAPR does not use iommu_ops
>and therefore does not call IOMMU API's bus_set_iommu() which
>1) sets iommu_ops for a bus
>2) registers a bus notifier
>Instead, PCI devices are added to IOMMU groups from
>subsys_initcall_sync(tce_iommu_init) which does basically the same
>thing without using iommu_ops callbacks.
>
>However Freescale PAMU driver (https://lkml.org/lkml/2013/7/1/158)
>implements iommu_ops and when tce_iommu_init is called, every PCI device
>is already added to some group so there is a conflict.
>
>This patch does 2 things:
>1. removes the loop in which PCI devices were added to groups and
>adds devices as soon as they get the iommu_table pointer assigned to them.
>For this, the set_iommu_table_base_and_group() function is introduced.
>2. moves a bus notifier to powernv code (for hotplug) in order to avoid
>conflict with the notifier from the Freescale driver.
>
>iommu_add_device() and iommu_del_device() are public now.

Small suggestion, how about add a prefix like "ppc_"?

Since on intel, it has intel_iommu_add_device. Maybe this could help the
audience.

>
>Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
>---
>
>@@ -623,3 +623,33 @@ void __init pnv_pci_init(void)
> 	ppc_md.teardown_msi_irqs = pnv_teardown_msi_irqs;
> #endif
> }
>+
>+static int tce_iommu_bus_notifier(struct notifier_block *nb,
>+		unsigned long action, void *data)
>+{
>+	struct device *dev = data;
>+
>+	switch (action) {
>+	case BUS_NOTIFY_ADD_DEVICE:
>+		return iommu_add_device(dev);
>+	case BUS_NOTIFY_DEL_DEVICE:
>+		iommu_del_device(dev);
>+		return 0;

Recently, I encounter a problem for device remove. In some cases, the device
will not belong to any iommu_group. For example, the DMA space is not enough
and can't allocate a TCE segment. (This happens on P7IOC. I think on P8 it
won't happen.) In this case, dev->iommu_group would be NULL and kernel crash
in iommu_group_remove_device(), since it try to reference group->notifier.

In iommu_bus_notifier(), it will check dev->iommu_group before calling the
remove_device. 
	if (ops->remove_device && dev->iommu_group)

So I suggest to add this check here too.

BTW, I have a patch like this, which I put the check in iommu_group_remove_device.
This could protect the kernel from do the removing without the check outside. 

Author: Wei Yang <weiyang@linux.vnet.ibm.com>
Date:   Wed Aug 14 04:45:06 2013 -0400

    iommu: check dev->iommu_group before removing a device 
    
    In some cases, one device may not associate with any iommu_group.
    For example, not enough DMA address space.
    
    For those devices, kernel will crash when try to remove it from an iommu_group.
    
    This patch do the check before remove it.
    
    Signed-off-by: Wei Yang <weiyang@linux.vnet.ibm.com>

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index fbe9ca7..fe41946 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -379,6 +379,9 @@ void iommu_group_remove_device(struct device *dev)
        struct iommu_group *group = dev->iommu_group;
        struct iommu_device *tmp_device, *device = NULL;
 
+       if (!group)
+               return;
+
        /* Pre-notify listeners that a device is being removed. */
        blocking_notifier_call_chain(&group->notifier,
                                     IOMMU_GROUP_NOTIFY_DEL_DEVICE, dev);

I am not sure which place is better, in iommu_group_remove_device() or in the 
tce_iommu_bus_notifier().

I am glad to hear your suggestions.


-- 
Richard Yang
Help you, Help me

^ permalink raw reply related

* [PATCH 5/8] powerpc/pseries: do all node initialization in dlpar_parse_cc_node
From: Tyrel Datwyler @ 2013-08-15  5:23 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: nfont, Tyrel Datwyler
In-Reply-To: <1376544232-24936-1-git-send-email-tyreld@linux.vnet.ibm.com>

Currently the OF_DYNAMIC and kref initialization for a node happens in
dlpar_attach_node. However, a node passed to dlpar_attach_node may be a tree
containing child nodes, and no initialization traversal is done on the
tree. Since the children never get their kref initialized or the OF_DYNAMIC
flag set these nodes are prevented from ever being released from memory
should they become detached. This initialization step is better done at the
time each node is allocated in dlpar_parse_cc_node.

Signed-off-by: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
---
 arch/powerpc/platforms/pseries/dlpar.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c
index a1a7b9a..c855233 100644
--- a/arch/powerpc/platforms/pseries/dlpar.c
+++ b/arch/powerpc/platforms/pseries/dlpar.c
@@ -83,6 +83,9 @@ static struct device_node *dlpar_parse_cc_node(struct cc_workarea *ccwa)
 		return NULL;
 	}
 
+	of_node_set_flag(dn, OF_DYNAMIC);
+	kref_init(&dn->kref);
+
 	return dn;
 }
 
@@ -256,8 +259,6 @@ int dlpar_attach_node(struct device_node *dn)
 {
 	int rc;
 
-	of_node_set_flag(dn, OF_DYNAMIC);
-	kref_init(&dn->kref);
 	dn->parent = derive_parent(dn->full_name);
 	if (!dn->parent)
 		return -ENOMEM;
-- 
1.7.12.4

^ permalink raw reply related

* [PATCH 8/8] powerpc/pseries: child nodes are not detached by dlpar_detach_node
From: Tyrel Datwyler @ 2013-08-15  5:23 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: nfont, Tyrel Datwyler
In-Reply-To: <1376544232-24936-1-git-send-email-tyreld@linux.vnet.ibm.com>

Calls to dlpar_detach_node do not iterate over child nodes detaching them as
well. By iterating and detaching the child nodes we ensure that they have the
OF_DETACHED flag set and that their reference counts are decremented such that
the node will be freed from memory by of_node_release.

Signed-off-by: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
---
 arch/powerpc/platforms/pseries/dlpar.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c
index 4ea667d..7cfdaae 100644
--- a/arch/powerpc/platforms/pseries/dlpar.c
+++ b/arch/powerpc/platforms/pseries/dlpar.c
@@ -286,8 +286,15 @@ int dlpar_attach_node(struct device_node *dn)
 
 int dlpar_detach_node(struct device_node *dn)
 {
+	struct device_node *child;
 	int rc;
 
+	child = of_get_next_child(dn, NULL);
+	while (child) {
+		dlpar_detach_node(child);
+		child = of_get_next_child(dn, child);
+	}
+
 	rc = of_detach_node(dn);
 	if (rc)
 		return rc;
-- 
1.7.12.4

^ permalink raw reply related

* [PATCH 4/8] powerpc/pseries: fix parsing of initial node path in update_dt_node
From: Tyrel Datwyler @ 2013-08-15  5:23 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: nfont, Tyrel Datwyler
In-Reply-To: <1376544232-24936-1-git-send-email-tyreld@linux.vnet.ibm.com>

On the first call to ibm,update-properties for a node the first property
returned is the full node path. Currently this is not parsed correctly by the
update_dt_node function. Commit 2e9b7b0 attempted to fix this, but was
incorrect as it made a wrong assumption about the layout of the first
property in the work area. Further, if ibm,update-properties must be called
multiple times for the same node this special property should only be skipped
after the initial call. The first property descriptor returned consists of
the property name, property value length, and property value. The property
name is an empty string, property length is encoded in 4 byte integer, and
the property value is the node path.

Signed-off-by: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
---
 arch/powerpc/platforms/pseries/mobility.c | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c
index 023e354..ed5426f 100644
--- a/arch/powerpc/platforms/pseries/mobility.c
+++ b/arch/powerpc/platforms/pseries/mobility.c
@@ -161,18 +161,19 @@ static int update_dt_node(u32 phandle, s32 scope)
 
 		prop_data = rtas_buf + sizeof(*upwa);
 
-		/* The first element of the buffer is the path of the node
-		 * being updated in the form of a 8 byte string length
-		 * followed by the string. Skip past this to get to the
-		 * properties being updated.
+		/* On the first call to ibm,update-properties for a node the
+		 * the first property value descriptor contains an empty
+		 * property name, the property value length encoded as u32,
+		 * and the property value is the node path being updated.
 		 */
-		vd = *prop_data++;
-		prop_data += vd;
+		if (*prop_data == 0) {
+			prop_data++;
+			vd = *(u32 *)prop_data;
+			prop_data += vd + sizeof(vd);
+			upwa->nprops--;
+		}
 
-		/* The path we skipped over is counted as one of the elements
-		 * returned so start counting at one.
-		 */
-		for (i = 1; i < upwa->nprops; i++) {
+		for (i = 0; i < upwa->nprops; i++) {
 			char *prop_name;
 
 			prop_name = prop_data;
-- 
1.7.12.4

^ permalink raw reply related

* [PATCH 6/8] powerpc/pseries: make dlpar_configure_connector parent node aware
From: Tyrel Datwyler @ 2013-08-15  5:23 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: nfont, Tyrel Datwyler
In-Reply-To: <1376544232-24936-1-git-send-email-tyreld@linux.vnet.ibm.com>

Currently the device nodes created in the device subtree returned by a call to
dlpar_configure_connector are all named in the root node. This is because the
the node name in the work area returned by ibm,configure-connector rtas call
only contains the node name and not the entire node path. Passing the parent
node where the new subtree will be created to dlpar_configure_connector allows
the correct node path to be prefixed in the full_name field.

Signed-off-by: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
---
 arch/powerpc/platforms/pseries/dlpar.c    | 55 ++++++++++++++++---------------
 arch/powerpc/platforms/pseries/mobility.c | 11 +++----
 arch/powerpc/platforms/pseries/pseries.h  |  2 +-
 3 files changed, 34 insertions(+), 34 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c
index c855233..4ea667d 100644
--- a/arch/powerpc/platforms/pseries/dlpar.c
+++ b/arch/powerpc/platforms/pseries/dlpar.c
@@ -63,21 +63,24 @@ static struct property *dlpar_parse_cc_property(struct cc_workarea *ccwa)
 	return prop;
 }
 
-static struct device_node *dlpar_parse_cc_node(struct cc_workarea *ccwa)
+static struct device_node *dlpar_parse_cc_node(struct cc_workarea *ccwa,
+					       const char *path)
 {
 	struct device_node *dn;
 	char *name;
 
+	/* If parent node path is "/" advance path to NULL terminator to
+	 * prevent double leading slashs in full_name.
+	 */
+	if (!path[1])
+		path++;
+
 	dn = kzalloc(sizeof(*dn), GFP_KERNEL);
 	if (!dn)
 		return NULL;
 
-	/* The configure connector reported name does not contain a
-	 * preceding '/', so we allocate a buffer large enough to
-	 * prepend this to the full_name.
-	 */
 	name = (char *)ccwa + ccwa->name_offset;
-	dn->full_name = kasprintf(GFP_KERNEL, "/%s", name);
+	dn->full_name = kasprintf(GFP_KERNEL, "%s/%s", path, name);
 	if (!dn->full_name) {
 		kfree(dn);
 		return NULL;
@@ -123,7 +126,8 @@ void dlpar_free_cc_nodes(struct device_node *dn)
 #define CALL_AGAIN	-2
 #define ERR_CFG_USE     -9003
 
-struct device_node *dlpar_configure_connector(u32 drc_index)
+struct device_node *dlpar_configure_connector(u32 drc_index,
+					      struct device_node *parent)
 {
 	struct device_node *dn;
 	struct device_node *first_dn = NULL;
@@ -132,6 +136,7 @@ struct device_node *dlpar_configure_connector(u32 drc_index)
 	struct property *last_property = NULL;
 	struct cc_workarea *ccwa;
 	char *data_buf;
+	const char *parent_path = parent->full_name;
 	int cc_token;
 	int rc = -1;
 
@@ -165,7 +170,7 @@ struct device_node *dlpar_configure_connector(u32 drc_index)
 			break;
 
 		case NEXT_SIBLING:
-			dn = dlpar_parse_cc_node(ccwa);
+			dn = dlpar_parse_cc_node(ccwa, parent_path);
 			if (!dn)
 				goto cc_error;
 
@@ -175,13 +180,17 @@ struct device_node *dlpar_configure_connector(u32 drc_index)
 			break;
 
 		case NEXT_CHILD:
-			dn = dlpar_parse_cc_node(ccwa);
+			if (first_dn)
+				parent_path = last_dn->full_name;
+
+			dn = dlpar_parse_cc_node(ccwa, parent_path);
 			if (!dn)
 				goto cc_error;
 
-			if (!first_dn)
+			if (!first_dn) {
+				dn->parent = parent;
 				first_dn = dn;
-			else {
+			} else {
 				dn->parent = last_dn;
 				if (last_dn)
 					last_dn->child = dn;
@@ -205,6 +214,7 @@ struct device_node *dlpar_configure_connector(u32 drc_index)
 
 		case PREV_PARENT:
 			last_dn = last_dn->parent;
+			parent_path = last_dn->parent->full_name;
 			break;
 
 		case CALL_AGAIN:
@@ -383,9 +393,8 @@ out:
 
 static ssize_t dlpar_cpu_probe(const char *buf, size_t count)
 {
-	struct device_node *dn;
+	struct device_node *dn, *parent;
 	unsigned long drc_index;
-	char *cpu_name;
 	int rc;
 
 	cpu_hotplug_driver_lock();
@@ -395,25 +404,19 @@ static ssize_t dlpar_cpu_probe(const char *buf, size_t count)
 		goto out;
 	}
 
-	dn = dlpar_configure_connector(drc_index);
-	if (!dn) {
-		rc = -EINVAL;
+	parent = of_find_node_by_path("/cpus");
+	if (!parent) {
+		rc = -ENODEV;
 		goto out;
 	}
 
-	/* configure-connector reports cpus as living in the base
-	 * directory of the device tree.  CPUs actually live in the
-	 * cpus directory so we need to fixup the full_name.
-	 */
-	cpu_name = kasprintf(GFP_KERNEL, "/cpus%s", dn->full_name);
-	if (!cpu_name) {
-		dlpar_free_cc_nodes(dn);
-		rc = -ENOMEM;
+	dn = dlpar_configure_connector(drc_index, parent);
+	if (!dn) {
+		rc = -EINVAL;
 		goto out;
 	}
 
-	kfree(dn->full_name);
-	dn->full_name = cpu_name;
+	of_node_put(parent);
 
 	rc = dlpar_acquire_drc(drc_index);
 	if (rc) {
diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c
index ed5426f..ff102e2 100644
--- a/arch/powerpc/platforms/pseries/mobility.c
+++ b/arch/powerpc/platforms/pseries/mobility.c
@@ -216,17 +216,14 @@ static int add_dt_node(u32 parent_phandle, u32 drc_index)
 	struct device_node *parent_dn;
 	int rc;
 
-	dn = dlpar_configure_connector(drc_index);
-	if (!dn)
+	parent_dn = of_find_node_by_phandle(parent_phandle);
+	if (!parent_dn)
 		return -ENOENT;
 
-	parent_dn = of_find_node_by_phandle(parent_phandle);
-	if (!parent_dn) {
-		dlpar_free_cc_nodes(dn);
+	dn = dlpar_configure_connector(drc_index, parent_dn);
+	if (!dn)
 		return -ENOENT;
-	}
 
-	dn->parent = parent_dn;
 	rc = dlpar_attach_node(dn);
 	if (rc)
 		dlpar_free_cc_nodes(dn);
diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h
index c2a3a25..defb3c9 100644
--- a/arch/powerpc/platforms/pseries/pseries.h
+++ b/arch/powerpc/platforms/pseries/pseries.h
@@ -56,7 +56,7 @@ extern void hvc_vio_init_early(void);
 /* Dynamic logical Partitioning/Mobility */
 extern void dlpar_free_cc_nodes(struct device_node *);
 extern void dlpar_free_cc_property(struct property *);
-extern struct device_node *dlpar_configure_connector(u32);
+extern struct device_node *dlpar_configure_connector(u32, struct device_node *);
 extern int dlpar_attach_node(struct device_node *);
 extern int dlpar_detach_node(struct device_node *);
 
-- 
1.7.12.4

^ permalink raw reply related

* [PATCH 0/8] powerpc/pseries: fix/cleanup broken mobility device-tree update code
From: Tyrel Datwyler @ 2013-08-15  5:23 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: nfont, Tyrel Datwyler

Currently we still perform updating of the device tree after a suspend or
migration from drmgr in userspace through the ugly /proc/ppc64/ofdt interface.
Code exists to do this update from within the kernel, but testing revealed it
to be severely broken to the point that the system hardlocks up stuck in an
infinite loop with irqs disabled.

The first 4 patches in the series fix several issues encountered tyring to
perform node property updates as dictated by the ibm,update-properties rtas
call. The next 2 patches refactor the logic of dlpar_configure_connector to
enusre that nodes created in a device nodes subtree are initialized
correctly. The remainder of the patchset fixes a couple problems with node
removal.

Tyrel Datwyler (8):
  powerpc/pseries: fix creation of loop in device node property list
  powerpc/pseries: fix over writing of rtas return code in
    update_dt_node
  powerpc/pseries: pack update_props_workarea to map correctly to rtas
    buffer header
  powerpc/pseries: fix parsing of initial node path in update_dt_node
  powerpc/pseries: do all node initialization in dlpar_parse_cc_node
  powerpc/pseries: make dlpar_configure_connector parent node aware
  powerpc/pseries: add mising of_node_put in delete_dt_node
  powerpc/pseries: child nodes are not detached by dlpar_detach_node

 arch/powerpc/platforms/pseries/dlpar.c    | 67 ++++++++++++++++++-------------
 arch/powerpc/platforms/pseries/mobility.c | 45 ++++++++++-----------
 arch/powerpc/platforms/pseries/pseries.h  |  2 +-
 3 files changed, 62 insertions(+), 52 deletions(-)

-- 
1.7.12.4

^ permalink raw reply

* [PATCH 7/8] powerpc/pseries: add mising of_node_put in delete_dt_node
From: Tyrel Datwyler @ 2013-08-15  5:23 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: nfont, Tyrel Datwyler
In-Reply-To: <1376544232-24936-1-git-send-email-tyreld@linux.vnet.ibm.com>

The node to be detached is retrieved via its phandle by a call to
of_find_node_by_phandle which increments the ref count. We need a matching
call to of_node_put to decrement the ref count and ensure the node is
actually freed.

Signed-off-by: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
---
 arch/powerpc/platforms/pseries/mobility.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c
index ff102e2..cde4e0a 100644
--- a/arch/powerpc/platforms/pseries/mobility.c
+++ b/arch/powerpc/platforms/pseries/mobility.c
@@ -62,6 +62,7 @@ static int delete_dt_node(u32 phandle)
 		return -ENOENT;
 
 	dlpar_detach_node(dn);
+	of_node_put(dn);
 	return 0;
 }
 
-- 
1.7.12.4

^ permalink raw reply related

* [PATCH 3/8] powerpc/pseries: pack update_props_workarea to map correctly to rtas buffer header
From: Tyrel Datwyler @ 2013-08-15  5:23 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: nfont, Tyrel Datwyler
In-Reply-To: <1376544232-24936-1-git-send-email-tyreld@linux.vnet.ibm.com>

The work area buffer returned by the ibm,update-properties rtas call contains
20 bytes of header information prior to the property value descriptor data.
Currently update_dt_node tries to advance over this header using sizeof(upwa).
The update_props_workarea struct contains 20 bytes worth of fields, that map
to the relevant header data, but the sizeof the structure is 24 bytes due to
4 bytes of padding at the end of the structure. Packing the structure ensures
that we don't advance too far over the rtas buffer.

Signed-off-by: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
---
 arch/powerpc/platforms/pseries/mobility.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c
index aaae85d..023e354 100644
--- a/arch/powerpc/platforms/pseries/mobility.c
+++ b/arch/powerpc/platforms/pseries/mobility.c
@@ -28,7 +28,7 @@ struct update_props_workarea {
 	u32 state;
 	u64 reserved;
 	u32 nprops;
-};
+} __packed;
 
 #define NODE_ACTION_MASK	0xff000000
 #define NODE_COUNT_MASK		0x00ffffff
-- 
1.7.12.4

^ permalink raw reply related

* [PATCH 1/8] powerpc/pseries: fix creation of loop in device node property list
From: Tyrel Datwyler @ 2013-08-15  5:23 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: nfont, Tyrel Datwyler
In-Reply-To: <1376544232-24936-1-git-send-email-tyreld@linux.vnet.ibm.com>

The update_dt_prop helper function fails to set the IN/OUT parameter prop to
NULL after a complete property has been parsed from the work area returned by
the ibm,update-properties rtas function. This results in the property list of
the device node being updated is corrupted and becomes a loop since the same
property structure is used repeatedly.

Signed-off-by: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
---
 arch/powerpc/platforms/pseries/mobility.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c
index 3d01eee..f28abee 100644
--- a/arch/powerpc/platforms/pseries/mobility.c
+++ b/arch/powerpc/platforms/pseries/mobility.c
@@ -119,7 +119,7 @@ static int update_dt_property(struct device_node *dn, struct property **prop,
 
 	if (!more) {
 		of_update_property(dn, new_prop);
-		new_prop = NULL;
+		*prop = NULL;
 	}
 
 	return 0;
-- 
1.7.12.4

^ permalink raw reply related

* [PATCH 2/8] powerpc/pseries: fix over writing of rtas return code in update_dt_node
From: Tyrel Datwyler @ 2013-08-15  5:23 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: nfont, Tyrel Datwyler
In-Reply-To: <1376544232-24936-1-git-send-email-tyreld@linux.vnet.ibm.com>

The rc variable is initially used to store the return code from the
ibm,update-properties rtas call which returns 0 or 1 on success. A return
code of 1 indicates that ibm,update-properties must be called again for the
node. However, the rc variable is overwritten by a call to update_dt_prop
which returns 0 on success. This results in ibm,update-properties not being
called again for the given node when the rtas call rc was previously 1.

Signed-off-by: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
---
 arch/powerpc/platforms/pseries/mobility.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c
index f28abee..aaae85d 100644
--- a/arch/powerpc/platforms/pseries/mobility.c
+++ b/arch/powerpc/platforms/pseries/mobility.c
@@ -130,7 +130,7 @@ static int update_dt_node(u32 phandle, s32 scope)
 	struct update_props_workarea *upwa;
 	struct device_node *dn;
 	struct property *prop = NULL;
-	int i, rc;
+	int i, rc, rtas_rc;
 	char *prop_data;
 	char *rtas_buf;
 	int update_properties_token;
@@ -154,9 +154,9 @@ static int update_dt_node(u32 phandle, s32 scope)
 	upwa->phandle = phandle;
 
 	do {
-		rc = mobility_rtas_call(update_properties_token, rtas_buf,
+		rtas_rc = mobility_rtas_call(update_properties_token, rtas_buf,
 					scope);
-		if (rc < 0)
+		if (rtas_rc < 0)
 			break;
 
 		prop_data = rtas_buf + sizeof(*upwa);
@@ -202,7 +202,7 @@ static int update_dt_node(u32 phandle, s32 scope)
 				prop_data += vd;
 			}
 		}
-	} while (rc == 1);
+	} while (rtas_rc == 1);
 
 	of_node_put(dn);
 	kfree(rtas_buf);
-- 
1.7.12.4

^ permalink raw reply related

* [PATCH 6/6] powerpc: Skip emulating & leave interrupts off for kernel program checks
From: Michael Ellerman @ 2013-08-15  5:22 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <1376544139-26783-1-git-send-email-michael@ellerman.id.au>

In the program check handler we handle some causes with interrupts off
and others with interrupts on.

We need to enable interrupts to handle the emulation cases, because they
access userspace memory and might sleep.

For faults in the kernel we don't want to do any emulation, and
emulate_instruction() enforces that. do_mathemu() doesn't but probably
should.

The other disadvantage of enabling interrupts for kernel faults is that
we may take another interrupt, and recurse. As seen below:

  --- Exception: e40 at c000000000004ee0 performance_monitor_relon_pSeries_1
  [link register   ] c00000000000f858 .arch_local_irq_restore+0x38/0x90
  [c000000fb185dc10] 0000000000000000 (unreliable)
  [c000000fb185dc80] c0000000007d8558 .program_check_exception+0x298/0x2d0
  [c000000fb185dd00] c000000000002f40 emulation_assist_common+0x140/0x180
  --- Exception: e40 at c000000000004ee0 performance_monitor_relon_pSeries_1
  [link register   ] c00000000000f858 .arch_local_irq_restore+0x38/0x90
  [c000000fb185dff0] 00000000008b9190 (unreliable)
  [c000000fb185e060] c0000000007d8558 .program_check_exception+0x298/0x2d0

So avoid both problems by checking if the fault was in the kernel and
skipping the enable of interrupts and the emulation. Go straight to
delivering the SIGILL, which for kernel faults calls die() and so on,
dropping us in the debugger etc.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
 arch/powerpc/kernel/traps.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index e435bc0..9515bde 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -1116,6 +1116,16 @@ void __kprobes program_check_exception(struct pt_regs *regs)
 	}
 #endif
 
+	/*
+	 * If we took the program check in the kernel skip down to sending a
+	 * SIGILL. The subsequent cases all relate to emulating instructions
+	 * which we should only do for userspace. We also do not want to enable
+	 * interrupts for kernel faults because that might lead to further
+	 * faults, and loose the context of the original exception.
+	 */
+	if (!user_mode(regs))
+		goto sigill;
+
 	/* We restore the interrupt state now */
 	if (!arch_irq_disabled_regs(regs))
 		local_irq_enable();
@@ -1168,6 +1178,7 @@ void __kprobes program_check_exception(struct pt_regs *regs)
 		}
 	}
 
+sigill:
 	if (reason & REASON_PRIVILEGED)
 		_exception(SIGILL, regs, ILL_PRVOPC, regs->nip);
 	else
-- 
1.8.1.2

^ permalink raw reply related

* [PATCH 5/6] powerpc: Add more exception trampolines for hypervisor exceptions
From: Michael Ellerman @ 2013-08-15  5:22 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <1376544139-26783-1-git-send-email-michael@ellerman.id.au>

This makes back traces and profiles easier to read.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
 arch/powerpc/kernel/exceptions-64s.S | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index ae902cae..e41f066 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -293,27 +293,31 @@ system_call_pSeries:
 	 * out of line to handle them
 	 */
 	. = 0xe00
-hv_exception_trampoline:
+hv_data_storage_trampoline:
 	SET_SCRATCH0(r13)
 	EXCEPTION_PROLOG_0(PACA_EXGEN)
 	b	h_data_storage_hv
 
 	. = 0xe20
+hv_instr_storage_trampoline:
 	SET_SCRATCH0(r13)
 	EXCEPTION_PROLOG_0(PACA_EXGEN)
 	b	h_instr_storage_hv
 
 	. = 0xe40
+emulation_assist_trampoline:
 	SET_SCRATCH0(r13)
 	EXCEPTION_PROLOG_0(PACA_EXGEN)
 	b	emulation_assist_hv
 
 	. = 0xe60
+hv_exception_trampoline:
 	SET_SCRATCH0(r13)
 	EXCEPTION_PROLOG_0(PACA_EXGEN)
 	b	hmi_exception_hv
 
 	. = 0xe80
+hv_doorbell_trampoline:
 	SET_SCRATCH0(r13)
 	EXCEPTION_PROLOG_0(PACA_EXGEN)
 	b	h_doorbell_hv
@@ -808,6 +812,7 @@ system_call_relon_pSeries:
 	b	.	/* Can't happen, see v2.07 Book III-S section 6.5 */
 
 	. = 0x4e40
+emulation_assist_relon_trampoline:
 	SET_SCRATCH0(r13)
 	EXCEPTION_PROLOG_0(PACA_EXGEN)
 	b	emulation_assist_relon_hv
@@ -816,6 +821,7 @@ system_call_relon_pSeries:
 	b	.	/* Can't happen, see v2.07 Book III-S section 6.5 */
 
 	. = 0x4e80
+h_doorbell_relon_trampoline:
 	SET_SCRATCH0(r13)
 	EXCEPTION_PROLOG_0(PACA_EXGEN)
 	b	h_doorbell_relon_hv
-- 
1.8.1.2

^ permalink raw reply related

* [PATCH 4/6] powerpc: Fix location and rename exception trampolines
From: Michael Ellerman @ 2013-08-15  5:22 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <1376544139-26783-1-git-send-email-michael@ellerman.id.au>

The symbols that name some of our exception trampolines are ahead of the
location they name. In most cases this is OK because the code is tightly
packed, but in some cases it means the symbol floats ahead of the
correct location, eg:

  c000000000000ea0 <performance_monitor_pSeries_1>:
          ...
  c000000000000f00:       7d b2 43 a6     mtsprg  2,r13

Fix them all by moving the symbol after the set of the location.

While we're moving them anyway, rename them to loose the camelcase and
to make it clear that they are trampolines.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
 arch/powerpc/kernel/exceptions-64s.S | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 902ca3c..ae902cae 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -323,32 +323,32 @@ hv_exception_trampoline:
 	 * prolog code of the PerformanceMonitor one. A little
 	 * trickery is thus necessary
 	 */
-performance_monitor_pSeries_1:
 	. = 0xf00
+performance_monitor_pseries_trampoline:
 	SET_SCRATCH0(r13)
 	EXCEPTION_PROLOG_0(PACA_EXGEN)
 	b	performance_monitor_pSeries
 
-altivec_unavailable_pSeries_1:
 	. = 0xf20
+altivec_unavailable_pseries_trampoline:
 	SET_SCRATCH0(r13)
 	EXCEPTION_PROLOG_0(PACA_EXGEN)
 	b	altivec_unavailable_pSeries
 
-vsx_unavailable_pSeries_1:
 	. = 0xf40
+vsx_unavailable_pseries_trampoline:
 	SET_SCRATCH0(r13)
 	EXCEPTION_PROLOG_0(PACA_EXGEN)
 	b	vsx_unavailable_pSeries
 
-facility_unavailable_trampoline:
 	. = 0xf60
+facility_unavailable_trampoline:
 	SET_SCRATCH0(r13)
 	EXCEPTION_PROLOG_0(PACA_EXGEN)
 	b	facility_unavailable_pSeries
 
-hv_facility_unavailable_trampoline:
 	. = 0xf80
+hv_facility_unavailable_trampoline:
 	SET_SCRATCH0(r13)
 	EXCEPTION_PROLOG_0(PACA_EXGEN)
 	b	facility_unavailable_hv
@@ -820,32 +820,32 @@ system_call_relon_pSeries:
 	EXCEPTION_PROLOG_0(PACA_EXGEN)
 	b	h_doorbell_relon_hv
 
-performance_monitor_relon_pSeries_1:
 	. = 0x4f00
+performance_monitor_relon_pseries_trampoline:
 	SET_SCRATCH0(r13)
 	EXCEPTION_PROLOG_0(PACA_EXGEN)
 	b	performance_monitor_relon_pSeries
 
-altivec_unavailable_relon_pSeries_1:
 	. = 0x4f20
+altivec_unavailable_relon_pseries_trampoline:
 	SET_SCRATCH0(r13)
 	EXCEPTION_PROLOG_0(PACA_EXGEN)
 	b	altivec_unavailable_relon_pSeries
 
-vsx_unavailable_relon_pSeries_1:
 	. = 0x4f40
+vsx_unavailable_relon_pseries_trampoline:
 	SET_SCRATCH0(r13)
 	EXCEPTION_PROLOG_0(PACA_EXGEN)
 	b	vsx_unavailable_relon_pSeries
 
-facility_unavailable_relon_trampoline:
 	. = 0x4f60
+facility_unavailable_relon_trampoline:
 	SET_SCRATCH0(r13)
 	EXCEPTION_PROLOG_0(PACA_EXGEN)
 	b	facility_unavailable_relon_pSeries
 
-hv_facility_unavailable_relon_trampoline:
 	. = 0x4f80
+hv_facility_unavailable_relon_trampoline:
 	SET_SCRATCH0(r13)
 	EXCEPTION_PROLOG_0(PACA_EXGEN)
 	b	hv_facility_unavailable_relon_hv
-- 
1.8.1.2

^ permalink raw reply related

* [PATCH 3/6] powerpc: Add more trap names to xmon
From: Michael Ellerman @ 2013-08-15  5:22 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <1376544139-26783-1-git-send-email-michael@ellerman.id.au>

We haven't updated these for a while it seems, it's nice to have in the
oops output.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
 arch/powerpc/xmon/xmon.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 96bf5bd..9f3655b 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -1256,11 +1256,18 @@ const char *getvecname(unsigned long vec)
 	case 0x700:	ret = "(Program Check)"; break;
 	case 0x800:	ret = "(FPU Unavailable)"; break;
 	case 0x900:	ret = "(Decrementer)"; break;
+	case 0x980:	ret = "(Hypervisor Decrementer)"; break;
+	case 0xa00:	ret = "(Doorbell)"; break;
 	case 0xc00:	ret = "(System Call)"; break;
 	case 0xd00:	ret = "(Single Step)"; break;
+	case 0xe40:	ret = "(Emulation Assist)"; break;
+	case 0xe60:	ret = "(HMI)"; break;
+	case 0xe80:	ret = "(Hypervisor Doorbell)"; break;
 	case 0xf00:	ret = "(Performance Monitor)"; break;
 	case 0xf20:	ret = "(Altivec Unavailable)"; break;
 	case 0x1300:	ret = "(Instruction Breakpoint)"; break;
+	case 0x1500:	ret = "(Denormalisation)"; break;
+	case 0x1700:	ret = "(Altivec Assist)"; break;
 	default: ret = "";
 	}
 	return ret;
-- 
1.8.1.2

^ permalink raw reply related

* [PATCH 2/6] powerpc/pseries: Add a warning in the case of cross-cpu VPA registration
From: Michael Ellerman @ 2013-08-15  5:22 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <1376544139-26783-1-git-send-email-michael@ellerman.id.au>

The spec says it "may be problematic" if CPU x registers the VPA of
CPU y. Add a warning in case we ever do that.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
 arch/powerpc/platforms/pseries/lpar.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index 8bad880..73d6c1b 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -68,6 +68,12 @@ void vpa_init(int cpu)
 	struct paca_struct *pp;
 	struct dtl_entry *dtl;
 
+	/*
+	 * The spec says it "may be problematic" if CPU x registers the VPA of
+	 * CPU y. We should never do that, but wail if we ever do.
+	 */
+	WARN_ON(cpu != smp_processor_id());
+
 	if (cpu_has_feature(CPU_FTR_ALTIVEC))
 		lppaca_of(cpu).vmxregs_in_use = 1;
 
-- 
1.8.1.2

^ permalink raw reply related

* [PATCH 1/6] powerpc: Update the 00-Index in Documentation/powerpc
From: Michael Ellerman @ 2013-08-15  5:22 UTC (permalink / raw)
  To: linuxppc-dev

People have been dropping things in here without updating the index, do
it for them.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
 Documentation/powerpc/00-INDEX | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/Documentation/powerpc/00-INDEX b/Documentation/powerpc/00-INDEX
index 05026ce..6db73df 100644
--- a/Documentation/powerpc/00-INDEX
+++ b/Documentation/powerpc/00-INDEX
@@ -5,13 +5,20 @@ please mail me.
 
 00-INDEX
 	- this file
+bootwrapper.txt
+	- Information on how the powerpc kernel is wrapped for boot on various
+	  different platforms.
 cpu_features.txt
 	- info on how we support a variety of CPUs with minimal compile-time
 	options.
 eeh-pci-error-recovery.txt
 	- info on PCI Bus EEH Error Recovery
+firmware-assisted-dump.txt
+	- Documentation on the firmware assisted dump mechanism "fadump".
 hvcs.txt
 	- IBM "Hypervisor Virtual Console Server" Installation Guide
+kvm_440.txt
+	- Various notes on the implementation of KVM for PowerPC 440.
 mpc52xx.txt
 	- Linux 2.6.x on MPC52xx family
 pmu-ebb.txt
@@ -19,3 +26,7 @@ pmu-ebb.txt
 qe_firmware.txt
 	- describes the layout of firmware binaries for the Freescale QUICC
 	  Engine and the code that parses and uploads the microcode therein.
+ptrace.txt
+	- Information on the ptrace interfaces for hardware debug registers.
+transactional_memory.txt
+	- Overview of the Power8 transactional memory support.
-- 
1.8.1.2

^ permalink raw reply related

* [PATCH v2] KVM: PPC: move iommu_add_device earlier
From: Alexey Kardashevskiy @ 2013-08-15  2:57 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Alexey Kardashevskiy, Paul Mackerras, linux-kernel

The current implementation of IOMMU on sPAPR does not use iommu_ops
and therefore does not call IOMMU API's bus_set_iommu() which
1) sets iommu_ops for a bus
2) registers a bus notifier
Instead, PCI devices are added to IOMMU groups from
subsys_initcall_sync(tce_iommu_init) which does basically the same
thing without using iommu_ops callbacks.

However Freescale PAMU driver (https://lkml.org/lkml/2013/7/1/158)
implements iommu_ops and when tce_iommu_init is called, every PCI device
is already added to some group so there is a conflict.

This patch does 2 things:
1. removes the loop in which PCI devices were added to groups and
adds devices as soon as they get the iommu_table pointer assigned to them.
For this, the set_iommu_table_base_and_group() function is introduced.
2. moves a bus notifier to powernv code (for hotplug) in order to avoid
conflict with the notifier from the Freescale driver.

iommu_add_device() and iommu_del_device() are public now.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
---

Changes:
v2:
* added a helper - set_iommu_table_base_and_group - which does
set_iommu_table_base() and iommu_add_device()

---
 arch/powerpc/include/asm/iommu.h            |  9 +++++++
 arch/powerpc/kernel/iommu.c                 | 41 +++--------------------------
 arch/powerpc/platforms/powernv/pci-ioda.c   |  8 +++---
 arch/powerpc/platforms/powernv/pci-p5ioc2.c |  2 +-
 arch/powerpc/platforms/powernv/pci.c        | 32 +++++++++++++++++++++-
 arch/powerpc/platforms/pseries/iommu.c      |  8 +++---
 6 files changed, 54 insertions(+), 46 deletions(-)

diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h
index c34656a..19ad77f 100644
--- a/arch/powerpc/include/asm/iommu.h
+++ b/arch/powerpc/include/asm/iommu.h
@@ -103,6 +103,15 @@ extern struct iommu_table *iommu_init_table(struct iommu_table * tbl,
 					    int nid);
 extern void iommu_register_group(struct iommu_table *tbl,
 				 int pci_domain_number, unsigned long pe_num);
+extern int iommu_add_device(struct device *dev);
+extern void iommu_del_device(struct device *dev);
+
+static inline void set_iommu_table_base_and_group(struct device *dev,
+						  void *base)
+{
+	set_iommu_table_base(dev, base);
+	iommu_add_device(dev);
+}
 
 extern int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
 			struct scatterlist *sglist, int nelems,
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index b20ff17..15f8ca8 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -1105,7 +1105,7 @@ void iommu_release_ownership(struct iommu_table *tbl)
 }
 EXPORT_SYMBOL_GPL(iommu_release_ownership);
 
-static int iommu_add_device(struct device *dev)
+int iommu_add_device(struct device *dev)
 {
 	struct iommu_table *tbl;
 	int ret = 0;
@@ -1134,46 +1134,13 @@ static int iommu_add_device(struct device *dev)
 
 	return ret;
 }
+EXPORT_SYMBOL_GPL(iommu_add_device);
 
-static void iommu_del_device(struct device *dev)
+void iommu_del_device(struct device *dev)
 {
 	iommu_group_remove_device(dev);
 }
-
-static int iommu_bus_notifier(struct notifier_block *nb,
-			      unsigned long action, void *data)
-{
-	struct device *dev = data;
-
-	switch (action) {
-	case BUS_NOTIFY_ADD_DEVICE:
-		return iommu_add_device(dev);
-	case BUS_NOTIFY_DEL_DEVICE:
-		iommu_del_device(dev);
-		return 0;
-	default:
-		return 0;
-	}
-}
-
-static struct notifier_block tce_iommu_bus_nb = {
-	.notifier_call = iommu_bus_notifier,
-};
-
-static int __init tce_iommu_init(void)
-{
-	struct pci_dev *pdev = NULL;
-
-	BUILD_BUG_ON(PAGE_SIZE < IOMMU_PAGE_SIZE);
-
-	for_each_pci_dev(pdev)
-		iommu_add_device(&pdev->dev);
-
-	bus_register_notifier(&pci_bus_type, &tce_iommu_bus_nb);
-	return 0;
-}
-
-subsys_initcall_sync(tce_iommu_init);
+EXPORT_SYMBOL_GPL(iommu_del_device);
 
 #else
 
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index d8140b1..756bb58 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -440,7 +440,7 @@ static void pnv_pci_ioda_dma_dev_setup(struct pnv_phb *phb, struct pci_dev *pdev
 		return;
 
 	pe = &phb->ioda.pe_array[pdn->pe_number];
-	set_iommu_table_base(&pdev->dev, &pe->tce32_table);
+	set_iommu_table_base_and_group(&pdev->dev, &pe->tce32_table);
 }
 
 static void pnv_ioda_setup_bus_dma(struct pnv_ioda_pe *pe, struct pci_bus *bus)
@@ -448,7 +448,7 @@ static void pnv_ioda_setup_bus_dma(struct pnv_ioda_pe *pe, struct pci_bus *bus)
 	struct pci_dev *dev;
 
 	list_for_each_entry(dev, &bus->devices, bus_list) {
-		set_iommu_table_base(&dev->dev, &pe->tce32_table);
+		set_iommu_table_base_and_group(&dev->dev, &pe->tce32_table);
 		if (dev->subordinate)
 			pnv_ioda_setup_bus_dma(pe, dev->subordinate);
 	}
@@ -611,7 +611,7 @@ static void pnv_pci_ioda_setup_dma_pe(struct pnv_phb *phb,
 	iommu_register_group(tbl, pci_domain_nr(pe->pbus), pe->pe_number);
 
 	if (pe->pdev)
-		set_iommu_table_base(&pe->pdev->dev, tbl);
+		set_iommu_table_base_and_group(&pe->pdev->dev, tbl);
 	else
 		pnv_ioda_setup_bus_dma(pe, pe->pbus);
 
@@ -687,7 +687,7 @@ static void pnv_pci_ioda2_setup_dma_pe(struct pnv_phb *phb,
 	iommu_init_table(tbl, phb->hose->node);
 
 	if (pe->pdev)
-		set_iommu_table_base(&pe->pdev->dev, tbl);
+		set_iommu_table_base_and_group(&pe->pdev->dev, tbl);
 	else
 		pnv_ioda_setup_bus_dma(pe, pe->pbus);
 
diff --git a/arch/powerpc/platforms/powernv/pci-p5ioc2.c b/arch/powerpc/platforms/powernv/pci-p5ioc2.c
index b68db63..ede341b 100644
--- a/arch/powerpc/platforms/powernv/pci-p5ioc2.c
+++ b/arch/powerpc/platforms/powernv/pci-p5ioc2.c
@@ -92,7 +92,7 @@ static void pnv_pci_p5ioc2_dma_dev_setup(struct pnv_phb *phb,
 				pci_domain_nr(phb->hose->bus), phb->opal_id);
 	}
 
-	set_iommu_table_base(&pdev->dev, &phb->p5ioc2.iommu_table);
+	set_iommu_table_base_and_group(&pdev->dev, &phb->p5ioc2.iommu_table);
 }
 
 static void __init pnv_pci_init_p5ioc2_phb(struct device_node *np, u64 hub_id,
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c
index a28d3b5..d69161f 100644
--- a/arch/powerpc/platforms/powernv/pci.c
+++ b/arch/powerpc/platforms/powernv/pci.c
@@ -504,7 +504,7 @@ static void pnv_pci_dma_fallback_setup(struct pci_controller *hose,
 		pdn->iommu_table = pnv_pci_setup_bml_iommu(hose);
 	if (!pdn->iommu_table)
 		return;
-	set_iommu_table_base(&pdev->dev, pdn->iommu_table);
+	set_iommu_table_base_and_group(&pdev->dev, pdn->iommu_table);
 }
 
 static void pnv_pci_dma_dev_setup(struct pci_dev *pdev)
@@ -623,3 +623,33 @@ void __init pnv_pci_init(void)
 	ppc_md.teardown_msi_irqs = pnv_teardown_msi_irqs;
 #endif
 }
+
+static int tce_iommu_bus_notifier(struct notifier_block *nb,
+		unsigned long action, void *data)
+{
+	struct device *dev = data;
+
+	switch (action) {
+	case BUS_NOTIFY_ADD_DEVICE:
+		return iommu_add_device(dev);
+	case BUS_NOTIFY_DEL_DEVICE:
+		iommu_del_device(dev);
+		return 0;
+	default:
+		return 0;
+	}
+}
+
+static struct notifier_block tce_iommu_bus_nb = {
+	.notifier_call = tce_iommu_bus_notifier,
+};
+
+static int __init tce_iommu_bus_notifier_init(void)
+{
+	BUILD_BUG_ON(PAGE_SIZE < IOMMU_PAGE_SIZE);
+
+	bus_register_notifier(&pci_bus_type, &tce_iommu_bus_nb);
+	return 0;
+}
+
+subsys_initcall_sync(tce_iommu_bus_notifier_init);
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 23fc1dc..884ae71 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -687,7 +687,8 @@ static void pci_dma_dev_setup_pSeries(struct pci_dev *dev)
 		iommu_table_setparms(phb, dn, tbl);
 		PCI_DN(dn)->iommu_table = iommu_init_table(tbl, phb->node);
 		iommu_register_group(tbl, pci_domain_nr(phb->bus), 0);
-		set_iommu_table_base(&dev->dev, PCI_DN(dn)->iommu_table);
+		set_iommu_table_base_and_group(&dev->dev,
+					       PCI_DN(dn)->iommu_table);
 		return;
 	}
 
@@ -699,7 +700,8 @@ static void pci_dma_dev_setup_pSeries(struct pci_dev *dev)
 		dn = dn->parent;
 
 	if (dn && PCI_DN(dn))
-		set_iommu_table_base(&dev->dev, PCI_DN(dn)->iommu_table);
+		set_iommu_table_base_and_group(&dev->dev,
+					       PCI_DN(dn)->iommu_table);
 	else
 		printk(KERN_WARNING "iommu: Device %s has no iommu table\n",
 		       pci_name(dev));
@@ -1193,7 +1195,7 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
 		pr_debug("  found DMA window, table: %p\n", pci->iommu_table);
 	}
 
-	set_iommu_table_base(&dev->dev, pci->iommu_table);
+	set_iommu_table_base_and_group(&dev->dev, pci->iommu_table);
 }
 
 static int dma_set_mask_pSeriesLP(struct device *dev, u64 dma_mask)
-- 
1.8.3.2

^ permalink raw reply related

* Re: [alsa-devel] [PATCH v4 resent 1/2] ASoC: fsl: Add S/PDIF CPU DAI driver
From: Nicolin Chen @ 2013-08-15  2:33 UTC (permalink / raw)
  To: Sascha Hauer
  Cc: devicetree, alsa-devel, lars, timur, rob.herring, broonie,
	p.zabel, shawn.guo, linuxppc-dev
In-Reply-To: <20130814121937.GY26614@pengutronix.de>

On Wed, Aug 14, 2013 at 02:19:37PM +0200, Sascha Hauer wrote:
> Yes, since the clk names are not an API. Exposing them to the devicetree
> is not an option. The fact that the names are defined in
> arch/arm/mach-imx/clk-imx6q.c and are used in the spdif driver makes
> this really clear.
> 
> The spdif core has 8 input clocks which have to be described in the
> devicetree. Nobody says the mapping which clock name corresponds to
> which bit combination has to be in the devicetree.

Thank you for the explain. I get your point and really appreciate it.

> Look at the possible clocks:
> 
> 0000 if (DPLL Locked) SPDIF_RxClk else extal
> 0001 if (DPLL Locked) SPDIF_RxClk else spdif_clk
> 0010 if (DPLL Locked) SPDIF_RxClk else asrc_clk
> 0011 if (DPLL Locked) SPDIF_RxClk else spdif_extclk
> 0100 if (DPLL Locked) SPDIF_Rxclk else esai_hckt
> 0101 extal_clk
> 0110 spdif_clk
> 0111 asrc_clk
> 1000 spdif_extclk
> 1001 esai_hckt
> 1010 if (DPLL Locked) SPDIF_RxClk else mlb_clk
> 1011 if (DPLL Locked) SPDIF_RxClk else mlb_phy_clk
> 1100 mkb_clk
> 1101 mlb_phy_clk
> 
> Only half of them actually are clocks. "if (DPLL Locked) SPDIF_RxClk
> else ..." is not a clock. Every sane hardware developer would have
> introduced a mux with 8 entries and an additional "Use DPLL if possible"
> bit. Now this is not the case here so we have to live with it and
> maintain the above table in the driver. And another one for the i.MX35
> and still another one for i.MX53.

I think I just have an idea for the table. I'll put them into the
next version. Please take a look after I send it.

Thank you,
Nicolin Chen
 

^ permalink raw reply

* Re: [PATCH v4 resent 1/2] ASoC: fsl: Add S/PDIF CPU DAI driver
From: Nicolin Chen @ 2013-08-15  2:28 UTC (permalink / raw)
  To: Philipp Zabel
  Cc: devicetree, alsa-devel, lars, Sascha Hauer, timur, rob.herring,
	broonie, linuxppc-dev
In-Reply-To: <1376481984.3994.20.camel@pizza.hi.pengutronix.de>

Hi Philipp,

   Thank again for the comments.

On Wed, Aug 14, 2013 at 02:06:24PM +0200, Philipp Zabel wrote:
> ==================================================================
> From i.MX53 reference manual:
> 
> 0000 if (DPLL Locked) SPDIF_RxClk else extal
> 0001 if (DPLL Locked) SPDIF_RxClk else spdif_clk
> 0011 if (DPLL Locked) SPDIF_RxClk else asrc_clk
> 0100 if (DPLL Locked) SPDIF_Rxclk else esai_hckt
> 0101 extal_clk
> 0110 spdif_clk
> 1000 asrc_clk
> 1001 esai_hckt
> 1010 if (DPLL Locked) SPDIF_RxClk else mlb_clk
> 1011 if (DPLL Locked) SPDIF_RxClk else camp_clk
> 1100 mkb_clk
> 1101 camp_clk
> ==================================================================
> 
> To me this looks like the device tree should just contain the list of
> unique clock inputs using phandles.
> 	/* for i.MX6Q: */
> 	clocks = <&...>;
> 	clock-names = "xtal", "spdif", "asrc",
> 	              "spdif_ext", "esai", "mlb";
> 
> 	/* for i.MX53: */
> 	clocks = <&...>;
> 	clock-names = "xtal", "spdif", "asrc",
> 	              "esai", "mlb", "camp";
> 
> The driver could contain this list of named inputs to the multiplexer
> and the DPLL locking information for each SoC version. The per-clock
> DPLL locking bit shouldn't be in the device tree at all.

I understand your point. I'll put the DPLL-locking info to the driver.
And I just found that the DPLL-lock condition seems to be fixed within
the range -- {0x0 ~ 0x4, 0xa ~ 0xb} (I checked i.MX6Q/6SL/53/35, all
of them are in such pattern.) So I don't need to put them into DT.

I'll revise it in next ver.

Thank you,
Nicolin Chen

^ permalink raw reply

* Re: [alsa-devel] [PATCH v4 1/2] ASoC: fsl: Add S/PDIF CPU DAI driver
From: Nicolin Chen @ 2013-08-15  2:18 UTC (permalink / raw)
  To: Stephen Warren
  Cc: devicetree, alsa-devel, lars, linuxppc-dev, timur, rob.herring,
	broonie, p.zabel, Shawn Guo, Fabio Estevam
In-Reply-To: <520BA687.4030905@wwwdotorg.org>

Hi Stephen,

On Wed, Aug 14, 2013 at 09:47:19AM -0600, Stephen Warren wrote:
> If the clock source name list is different, then it needs a different
> compatible value, so that each compatible value can specify which clock
> names are required.
> 
> Also, the compatible value itself should always include the exact HW
> that's present (most specific HW version), as well as any other HW it's
> compatible with.
 
Thank you for the comments. Yes, I did so in v1-v3, but after rethinking
about the situation (Actually both the HW version and the clock mux itself
are same, just the clock sources connecting to the mux might be different),
so I decided to do this by abstracting the driver from those source info
and letting DT binding to pass such information. Because I think putting 
the clock sources into the driver differed by compatible value would make
the driver more like SoC-specified, not the ideal way -- SoC-independent,
since the clock sources are based on SoC design, not on itself.

Thank you,
Nicolin Chen

^ permalink raw reply

* Re: [RFC][PATCH] drivers: base: dynamic memory block creation
From: Michael Ellerman @ 2013-08-15  2:12 UTC (permalink / raw)
  To: Seth Jennings
  Cc: Dave Hansen, Lai Jiangshan, linuxppc-dev, Greg Kroah-Hartman,
	Rafael J. Wysocki, Linux Kernel Mailing List, Linux MM,
	Yinghai Lu, H. Peter Anvin, Nathan Fontenot, Andrew Morton,
	Cody P Schafer
In-Reply-To: <20130814215253.GC17423@variantweb.net>

On Wed, Aug 14, 2013 at 04:52:53PM -0500, Seth Jennings wrote:
> On Wed, Aug 14, 2013 at 02:37:26PM -0700, Yinghai Lu wrote:
> > On Wed, Aug 14, 2013 at 1:35 PM, Greg Kroah-Hartman
> > <gregkh@linuxfoundation.org> wrote:
> > > On Wed, Aug 14, 2013 at 01:05:33PM -0700, Dave Hansen wrote:
> > >> On 08/14/2013 12:43 PM, Greg Kroah-Hartman wrote:
> > >> > On Wed, Aug 14, 2013 at 02:31:45PM -0500, Seth Jennings wrote:
> > >> >> ppc64 has a normal memory block size of 256M (however sometimes as low
> > >> >> as 16M depending on the system LMB size), and (I think) x86 is 128M.  With
> > >> >> 1TB of RAM and a 256M block size, that's 4k memory blocks with 20 sysfs
> > >> >> entries per block that's around 80k items that need be created at boot
> > >> >> time in sysfs.  Some systems go up to 16TB where the issue is even more
> > >> >> severe.
> > >> >
> > >> > The x86 developers are working with larger memory sizes and they haven't
> > >> > seen the problem in this area, for them it's in other places, as I
> > >> > referred to in my other email.
> > >>
> > >> The SGI guys don't run normal distro kernels and don't turn on memory
> > >> hotplug, so they don't see this.  I do the same in my testing of
> > >> large-memory x86 systems to speed up my boots.  I'll go stick it back in
> > >> there and see if I can generate some numbers for a 1TB machine.
> > >>
> > >> But, the problem on x86 is at _worst_ 1/8 of the problem on ppc64 since
> > >> the SECTION_SIZE is so 8x bigger by default.
> > >>
> > >> Also, the cost of creating sections on ppc is *MUCH* higher than x86
> > >> when amortized across the number of pages that you're initializing.  A
> > >> section on ppc64 has to be created for each (2^24/2^16)=256 pages while
> > >> one on x86 is created for each (2^27/2^12)=32768 pages.
> > >>
> > >> Thus, x86 folks with our small pages and large sections tend to be
> > >> focused on per-page costs.  The ppc folks with their small sections and
> > >> larger pages tend to be focused on the per-section costs.
> > >
> > > Ah, thanks for the explaination, now it makes more sense why they are
> > > both optimizing in different places.
> > 
> > I had one local patch that sent before, it will probe block size for
> > generic x86_64.
> > set it to 2G looks more reasonable for system with 1T+ ram.
> 
> If I am understanding you correctly, you are suggesting we make the block size
> a boot time tunable.  It can't be a runtime tunable since the memory blocks are
> currently created a boot time.
> 
> On ppc64, we can't just just choose a memory block size since it must align
> with the underlying LMB (logical memory block) size, set in the hardware ahead
> of time.

As long as the Linux block size is a multiple of the LMB size it should
be possible. You'd just have to plug/unplug multiple LMBs at once.

It would be possible to construct an LMB layout that defeats that, eg.
every 2nd LMB not present, but I don't think that's actually a concern
in practice.

cheers

^ permalink raw reply

* Re: [GIT PULL] DT/core: cpu_ofnode updates for v3.12
From: Benjamin Herrenschmidt @ 2013-08-14 22:57 UTC (permalink / raw)
  To: Sudeep KarkadaNagesha
  Cc: devicetree@vger.kernel.org, linux-pm@vger.kernel.org,
	Viresh Kumar, linux-kernel@vger.kernel.org,
	rob.herring@calxeda.com, Rafael J. Wysocki, Olof Johansson,
	linuxppc-dev@lists.ozlabs.org,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <520B8468.7050307@arm.com>

On Wed, 2013-08-14 at 14:21 +0100, Sudeep KarkadaNagesha wrote:
> IMO moving of handling ibm,ppc-interrupt-server#s to generic code
> under
> #ifdef CONFIG_PPC seems to be cleaner approach than weak definitation.
> 
> As per my understanding each thread is a different logical cpu.
> Each logical cpu is mapped to unique physical id(either present in reg
> field or legacy ibm,ppc-interrupt-server#s field). So given a logical
> cpu id we can get the cpu node corresponding to it.
> Looking @ smp_setup_cpu_maps in arch/powerpc/kernel/setup-common.c
> and the comment in the same file: "This implementation only supports
> power of 2 number of threads.." the thread id id is implicit in the
> logical cpu id. Do we need to fetch that from DT ?

I don't want those parsing routines to make those assumptions. We have
changed our logical numbering in the past and may again.

Cheers,
Ben.

^ permalink raw reply

* [PATCH] crypto:nx - fix nx-aes-gcm verification
From: jmlatten @ 2013-08-14 22:17 UTC (permalink / raw)
  To: herbert; +Cc: linuxppc-dev, linux-crypto

This patch fixes a bug in the nx-aes-gcm implementation.
Corrected the code so that the authtag is always verified after
decrypting and not just when there is associated data included.
Also, corrected the code to retrieve the input authtag from src
instead of dst. 

Reviewed-by: Fionnuala Gunter <fin@linux.vnet.ibm.com>
Reviewed-by: Marcelo Cerri <mhcerri@linux.vnet.ibm.com>
Signed-off-by: Joy Latten <jmlatten@linux.vnet.ibm.com>

diff --git a/drivers/crypto/nx/nx-aes-gcm.c b/drivers/crypto/nx/nx-aes-gcm.c
index 6cca6c3..eb851bb 100644
--- a/drivers/crypto/nx/nx-aes-gcm.c
+++ b/drivers/crypto/nx/nx-aes-gcm.c
@@ -243,11 +243,11 @@ static int gcm_aes_nx_crypt(struct aead_request *req, int enc)
 				 req->dst, nbytes,
 				 crypto_aead_authsize(crypto_aead_reqtfm(req)),
 				 SCATTERWALK_TO_SG);
-	} else if (req->assoclen) {
+	} else {
 		u8 *itag = nx_ctx->priv.gcm.iauth_tag;
 		u8 *otag = csbcpb->cpb.aes_gcm.out_pat_or_mac;
 
-		scatterwalk_map_and_copy(itag, req->dst, nbytes,
+		scatterwalk_map_and_copy(itag, req->src, nbytes,
 				 crypto_aead_authsize(crypto_aead_reqtfm(req)),
 				 SCATTERWALK_FROM_SG);
 		rc = memcmp(itag, otag,

^ permalink raw reply related


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