Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
ced9f6b
NFSv4: Fix dropped lock for racing OPEN and delegation return
PlaidCat Feb 14, 2025
72add98
scsi: core: Consult supported VPD page list prior to fetching page
PlaidCat Feb 14, 2025
f5bae85
scsi: core: Fix unremoved procfs host directory regression
PlaidCat Feb 14, 2025
7553d0f
scsi: core: Handle devices which return an unusually large VPD page c…
PlaidCat Feb 14, 2025
d8e460d
arm64/sve: Discard stale CPU state when handling SVE traps
PlaidCat Feb 14, 2025
26d9a06
Rebuild rocky8_10 with kernel-4.18.0-553.37.1.el8_10
PlaidCat Feb 14, 2025
184ff1f
s390/pci: Handle PCI error codes other than 0x3a
PlaidCat Feb 14, 2025
40181f9
s390/iucv: MSG_PEEK causes memory leak in iucv_sock_destruct()
PlaidCat Feb 14, 2025
da40572
s390/pci: Sort PCI functions prior to creating virtual busses
PlaidCat Feb 14, 2025
6a873e0
s390/pci: Use topology ID for multi-function devices
PlaidCat Feb 14, 2025
dfbf357
s390/pci: Ignore RID for isolated VFs
PlaidCat Feb 14, 2025
db6422d
s390/pci: Fix leak of struct zpci_dev when zpci_add_device() fails
PlaidCat Feb 14, 2025
bae7ae0
s390/pci: Refactor arch_setup_msi_irqs()
PlaidCat Feb 14, 2025
109c9ff
s390/pci: Allow allocation of more than 1 MSI interrupt
PlaidCat Feb 14, 2025
59464a2
net: usb: lan78xx: add Allied Telesis AT29M2-AF
PlaidCat Feb 14, 2025
0e27ffd
gfs2: Truncate address space when flipping GFS2_DIF_JDATA flag
PlaidCat Feb 14, 2025
8643975
media: uvcvideo: Skip parsing frames of type UVC_VS_UNDEFINED in uvc_…
PlaidCat Feb 14, 2025
0dbf877
Rebuild rocky8_10 with kernel-4.18.0-553.40.1.el8_10
PlaidCat Feb 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile.rhelver
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ RHEL_MINOR = 10
#
# Use this spot to avoid future merge conflicts.
# Do not trim this comment.
RHEL_RELEASE = 553.36.1
RHEL_RELEASE = 553.40.1

#
# ZSTREAM
Expand Down
1 change: 1 addition & 0 deletions arch/arm64/kernel/fpsimd.c
Original file line number Diff line number Diff line change
Expand Up @@ -975,6 +975,7 @@ void do_sve_acc(unsigned int esr, struct pt_regs *regs)
fpsimd_bind_task_to_cpu();
} else {
fpsimd_to_sve(current);
fpsimd_flush_task_state(current);
}

put_cpu_fpsimd_context();
Expand Down
14 changes: 10 additions & 4 deletions arch/s390/include/asm/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,10 @@ struct zpci_bus {
struct list_head resources;
struct list_head bus_next;
struct resource bus_resource;
int pchid;
int topo; /* TID if topo_is_tid, PCHID otherwise */
int domain_nr;
bool multifunction;
u8 multifunction : 1;
u8 topo_is_tid : 1;
enum pci_bus_speed max_bus_speed;
};

