AMD General
Hi Nicolas,
Agreed that pci_read_config() has no lockdown check, standardized PCI config
space reads are not blocked under [integrity]. But amdgpu_regs is not
equivalent to config space reads. It provides arbitrary read access to the full
GPU MMIO register space via RREG32, which is the same class of access as
pci_mmap_resource(), a user-space mapping of the PCI BAR. That function is
explicitly blocked at integrity with LOCKDOWN_PCI_ACCESS:
/* drivers/pci/pci-sysfs.c */
static int pci_mmap_resource(struct kobject *kobj, ...)
{
ret = security_locked_down(LOCKDOWN_PCI_ACCESS);
if (ret)
return ret;
...
}
pci_mmap_resource() is blocked not only because the mapping enables writes, but
because it grants direct, unmediated access to the BAR, the same unmediated
hardware access that amdgpu_regs provides through a serial interface. The
distinction is not read vs. write, it is mediated (config space via kernel
abstractions) vs. unmediated (direct BAR/MMIO access).
The /dev/mem precedent reinforces this. open_port() checks LOCKDOWN_DEV_MEM
(which is before LOCKDOWN_INTEGRITY_MAX) on open, blocking both reads and
writes unconditionally, because raw hardware memory access of any kind bypasses
the kernel's protection model:
/* drivers/char/mem.c */
static int open_port(struct inode *inode, struct file *filp)
{
rc = security_locked_down(LOCKDOWN_DEV_MEM);
if (rc)
return rc;
...
}
RREG32 on an arbitrary register offset is the GPU equivalent of a /dev/mem read
of a BAR-mapped region. Blocking it at integrity with LOCKDOWN_PCI_ACCESS is
consistent with both of these existing kernel precedents.
We prefer to keep the current approach.
Thanks & Regards
Asad
-----Original Message-----
From: Nicolas Bouchinet <[email protected]>
Sent: Monday, June 8, 2026 4:58 PM
To: Kamal, Asad <[email protected]>
Cc: [email protected]; Lazar, Lijo <[email protected]>; Zhang,
Hawking <[email protected]>; Ma, Le <[email protected]>; Zhang, Morris
<[email protected]>; Deucher, Alexander <[email protected]>; Wang,
Yang(Kevin) <[email protected]>; StDenis, Tom <[email protected]>
Subject: Re: [PATCH v3] drm/amdgpu: Gate debugfs MMIO access on kernel lockdown
[You don't often get email from [email protected]. Learn why
this is important at https://aka.ms/LearnAboutSenderIdentification ]
On Mon, Jun 08, 2026 at 11:03:05AM +0000, Kamal, Asad wrote:
> AMD General
>
> Hi @Nicolas Bouchinet
>
> Thank you for the review.
>
> The commit message references v1 behavior and is no longer accurate. Writes
> are already blocked, the existing debugfs_locked_down() in fs/debugfs/file.c
> handles writes when FMODE_WRITE is set, the early-return guard fails and
> security_locked_down(LOCKDOWN_DEBUGFS) blocks the open under [integrity].
>
> The patch addresses only the read path. Here is why reads are not blocked by
> debugfs_locked_down():
>
> static int debugfs_locked_down(struct inode *inode,
> struct file *filp,
> const struct file_operations
> *real_fops) {
> if ((inode->i_mode & 07777 & ~0444) == 0 &&
> !(filp->f_mode & FMODE_WRITE) &&
> (!real_fops || (!real_fops->unlocked_ioctl &&
> !real_fops->compat_ioctl &&
> !real_fops->mmap)))
> return 0;
> if (security_locked_down(LOCKDOWN_DEBUGFS))
> return -EPERM;
> return 0;
> }
>
> For a read-only open of amdgpu_regs (mode 0400, no ioctl, no mmap):
>
> 1) (0400 & 07777 & ~0444) == 0 → true - any mode with no bits set outside the
> 0444 mask (e.g. 0400, 0440, 0444) 0400 satisfies that.
> 2) !(filp->f_mode & FMODE_WRITE) → true for a read-only open.
> 3) No unlocked_ioctl, compat_ioctl, or mmap in amdgpu_debugfs_regs_fops →
> true.
>
> All three conditions hold, so debugfs_locked_down() returns 0 and the read
> open proceeds. The read handler then calls RREG32, a direct hardware MMIO
> read, with no further lockdown check. That is the gap which this patch is
> addressing.
>
> Thanks & Regards
> Asad
Thanks Asad for your explaination !
`LOCKDOWN_PCI_ACCESS` is used in the `integrity` mode of Lockdown and should be
used to protect against Kernel integrity tampering.
IIUC your issue, the access is read-only and thus, you should use one of the
existing `confidentiality` lockdown_reasons. You are free to add a new one if
none of the existing one covers your use case.
Best regards,
Nicolas