[PATCH 0/1] nvme: Export CSTS register via sysfs
Keith Busch
kbusch at kernel.org
Thu Mar 18 19:46:53 GMT 2021
On Thu, Mar 18, 2021 at 06:39:37PM +0000, Alan Adamson wrote:
>
>
> > On Mar 18, 2021, at 9:52 AM, Keith Busch <kbusch at kernel.org> wrote:
> >
> > On Thu, Mar 18, 2021 at 04:28:24PM +0000, Alan Adamson wrote:
> >>
> >>
> >>> On Mar 17, 2021, at 9:38 PM, Christoph Hellwig <hch at lst.de> wrote:
> >>>
> >>> On Wed, Mar 17, 2021 at 04:46:14PM -0400, Alan Adamson wrote:
> >>>> This patch exports the NVMe Controller CSTS register via sysfs. This
> >>>> feature can be used by userland executables that accessed CSTS and
> >>>> possibly other registers by mapping them into user space. Since this ability
> >>>> may not always available, exporting certain registers via sysfs provides
> >>>> a safe/read-only way to access registers from outside the kernel.
> >>>
> >>> So what is this application doings with it? Should we just have a
> >>> ready attribute instead of exporting a raw register encoding?
> >>
> >>
> >> Was using nvme-cli show-regs to manage nvme devices. This is no longer an option.
> >
> > Most distributions ship with kernel CONFIG_IO_STRICT_DEVMEM these days,
> > so that user command will very rarely work on PCIe targets anymore.
> >
> > Perhaps we could introduce a driver option allowing read-only mmap on
> > this memory? While you're currently asking for just one register
> > attribute, it would be nice if we can make all future requests available
> > without piling on more sysfs properties.
>
> This could be a good solution (along with a nvme-cli change). I’ll code this up.
I don't think it should require user space modifications. Just mmap the
current resource as-is but let the driver allow read-only in the
precense of CONFIG_IO_STRICT_DEVMEM. The below is a rough idea of what I
had in mind (compile tested only, and a proper solution should restrict
access to a specific address range)
---
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index d47bb18b976a..c70965135276 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -2362,6 +2362,7 @@ static int nvme_pci_enable(struct nvme_dev *dev)
return result;
pci_set_master(pdev);
+ pdev->allow_ro_mmap = true;
if (dev->ctrl.quirks & NVME_QUIRK_DMA_ADDRESS_BITS_48)
dma_address_bits = 48;
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index f8afd54ca3e1..b92f2172497c 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -1028,7 +1028,10 @@ static int pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
if (ret)
return ret;
- if (res->flags & IORESOURCE_MEM && iomem_is_exclusive(res->start))
+ if (res->flags & IORESOURCE_MEM && iomem_is_exclusive(res->start) &&
+ !(pdev->allow_ro_mmap &&
+ !((vma->vm_flags & VM_SHARED) ||
+ (vma->vm_flags & VM_MAYWRITE))))
return -EINVAL;
if (!pci_mmap_fits(pdev, bar, vma, PCI_MMAP_SYSFS))
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 86c799c97b77..ca1598fa46d5 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -379,6 +379,7 @@ struct pci_dev {
user sysfs */
unsigned int clear_retrain_link:1; /* Need to clear Retrain Link
bit manually */
+ unsigned int allow_ro_mmap; /* allow read only even if CONFIG_IO_STRICT_DEVMEM */
unsigned int d3hot_delay; /* D3hot->D0 transition time in ms */
unsigned int d3cold_delay; /* D3cold->D0 transition time in ms */
--
More information about the Linux-nvme
mailing list