Re: [PATCH 12/32] s390/pci: get SHM information from list pci

From: Christian Borntraeger
Date: Thu Dec 09 2021 - 10:47:15 EST


Am 07.12.21 um 21:57 schrieb Matthew Rosato:
KVM will need information on the special handle mask used to indicate
emulated devices. In order to obtain this, a new type of list pci call
must be made to gather the information. Remove the unused data pointer
from clp_list_pci and __clp_add and instead optionally pass a pointer to
a model-dependent-data field. Additionally, allow for clp_list_pci calls
that don't specify a callback - in this case, just do the first pass of
list pci and exit.

Signed-off-by: Matthew Rosato <mjrosato@xxxxxxxxxxxxx>
---
arch/s390/include/asm/pci.h | 6 ++++++
arch/s390/include/asm/pci_clp.h | 2 +-
arch/s390/pci/pci.c | 19 +++++++++++++++++++
arch/s390/pci/pci_clp.c | 16 ++++++++++------
4 files changed, 36 insertions(+), 7 deletions(-)

diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h
index 00a2c24d6d2b..86f43644756d 100644
--- a/arch/s390/include/asm/pci.h
+++ b/arch/s390/include/asm/pci.h
@@ -219,12 +219,18 @@ int zpci_unregister_ioat(struct zpci_dev *, u8);
void zpci_remove_reserved_devices(void);
void zpci_update_fh(struct zpci_dev *zdev, u32 fh);
+int zpci_get_mdd(u32 *mdd);
+
/* CLP */
+void *clp_alloc_block(gfp_t gfp_mask);
+void clp_free_block(void *ptr);
int clp_setup_writeback_mio(void);
int clp_scan_pci_devices(void);
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);
+int clp_list_pci(struct clp_req_rsp_list_pci *rrb, u32 *mdd,
+ void (*cb)(struct clp_fh_list_entry *));
int clp_get_state(u32 fid, enum zpci_state *state);
int clp_refresh_fh(u32 fid, u32 *fh);
diff --git a/arch/s390/include/asm/pci_clp.h b/arch/s390/include/asm/pci_clp.h
index 124fadfb74b9..d6bc324763f3 100644
--- a/arch/s390/include/asm/pci_clp.h
+++ b/arch/s390/include/asm/pci_clp.h
@@ -76,7 +76,7 @@ struct clp_req_list_pci {
struct clp_rsp_list_pci {
struct clp_rsp_hdr hdr;
u64 resume_token;
- u32 reserved2;
+ u32 mdd;
u16 max_fn;
u8 : 7;
u8 uid_checking : 1;
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
index af1c0ae017b1..175854c861cd 100644
--- a/arch/s390/pci/pci.c
+++ b/arch/s390/pci/pci.c
@@ -531,6 +531,25 @@ void zpci_update_fh(struct zpci_dev *zdev, u32 fh)
zpci_do_update_iomap_fh(zdev, fh);
}
+int zpci_get_mdd(u32 *mdd)
+{
+ struct clp_req_rsp_list_pci *rrb;
+ int rc;
+
+ if (!mdd)
+ return -EINVAL;
+
+ rrb = clp_alloc_block(GFP_KERNEL);
+ if (!rrb)
+ return -ENOMEM;
+
+ rc = clp_list_pci(rrb, mdd, NULL);
+
+ clp_free_block(rrb);
+ return rc;
+}
+EXPORT_SYMBOL_GPL(zpci_get_mdd);

Maybe move this into pci_clp.c to avoid the export of clp_alloc_block and void clp_free_block?
Niklas?
In any case the code looks correct from a HW perspective.

Reviewed-by: Christian Borntraeger <borntraeger@xxxxxxxxxx>


+
static struct resource *__alloc_res(struct zpci_dev *zdev, unsigned long start,
unsigned long size, unsigned long flags)
{
diff --git a/arch/s390/pci/pci_clp.c b/arch/s390/pci/pci_clp.c
index bc7446566cbc..e18a548ac22d 100644
--- a/arch/s390/pci/pci_clp.c
+++ b/arch/s390/pci/pci_clp.c
@@ -84,12 +84,12 @@ static __always_inline int clp_req(void *data, unsigned int lps)
return cc;
}
-static void *clp_alloc_block(gfp_t gfp_mask)
+void *clp_alloc_block(gfp_t gfp_mask)
{
return (void *) __get_free_pages(gfp_mask, get_order(CLP_BLK_SIZE));
}
-static void clp_free_block(void *ptr)
+void clp_free_block(void *ptr)
{
free_pages((unsigned long) ptr, get_order(CLP_BLK_SIZE));
}
@@ -358,8 +358,8 @@ static int clp_list_pci_req(struct clp_req_rsp_list_pci *rrb,
return rc;
}
-static int clp_list_pci(struct clp_req_rsp_list_pci *rrb, void *data,
- void (*cb)(struct clp_fh_list_entry *, void *))
+int clp_list_pci(struct clp_req_rsp_list_pci *rrb, u32 *mdd,
+ void (*cb)(struct clp_fh_list_entry *))
{
u64 resume_token = 0;
int nentries, i, rc;
@@ -368,8 +368,12 @@ static int clp_list_pci(struct clp_req_rsp_list_pci *rrb, void *data,
rc = clp_list_pci_req(rrb, &resume_token, &nentries);
if (rc)
return rc;
+ if (mdd)
+ *mdd = rrb->response.mdd;
+ if (!cb)
+ return 0;
for (i = 0; i < nentries; i++)
- cb(&rrb->response.fh_list[i], data);
+ cb(&rrb->response.fh_list[i]);
} while (resume_token);
return rc;
@@ -398,7 +402,7 @@ static int clp_find_pci(struct clp_req_rsp_list_pci *rrb, u32 fid,
return -ENODEV;
}
-static void __clp_add(struct clp_fh_list_entry *entry, void *data)
+static void __clp_add(struct clp_fh_list_entry *entry)
{
struct zpci_dev *zdev;