Re: [PATCH v3 3/3] PCI/sysfs: Prohibit unaligned access to I/O port on non-x86
From: duziming
Date: Thu Jan 08 2026 - 11:03:25 EST
在 2026/1/8 16:56, David Laight 写道:
On Thu, 8 Jan 2026 09:59:44 +0800Just to confirm: should all architectures prohibit unaligned access to device registers?
Ziming Du <duziming2@xxxxxxxxxx> wrote:
From: Yongqiang Liu <liuyongqiang13@xxxxxxxxxx>I'm not sure it makes any real sense for x86 either.
Unaligned access is harmful for non-x86 archs such as arm64. When we
use pwrite or pread to access the I/O port resources with unaligned
offset, system will crash as follows:
Unable to handle kernel paging request at virtual address fffffbfffe8010c1
Internal error: Oops: 0000000096000061 [#1] SMP
Call trace:
_outw include/asm-generic/io.h:594 [inline]
logic_outw+0x54/0x218 lib/logic_pio.c:305
pci_resource_io drivers/pci/pci-sysfs.c:1157 [inline]
pci_write_resource_io drivers/pci/pci-sysfs.c:1191 [inline]
pci_write_resource_io+0x208/0x260 drivers/pci/pci-sysfs.c:1181
sysfs_kf_bin_write+0x188/0x210 fs/sysfs/file.c:158
kernfs_fop_write_iter+0x2e8/0x4b0 fs/kernfs/file.c:338
vfs_write+0x7bc/0xac8 fs/read_write.c:586
ksys_write+0x12c/0x270 fs/read_write.c:639
__arm64_sys_write+0x78/0xb8 fs/read_write.c:648
Powerpc seems affected as well, so prohibit the unaligned access
on non-x86 archs.
IIRC io space is just like memory space, so a 16bit io access looks the
same as two 8bit accesses to an 8bit device (some put the 'data fifo' on
addresses 0 and 1 so the code could use 16bit io accesses to speed things up).
The same will have applied to misaligned accesses.
But, in reality, all device registers are aligned.
I'm not sure EFAULT is the best error code though, EINVAL might be better.
(EINVAL is returned for other address/size errors.)
EFAULT is usually returned for errors accessing the user buffer, a least
one unix system raises SIGSEGV whenever EFAULT is returned.
David
Fixes: 8633328be242 ("PCI: Allow read/write access to sysfs I/O port resources")
Signed-off-by: Yongqiang Liu <liuyongqiang13@xxxxxxxxxx>
Signed-off-by: Ziming Du <duziming2@xxxxxxxxxx>
---
drivers/pci/pci-sysfs.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 7e697b82c5e1..11d8b7ec4263 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -31,6 +31,7 @@
#include <linux/of.h>
#include <linux/aperture.h>
#include <linux/unaligned.h>
+#include <linux/align.h>
#include "pci.h"
#ifndef ARCH_PCI_DEV_GROUPS
@@ -1166,12 +1167,20 @@ static ssize_t pci_resource_io(struct file *filp, struct kobject *kobj,
*(u8 *)buf = inb(port);
return 1;
case 2:
+ #if !defined(CONFIG_X86)
+ if (!IS_ALIGNED(port, count))
+ return -EFAULT;
+ #endif
if (write)
outw(*(u16 *)buf, port);
else
*(u16 *)buf = inw(port);
return 2;
case 4:
+ #if !defined(CONFIG_X86)
+ if (!IS_ALIGNED(port, count))
+ return -EFAULT;
+ #endif
if (write)
outl(*(u32 *)buf, port);
else