[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v3 08/11] vpci: Refactor vpci_remove_register to remove matched registers
vpci_remove_register() only supports removing a register in a time, but the follow-on changes need to remove all registers within a range. And vpci_remove_register() is only used for test currently. So, refactor it to support removing all matched registers in a calling time. And it is no matter to remove a non exist register, so remove the __must_check prefix. Signed-off-by: Jiqian Chen <Jiqian.Chen@xxxxxxx> --- cc: "Roger Pau Monné" <roger.pau@xxxxxxxxxx> cc: Anthony PERARD <anthony.perard@xxxxxxxxxx> --- v2->v3 changes: * Add new check to return error if registers overlap but not inside range. v1->v2 changes: new patch Best regards, Jiqian Chen. --- tools/tests/vpci/main.c | 4 ++-- xen/drivers/vpci/vpci.c | 34 ++++++++++++++++++++-------------- xen/include/xen/vpci.h | 4 ++-- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/tools/tests/vpci/main.c b/tools/tests/vpci/main.c index 33223db3eb77..ca72877d60cd 100644 --- a/tools/tests/vpci/main.c +++ b/tools/tests/vpci/main.c @@ -132,10 +132,10 @@ static void vpci_write32_mask(const struct pci_dev *pdev, unsigned int reg, rsvdz_mask)) #define VPCI_REMOVE_REG(off, size) \ - assert(!vpci_remove_register(test_pdev.vpci, off, size)) + assert(!vpci_remove_registers(test_pdev.vpci, off, size)) #define VPCI_REMOVE_INVALID_REG(off, size) \ - assert(vpci_remove_register(test_pdev.vpci, off, size)) + assert(vpci_remove_registers(test_pdev.vpci, off, size)) /* Read a 32b register using all possible sizes. */ void multiread4_check(unsigned int reg, uint32_t val) diff --git a/xen/drivers/vpci/vpci.c b/xen/drivers/vpci/vpci.c index 8ff5169bdd18..904770628a2a 100644 --- a/xen/drivers/vpci/vpci.c +++ b/xen/drivers/vpci/vpci.c @@ -497,34 +497,40 @@ int vpci_add_register_mask(struct vpci *vpci, vpci_read_t *read_handler, return 0; } -int vpci_remove_register(struct vpci *vpci, unsigned int offset, - unsigned int size) +int vpci_remove_registers(struct vpci *vpci, unsigned int start, + unsigned int size) { - const struct vpci_register r = { .offset = offset, .size = size }; struct vpci_register *rm; + unsigned int end = start + size; spin_lock(&vpci->lock); list_for_each_entry ( rm, &vpci->handlers, node ) { - int cmp = vpci_register_cmp(&r, rm); - - /* - * NB: do not use a switch so that we can use break to - * get out of the list loop earlier if required. - */ - if ( !cmp && rm->offset == offset && rm->size == size ) + /* Remove rm if rm is inside the range. */ + if ( rm->offset >= start && rm->offset + rm->size <= end ) { + struct vpci_register *prev = + list_entry(rm->node.prev, struct vpci_register, node); + list_del(&rm->node); - spin_unlock(&vpci->lock); xfree(rm); - return 0; + rm = prev; + continue; } - if ( cmp <= 0 ) + + /* Return error if registers overlap but not inside. */ + if ( rm->offset + rm->size > start && rm->offset < end ) + { + spin_unlock(&vpci->lock); + return -EINVAL; + } + + if ( start < rm->offset ) break; } spin_unlock(&vpci->lock); - return -ENOENT; + return 0; } /* Wrappers for performing reads/writes to the underlying hardware. */ diff --git a/xen/include/xen/vpci.h b/xen/include/xen/vpci.h index 8e815b418b7d..4e226331fdf3 100644 --- a/xen/include/xen/vpci.h +++ b/xen/include/xen/vpci.h @@ -69,8 +69,8 @@ static inline int __must_check vpci_add_register(struct vpci *vpci, size, data, 0, 0, 0, 0); } -int __must_check vpci_remove_register(struct vpci *vpci, unsigned int offset, - unsigned int size); +int vpci_remove_registers(struct vpci *vpci, unsigned int start, + unsigned int size); /* Generic read/write handlers for the PCI config space. */ uint32_t vpci_read(pci_sbdf_t sbdf, unsigned int reg, unsigned int size); -- 2.34.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |