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); + 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; -- 2.27.0