diff --git a/drivers/gpu/drm/xe/xe_guc_fwif.h b/drivers/gpu/drm/xe/xe_guc_fwif.h index a33ea288b907..bb8f71d38611 100644 --- a/drivers/gpu/drm/xe/xe_guc_fwif.h +++ b/drivers/gpu/drm/xe/xe_guc_fwif.h @@ -261,7 +261,8 @@ struct xe_guc_pagefault_desc { #define PFD_ACCESS_TYPE GENMASK(1, 0) #define PFD_FAULT_TYPE GENMASK(3, 2) #define PFD_VFID GENMASK(9, 4) -#define PFD_RSVD_1 GENMASK(11, 10) +#define PFD_RSVD_1 BIT(10) +#define PFD_PREFETCH BIT(11) /* Only valid on Xe3+, reserved on prior platforms */ #define PFD_VIRTUAL_ADDR_LO GENMASK(31, 12) #define PFD_VIRTUAL_ADDR_LO_SHIFT 12 @@ -281,7 +282,7 @@ struct xe_guc_pagefault_reply { u32 dw1; #define PFR_VFID GENMASK(5, 0) -#define PFR_RSVD_1 BIT(6) +#define PFR_PREFETCH BIT(6) /* Only valid on Xe3+, reserved on prior platforms */ #define PFR_ENG_INSTANCE GENMASK(12, 7) #define PFR_ENG_CLASS GENMASK(15, 13) #define PFR_PDATA GENMASK(31, 16) diff --git a/drivers/gpu/drm/xe/xe_guc_pagefault.c b/drivers/gpu/drm/xe/xe_guc_pagefault.c index d48f6ed103bb..607e32392f46 100644 --- a/drivers/gpu/drm/xe/xe_guc_pagefault.c +++ b/drivers/gpu/drm/xe/xe_guc_pagefault.c @@ -8,10 +8,12 @@ #include "xe_guc_ct.h" #include "xe_guc_pagefault.h" #include "xe_pagefault.h" +#include "xe_pagefault_types.h" static void guc_ack_fault(struct xe_pagefault *pf, int err) { u32 vfid = FIELD_GET(PFD_VFID, pf->producer.msg[2]); + u32 prefetch = FIELD_GET(PFD_PREFETCH, pf->producer.msg[2]); u32 engine_instance = FIELD_GET(PFD_ENG_INSTANCE, pf->producer.msg[0]); u32 engine_class = FIELD_GET(PFD_ENG_CLASS, pf->producer.msg[0]); u32 pdata = FIELD_GET(PFD_PDATA_LO, pf->producer.msg[0]) | @@ -28,6 +30,7 @@ static void guc_ack_fault(struct xe_pagefault *pf, int err) FIELD_PREP(PFR_ASID, asid), FIELD_PREP(PFR_VFID, vfid) | + FIELD_PREP(PFR_PREFETCH, err ? prefetch : 0) | FIELD_PREP(PFR_ENG_INSTANCE, engine_instance) | FIELD_PREP(PFR_ENG_CLASS, engine_class) | FIELD_PREP(PFR_PDATA, pdata), @@ -76,7 +79,8 @@ int xe_guc_pagefault_handler(struct xe_guc *guc, u32 *msg, u32 len) (FIELD_GET(PFD_VIRTUAL_ADDR_LO, msg[2]) << PFD_VIRTUAL_ADDR_LO_SHIFT); pf.consumer.asid = FIELD_GET(PFD_ASID, msg[1]); - pf.consumer.access_type = FIELD_GET(PFD_ACCESS_TYPE, msg[2]); + pf.consumer.access_type = FIELD_GET(PFD_ACCESS_TYPE, msg[2]) | + (FIELD_GET(PFD_PREFETCH, msg[2]) ? XE_PAGEFAULT_ACCESS_PREFETCH : 0); if (FIELD_GET(XE2_PFD_TRVA_FAULT, msg[0])) pf.consumer.fault_type_level = XE_PAGEFAULT_TYPE_LEVEL_NACK; else diff --git a/drivers/gpu/drm/xe/xe_pagefault.c b/drivers/gpu/drm/xe/xe_pagefault.c index 72f589fd2b64..ea4857acf28d 100644 --- a/drivers/gpu/drm/xe/xe_pagefault.c +++ b/drivers/gpu/drm/xe/xe_pagefault.c @@ -136,7 +136,7 @@ unlock_dma_resv: static bool xe_pagefault_access_is_atomic(enum xe_pagefault_access_type access_type) { - return access_type == XE_PAGEFAULT_ACCESS_TYPE_ATOMIC; + return (access_type & XE_PAGEFAULT_ACCESS_TYPE_MASK) == XE_PAGEFAULT_ACCESS_TYPE_ATOMIC; } static struct xe_vm *xe_pagefault_asid_to_vm(struct xe_device *xe, u32 asid) @@ -226,7 +226,7 @@ static void xe_pagefault_print(struct xe_pagefault *pf) xe_gt_info(pf->gt, "\n\tASID: %d\n" "\tFaulted Address: 0x%08x%08x\n" "\tFaultType: %lu\n" - "\tAccessType: %d\n" + "\tAccessType: %lu\n" "\tFaultLevel: %lu\n" "\tEngineClass: %d %s\n" "\tEngineInstance: %d\n", @@ -235,7 +235,8 @@ static void xe_pagefault_print(struct xe_pagefault *pf) lower_32_bits(pf->consumer.page_addr), FIELD_GET(XE_PAGEFAULT_TYPE_MASK, pf->consumer.fault_type_level), - pf->consumer.access_type, + FIELD_GET(XE_PAGEFAULT_ACCESS_TYPE_MASK, + pf->consumer.access_type), FIELD_GET(XE_PAGEFAULT_LEVEL_MASK, pf->consumer.fault_type_level), pf->consumer.engine_class, @@ -261,9 +262,15 @@ static void xe_pagefault_queue_work(struct work_struct *w) err = xe_pagefault_service(&pf); if (err) { - xe_pagefault_print(&pf); - xe_gt_info(pf.gt, "Fault response: Unsuccessful %pe\n", - ERR_PTR(err)); + if (!(pf.consumer.access_type & XE_PAGEFAULT_ACCESS_PREFETCH)) { + xe_pagefault_print(&pf); + xe_gt_info(pf.gt, "Fault response: Unsuccessful %pe\n", + ERR_PTR(err)); + } else { + xe_gt_stats_incr(pf.gt, XE_GT_STATS_ID_INVALID_PREFETCH_PAGEFAULT_COUNT, 1); + xe_gt_dbg(pf.gt, "Prefetch Fault response: Unsuccessful %pe\n", + ERR_PTR(err)); + } } pf.producer.ops->ack_fault(&pf, err); diff --git a/drivers/gpu/drm/xe/xe_pagefault_types.h b/drivers/gpu/drm/xe/xe_pagefault_types.h index 0e378f41ede6..b3289219b1be 100644 --- a/drivers/gpu/drm/xe/xe_pagefault_types.h +++ b/drivers/gpu/drm/xe/xe_pagefault_types.h @@ -68,10 +68,12 @@ struct xe_pagefault { /** @consumer.asid: address space ID */ u32 asid; /** - * @consumer.access_type: access type, u8 rather than enum to - * keep size compact + * @consumer.access_type: access type and prefetch flag packed + * into a u8. */ u8 access_type; +#define XE_PAGEFAULT_ACCESS_TYPE_MASK GENMASK(1, 0) +#define XE_PAGEFAULT_ACCESS_PREFETCH BIT(7) /** * @consumer.fault_type_level: fault type and level, u8 rather * than enum to keep size compact