From 0b7589ecca2b6f962cf3314a3a5a675deeefb624 Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Wed, 15 Jun 2016 13:07:51 +0200 Subject: s390/pci: query fmb length Query the length of the fmb and abort fmb registration if the size of the associated measurement block is too small. Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/pci.h | 1 + arch/s390/include/asm/pci_clp.h | 3 ++- arch/s390/pci/pci.c | 2 +- arch/s390/pci/pci_clp.c | 1 + 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h index 6611f798d2be..4e3186649578 100644 --- a/arch/s390/include/asm/pci.h +++ b/arch/s390/include/asm/pci.h @@ -133,6 +133,7 @@ struct zpci_dev { /* Function measurement block */ struct zpci_fmb *fmb; u16 fmb_update; /* update interval */ + u16 fmb_length; /* software counters */ atomic64_t allocated_pages; atomic64_t mapped_pages; diff --git a/arch/s390/include/asm/pci_clp.h b/arch/s390/include/asm/pci_clp.h index c232ef9711f5..d6f1b1d94352 100644 --- a/arch/s390/include/asm/pci_clp.h +++ b/arch/s390/include/asm/pci_clp.h @@ -87,7 +87,8 @@ struct clp_rsp_query_pci { u16 pchid; u32 bar[PCI_BAR_COUNT]; u8 pfip[CLP_PFIP_NR_SEGMENTS]; /* pci function internal path */ - u32 : 24; + u32 : 16; + u8 fmb_len; u8 pft; /* pci function type */ u64 sdma; /* start dma as */ u64 edma; /* end dma as */ diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index 64e1734bebb7..38e17d4d9884 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c @@ -180,7 +180,7 @@ int zpci_fmb_enable_device(struct zpci_dev *zdev) { struct mod_pci_args args = { 0, 0, 0, 0 }; - if (zdev->fmb) + if (zdev->fmb || sizeof(*zdev->fmb) < zdev->fmb_length) return -EINVAL; zdev->fmb = kmem_cache_zalloc(zdev_fmb_cache, GFP_KERNEL); diff --git a/arch/s390/pci/pci_clp.c b/arch/s390/pci/pci_clp.c index e3ef63b36b5a..1c3332ac1957 100644 --- a/arch/s390/pci/pci_clp.c +++ b/arch/s390/pci/pci_clp.c @@ -148,6 +148,7 @@ static int clp_store_query_pci_fn(struct zpci_dev *zdev, zdev->pft = response->pft; zdev->vfn = response->vfn; zdev->uid = response->uid; + zdev->fmb_length = sizeof(u32) * response->fmb_len; memcpy(zdev->pfip, response->pfip, sizeof(zdev->pfip)); if (response->util_str_avail) { -- cgit