Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions drivers/iommu/riscv/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ config RISCV_IOMMU
select GENERIC_PT
select IOMMU_PT
select IOMMU_PT_RISCV64
select AUXILIARY_BUS
help
Support for implementations of the RISC-V IOMMU architecture that
complements the RISC-V MMU capabilities, providing similar address
Expand Down
61 changes: 0 additions & 61 deletions drivers/iommu/riscv/iommu-bits.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,67 +192,6 @@ enum riscv_iommu_ddtp_modes {
#define RISCV_IOMMU_IPSR_PMIP BIT(RISCV_IOMMU_INTR_PM)
#define RISCV_IOMMU_IPSR_PIP BIT(RISCV_IOMMU_INTR_PQ)

/* 5.19 Performance monitoring counter overflow status (32bits) */
#define RISCV_IOMMU_REG_IOCOUNTOVF 0x0058
#define RISCV_IOMMU_IOCOUNTOVF_CY BIT(0)
#define RISCV_IOMMU_IOCOUNTOVF_HPM GENMASK_ULL(31, 1)

/* 5.20 Performance monitoring counter inhibits (32bits) */
#define RISCV_IOMMU_REG_IOCOUNTINH 0x005C
#define RISCV_IOMMU_IOCOUNTINH_CY BIT(0)
#define RISCV_IOMMU_IOCOUNTINH_HPM GENMASK(31, 1)

/* 5.21 Performance monitoring cycles counter (64bits) */
#define RISCV_IOMMU_REG_IOHPMCYCLES 0x0060
#define RISCV_IOMMU_IOHPMCYCLES_COUNTER GENMASK_ULL(62, 0)
#define RISCV_IOMMU_IOHPMCYCLES_OF BIT_ULL(63)

/* 5.22 Performance monitoring event counters (31 * 64bits) */
#define RISCV_IOMMU_REG_IOHPMCTR_BASE 0x0068
#define RISCV_IOMMU_REG_IOHPMCTR(_n) (RISCV_IOMMU_REG_IOHPMCTR_BASE + ((_n) * 0x8))

/* 5.23 Performance monitoring event selectors (31 * 64bits) */
#define RISCV_IOMMU_REG_IOHPMEVT_BASE 0x0160
#define RISCV_IOMMU_REG_IOHPMEVT(_n) (RISCV_IOMMU_REG_IOHPMEVT_BASE + ((_n) * 0x8))
#define RISCV_IOMMU_IOHPMEVT_EVENTID GENMASK_ULL(14, 0)
#define RISCV_IOMMU_IOHPMEVT_DMASK BIT_ULL(15)
#define RISCV_IOMMU_IOHPMEVT_PID_PSCID GENMASK_ULL(35, 16)
#define RISCV_IOMMU_IOHPMEVT_DID_GSCID GENMASK_ULL(59, 36)
#define RISCV_IOMMU_IOHPMEVT_PV_PSCV BIT_ULL(60)
#define RISCV_IOMMU_IOHPMEVT_DV_GSCV BIT_ULL(61)
#define RISCV_IOMMU_IOHPMEVT_IDT BIT_ULL(62)
#define RISCV_IOMMU_IOHPMEVT_OF BIT_ULL(63)

/* Number of defined performance-monitoring event selectors */
#define RISCV_IOMMU_IOHPMEVT_CNT 31

/**
* enum riscv_iommu_hpmevent_id - Performance-monitoring event identifier
*
* @RISCV_IOMMU_HPMEVENT_INVALID: Invalid event, do not count
* @RISCV_IOMMU_HPMEVENT_URQ: Untranslated requests
* @RISCV_IOMMU_HPMEVENT_TRQ: Translated requests
* @RISCV_IOMMU_HPMEVENT_ATS_RQ: ATS translation requests
* @RISCV_IOMMU_HPMEVENT_TLB_MISS: TLB misses
* @RISCV_IOMMU_HPMEVENT_DD_WALK: Device directory walks
* @RISCV_IOMMU_HPMEVENT_PD_WALK: Process directory walks
* @RISCV_IOMMU_HPMEVENT_S_VS_WALKS: First-stage page table walks
* @RISCV_IOMMU_HPMEVENT_G_WALKS: Second-stage page table walks
* @RISCV_IOMMU_HPMEVENT_MAX: Value to denote maximum Event IDs
*/
enum riscv_iommu_hpmevent_id {
RISCV_IOMMU_HPMEVENT_INVALID = 0,
RISCV_IOMMU_HPMEVENT_URQ = 1,
RISCV_IOMMU_HPMEVENT_TRQ = 2,
RISCV_IOMMU_HPMEVENT_ATS_RQ = 3,
RISCV_IOMMU_HPMEVENT_TLB_MISS = 4,
RISCV_IOMMU_HPMEVENT_DD_WALK = 5,
RISCV_IOMMU_HPMEVENT_PD_WALK = 6,
RISCV_IOMMU_HPMEVENT_S_VS_WALKS = 7,
RISCV_IOMMU_HPMEVENT_G_WALKS = 8,
RISCV_IOMMU_HPMEVENT_MAX = 9
};

/* 5.24 Translation request IOVA (64bits) */
#define RISCV_IOMMU_REG_TR_REQ_IOVA 0x0258
#define RISCV_IOMMU_TR_REQ_IOVA_VPN GENMASK_ULL(63, 12)
Expand Down
37 changes: 37 additions & 0 deletions drivers/iommu/riscv/iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include <linux/acpi.h>
#include <linux/acpi_rimt.h>
#include <linux/auxiliary_bus.h>
#include <linux/compiler.h>
#include <linux/crash_dump.h>
#include <linux/init.h>
Expand Down Expand Up @@ -48,6 +49,9 @@
static DEFINE_IDA(riscv_iommu_pscids);
#define RISCV_IOMMU_MAX_PSCID (BIT(20) - 1)

/* IOMMU PMU auxiliary device id allocation namespace. */
static DEFINE_IDA(riscv_iommu_pmu_ida);

/* Device resource-managed allocations */
struct riscv_iommu_devres {
void *addr;
Expand Down Expand Up @@ -565,6 +569,36 @@ static irqreturn_t riscv_iommu_fltq_process(int irq, void *data)
return IRQ_HANDLED;
}

/*
* IOMMU Hardware performance monitor
*/
static void riscv_iommu_pmu_id_free(void *data)
{
ida_free(&riscv_iommu_pmu_ida, (unsigned long)data);
}

static int riscv_iommu_hpm_enable(struct riscv_iommu_device *iommu)
{
struct auxiliary_device *auxdev;
int id, ret;

id = ida_alloc(&riscv_iommu_pmu_ida, GFP_KERNEL);
if (id < 0)
return id;

ret = devm_add_action_or_reset(iommu->dev, riscv_iommu_pmu_id_free,
(void *)(unsigned long)id);
if (ret)
return ret;

auxdev = __devm_auxiliary_device_create(iommu->dev, "riscv-iommu",
"pmu", iommu, id);
if (!auxdev)
return -ENODEV;

return 0;
}

/* Lookup and initialize device context info structure. */
static struct riscv_iommu_dc *riscv_iommu_get_dc(struct riscv_iommu_device *iommu,
unsigned int devid)
Expand Down Expand Up @@ -1613,6 +1647,9 @@ int riscv_iommu_init(struct riscv_iommu_device *iommu)
goto err_remove_sysfs;
}

