diff --git a/arch/arm64/include/asm/kvm_s2mpu.h b/arch/arm64/include/asm/kvm_s2mpu.h index d60790029e1f..d8c552da273f 100644 --- a/arch/arm64/include/asm/kvm_s2mpu.h +++ b/arch/arm64/include/asm/kvm_s2mpu.h @@ -28,6 +28,7 @@ #define REG_NS_INTERRUPT_ENABLE_PER_VID_SET 0x20 #define REG_NS_INTERRUPT_CLEAR 0x2c #define REG_NS_VERSION 0x60 +#define REG_NS_INFO 0x64 #define REG_NS_STATUS 0x68 #define REG_NS_NUM_CONTEXT 0x100 #define REG_NS_CONTEXT_CFG_VALID_VID 0x104 @@ -39,6 +40,10 @@ #define REG_NS_FAULT_PA_LOW(vid) (0x2004 + ((vid) * 0x20)) #define REG_NS_FAULT_PA_HIGH(vid) (0x2008 + ((vid) * 0x20)) #define REG_NS_FAULT_INFO(vid) (0x2010 + ((vid) * 0x20)) +#define REG_NS_READ_MPTC 0x3000 +#define REG_NS_READ_MPTC_TAG_PPN 0x3004 +#define REG_NS_READ_MPTC_TAG_OTHERS 0x3008 +#define REG_NS_READ_MPTC_DATA 0x3010 #define REG_NS_L1ENTRY_L2TABLE_ADDR(vid, gb) (0x4000 + ((vid) * 0x200) + ((gb) * 0x8)) #define REG_NS_L1ENTRY_ATTR(vid, gb) (0x4004 + ((vid) * 0x200) + ((gb) * 0x8)) @@ -72,6 +77,8 @@ VERSION_MINOR_ARCH_VER_MASK | \ VERSION_REV_ARCH_VER_MASK) +#define INFO_NUM_SET_MASK GENMASK(15, 0) + #define STATUS_BUSY BIT(0) #define STATUS_ON_INVALIDATING BIT(1) @@ -97,6 +104,20 @@ #define L1ENTRY_L2TABLE_ADDR_SHIFT 4 #define L1ENTRY_L2TABLE_ADDR(pa) ((pa) >> L1ENTRY_L2TABLE_ADDR_SHIFT) +#define READ_MPTC_WAY_MASK GENMASK(18, 16) +#define READ_MPTC_SET_MASK GENMASK(15, 0) +#define READ_MPTC_MASK (READ_MPTC_WAY_MASK | READ_MPTC_SET_MASK) +#define READ_MPTC_WAY(way) FIELD_PREP(READ_MPTC_WAY_MASK, (way)) +#define READ_MPTC_SET(set) FIELD_PREP(READ_MPTC_SET_MASK, (set)) +#define READ_MPTC(set, way) (READ_MPTC_SET(set) | READ_MPTC_WAY(way)) +#define READ_MPTC_TAG_PPN_MASK GENMASK(23, 0) +#define READ_MPTC_TAG_OTHERS_VID_MASK GENMASK(10, 8) +#define READ_MPTC_TAG_OTHERS_GRAN_MASK GENMASK(5, 4) +#define READ_MPTC_TAG_OTHERS_VALID_BIT BIT(0) +#define READ_MPTC_TAG_OTHERS_MASK (READ_MPTC_TAG_OTHERS_VID_MASK | \ + READ_MPTC_TAG_OTHERS_GRAN_MASK | \ + READ_MPTC_TAG_OTHERS_VALID_BIT) + #define L1ENTRY_ATTR_L2TABLE_EN BIT(0) #define L1ENTRY_ATTR_GRAN_4K 0x0 #define L1ENTRY_ATTR_GRAN_64K 0x1 diff --git a/arch/arm64/kvm/hyp/nvhe/iommu/s2mpu.c b/arch/arm64/kvm/hyp/nvhe/iommu/s2mpu.c index 89967f2fefcd..50f842a3b0de 100644 --- a/arch/arm64/kvm/hyp/nvhe/iommu/s2mpu.c +++ b/arch/arm64/kvm/hyp/nvhe/iommu/s2mpu.c @@ -397,9 +397,25 @@ static u32 host_mmio_reg_access_mask(size_t off, bool is_write) /* Allow EL1 IRQ handler to clear interrupts. */ case REG_NS_INTERRUPT_CLEAR: return write_only & ALL_VIDS_BITMAP; + /* Allow reading number of sets used by MPTC. */ + case REG_NS_INFO: + return read_only & INFO_NUM_SET_MASK; /* Allow EL1 IRQ handler to read bitmap of pending interrupts. */ case REG_NS_FAULT_STATUS: return read_only & ALL_VIDS_BITMAP; + /* + * Allow reading MPTC entries for debugging. That involves: + * - writing (set,way) to READ_MPTC + * - reading READ_MPTC_* + */ + case REG_NS_READ_MPTC: + return write_only & READ_MPTC_MASK; + case REG_NS_READ_MPTC_TAG_PPN: + return read_only & READ_MPTC_TAG_PPN_MASK; + case REG_NS_READ_MPTC_TAG_OTHERS: + return read_only & READ_MPTC_TAG_OTHERS_MASK; + case REG_NS_READ_MPTC_DATA: + return read_only; } /* Allow reading L1ENTRY registers for debugging. */