Expand All @@ -129,6 +130,8 @@ struct zpci_dev {
u16 vfn; /* virtual function number */
u16 pchid; /* physical channel ID */
u16 maxstbl; /* Maximum store block size */
u16 rid; /* RID as supplied by firmware */
u16 tid; /* Topology for which RID is valid */
u8 pfgid; /* function group ID */
u8 pft; /* pci function type */
u8 port;
Expand All @@ -139,7 +142,8 @@ struct zpci_dev {
u8 is_physfn : 1;
u8 util_str_avail : 1;
u8 irqs_registered : 1;
u8 reserved : 2;
u8 tid_avail : 1;
u8 reserved : 1;
unsigned int devfn; /* DEVFN part of the RID*/

struct mutex lock;
Expand Down Expand Up @@ -215,12 +219,14 @@ extern struct airq_iv *zpci_aif_sbv;
----------------------------------------------------------------------------- */
/* Base stuff */
struct zpci_dev *zpci_create_device(u32 fid, u32 fh, enum zpci_state state);
int zpci_add_device(struct zpci_dev *zdev);
int zpci_enable_device(struct zpci_dev *);
int zpci_disable_device(struct zpci_dev *);
int zpci_scan_configured_device(struct zpci_dev *zdev, u32 fh);
int zpci_deconfigure_device(struct zpci_dev *zdev);
void zpci_device_reserved(struct zpci_dev *zdev);
bool zpci_is_device_configured(struct zpci_dev *zdev);
int zpci_scan_devices(void);

int zpci_hot_reset_device(struct zpci_dev *zdev);
int zpci_register_ioat(struct zpci_dev *, u8, u64, u64, u64, u8 *);
Expand All @@ -231,7 +237,7 @@ void zpci_update_fh(struct zpci_dev *zdev, u32 fh);
/* CLP */
int rhel8_clp_rescan_pci_devices_simple(void);
int clp_setup_writeback_mio(void);
int clp_scan_pci_devices(void);
int clp_scan_pci_devices(struct list_head *scan_list);
int clp_query_pci_fn(struct zpci_dev *zdev);
int clp_enable_fh(struct zpci_dev *zdev, u32 *fh, u8 nr_dma_as);
int clp_disable_fh(struct zpci_dev *zdev, u32 *fh);
Expand Down
8 changes: 5 additions & 3 deletions arch/s390/include/asm/pci_clp.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ struct clp_req_query_pci {
struct clp_rsp_query_pci {
struct clp_rsp_hdr hdr;
u16 vfn; /* virtual fn number */
u16 : 3;
u16 : 2;
u16 tid_avail : 1;
u16 rid_avail : 1;
u16 is_physfn : 1;
u16 reserved1 : 1;
Expand All @@ -127,8 +128,9 @@ struct clp_rsp_query_pci {
u64 edma; /* end dma as */
#define ZPCI_RID_MASK_DEVFN 0x00ff
u16 rid; /* BUS/DEVFN PCI address */
u16 reserved0;
u32 reserved[10];
u32 reserved0;
u16 tid;
u32 reserved[9];
u32 uid; /* user defined id */
u8 util_str[CLP_UTIL_STR_LEN]; /* utility string */
u32 reserved2[16];
Expand Down
88 changes: 77 additions & 11 deletions arch/s390/pci/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <linux/seq_file.h>
#include <linux/jump_label.h>
#include <linux/pci.h>
#include <linux/list_sort.h>

#include <asm/isc.h>
#include <asm/airq.h>
Expand Down Expand Up @@ -859,8 +860,9 @@ int zpci_hot_reset_device(struct zpci_dev *zdev)
* @fh: Current Function Handle of the device to be created
* @state: Initial state after creation either Standby or Configured
*
* Creates a new zpci device and adds it to its, possibly newly created, zbus
* as well as zpci_list.
* Allocates a new struct zpci_dev and queries the platform for its details.
* If successful the device can subsequently be added to the zPCI subsystem
* using zpci_add_device().
*
* Returns: the zdev on success or an error pointer otherwise
*/
Expand All @@ -869,7 +871,6 @@ struct zpci_dev *zpci_create_device(u32 fid, u32 fh, enum zpci_state state)
struct zpci_dev *zdev;
int rc;

zpci_dbg(1, "add fid:%x, fh:%x, c:%d\n", fid, fh, state);
zdev = kzalloc(sizeof(*zdev), GFP_KERNEL);
if (!zdev)
return ERR_PTR(-ENOMEM);
Expand All @@ -884,10 +885,33 @@ struct zpci_dev *zpci_create_device(u32 fid, u32 fh, enum zpci_state state)
goto error;
zdev->state = state;

kref_init(&zdev->kref);
mutex_init(&zdev->lock);
mutex_init(&zdev->kzdev_lock);

return zdev;

error:
zpci_dbg(0, "crt fid:%x, rc:%d\n", fid, rc);
kfree(zdev);
return ERR_PTR(rc);
}

/**
* zpci_add_device() - Add a previously created zPCI device to the zPCI subsystem
* @zdev: The zPCI device to be added
*
* A struct zpci_dev is added to the zPCI subsystem and to a virtual PCI bus creating
* a new one as necessary. A hotplug slot is created and events start to be handled.
* If successful from this point on zpci_zdev_get() and zpci_zdev_put() must be used.
* If adding the struct zpci_dev fails the device was not added and should be freed.
*
* Return: 0 on success, or an error code otherwise
*/
int zpci_add_device(struct zpci_dev *zdev)
{
int rc;

zpci_dbg(1, "add fid:%x, fh:%x, c:%d\n", zdev->fid, zdev->fh, zdev->state);
rc = zpci_init_iommu(zdev);
if (rc)
goto error;
Expand All @@ -896,18 +920,17 @@ struct zpci_dev *zpci_create_device(u32 fid, u32 fh, enum zpci_state state)
if (rc)
goto error_destroy_iommu;

kref_init(&zdev->kref);
spin_lock(&zpci_list_lock);
list_add_tail(&zdev->entry, &zpci_list);
spin_unlock(&zpci_list_lock);

return zdev;
return 0;

error_destroy_iommu:
zpci_destroy_iommu(zdev);
error:
zpci_dbg(0, "add fid:%x, rc:%d\n", fid, rc);
kfree(zdev);
return ERR_PTR(rc);
zpci_dbg(0, "add fid:%x, rc:%d\n", zdev->fid, rc);
return rc;
}

bool zpci_is_device_configured(struct zpci_dev *zdev)
Expand Down Expand Up @@ -1168,6 +1191,50 @@ bool zpci_is_enabled(void)
return s390_pci_initialized;
}

static int zpci_cmp_rid(void *priv, struct list_head *a,
struct list_head *b)
{
struct zpci_dev *za = container_of(a, struct zpci_dev, entry);
struct zpci_dev *zb = container_of(b, struct zpci_dev, entry);

/*
* PCI functions without RID available maintain original order
* between themselves but sort before those with RID.
*/
if (za->rid == zb->rid)
return za->rid_available > zb->rid_available;
/*
* PCI functions with RID sort by RID ascending.
*/
return za->rid > zb->rid;
}

static void zpci_add_devices(struct list_head *scan_list)
{
struct zpci_dev *zdev, *tmp;

list_sort(NULL, scan_list, &zpci_cmp_rid);
list_for_each_entry_safe(zdev, tmp, scan_list, entry) {
list_del_init(&zdev->entry);
if (zpci_add_device(zdev))
kfree(zdev);
}
}

int zpci_scan_devices(void)
{
LIST_HEAD(scan_list);
int rc;

rc = clp_scan_pci_devices(&scan_list);
if (rc)
return rc;

zpci_add_devices(&scan_list);
zpci_bus_scan_busses();
return 0;
}

static int __init pci_base_init(void)
{
int rc;
Expand Down Expand Up @@ -1201,10 +1268,9 @@ static int __init pci_base_init(void)
if (rc)
goto out_dma;

rc = clp_scan_pci_devices();
rc = zpci_scan_devices();
if (rc)
goto out_find;
zpci_bus_scan_busses();

s390_pci_initialized = 1;
return 0;
Expand Down
48 changes: 29 additions & 19 deletions arch/s390/pci/pci_bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,9 +173,16 @@ void zpci_bus_scan_busses(void)
mutex_unlock(&zbus_list_lock);
}

static bool zpci_bus_is_multifunction_root(struct zpci_dev *zdev)
{
return !s390_pci_no_rid && zdev->rid_available &&
zpci_is_device_configured(zdev) &&
!zdev->vfn;
}

/* zpci_bus_create_pci_bus - Create the PCI bus associated with this zbus
* @zbus: the zbus holding the zdevices
* @fr: PCI root function that will determine the bus's domain, and bus speeed
* @fr: PCI root function that will determine the bus's domain, and bus speed
* @ops: the pci operations
*
* The PCI function @fr determines the domain (its UID), multifunction property
Expand All @@ -193,7 +200,7 @@ static int zpci_bus_create_pci_bus(struct zpci_bus *zbus, struct zpci_dev *fr, s
return domain;

zbus->domain_nr = domain;
zbus->multifunction = fr->rid_available;
zbus->multifunction = zpci_bus_is_multifunction_root(fr);
zbus->max_bus_speed = fr->max_bus_speed;

/*
Expand Down Expand Up @@ -237,13 +244,15 @@ static void zpci_bus_put(struct zpci_bus *zbus)
kref_put(&zbus->kref, zpci_bus_release);
}

static struct zpci_bus *zpci_bus_get(int pchid)
static struct zpci_bus *zpci_bus_get(int topo, bool topo_is_tid)
{
struct zpci_bus *zbus;

mutex_lock(&zbus_list_lock);
list_for_each_entry(zbus, &zbus_list, bus_next) {
if (pchid == zbus->pchid) {
if (!zbus->multifunction)
continue;
if (topo_is_tid == zbus->topo_is_tid && topo == zbus->topo) {
kref_get(&zbus->kref);
goto out_unlock;
}
Expand All @@ -254,15 +263,16 @@ static struct zpci_bus *zpci_bus_get(int pchid)
return zbus;
}

static struct zpci_bus *zpci_bus_alloc(int pchid)
static struct zpci_bus *zpci_bus_alloc(int topo, bool topo_is_tid)
{
struct zpci_bus *zbus;

zbus = kzalloc(sizeof(*zbus), GFP_KERNEL);
if (!zbus)
return NULL;

zbus->pchid = pchid;
zbus->topo = topo;
zbus->topo_is_tid = topo_is_tid;
INIT_LIST_HEAD(&zbus->bus_next);
mutex_lock(&zbus_list_lock);
list_add_tail(&zbus->bus_next, &zbus_list);
Expand Down Expand Up @@ -297,19 +307,22 @@ static int zpci_bus_add_device(struct zpci_bus *zbus, struct zpci_dev *zdev)
{
int rc = -EINVAL;

if (zbus->multifunction) {
if (!zdev->rid_available) {
WARN_ONCE(1, "rid_available not set for multifunction\n");
return rc;
}
zdev->devfn = zdev->rid & ZPCI_RID_MASK_DEVFN;
}

if (zbus->function[zdev->devfn]) {
pr_err("devfn %04x is already assigned\n", zdev->devfn);
return rc;
}

zdev->zbus = zbus;
zbus->function[zdev->devfn] = zdev;
zpci_nb_devices++;

if (zbus->multifunction && !zdev->rid_available) {
WARN_ONCE(1, "rid_available not set for multifunction\n");
goto error;
}
rc = zpci_init_slot(zdev);
if (rc)
goto error;
Expand All @@ -326,23 +339,20 @@ static int zpci_bus_add_device(struct zpci_bus *zbus, struct zpci_dev *zdev)

int zpci_bus_device_register(struct zpci_dev *zdev, struct pci_ops *ops)
{
bool topo_is_tid = zdev->tid_avail;
struct zpci_bus *zbus = NULL;
int rc = -EBADF;
int topo, rc = -EBADF;

if (zpci_nb_devices == ZPCI_NR_DEVICES) {
pr_warn("Adding PCI function %08x failed because the configured limit of %d is reached\n",
zdev->fid, ZPCI_NR_DEVICES);
return -ENOSPC;
}

if (zdev->devfn >= ZPCI_FUNCTIONS_PER_BUS)
return -EINVAL;

if (!s390_pci_no_rid && zdev->rid_available)
zbus = zpci_bus_get(zdev->pchid);

topo = topo_is_tid ? zdev->tid : zdev->pchid;
zbus = zpci_bus_get(topo, topo_is_tid);
if (!zbus) {
zbus = zpci_bus_alloc(zdev->pchid);
zbus = zpci_bus_alloc(topo, topo_is_tid);
if (!zbus)
return -ENOMEM;
}
Expand Down
Loading