Message ID | 610abe685f90870be52bc7c2ca45ab5235bd8eb4.1689792825.git.tjeznach@rivosinc.com (mailing list archive) |
---|---|
State | Awaiting Upstream, archived |
Headers | show |
Series | Linux RISC-V IOMMU Support | expand |
On 19/07/2023 21:33, Tomasz Jeznach wrote: > Enable sysfs debug / visibility interface providing restricted > access to hardware registers. Please use subject prefixes matching the subsystem. You can get them for example with `git log --oneline -- DIRECTORY_OR_FILE` on the directory your patch is touching. > > Signed-off-by: Tomasz Jeznach <tjeznach@rivosinc.com> > --- > drivers/iommu/riscv/Makefile | 2 +- > drivers/iommu/riscv/iommu-sysfs.c | 183 ++++++++++++++++++++++++++++++ > drivers/iommu/riscv/iommu.c | 7 ++ > drivers/iommu/riscv/iommu.h | 2 + > 4 files changed, 193 insertions(+), 1 deletion(-) > create mode 100644 drivers/iommu/riscv/iommu-sysfs.c > > diff --git a/drivers/iommu/riscv/Makefile b/drivers/iommu/riscv/Makefile > index 38730c11e4a8..9523eb053cfc 100644 > --- a/drivers/iommu/riscv/Makefile > +++ b/drivers/iommu/riscv/Makefile > @@ -1 +1 @@ > -obj-$(CONFIG_RISCV_IOMMU) += iommu.o iommu-pci.o iommu-platform.o > \ No newline at end of file > +obj-$(CONFIG_RISCV_IOMMU) += iommu.o iommu-pci.o iommu-platform.o iommu-sysfs.o > \ No newline at end of file You have this error in multiple places. > diff --git a/drivers/iommu/riscv/iommu-sysfs.c b/drivers/iommu/riscv/iommu-sysfs.c > new file mode 100644 > index 000000000000..f038ea8445c5 > --- /dev/null > +++ b/drivers/iommu/riscv/iommu-sysfs.c > @@ -0,0 +1,183 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* > + * IOMMU API for RISC-V architected Ziommu implementations. > + * > + * Copyright © 2022-2023 Rivos Inc. > + * > + * Author: Tomasz Jeznach <tjeznach@rivosinc.com> > + */ > + > +#include <linux/module.h> > +#include <linux/kernel.h> > +#include <linux/compiler.h> > +#include <linux/iommu.h> > +#include <linux/platform_device.h> > +#include <asm/page.h> > + > +#include "iommu.h" > + > +#define sysfs_dev_to_iommu(dev) \ > + container_of(dev_get_drvdata(dev), struct riscv_iommu_device, iommu) > + > +static ssize_t address_show(struct device *dev, > + struct device_attribute *attr, char *buf) Where is the sysfs ABI documented? Best regards, Krzysztof
On 2023/7/20 3:33, Tomasz Jeznach wrote: > +#define sysfs_dev_to_iommu(dev) \ > + container_of(dev_get_drvdata(dev), struct riscv_iommu_device, iommu) > + > +static ssize_t address_show(struct device *dev, > + struct device_attribute *attr, char *buf) > +{ > + struct riscv_iommu_device *iommu = sysfs_dev_to_iommu(dev); > + return sprintf(buf, "%llx\n", iommu->reg_phys); Use sysfs_emit() please. > +} > + > +static DEVICE_ATTR_RO(address); > + > +#define ATTR_RD_REG32(name, offset) \ > + ssize_t reg_ ## name ## _show(struct device *dev, \ > + struct device_attribute *attr, char *buf) \ > +{ \ > + struct riscv_iommu_device *iommu = sysfs_dev_to_iommu(dev); \ > + return sprintf(buf, "0x%x\n", \ > + riscv_iommu_readl(iommu, offset)); \ > +} > + > +#define ATTR_RD_REG64(name, offset) \ > + ssize_t reg_ ## name ## _show(struct device *dev, \ > + struct device_attribute *attr, char *buf) \ > +{ \ > + struct riscv_iommu_device *iommu = sysfs_dev_to_iommu(dev); \ > + return sprintf(buf, "0x%llx\n", \ > + riscv_iommu_readq(iommu, offset)); \ > +} > + > +#define ATTR_WR_REG32(name, offset) \ > + ssize_t reg_ ## name ## _store(struct device *dev, \ > + struct device_attribute *attr, \ > + const char *buf, size_t len) \ > +{ \ > + struct riscv_iommu_device *iommu = sysfs_dev_to_iommu(dev); \ > + unsigned long val; \ > + int ret; \ > + ret = kstrtoul(buf, 0, &val); \ > + if (ret) \ > + return ret; \ > + riscv_iommu_writel(iommu, offset, val); \ > + return len; \ > +} > + > +#define ATTR_WR_REG64(name, offset) \ > + ssize_t reg_ ## name ## _store(struct device *dev, \ > + struct device_attribute *attr, \ > + const char *buf, size_t len) \ > +{ \ > + struct riscv_iommu_device *iommu = sysfs_dev_to_iommu(dev); \ > + unsigned long long val; \ > + int ret; \ > + ret = kstrtoull(buf, 0, &val); \ > + if (ret) \ > + return ret; \ > + riscv_iommu_writeq(iommu, offset, val); \ > + return len; \ > +} So this allows users to change the registers through sysfs? How does it synchronize with the iommu driver? Best regards, baolu
On Thu, Jul 20, 2023 at 5:51 AM Baolu Lu <baolu.lu@linux.intel.com> wrote: > > On 2023/7/20 3:33, Tomasz Jeznach wrote: > > +#define sysfs_dev_to_iommu(dev) \ > > + container_of(dev_get_drvdata(dev), struct riscv_iommu_device, iommu) > > + > > +static ssize_t address_show(struct device *dev, > > + struct device_attribute *attr, char *buf) > > +{ > > + struct riscv_iommu_device *iommu = sysfs_dev_to_iommu(dev); > > + return sprintf(buf, "%llx\n", iommu->reg_phys); > > Use sysfs_emit() please. > ack. Thanks, will update. > > +} > > + > > +static DEVICE_ATTR_RO(address); > > + > > +#define ATTR_RD_REG32(name, offset) \ > > + ssize_t reg_ ## name ## _show(struct device *dev, \ > > + struct device_attribute *attr, char *buf) \ > > +{ \ > > + struct riscv_iommu_device *iommu = sysfs_dev_to_iommu(dev); \ > > + return sprintf(buf, "0x%x\n", \ > > + riscv_iommu_readl(iommu, offset)); \ > > +} > > + > > +#define ATTR_RD_REG64(name, offset) \ > > + ssize_t reg_ ## name ## _show(struct device *dev, \ > > + struct device_attribute *attr, char *buf) \ > > +{ \ > > + struct riscv_iommu_device *iommu = sysfs_dev_to_iommu(dev); \ > > + return sprintf(buf, "0x%llx\n", \ > > + riscv_iommu_readq(iommu, offset)); \ > > +} > > + > > +#define ATTR_WR_REG32(name, offset) \ > > + ssize_t reg_ ## name ## _store(struct device *dev, \ > > + struct device_attribute *attr, \ > > + const char *buf, size_t len) \ > > +{ \ > > + struct riscv_iommu_device *iommu = sysfs_dev_to_iommu(dev); \ > > + unsigned long val; \ > > + int ret; \ > > + ret = kstrtoul(buf, 0, &val); \ > > + if (ret) \ > > + return ret; \ > > + riscv_iommu_writel(iommu, offset, val); \ > > + return len; \ > > +} > > + > > +#define ATTR_WR_REG64(name, offset) \ > > + ssize_t reg_ ## name ## _store(struct device *dev, \ > > + struct device_attribute *attr, \ > > + const char *buf, size_t len) \ > > +{ \ > > + struct riscv_iommu_device *iommu = sysfs_dev_to_iommu(dev); \ > > + unsigned long long val; \ > > + int ret; \ > > + ret = kstrtoull(buf, 0, &val); \ > > + if (ret) \ > > + return ret; \ > > + riscv_iommu_writeq(iommu, offset, val); \ > > + return len; \ > > +} > > So this allows users to change the registers through sysfs? How does > it synchronize with the iommu driver? > The only writable registers are for debug interface and performance monitoring counters, without any synchronization requirements between user / driver. In follow up patch series performance counters will be also removed from sysfs, replaced by integration with perfmon subsystem. The only remaining will be a debug access, providing user access to address translation, in short it provides an interface to query SPA based on provided IOVA/RID/PASID. There was a discussion in RVI IOMMU TG forum if it's acceptable to expose such an interface to the privileged user, and the conclusion was that it's very likely not exposing more info than privileged users already are able to acquire by looking at in-memory data structures. Read-only registers are to provide debug access to track queue head/tail pointers and interrupt states. > Best regards, > baolu regards, - Tomasz
On Wed, Jul 19, 2023 at 11:38 PM Krzysztof Kozlowski <krzk@kernel.org> wrote: > > On 19/07/2023 21:33, Tomasz Jeznach wrote: > > Enable sysfs debug / visibility interface providing restricted > > access to hardware registers. > > Please use subject prefixes matching the subsystem. You can get them for > example with `git log --oneline -- DIRECTORY_OR_FILE` on the directory > your patch is touching. > ack. > > > > Signed-off-by: Tomasz Jeznach <tjeznach@rivosinc.com> > > --- > > drivers/iommu/riscv/Makefile | 2 +- > > drivers/iommu/riscv/iommu-sysfs.c | 183 ++++++++++++++++++++++++++++++ > > drivers/iommu/riscv/iommu.c | 7 ++ > > drivers/iommu/riscv/iommu.h | 2 + > > 4 files changed, 193 insertions(+), 1 deletion(-) > > create mode 100644 drivers/iommu/riscv/iommu-sysfs.c > > > > diff --git a/drivers/iommu/riscv/Makefile b/drivers/iommu/riscv/Makefile > > index 38730c11e4a8..9523eb053cfc 100644 > > --- a/drivers/iommu/riscv/Makefile > > +++ b/drivers/iommu/riscv/Makefile > > @@ -1 +1 @@ > > -obj-$(CONFIG_RISCV_IOMMU) += iommu.o iommu-pci.o iommu-platform.o > > \ No newline at end of file > > +obj-$(CONFIG_RISCV_IOMMU) += iommu.o iommu-pci.o iommu-platform.o iommu-sysfs.o > > \ No newline at end of file > > You have this error in multiple places. > ack. next version will run through checkpatch.pl, should spot such problems. > > diff --git a/drivers/iommu/riscv/iommu-sysfs.c b/drivers/iommu/riscv/iommu-sysfs.c > > new file mode 100644 > > index 000000000000..f038ea8445c5 > > --- /dev/null > > +++ b/drivers/iommu/riscv/iommu-sysfs.c > > @@ -0,0 +1,183 @@ > > +// SPDX-License-Identifier: GPL-2.0-only > > +/* > > + * IOMMU API for RISC-V architected Ziommu implementations. > > + * > > + * Copyright © 2022-2023 Rivos Inc. > > + * > > + * Author: Tomasz Jeznach <tjeznach@rivosinc.com> > > + */ > > + > > +#include <linux/module.h> > > +#include <linux/kernel.h> > > +#include <linux/compiler.h> > > +#include <linux/iommu.h> > > +#include <linux/platform_device.h> > > +#include <asm/page.h> > > + > > +#include "iommu.h" > > + > > +#define sysfs_dev_to_iommu(dev) \ > > + container_of(dev_get_drvdata(dev), struct riscv_iommu_device, iommu) > > + > > +static ssize_t address_show(struct device *dev, > > + struct device_attribute *attr, char *buf) > > > Where is the sysfs ABI documented? > Sysfs for now is used only to expose selected IOMMU memory mapped registers, with complete documentation in the RISC-V IOMMU Arch Spec [1], and some comments in iommu-bits.h file. LMK If it would be better to put a dedicated file documenting those with the patch itself. [1] https://github.com/riscv-non-isa/riscv-iommu/releases/download/v1.0/riscv-iommu.pdf > > Best regards, > Krzysztof > regards, - Tomasz
On 20/07/2023 20:30, Tomasz Jeznach wrote: u.h" >>> + >>> +#define sysfs_dev_to_iommu(dev) \ >>> + container_of(dev_get_drvdata(dev), struct riscv_iommu_device, iommu) >>> + >>> +static ssize_t address_show(struct device *dev, >>> + struct device_attribute *attr, char *buf) >> >> >> Where is the sysfs ABI documented? >> > > Sysfs for now is used only to expose selected IOMMU memory mapped > registers, with complete documentation in the RISC-V IOMMU Arch Spec > [1], and some comments in iommu-bits.h file. > LMK If it would be better to put a dedicated file documenting those > with the patch itself. I meant, you created new sysfs interface. Maybe I missed something in the patchset, but each new sysfs interface required documenting in Documentation/ABI/. Best regards, Krzysztof
On Thu, Jul 20, 2023 at 11:37:50PM +0200, Krzysztof Kozlowski wrote: > On 20/07/2023 20:30, Tomasz Jeznach wrote: > >>> +#define sysfs_dev_to_iommu(dev) \ > >>> + container_of(dev_get_drvdata(dev), struct riscv_iommu_device, iommu) > >>> + > >>> +static ssize_t address_show(struct device *dev, > >>> + struct device_attribute *attr, char *buf) > >> > >> > >> Where is the sysfs ABI documented? > >> > > > > Sysfs for now is used only to expose selected IOMMU memory mapped > > registers, with complete documentation in the RISC-V IOMMU Arch Spec > > [1], and some comments in iommu-bits.h file. > > LMK If it would be better to put a dedicated file documenting those > > with the patch itself. > > I meant, you created new sysfs interface. Maybe I missed something in > the patchset, but each new sysfs interface required documenting in > Documentation/ABI/. | expose selected IOMMU memory mapped registers | Enable sysfs debug / visibility interface providing restricted | access to hardware registers. Documentation requirements of sysfs stuff aside, I'm not sure that we even want a sysfs interface for this in the first place? Seems like, if at all, this should be debugfs instead? Seems like the only use case for it is debugging/development...
On Thu, Jul 20, 2023 at 3:08 PM Conor Dooley <conor@kernel.org> wrote: > > On Thu, Jul 20, 2023 at 11:37:50PM +0200, Krzysztof Kozlowski wrote: > > On 20/07/2023 20:30, Tomasz Jeznach wrote: > > > >>> +#define sysfs_dev_to_iommu(dev) \ > > >>> + container_of(dev_get_drvdata(dev), struct riscv_iommu_device, iommu) > > >>> + > > >>> +static ssize_t address_show(struct device *dev, > > >>> + struct device_attribute *attr, char *buf) > > >> > > >> > > >> Where is the sysfs ABI documented? > > >> > > > > > > Sysfs for now is used only to expose selected IOMMU memory mapped > > > registers, with complete documentation in the RISC-V IOMMU Arch Spec > > > [1], and some comments in iommu-bits.h file. > > > LMK If it would be better to put a dedicated file documenting those > > > with the patch itself. > > > > I meant, you created new sysfs interface. Maybe I missed something in > > the patchset, but each new sysfs interface required documenting in > > Documentation/ABI/. > > | expose selected IOMMU memory mapped registers > > | Enable sysfs debug / visibility interface providing restricted > | access to hardware registers. > > Documentation requirements of sysfs stuff aside, I'm not sure that we > even want a sysfs interface for this in the first place? Seems like, if > at all, this should be debugfs instead? Seems like the only use case for > it is debugging/development... Thanks Conor, will switch to debugfs. This will be a more suitable interface. regards, - Tomasz
diff --git a/drivers/iommu/riscv/Makefile b/drivers/iommu/riscv/Makefile index 38730c11e4a8..9523eb053cfc 100644 --- a/drivers/iommu/riscv/Makefile +++ b/drivers/iommu/riscv/Makefile @@ -1 +1 @@ -obj-$(CONFIG_RISCV_IOMMU) += iommu.o iommu-pci.o iommu-platform.o \ No newline at end of file +obj-$(CONFIG_RISCV_IOMMU) += iommu.o iommu-pci.o iommu-platform.o iommu-sysfs.o \ No newline at end of file diff --git a/drivers/iommu/riscv/iommu-sysfs.c b/drivers/iommu/riscv/iommu-sysfs.c new file mode 100644 index 000000000000..f038ea8445c5 --- /dev/null +++ b/drivers/iommu/riscv/iommu-sysfs.c @@ -0,0 +1,183 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * IOMMU API for RISC-V architected Ziommu implementations. + * + * Copyright © 2022-2023 Rivos Inc. + * + * Author: Tomasz Jeznach <tjeznach@rivosinc.com> + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/compiler.h> +#include <linux/iommu.h> +#include <linux/platform_device.h> +#include <asm/page.h> + +#include "iommu.h" + +#define sysfs_dev_to_iommu(dev) \ + container_of(dev_get_drvdata(dev), struct riscv_iommu_device, iommu) + +static ssize_t address_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct riscv_iommu_device *iommu = sysfs_dev_to_iommu(dev); + return sprintf(buf, "%llx\n", iommu->reg_phys); +} + +static DEVICE_ATTR_RO(address); + +#define ATTR_RD_REG32(name, offset) \ + ssize_t reg_ ## name ## _show(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +{ \ + struct riscv_iommu_device *iommu = sysfs_dev_to_iommu(dev); \ + return sprintf(buf, "0x%x\n", \ + riscv_iommu_readl(iommu, offset)); \ +} + +#define ATTR_RD_REG64(name, offset) \ + ssize_t reg_ ## name ## _show(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +{ \ + struct riscv_iommu_device *iommu = sysfs_dev_to_iommu(dev); \ + return sprintf(buf, "0x%llx\n", \ + riscv_iommu_readq(iommu, offset)); \ +} + +#define ATTR_WR_REG32(name, offset) \ + ssize_t reg_ ## name ## _store(struct device *dev, \ + struct device_attribute *attr, \ + const char *buf, size_t len) \ +{ \ + struct riscv_iommu_device *iommu = sysfs_dev_to_iommu(dev); \ + unsigned long val; \ + int ret; \ + ret = kstrtoul(buf, 0, &val); \ + if (ret) \ + return ret; \ + riscv_iommu_writel(iommu, offset, val); \ + return len; \ +} + +#define ATTR_WR_REG64(name, offset) \ + ssize_t reg_ ## name ## _store(struct device *dev, \ + struct device_attribute *attr, \ + const char *buf, size_t len) \ +{ \ + struct riscv_iommu_device *iommu = sysfs_dev_to_iommu(dev); \ + unsigned long long val; \ + int ret; \ + ret = kstrtoull(buf, 0, &val); \ + if (ret) \ + return ret; \ + riscv_iommu_writeq(iommu, offset, val); \ + return len; \ +} + +#define ATTR_RO_REG32(name, offset) \ +static ATTR_RD_REG32(name, offset); \ +static DEVICE_ATTR_RO(reg_ ## name) + +#define ATTR_RW_REG32(name, offset) \ +static ATTR_RD_REG32(name, offset); \ +static ATTR_WR_REG32(name, offset); \ +static DEVICE_ATTR_RW(reg_ ## name) + +#define ATTR_RO_REG64(name, offset) \ +static ATTR_RD_REG64(name, offset); \ +static DEVICE_ATTR_RO(reg_ ## name) + +#define ATTR_RW_REG64(name, offset) \ +static ATTR_RD_REG64(name, offset); \ +static ATTR_WR_REG64(name, offset); \ +static DEVICE_ATTR_RW(reg_ ## name) + +ATTR_RO_REG64(cap, RISCV_IOMMU_REG_CAP); +ATTR_RO_REG64(fctl, RISCV_IOMMU_REG_FCTL); +ATTR_RO_REG32(cqh, RISCV_IOMMU_REG_CQH); +ATTR_RO_REG32(cqt, RISCV_IOMMU_REG_CQT); +ATTR_RO_REG32(cqcsr, RISCV_IOMMU_REG_CQCSR); +ATTR_RO_REG32(fqh, RISCV_IOMMU_REG_FQH); +ATTR_RO_REG32(fqt, RISCV_IOMMU_REG_FQT); +ATTR_RO_REG32(fqcsr, RISCV_IOMMU_REG_FQCSR); +ATTR_RO_REG32(pqh, RISCV_IOMMU_REG_PQH); +ATTR_RO_REG32(pqt, RISCV_IOMMU_REG_PQT); +ATTR_RO_REG32(pqcsr, RISCV_IOMMU_REG_PQCSR); +ATTR_RO_REG32(ipsr, RISCV_IOMMU_REG_IPSR); +ATTR_RO_REG32(ivec, RISCV_IOMMU_REG_IVEC); +ATTR_RW_REG64(tr_iova, RISCV_IOMMU_REG_TR_REQ_IOVA); +ATTR_RW_REG64(tr_ctrl, RISCV_IOMMU_REG_TR_REQ_CTL); +ATTR_RW_REG64(tr_response, RISCV_IOMMU_REG_TR_RESPONSE); +ATTR_RW_REG32(iocntovf, RISCV_IOMMU_REG_IOCOUNTOVF); +ATTR_RW_REG32(iocntinh, RISCV_IOMMU_REG_IOCOUNTINH); +ATTR_RW_REG64(iohpmcycles, RISCV_IOMMU_REG_IOHPMCYCLES); +ATTR_RW_REG64(iohpmevt_1, RISCV_IOMMU_REG_IOHPMEVT(0)); +ATTR_RW_REG64(iohpmevt_2, RISCV_IOMMU_REG_IOHPMEVT(1)); +ATTR_RW_REG64(iohpmevt_3, RISCV_IOMMU_REG_IOHPMEVT(2)); +ATTR_RW_REG64(iohpmevt_4, RISCV_IOMMU_REG_IOHPMEVT(3)); +ATTR_RW_REG64(iohpmevt_5, RISCV_IOMMU_REG_IOHPMEVT(4)); +ATTR_RW_REG64(iohpmevt_6, RISCV_IOMMU_REG_IOHPMEVT(5)); +ATTR_RW_REG64(iohpmevt_7, RISCV_IOMMU_REG_IOHPMEVT(6)); +ATTR_RW_REG64(iohpmctr_1, RISCV_IOMMU_REG_IOHPMCTR(0)); +ATTR_RW_REG64(iohpmctr_2, RISCV_IOMMU_REG_IOHPMCTR(1)); +ATTR_RW_REG64(iohpmctr_3, RISCV_IOMMU_REG_IOHPMCTR(2)); +ATTR_RW_REG64(iohpmctr_4, RISCV_IOMMU_REG_IOHPMCTR(3)); +ATTR_RW_REG64(iohpmctr_5, RISCV_IOMMU_REG_IOHPMCTR(4)); +ATTR_RW_REG64(iohpmctr_6, RISCV_IOMMU_REG_IOHPMCTR(5)); +ATTR_RW_REG64(iohpmctr_7, RISCV_IOMMU_REG_IOHPMCTR(6)); + +static struct attribute *riscv_iommu_attrs[] = { + &dev_attr_address.attr, + &dev_attr_reg_cap.attr, + &dev_attr_reg_fctl.attr, + &dev_attr_reg_cqh.attr, + &dev_attr_reg_cqt.attr, + &dev_attr_reg_cqcsr.attr, + &dev_attr_reg_fqh.attr, + &dev_attr_reg_fqt.attr, + &dev_attr_reg_fqcsr.attr, + &dev_attr_reg_pqh.attr, + &dev_attr_reg_pqt.attr, + &dev_attr_reg_pqcsr.attr, + &dev_attr_reg_ipsr.attr, + &dev_attr_reg_ivec.attr, + &dev_attr_reg_tr_iova.attr, + &dev_attr_reg_tr_ctrl.attr, + &dev_attr_reg_tr_response.attr, + &dev_attr_reg_iocntovf.attr, + &dev_attr_reg_iocntinh.attr, + &dev_attr_reg_iohpmcycles.attr, + &dev_attr_reg_iohpmctr_1.attr, + &dev_attr_reg_iohpmevt_1.attr, + &dev_attr_reg_iohpmctr_2.attr, + &dev_attr_reg_iohpmevt_2.attr, + &dev_attr_reg_iohpmctr_3.attr, + &dev_attr_reg_iohpmevt_3.attr, + &dev_attr_reg_iohpmctr_4.attr, + &dev_attr_reg_iohpmevt_4.attr, + &dev_attr_reg_iohpmctr_5.attr, + &dev_attr_reg_iohpmevt_5.attr, + &dev_attr_reg_iohpmctr_6.attr, + &dev_attr_reg_iohpmevt_6.attr, + &dev_attr_reg_iohpmctr_7.attr, + &dev_attr_reg_iohpmevt_7.attr, + NULL, +}; + +static struct attribute_group riscv_iommu_group = { + .name = "riscv-iommu", + .attrs = riscv_iommu_attrs, +}; + +const struct attribute_group *riscv_iommu_groups[] = { + &riscv_iommu_group, + NULL, +}; + +int riscv_iommu_sysfs_add(struct riscv_iommu_device *iommu) { + return iommu_device_sysfs_add(&iommu->iommu, NULL, + riscv_iommu_groups, "riscv-iommu@%llx", iommu->reg_phys); +} + diff --git a/drivers/iommu/riscv/iommu.c b/drivers/iommu/riscv/iommu.c index 8c236242e2cc..31dc3c458e13 100644 --- a/drivers/iommu/riscv/iommu.c +++ b/drivers/iommu/riscv/iommu.c @@ -608,6 +608,7 @@ static const struct iommu_ops riscv_iommu_ops = { void riscv_iommu_remove(struct riscv_iommu_device *iommu) { iommu_device_unregister(&iommu->iommu); + iommu_device_sysfs_remove(&iommu->iommu); riscv_iommu_enable(iommu, RISCV_IOMMU_DDTP_MODE_OFF); } @@ -646,6 +647,12 @@ int riscv_iommu_init(struct riscv_iommu_device *iommu) goto fail; } + ret = riscv_iommu_sysfs_add(iommu); + if (ret) { + dev_err(dev, "cannot register sysfs interface (%d)\n", ret); + goto fail; + } + ret = iommu_device_register(&iommu->iommu, &riscv_iommu_ops, dev); if (ret) { dev_err(dev, "cannot register iommu interface (%d)\n", ret); diff --git a/drivers/iommu/riscv/iommu.h b/drivers/iommu/riscv/iommu.h index 7baefd3630b3..7dc9baa59a50 100644 --- a/drivers/iommu/riscv/iommu.h +++ b/drivers/iommu/riscv/iommu.h @@ -112,4 +112,6 @@ static inline void riscv_iommu_writeq(struct riscv_iommu_device *iommu, int riscv_iommu_init(struct riscv_iommu_device *iommu); void riscv_iommu_remove(struct riscv_iommu_device *iommu); +int riscv_iommu_sysfs_add(struct riscv_iommu_device *iommu); + #endif
Enable sysfs debug / visibility interface providing restricted access to hardware registers. Signed-off-by: Tomasz Jeznach <tjeznach@rivosinc.com> --- drivers/iommu/riscv/Makefile | 2 +- drivers/iommu/riscv/iommu-sysfs.c | 183 ++++++++++++++++++++++++++++++ drivers/iommu/riscv/iommu.c | 7 ++ drivers/iommu/riscv/iommu.h | 2 + 4 files changed, 193 insertions(+), 1 deletion(-) create mode 100644 drivers/iommu/riscv/iommu-sysfs.c