[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-arm] [PATCH v11 08/17] hw/arm/smmuv3: Event queue recording he
From: |
Auger Eric |
Subject: |
Re: [Qemu-arm] [PATCH v11 08/17] hw/arm/smmuv3: Event queue recording helper |
Date: |
Mon, 23 Apr 2018 22:17:48 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.4.0 |
Hi Peter,
On 04/16/2018 06:51 PM, Peter Maydell wrote:
> On 12 April 2018 at 08:37, Eric Auger <address@hidden> wrote:
>> Let's introduce a helper function aiming at recording an
>> event in the event queue.
>>
>> Signed-off-by: Eric Auger <address@hidden>
>>
>> ---
>> v9 -> v10:
>> - rework SMMU_EVENT_STRING
>> - trigger a GERROR EVENTQ_ABT_ERR in case of eventq write failure
>>
>> v8 -> v9:
>> - add SMMU_EVENT_STRING
>>
>> v7 -> v8:
>> - use dma_addr_t instead of hwaddr in smmuv3_record_event()
>> - introduce struct SMMUEventInfo
>> - add event_stringify + helpers for all fields
>> ---
>> hw/arm/smmuv3-internal.h | 142
>> ++++++++++++++++++++++++++++++++++++++++++++++-
>> hw/arm/smmuv3.c | 108 +++++++++++++++++++++++++++++++++--
>> hw/arm/trace-events | 1 +
>> 3 files changed, 243 insertions(+), 8 deletions(-)
>>
>> diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
>> index 8550be0..8e546bf 100644
>> --- a/hw/arm/smmuv3-internal.h
>> +++ b/hw/arm/smmuv3-internal.h
>> @@ -205,8 +205,6 @@ static inline void smmu_write_cmdq_err(SMMUv3State *s,
>> uint32_t err_type)
>> s->cmdq.cons = FIELD_DP32(s->cmdq.cons, CMDQ_CONS, ERR, err_type);
>> }
>>
>> -void smmuv3_write_eventq(SMMUv3State *s, Evt *evt);
>> -
>> /* Commands */
>>
>> typedef enum SMMUCommandType {
>> @@ -308,4 +306,144 @@ enum { /* Command completion notification */
>>
>> #define SMMU_FEATURE_2LVL_STE (1 << 0)
>>
>> +/* Events */
>> +
>> +typedef enum SMMUEventType {
>> + SMMU_EVT_OK = 0x00,
>> + SMMU_EVT_F_UUT = 0x01,
>> + SMMU_EVT_C_BAD_STREAMID = 0x02,
>> + SMMU_EVT_F_STE_FETCH = 0x03,
>> + SMMU_EVT_C_BAD_STE = 0x04,
>> + SMMU_EVT_F_BAD_ATS_TREQ = 0x05,
>> + SMMU_EVT_F_STREAM_DISABLED = 0x06,
>> + SMMU_EVT_F_TRANS_FORBIDDEN = 0x07,
>> + SMMU_EVT_C_BAD_SUBSTREAMID = 0x08,
>> + SMMU_EVT_F_CD_FETCH = 0x09,
>> + SMMU_EVT_C_BAD_CD = 0x0a,
>> + SMMU_EVT_F_WALK_EABT = 0x0b,
>
> Most of the other enums you let the auto-increment deal
> with long runs of consecutive integers like this. I don't
> much care which but being consistent is generally nicer.
>
>> + SMMU_EVT_F_TRANSLATION = 0x10,
>> + SMMU_EVT_F_ADDR_SIZE = 0x11,
>> + SMMU_EVT_F_ACCESS = 0x12,
>> + SMMU_EVT_F_PERMISSION = 0x13,
>> + SMMU_EVT_F_TLB_CONFLICT = 0x20,
>> + SMMU_EVT_F_CFG_CONFLICT = 0x21,
>> + SMMU_EVT_E_PAGE_REQ = 0x24,
>> +} SMMUEventType;
>> +
>> +static const char *event_stringify[] = {
>> + [SMMU_EVT_OK] = "SMMU_EVT_OK",
>> + [SMMU_EVT_F_UUT] = "SMMU_EVT_F_UUT",
>> + [SMMU_EVT_C_BAD_STREAMID] = "SMMU_EVT_C_BAD_STREAMID",
>> + [SMMU_EVT_F_STE_FETCH] = "SMMU_EVT_F_STE_FETCH",
>> + [SMMU_EVT_C_BAD_STE] = "SMMU_EVT_C_BAD_STE",
>> + [SMMU_EVT_F_BAD_ATS_TREQ] = "SMMU_EVT_F_BAD_ATS_TREQ",
>> + [SMMU_EVT_F_STREAM_DISABLED] = "SMMU_EVT_F_STREAM_DISABLED",
>> + [SMMU_EVT_F_TRANS_FORBIDDEN] = "SMMU_EVT_F_TRANS_FORBIDDEN",
>> + [SMMU_EVT_C_BAD_SUBSTREAMID] = "SMMU_EVT_C_BAD_SUBSTREAMID",
>> + [SMMU_EVT_F_CD_FETCH] = "SMMU_EVT_F_CD_FETCH",
>> + [SMMU_EVT_C_BAD_CD] = "SMMU_EVT_C_BAD_CD",
>> + [SMMU_EVT_F_WALK_EABT] = "SMMU_EVT_F_WALK_EABT",
>> + [SMMU_EVT_F_TRANSLATION] = "SMMU_EVT_F_TRANSLATION",
>> + [SMMU_EVT_F_ADDR_SIZE] = "SMMU_EVT_F_ADDR_SIZE",
>> + [SMMU_EVT_F_ACCESS] = "SMMU_EVT_F_ACCESS",
>> + [SMMU_EVT_F_PERMISSION] = "SMMU_EVT_F_PERMISSION",
>> + [SMMU_EVT_F_TLB_CONFLICT] = "SMMU_EVT_F_TLB_CONFLICT",
>> + [SMMU_EVT_F_CFG_CONFLICT] = "SMMU_EVT_F_CFG_CONFLICT",
>> + [SMMU_EVT_E_PAGE_REQ] = "SMMU_EVT_E_PAGE_REQ",
>> +};
>> +
>> +static inline const char *smmu_event_string(SMMUEventType type)
>> +{
>> + return event_stringify[type] ? event_stringify[type] : "UNKNOWN";
>
> Same remarks about being defensive about out of range values
> apply here, I expect.
I think this one is safe as called from smmuv3_record_event(). Type is
is sanitized in that case. Adding the check against ARRAY_SIZE though.
Thanks
Eric
>
>> +}
>> +
>> +/* Encode an event record */
>> +typedef struct SMMUEventInfo {
>> + SMMUEventType type;
>> + uint32_t sid;
>> + bool recorded;
>> + bool record_trans_faults;
>> + union {
>> + struct {
>> + uint32_t ssid;
>> + bool ssv;
>> + dma_addr_t addr;
>> + bool rnw;
>> + bool pnu;
>> + bool ind;
>> + } f_uut;
>> + struct ssid_info {
>> + uint32_t ssid;
>> + bool ssv;
>> + } c_bad_streamid;
>
> If we were being really picky about coding style these
> embedded struct names like ssid_info ought to be camelcase.
>
>> + struct ssid_addr_info {
>> + uint32_t ssid;
>> + bool ssv;
>> + dma_addr_t addr;
>> + } f_ste_fetch;
>> + struct ssid_info c_bad_ste;
>> + struct {
>> + dma_addr_t addr;
>> + bool rnw;
>> + } f_transl_forbidden;
>> + struct {
>> + uint32_t ssid;
>> + } c_bad_substream;
>> + struct ssid_addr_info f_cd_fetch;
>> + struct ssid_info c_bad_cd;
>> + struct full_info {
>> + bool stall;
>> + uint16_t stag;
>> + uint32_t ssid;
>> + bool ssv;
>> + bool s2;
>> + dma_addr_t addr;
>> + bool rnw;
>> + bool pnu;
>> + bool ind;
>> + uint8_t class;
>> + dma_addr_t addr2;
>> + } f_walk_eabt;
>> + struct full_info f_translation;
>> + struct full_info f_addr_size;
>> + struct full_info f_access;
>> + struct full_info f_permission;
>> + struct ssid_info f_cfg_conflict;
>> + /**
>> + * not supported yet:
>> + * F_BAD_ATS_TREQ
>> + * F_BAD_ATS_TREQ
>> + * F_TLB_CONFLICT
>> + * E_PAGE_REQUEST
>> + * IMPDEF_EVENTn
>> + */
>> + } u;
>> +} SMMUEventInfo;
>> +
>> +/* EVTQ fields */
>> +
>> +#define EVT_Q_OVERFLOW (1 << 31)
>> +
>> +#define EVT_SET_TYPE(x, v) deposit32((x)->word[0], 0 , 8 , v)
>> +#define EVT_SET_SSV(x, v) deposit32((x)->word[0], 11, 1 , v)
>> +#define EVT_SET_SSID(x, v) deposit32((x)->word[0], 12, 20, v)
>> +#define EVT_SET_SID(x, v) ((x)->word[1] = v)
>> +#define EVT_SET_STAG(x, v) deposit32((x)->word[2], 0 , 16, v)
>> +#define EVT_SET_STALL(x, v) deposit32((x)->word[2], 31, 1 , v)
>> +#define EVT_SET_PNU(x, v) deposit32((x)->word[3], 1 , 1 , v)
>> +#define EVT_SET_IND(x, v) deposit32((x)->word[3], 2 , 1 , v)
>> +#define EVT_SET_RNW(x, v) deposit32((x)->word[3], 3 , 1 , v)
>> +#define EVT_SET_S2(x, v) deposit32((x)->word[3], 7 , 1 , v)
>> +#define EVT_SET_CLASS(x, v) deposit32((x)->word[3], 8 , 2 , v)
>
> There's some weird extra spaces in these macros.
>
>> +#define EVT_SET_ADDR(x, addr) ({ \
>> + (x)->word[5] = (uint32_t)(addr >> 32); \
>> + (x)->word[4] = (uint32_t)(addr & 0xffffffff); \
>> + })
>> +#define EVT_SET_ADDR2(x, addr) ({ \
>> + deposit32((x)->word[7], 3, 29, addr >> 16); \
>> + deposit32((x)->word[7], 0, 16, addr & 0xffff); \
>> + })
>
> These don't need the GCC ({ }) extension -- you can just do them
> as normal do { ... } while (0) macros.
>
> Otherwise
> Reviewed-by: Peter Maydell <address@hidden>
>
> thanks
> -- PMM
>
- Re: [Qemu-arm] [PATCH v11 04/17] hw/arm/smmuv3: Skeleton, (continued)
- [Qemu-arm] [PATCH v11 05/17] hw/arm/smmuv3: Wired IRQ and GERROR helpers, Eric Auger, 2018/04/12
- [Qemu-arm] [PATCH v11 07/17] hw/arm/smmuv3: Implement MMIO write operations, Eric Auger, 2018/04/12
- [Qemu-arm] [PATCH v11 06/17] hw/arm/smmuv3: Queue helpers, Eric Auger, 2018/04/12
- [Qemu-arm] [PATCH v11 08/17] hw/arm/smmuv3: Event queue recording helper, Eric Auger, 2018/04/12
- [Qemu-arm] [PATCH v11 09/17] hw/arm/smmuv3: Implement translate callback, Eric Auger, 2018/04/12
- [Qemu-arm] [PATCH v11 10/17] hw/arm/smmuv3: Abort on vfio or vhost case, Eric Auger, 2018/04/12
- [Qemu-arm] [PATCH v11 11/17] target/arm/kvm: Translate the MSI doorbell in kvm_arch_fixup_msi_route, Eric Auger, 2018/04/12
- [Qemu-arm] [PATCH v11 12/17] hw/arm/virt: Add SMMUv3 to the virt board, Eric Auger, 2018/04/12
- [Qemu-arm] [PATCH v11 13/17] hw/arm/virt-acpi-build: Add smmuv3 node in IORT table, Eric Auger, 2018/04/12
- [Qemu-arm] [PATCH v11 14/17] hw/arm/virt: Introduce the iommu option, Eric Auger, 2018/04/12