From e101d146e667f742f9072b4c150a3e4b432ca48c Mon Sep 17 00:00:00 2001 From: Vamsi Attunuru Date: Tue, 3 Jun 2025 16:57:03 +0530 Subject: [PATCH] lib/pem: fix SDP queue mapping The firmware previously mapped the maximum number of SDP queues to each pseudo device, which limited the number of queues available per SDP VF. Firmware has been fixed to map only the required number of queues to each pseudo device, allowing SDP VFs to be configured with desired number of queues. Patch also fixes miscellaneous address range checks in register read & write routines. Fixes: e734ded691c0 ("lib/vfio: use pseudo RVU SDP devices") Signed-off-by: Vamsi Attunuru --- lib/pem/pem.c | 2 +- lib/pem/sdp.c | 34 +++++++++++++++++++++------------- lib/pem/sdp.h | 2 +- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/lib/pem/pem.c b/lib/pem/pem.c index b781f403..46c5e9dc 100644 --- a/lib/pem/pem.c +++ b/lib/pem/pem.c @@ -417,7 +417,7 @@ dao_pem_host_interrupt_setup(uint16_t pem_devid, int vfid, uint64_t **intr_addr) uint64_t reg_val; uint8_t rpvf; - reg_val = sdp_reg_read(&pem->sdp_pdev, SDP_VF_MBOX_DATA(0)); + sdp_reg_read(&pem->sdp_pdev, SDP_VF_MBOX_DATA(0), ®_val); rpvf = (reg_val >> SDP_EPFX_RINFO_RPVF_SHIFT) & 0xf; if (!rpvf) { diff --git a/lib/pem/sdp.c b/lib/pem/sdp.c index 78b704d1..6cd31746 100644 --- a/lib/pem/sdp.c +++ b/lib/pem/sdp.c @@ -17,29 +17,35 @@ #define SDP0_PCIE_DEV_NAME "0002:18:00.0" #define SDP1_PCIE_DEV_NAME "0002:19:00.0" +static inline int sdp_offset_valid(struct dao_vfio_device *sdp_pdev, uint64_t offset) +{ + return offset < sdp_pdev->mem[DAO_VFIO_DEV_BAR2].len; +} + int sdp_reg_write(struct dao_vfio_device *sdp_pdev, uint64_t offset, uint64_t val) { - if (offset > sdp_pdev->mem[DAO_VFIO_DEV_BAR2].len) + if (!sdp_offset_valid(sdp_pdev, offset)) return -ENOMEM; *((volatile uint64_t *)(sdp_pdev->mem[DAO_VFIO_DEV_BAR2].addr + offset)) = val; return 0; } -uint64_t -sdp_reg_read(struct dao_vfio_device *sdp_pdev, uint64_t offset) +int +sdp_reg_read(struct dao_vfio_device *sdp_pdev, uint64_t offset, uint64_t *val) { - if (offset > sdp_pdev->mem[DAO_VFIO_DEV_BAR2].len) + if (!sdp_pdev || !val || !sdp_offset_valid(sdp_pdev, offset)) return -ENOMEM; - return *(volatile uint64_t *)(sdp_pdev->mem[DAO_VFIO_DEV_BAR2].addr + offset); + *val = *(volatile uint64_t *)(sdp_pdev->mem[DAO_VFIO_DEV_BAR2].addr + offset); + return 0; } uint64_t * sdp_reg_addr(struct dao_vfio_device *sdp_pdev, uint64_t offset) { - if (offset > sdp_pdev->mem[DAO_VFIO_DEV_BAR2].len) + if (!sdp_offset_valid(sdp_pdev, offset)) return NULL; return (uint64_t *)(sdp_pdev->mem[DAO_VFIO_DEV_BAR2].addr + offset); @@ -66,14 +72,14 @@ sdp_init(struct dao_vfio_device *sdp_pdev) sdp_pdev->mbar = DAO_VFIO_DEV_BAR4; if (sdp_pdev->prime) { - reg_val = sdp_reg_read(sdp_pdev, SDP_EPFX_RINFO(0)); + sdp_reg_read(sdp_pdev, SDP_EPFX_RINFO(0), ®_val); reg_val &= ~SDP_EPFX_RINFO_SRN_MASK; sdp_reg_write(sdp_pdev, SDP_EPFX_RINFO(0), reg_val); - reg_val = sdp_reg_read(sdp_pdev, SDP_EPFX_RINFO(0)); + sdp_reg_read(sdp_pdev, SDP_EPFX_RINFO(0), ®_val); rpvf = (reg_val >> SDP_EPFX_RINFO_RPVF_SHIFT) & 0xf; - num_vfs = (reg_val >> SDP_EPFX_RINFO_RPVF_SHIFT) & 0x7f; + num_vfs = (reg_val >> SDP_EPFX_RINFO_NVVF_SHIFT) & 0x7f; /* Disable PF Ring */ - reg_val = sdp_reg_read(sdp_pdev, SDP_MAC0_PF_RING_CTL); + sdp_reg_read(sdp_pdev, SDP_MAC0_PF_RING_CTL, ®_val); reg_val &= ~SDP_MAC0_PF_RING_CTL_RPPF_MASK; sdp_reg_write(sdp_pdev, SDP_MAC0_PF_RING_CTL, reg_val); @@ -90,9 +96,11 @@ sdp_init(struct dao_vfio_device *sdp_pdev) info <<= 32; sdp_reg_write(sdp_pdev, SDP_PF_MBOX_DATA(0), info); vfid = num_vfs >> 1; - info = rpvf | ((uint64_t)vfid << 8) | ((uint64_t)num_vfs << 16); - info <<= 32; - sdp_reg_write(sdp_pdev, SDP_PF_MBOX_DATA(32), info); + if (vfid) { + info = rpvf | ((uint64_t)vfid << 8) | ((uint64_t)num_vfs << 16); + info <<= 32; + sdp_reg_write(sdp_pdev, SDP_PF_MBOX_DATA(vfid * rpvf), info); + } } return 0; diff --git a/lib/pem/sdp.h b/lib/pem/sdp.h index 6295d4e0..dd28dc9d 100644 --- a/lib/pem/sdp.h +++ b/lib/pem/sdp.h @@ -23,7 +23,7 @@ #define SDP_EPFX_RINFO_SRN_MASK DAO_GENMASK_ULL(6, 0) int sdp_init(struct dao_vfio_device *sdp_pdev); -uint64_t sdp_reg_read(struct dao_vfio_device *sdp_pdev, uint64_t offset); +int sdp_reg_read(struct dao_vfio_device *sdp_pdev, uint64_t offset, uint64_t *val); int sdp_reg_write(struct dao_vfio_device *sdp_pdev, uint64_t offset, uint64_t val); uint64_t *sdp_reg_addr(struct dao_vfio_device *sdp_pdev, uint64_t offset); void sdp_fini(struct dao_vfio_device *sdp_pdev);