if (iommu->caps & RISCV_IOMMU_CAPABILITIES_HPM)
riscv_iommu_hpm_enable(iommu);

return 0;

err_remove_sysfs:
Expand Down
12 changes: 12 additions & 0 deletions drivers/perf/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,18 @@ config RISCV_PMU_SBI
full perf feature support i.e. counter overflow, privilege mode
filtering, counter configuration.

config RISCV_IOMMU_PMU
depends on RISCV || COMPILE_TEST
depends on RISCV_IOMMU
bool "RISC-V IOMMU Hardware Performance Monitor"
default y
help
Say Y if you want to use the RISC-V IOMMU performance monitor
implementation. The performance monitor is an optional hardware
feature, and whether it is actually enabled depends on IOMMU
hardware support. If the underlying hardware does not implement
the PMU, this option will have no effect.

config STARFIVE_STARLINK_PMU
depends on ARCH_STARFIVE || COMPILE_TEST
depends on 64BIT
Expand Down
1 change: 1 addition & 0 deletions drivers/perf/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ obj-$(CONFIG_QCOM_L3_PMU) += qcom_l3_pmu.o
obj-$(CONFIG_RISCV_PMU) += riscv_pmu.o
obj-$(CONFIG_RISCV_PMU_LEGACY) += riscv_pmu_legacy.o
obj-$(CONFIG_RISCV_PMU_SBI) += riscv_pmu_sbi.o
obj-$(CONFIG_RISCV_IOMMU_PMU) += riscv_iommu_pmu.o
obj-$(CONFIG_STARFIVE_STARLINK_PMU) += starfive_starlink_pmu.o
obj-$(CONFIG_THUNDERX2_PMU) += thunderx2_pmu.o
obj-$(CONFIG_XGENE_PMU) += xgene_pmu.o
Expand Down
Loading
Loading