aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGavin Shan <gwshan@linux.vnet.ibm.com>2016-09-08 15:42:00 +1000
committerStewart Smith <stewart@linux.vnet.ibm.com>2016-11-07 17:47:47 +1100
commite2fa37e75e428220940e0d901f0ad6d0cf0db37c (patch)
treea685cc3815c19ac00c0eaa32f8a005e6b6aa4713
parent414d62e7d45968deb3934ba2ab40266c0c82b661 (diff)
downloadskiboot-e2fa37e75e428220940e0d901f0ad6d0cf0db37c.zip
skiboot-e2fa37e75e428220940e0d901f0ad6d0cf0db37c.tar.gz
skiboot-e2fa37e75e428220940e0d901f0ad6d0cf0db37c.tar.bz2
core/pci: Fix criteria in pci_cfg_reg_filter()
The criteria to match the filter according to PCI config register offset and length is strict one, meaning the accessed region should matches with the filter's tracking region. However, the code isn't correct enough - @len should be replaced with @pcrf->len. The strict matching has to account for the length of current PCI config register access. We have to specify precise region through @start and @len in pci_virt_add_filter() when creating the filter. We lost flexibility. This changes the strict criteria to a relaxed one - the matched filter is returned when the accessed region is overlapped with the filter's region. With this change, the individual filter's handlers should validate the accessed (register) region if necessary. Fixes: 85daa7f00c50 ("core/pci: Support virtual device") Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com> Reviewed-by: Alistair Popple <alistair@popple.id.au> Acked-by: Alistair Popple <alistair@popple.id.au> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
-rw-r--r--core/pci-virt.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/core/pci-virt.c b/core/pci-virt.c
index 570c6e8..b531470 100644
--- a/core/pci-virt.c
+++ b/core/pci-virt.c
@@ -55,9 +55,14 @@ static struct pci_cfg_reg_filter *pci_virt_find_filter(
if (!pvd || !len || start >= pvd->cfg_size)
return NULL;
+ /* Return filter if there is overlapped region. We don't
+ * require strict matching for more flexibility. It also
+ * means the associated handler should validate the register
+ * offset and length.
+ */
list_for_each(&pvd->pcrf, pcrf, link) {
- if (start >= pcrf->start &&
- (start + len) <= (pcrf->start + len))
+ if (start < (pcrf->start + pcrf->len) &&
+ (start + len) > pcrf->start)
return pcrf;
}