From 5d2ff7718d35f15636e231219d50d84fbd73ffb5 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Pali=20Roh=C3=A1r?= Date: Sat, 5 Nov 2022 17:32:38 +0100 Subject: [PATCH] libpci: mmio-ports: Bypass CPU cache and add barriers for read/write Between accessing address address and data I/O ports it is needed to issue barriers. Use explicit readl() for barrier and O_DSYNC to bypass CPU cache. --- lib/mmio-ports.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/mmio-ports.c b/lib/mmio-ports.c index b9e3926..50cbee7 100644 --- a/lib/mmio-ports.c +++ b/lib/mmio-ports.c @@ -269,7 +269,7 @@ conf1_init(struct pci_access *a) if (!validate_addrs(addrs)) a->error("Option mmio-conf1.addrs has invalid address format \"%s\".", addrs); - a->fd = open(devmem, O_RDWR); + a->fd = open(devmem, O_RDWR | O_DSYNC); /* O_DSYNC bypass CPU cache for mmap() on Linux */ if (a->fd < 0) a->error("Cannot open %s: %s.", devmem, strerror(errno)); } @@ -316,6 +316,7 @@ conf1_read(struct pci_dev *d, int pos, byte *buf, int len) return 0; writel(0x80000000 | ((d->bus & 0xff) << 16) | (PCI_DEVFN(d->dev, d->func) << 8) | (pos & 0xfc), addr); + readl(addr); /* write barrier for address */ switch (len) { @@ -353,6 +354,7 @@ conf1_write(struct pci_dev *d, int pos, byte *buf, int len) return 0; writel(0x80000000 | ((d->bus & 0xff) << 16) | (PCI_DEVFN(d->dev, d->func) << 8) | (pos & 0xfc), addr); + readl(addr); /* write barrier for address */ switch (len) { @@ -367,6 +369,17 @@ conf1_write(struct pci_dev *d, int pos, byte *buf, int len) break; } + /* + * write barrier for data + * Note that we cannot read from data port because it may have side effect. + * Instead we read from address port (which should not have side effect) to + * create a barrier between two conf1_write() calls. But this does not have + * to be 100% correct as it does not ensure barrier on data port itself. + * Correct way is to issue CPU instruction for full hw sync barrier but gcc + * does not provide any (builtin) function yet. + */ + readl(addr); + return 1; } -- 2.39.2