On Thu, Mar 16 2017, Greg KH wrote: > On Tue, Mar 07, 2017 at 03:09:46PM +0100, Michal Sojka wrote: >> Since commit b65502879556 ("uio: we cannot mmap unaligned page >> contents") addresses and sizes of UIO memory regions must be >> page-aligned. If the address in the BAR register is not page-aligned, >> the mentioned commit forces the UIO driver to round the address down >> to the page size. Then, there is no easy way for user-space to learn >> the offset of the actual memory region within the page, because the >> offset seen in the sysfs is calculated from the rounded address and >> thus it is always zero. >> >> Fix that problem by including the offset in struct uio_mem. UIO >> drivers can set this field and its value is reported via sysfs. > > It is, where?
/sys/class/uio/uio0/maps/map0/offset >> >> Drivers for hardware with page-aligned BARs need not to be modified >> provided that they initialize struct uio_info with zeros. >> >> Signed-off-by: Michal Sojka <sojk...@fel.cvut.cz> >> --- >> drivers/uio/uio.c | 2 +- >> include/linux/uio_driver.h | 13 ++++++++----- >> 2 files changed, 9 insertions(+), 6 deletions(-) >> >> diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c >> index fba021f5736a..27c329131350 100644 >> --- a/drivers/uio/uio.c >> +++ b/drivers/uio/uio.c >> @@ -66,7 +66,7 @@ static ssize_t map_size_show(struct uio_mem *mem, char >> *buf) >> >> static ssize_t map_offset_show(struct uio_mem *mem, char *buf) >> { >> - return sprintf(buf, "0x%llx\n", (unsigned long long)mem->addr & >> ~PAGE_MASK); >> + return sprintf(buf, "0x%llx\n", (unsigned long long)mem->offs); > > All you changed was this value that sysfs shows. > >> } >> >> struct map_sysfs_entry { >> diff --git a/include/linux/uio_driver.h b/include/linux/uio_driver.h >> index 32c0e83d6239..89b53094f127 100644 >> --- a/include/linux/uio_driver.h >> +++ b/include/linux/uio_driver.h >> @@ -23,11 +23,13 @@ struct uio_map; >> /** >> * struct uio_mem - description of a UIO memory region >> * @name: name of the memory region for identification >> - * @addr: address of the device's memory (phys_addr is used since >> - * addr can be logical, virtual, or physical & phys_addr_t >> - * should always be large enough to handle any of the >> - * address types) >> - * @size: size of IO >> + * @addr: address of the device's memory rounded to page >> + * size (phys_addr is used since addr can be >> + * logical, virtual, or physical & phys_addr_t >> + * should always be large enough to handle any of >> + * the address types) >> + * @offs: offset of device memory within the page >> + * @size: size of IO (multiple of page size) >> * @memtype: type of memory addr points to >> * @internal_addr: ioremap-ped version of addr, for driver internal use >> * @map: for use by the UIO core only. >> @@ -35,6 +37,7 @@ struct uio_map; >> struct uio_mem { >> const char *name; >> phys_addr_t addr; >> + unsigned long offs;; > > Did you really test this patch? Why the two ;;? And who sets this? > > I think you broke things :( This is set in patch 3/3 and it works correctly on my hardware. It seems like you would like to have patches 2/3 and 3/3 merged in a single one. I'll send v2 in a while and address your other comments as well. Thanks. -Michal