s390/pci: query fmb length
authorSebastian Ott <sebott@linux.vnet.ibm.com>
Wed, 15 Jun 2016 11:07:51 +0000 (13:07 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Wed, 14 Dec 2016 15:33:41 +0000 (16:33 +0100)
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 <sebott@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
arch/s390/include/asm/pci.h
arch/s390/include/asm/pci_clp.h
arch/s390/pci/pci.c
arch/s390/pci/pci_clp.c

index 6611f798d2be6f5db9045e605259fef4994a18ef..4e31866495787a844f269ccc0885ddff2eed02ad 100644 (file)
@@ -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;
index c232ef9711f5784642907fb3cc3d6e9231ffb5db..d6f1b1d94352000035d61546cb6b2688b3081e0e 100644 (file)
@@ -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 */
index 64e1734bebb78eb9808f0ad439ae1e25c413d2cb..38e17d4d9884ddd240b8221a1155d991e00a253d 100644 (file)
@@ -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);
index e3ef63b36b5aad143ece542b709674b07f96cecf..1c3332ac1957f7926a51dbe7b0962dcfe449a5bc 100644 (file)
@@ -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) {