All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] cxl: prevent read/write to AFU config space while AFU not configured
@ 2016-12-09  6:18 Andrew Donnellan
  2016-12-09 16:30 ` Frederic Barrat
  2017-01-27  0:40 ` [v2] " Michael Ellerman
  0 siblings, 2 replies; 8+ messages in thread
From: Andrew Donnellan @ 2016-12-09  6:18 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: ukrishn, vaibhav, imunsie, fbarrat

During EEH recovery, we deconfigure all AFUs whilst leaving the
corresponding vPHB and virtual PCI device in place.

If something attempts to interact with the AFU's PCI config space (e.g.
running lspci) after the AFU has been deconfigured and before it's
reconfigured, cxl_pcie_{read,write}_config() will read invalid values from
the deconfigured struct cxl_afu and proceed to Oops when they try to
dereference pointers that have been set to NULL during deconfiguration.

Add a rwsem to struct cxl_afu so we can prevent interaction with config
space while the AFU is deconfigured.

Reported-by: Pradipta Ghosh <pradghos@in.ibm.com>
Suggested-by: Frederic Barrat <fbarrat@linux.vnet.ibm.com>
Cc: stable@vger.kernel.org # v4.9+
Signed-off-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
Signed-off-by: Vaibhav Jain <vaibhav@linux.vnet.ibm.com>

---

v1 -> v2:

* Refactored to avoid locking over function boundaries - we now both lock
and unlock in cxl_pcie_{read,write}_config(), rather than locking in
cxl_pcie_config_info() and unlocking from the caller. Thanks Vaibhav.

* Changed the stable tag to 4.9 rather than 4.4 - by the time this is
merged, 4.9 will have landed, and I'll need to manually backport this for
4.4.
---
 drivers/misc/cxl/cxl.h  |  2 ++
 drivers/misc/cxl/main.c |  3 ++-
 drivers/misc/cxl/pci.c  |  2 ++
 drivers/misc/cxl/vphb.c | 51 ++++++++++++++++++++++++++++---------------------
 4 files changed, 35 insertions(+), 23 deletions(-)

diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h
index a144073..379c463 100644
--- a/drivers/misc/cxl/cxl.h
+++ b/drivers/misc/cxl/cxl.h
@@ -418,6 +418,8 @@ struct cxl_afu {
 	struct dentry *debugfs;
 	struct mutex contexts_lock;
 	spinlock_t afu_cntl_lock;
+	/* Used to block access to AFU config space while deconfigured */
+	struct rw_semaphore configured_rwsem;
 
 	/* AFU error buffer fields and bin attribute for sysfs */
 	u64 eb_len, eb_offset;
diff --git a/drivers/misc/cxl/main.c b/drivers/misc/cxl/main.c
index 62e0dfb..2a6bf1d 100644
--- a/drivers/misc/cxl/main.c
+++ b/drivers/misc/cxl/main.c
@@ -268,7 +268,8 @@ struct cxl_afu *cxl_alloc_afu(struct cxl *adapter, int slice)
 	idr_init(&afu->contexts_idr);
 	mutex_init(&afu->contexts_lock);
 	spin_lock_init(&afu->afu_cntl_lock);
-
+	init_rwsem(&afu->configured_rwsem);
+	down_write(&afu->configured_rwsem);
 	afu->prefault_mode = CXL_PREFAULT_NONE;
 	afu->irqs_max = afu->adapter->user_irqs;
 
diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c
index c4d79b5d..c7b2121 100644
--- a/drivers/misc/cxl/pci.c
+++ b/drivers/misc/cxl/pci.c
@@ -1129,6 +1129,7 @@ static int pci_configure_afu(struct cxl_afu *afu, struct cxl *adapter, struct pc
 	if ((rc = cxl_native_register_psl_irq(afu)))
 		goto err2;
 
+	up_write(&afu->configured_rwsem);
 	return 0;
 
 err2:
@@ -1141,6 +1142,7 @@ static int pci_configure_afu(struct cxl_afu *afu, struct cxl *adapter, struct pc
 
 static void pci_deconfigure_afu(struct cxl_afu *afu)
 {
+	down_write(&afu->configured_rwsem);
 	cxl_native_release_psl_irq(afu);
 	if (afu->adapter->native->sl_ops->release_serr_irq)
 		afu->adapter->native->sl_ops->release_serr_irq(afu);
diff --git a/drivers/misc/cxl/vphb.c b/drivers/misc/cxl/vphb.c
index 3519ace..639a343 100644
--- a/drivers/misc/cxl/vphb.c
+++ b/drivers/misc/cxl/vphb.c
@@ -76,23 +76,22 @@ static int cxl_pcie_cfg_record(u8 bus, u8 devfn)
 	return (bus << 8) + devfn;
 }
 
-static int cxl_pcie_config_info(struct pci_bus *bus, unsigned int devfn,
-				struct cxl_afu **_afu, int *_record)
+static inline struct cxl_afu *pci_bus_to_afu(struct pci_bus *bus)
 {
-	struct pci_controller *phb;
-	struct cxl_afu *afu;
-	int record;
+	struct pci_controller *phb = bus ? pci_bus_to_host(bus) : NULL;
 
-	phb = pci_bus_to_host(bus);
-	if (phb == NULL)
-		return PCIBIOS_DEVICE_NOT_FOUND;
+	return phb ? phb->private_data : NULL;
+}
+
+static inline int cxl_pcie_config_info(struct pci_bus *bus, unsigned int devfn,
+				       struct cxl_afu *afu, int *_record)
+{
+	int record;
 
-	afu = (struct cxl_afu *)phb->private_data;
 	record = cxl_pcie_cfg_record(bus->number, devfn);
 	if (record > afu->crs_num)
 		return PCIBIOS_DEVICE_NOT_FOUND;
 
-	*_afu = afu;
 	*_record = record;
 	return 0;
 }
@@ -106,9 +105,14 @@ static int cxl_pcie_read_config(struct pci_bus *bus, unsigned int devfn,
 	u16 val16;
 	u32 val32;
 
-	rc = cxl_pcie_config_info(bus, devfn, &afu, &record);
+	afu = pci_bus_to_afu(bus);
+	/* Grab a reader lock on afu. */
+	if (afu == NULL || !down_read_trylock(&afu->configured_rwsem))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	rc = cxl_pcie_config_info(bus, devfn, afu, &record);
 	if (rc)
-		return rc;
+		goto out;
 
 	switch (len) {
 	case 1:
@@ -127,10 +131,9 @@ static int cxl_pcie_read_config(struct pci_bus *bus, unsigned int devfn,
 		WARN_ON(1);
 	}
 
-	if (rc)
-		return PCIBIOS_DEVICE_NOT_FOUND;
-
-	return PCIBIOS_SUCCESSFUL;
+out:
+	up_read(&afu->configured_rwsem);
+	return rc ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
 }
 
 static int cxl_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
@@ -139,9 +142,14 @@ static int cxl_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
 	int rc, record;
 	struct cxl_afu *afu;
 
-	rc = cxl_pcie_config_info(bus, devfn, &afu, &record);
+	afu = pci_bus_to_afu(bus);
+	/* Grab a reader lock on afu. */
+	if (afu == NULL || !down_read_trylock(&afu->configured_rwsem))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	rc = cxl_pcie_config_info(bus, devfn, afu, &record);
 	if (rc)
-		return rc;
+		goto out;
 
 	switch (len) {
 	case 1:
@@ -157,10 +165,9 @@ static int cxl_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
 		WARN_ON(1);
 	}
 
-	if (rc)
-		return PCIBIOS_SET_FAILED;
-
-	return PCIBIOS_SUCCESSFUL;
+out:
+	up_read(&afu->configured_rwsem);
+	return rc ? PCIBIOS_SET_FAILED : PCIBIOS_SUCCESSFUL;
 }
 
 static struct pci_ops cxl_pcie_pci_ops =
-- 
Andrew Donnellan              OzLabs, ADL Canberra
andrew.donnellan@au1.ibm.com  IBM Australia Limited

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v2] cxl: prevent read/write to AFU config space while AFU not configured
  2016-12-09  6:18 [PATCH v2] cxl: prevent read/write to AFU config space while AFU not configured Andrew Donnellan
@ 2016-12-09 16:30 ` Frederic Barrat
  2016-12-13  6:11   ` Andrew Donnellan
  2017-01-27  0:40 ` [v2] " Michael Ellerman
  1 sibling, 1 reply; 8+ messages in thread
From: Frederic Barrat @ 2016-12-09 16:30 UTC (permalink / raw)
  To: Andrew Donnellan, linuxppc-dev; +Cc: ukrishn, vaibhav, imunsie



> diff --git a/drivers/misc/cxl/vphb.c b/drivers/misc/cxl/vphb.c
> index 3519ace..639a343 100644
> --- a/drivers/misc/cxl/vphb.c
> +++ b/drivers/misc/cxl/vphb.c
> @@ -76,23 +76,22 @@ static int cxl_pcie_cfg_record(u8 bus, u8 devfn)
>  	return (bus << 8) + devfn;
>  }
>
> -static int cxl_pcie_config_info(struct pci_bus *bus, unsigned int devfn,
> -				struct cxl_afu **_afu, int *_record)
> +static inline struct cxl_afu *pci_bus_to_afu(struct pci_bus *bus)
>  {
> -	struct pci_controller *phb;
> -	struct cxl_afu *afu;
> -	int record;
> +	struct pci_controller *phb = bus ? pci_bus_to_host(bus) : NULL;
>
> -	phb = pci_bus_to_host(bus);
> -	if (phb == NULL)
> -		return PCIBIOS_DEVICE_NOT_FOUND;
> +	return phb ? phb->private_data : NULL;
> +}
> +
> +static inline int cxl_pcie_config_info(struct pci_bus *bus, unsigned int devfn,
> +				       struct cxl_afu *afu, int *_record)
> +{
> +	int record;
>
> -	afu = (struct cxl_afu *)phb->private_data;
>  	record = cxl_pcie_cfg_record(bus->number, devfn);
>  	if (record > afu->crs_num)
>  		return PCIBIOS_DEVICE_NOT_FOUND;
>
> -	*_afu = afu;
>  	*_record = record;
>  	return 0;
>  }


There's no reason to pass the afu parameter to that function, is it?
Pushing it further, do we need cxl_pcie_config_info()? It's now a simple 
wrapper around cxl_pcie_cfg_record()

   Fred

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2] cxl: prevent read/write to AFU config space while AFU not configured
  2016-12-09 16:30 ` Frederic Barrat
@ 2016-12-13  6:11   ` Andrew Donnellan
  0 siblings, 0 replies; 8+ messages in thread
From: Andrew Donnellan @ 2016-12-13  6:11 UTC (permalink / raw)
  To: Frederic Barrat, linuxppc-dev; +Cc: ukrishn, vaibhav, imunsie

It looks like there may still be a recursive locking issue in this 
patch, please don't merge just yet...

On 10/12/16 03:30, Frederic Barrat wrote:
>> +static inline int cxl_pcie_config_info(struct pci_bus *bus, unsigned
>> int devfn,
>> +                       struct cxl_afu *afu, int *_record)
>> +{
>> +    int record;
>>
>> -    afu = (struct cxl_afu *)phb->private_data;
>>      record = cxl_pcie_cfg_record(bus->number, devfn);
>>      if (record > afu->crs_num)
>>          return PCIBIOS_DEVICE_NOT_FOUND;
>>
>> -    *_afu = afu;
>>      *_record = record;
>>      return 0;
>>  }
>
>
> There's no reason to pass the afu parameter to that function, is it?

We use it to check afu->crs_num.

> Pushing it further, do we need cxl_pcie_config_info()? It's now a simple
> wrapper around cxl_pcie_cfg_record()

Hmm...

-- 
Andrew Donnellan              OzLabs, ADL Canberra
andrew.donnellan@au1.ibm.com  IBM Australia Limited

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [v2] cxl: prevent read/write to AFU config space while AFU not configured
  2016-12-09  6:18 [PATCH v2] cxl: prevent read/write to AFU config space while AFU not configured Andrew Donnellan
  2016-12-09 16:30 ` Frederic Barrat
@ 2017-01-27  0:40 ` Michael Ellerman
  2017-01-27  0:57   ` Andrew Donnellan
  1 sibling, 1 reply; 8+ messages in thread
From: Michael Ellerman @ 2017-01-27  0:40 UTC (permalink / raw)
  To: Andrew Donnellan, linuxppc-dev; +Cc: ukrishn, vaibhav, fbarrat, imunsie

On Fri, 2016-12-09 at 06:18:50 UTC, Andrew Donnellan wrote:
> During EEH recovery, we deconfigure all AFUs whilst leaving the
> corresponding vPHB and virtual PCI device in place.
> 
> If something attempts to interact with the AFU's PCI config space (e.g.
> running lspci) after the AFU has been deconfigured and before it's
> reconfigured, cxl_pcie_{read,write}_config() will read invalid values from
> the deconfigured struct cxl_afu and proceed to Oops when they try to
> dereference pointers that have been set to NULL during deconfiguration.
> 
> Add a rwsem to struct cxl_afu so we can prevent interaction with config
> space while the AFU is deconfigured.
> 
> Reported-by: Pradipta Ghosh <pradghos@in.ibm.com>
> Suggested-by: Frederic Barrat <fbarrat@linux.vnet.ibm.com>
> Cc: stable@vger.kernel.org # v4.9+
> Signed-off-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
> Signed-off-by: Vaibhav Jain <vaibhav@linux.vnet.ibm.com>

Applied to powerpc next, thanks.

https://git.kernel.org/powerpc/c/14a3ae34bfd0bcb1cc12d55b06a858

cheers

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [v2] cxl: prevent read/write to AFU config space while AFU not configured
  2017-01-27  0:40 ` [v2] " Michael Ellerman
@ 2017-01-27  0:57   ` Andrew Donnellan
  2017-02-06  1:15     ` Andrew Donnellan
  0 siblings, 1 reply; 8+ messages in thread
From: Andrew Donnellan @ 2017-01-27  0:57 UTC (permalink / raw)
  To: Michael Ellerman, linuxppc-dev; +Cc: ukrishn, vaibhav, fbarrat, imunsie

On 27/01/17 11:40, Michael Ellerman wrote:
> Applied to powerpc next, thanks.
>
> https://git.kernel.org/powerpc/c/14a3ae34bfd0bcb1cc12d55b06a858

Will fix the remaining locking issue in a follow up patch...

-- 
Andrew Donnellan              OzLabs, ADL Canberra
andrew.donnellan@au1.ibm.com  IBM Australia Limited

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [v2] cxl: prevent read/write to AFU config space while AFU not configured
  2017-01-27  0:57   ` Andrew Donnellan
@ 2017-02-06  1:15     ` Andrew Donnellan
  2017-02-06  9:43       ` Greg KH
  0 siblings, 1 reply; 8+ messages in thread
From: Andrew Donnellan @ 2017-02-06  1:15 UTC (permalink / raw)
  To: Michael Ellerman, linuxppc-dev, stable; +Cc: ukrishn, vaibhav, fbarrat, imunsie

On 27/01/17 11:57, Andrew Donnellan wrote:
> On 27/01/17 11:40, Michael Ellerman wrote:
>> Applied to powerpc next, thanks.
>>
>> https://git.kernel.org/powerpc/c/14a3ae34bfd0bcb1cc12d55b06a858
>
> Will fix the remaining locking issue in a follow up patch...

Stable team - please make sure this doesn't go in without 
http://patchwork.ozlabs.org/patch/724315/ once that's merged.


Thanks,
-- 
Andrew Donnellan              OzLabs, ADL Canberra
andrew.donnellan@au1.ibm.com  IBM Australia Limited


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [v2] cxl: prevent read/write to AFU config space while AFU not configured
  2017-02-06  1:15     ` Andrew Donnellan
@ 2017-02-06  9:43       ` Greg KH
  2017-02-07  2:15         ` Michael Ellerman
  0 siblings, 1 reply; 8+ messages in thread
From: Greg KH @ 2017-02-06  9:43 UTC (permalink / raw)
  To: Andrew Donnellan
  Cc: Michael Ellerman, linuxppc-dev, stable, ukrishn, vaibhav,
	fbarrat, imunsie

On Mon, Feb 06, 2017 at 12:15:59PM +1100, Andrew Donnellan wrote:
> On 27/01/17 11:57, Andrew Donnellan wrote:
> > On 27/01/17 11:40, Michael Ellerman wrote:
> > > Applied to powerpc next, thanks.
> > > 
> > > https://git.kernel.org/powerpc/c/14a3ae34bfd0bcb1cc12d55b06a858
> > 
> > Will fix the remaining locking issue in a follow up patch...
> 
> Stable team - please make sure this doesn't go in without
> http://patchwork.ozlabs.org/patch/724315/ once that's merged.

Ok, hopefully they show up in Linus's tree at the same time :)

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [v2] cxl: prevent read/write to AFU config space while AFU not configured
  2017-02-06  9:43       ` Greg KH
@ 2017-02-07  2:15         ` Michael Ellerman
  0 siblings, 0 replies; 8+ messages in thread
From: Michael Ellerman @ 2017-02-07  2:15 UTC (permalink / raw)
  To: Greg KH, Andrew Donnellan
  Cc: linuxppc-dev, stable, ukrishn, vaibhav, fbarrat, imunsie

Greg KH <greg@kroah.com> writes:

> On Mon, Feb 06, 2017 at 12:15:59PM +1100, Andrew Donnellan wrote:
>> On 27/01/17 11:57, Andrew Donnellan wrote:
>> > On 27/01/17 11:40, Michael Ellerman wrote:
>> > > Applied to powerpc next, thanks.
>> > > 
>> > > https://git.kernel.org/powerpc/c/14a3ae34bfd0bcb1cc12d55b06a858
>> > 
>> > Will fix the remaining locking issue in a follow up patch...
>> 
>> Stable team - please make sure this doesn't go in without
>> http://patchwork.ozlabs.org/patch/724315/ once that's merged.
>
> Ok, hopefully they show up in Linus's tree at the same time :)

Yeah they will.

cheers

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2017-02-07  2:15 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-12-09  6:18 [PATCH v2] cxl: prevent read/write to AFU config space while AFU not configured Andrew Donnellan
2016-12-09 16:30 ` Frederic Barrat
2016-12-13  6:11   ` Andrew Donnellan
2017-01-27  0:40 ` [v2] " Michael Ellerman
2017-01-27  0:57   ` Andrew Donnellan
2017-02-06  1:15     ` Andrew Donnellan
2017-02-06  9:43       ` Greg KH
2017-02-07  2:15         ` Michael Ellerman

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.