[PATCH v4 4/6] drm/xe/pf: Force GuC virtualization mode

Piotr Piórkowski piotr.piorkowski at intel.com
Tue Jul 15 07:13:45 UTC 2025


Michal Wajdeczko <michal.wajdeczko at intel.com> wrote on pią [2025-lip-11 21:33:14 +0200]:
> By default the GuC starts in the 'native' mode and enables the VGT
> mode (aka 'virtualization' mode) only after it receives at least one
> set of VF configuration data. While this happens naturally while PF
> begins VFs provisioning, we might need this sooner as some actions,
> like TLB_INVALIDATION_ALL(0x7002), is supported by the GuC only in
> the VGT mode.
> 
> And this becomes a real problem if we would want to use above action
> to invalidate the LMTT early during VFs auto-provisioning, before VFs
> are enabled, as such H2G would be rejected:
> 
>  [ ] xe 0000:4d:00.0: [drm] *ERROR* GT0: FAST_REQ H2G fence 0x804e failed! e=0x30, h=0
>  [ ] xe 0000:4d:00.0: [drm] *ERROR* GT0: Fence 0x804e was used by action 0x7002 sent at:
>       h2g_write+0x33e/0x870 [xe]
>       __guc_ct_send_locked+0x1e1/0x1110 [xe]
>       guc_ct_send_locked+0x9f/0x740 [xe]
>       xe_guc_ct_send_locked+0x19/0x60 [xe]
>       send_tlb_invalidation+0xc2/0x470 [xe]
>       xe_gt_tlb_invalidation_all_async+0x45/0xa0 [xe]
>       xe_gt_tlb_invalidation_all+0x4b/0xa0 [xe]
>       lmtt_invalidate_hw+0x64/0x1a0 [xe]
>       xe_lmtt_invalidate_hw+0x5c/0x340 [xe]
>       pf_update_vf_lmtt+0x398/0xae0 [xe]
>       pf_provision_vf_lmem+0x350/0xa60 [xe]
>       xe_gt_sriov_pf_config_bulk_set_lmem+0xe2/0x410 [xe]
>       xe_gt_sriov_pf_config_set_fair_lmem+0x1c6/0x620 [xe]
>       xe_gt_sriov_pf_config_set_fair+0xd5/0x3f0 [xe]
>       xe_pci_sriov_configure+0x360/0x1200 [xe]
>       sriov_numvfs_store+0xbc/0x1d0
>       dev_attr_store+0x17/0x40
>       sysfs_kf_write+0x4a/0x80
>       kernfs_fop_write_iter+0x166/0x220
>       vfs_write+0x2ba/0x580
>       ksys_write+0x77/0x100
>       __x64_sys_write+0x19/0x30
>       x64_sys_call+0x2bf/0x2660
>       do_syscall_64+0x93/0x7a0
>       entry_SYSCALL_64_after_hwframe+0x76/0x7e
>  [ ] xe 0000:4d:00.0: [drm] *ERROR* GT0: CT dequeue failed: -71
>  [ ] xe 0000:4d:00.0: [drm] GT0: trying reset from receive_g2h [xe]
> 
> This could be mitigated by pushing earlier a PF self-configuration
> with some hard-coded values that cover unlimited access to the GGTT,
> use of all GuC contexts and doorbells.  This step is sufficient for
> the GuC to switch into the VGT mode.
> 
> Signed-off-by: Michal Wajdeczko <michal.wajdeczko at intel.com>
> ---
> v2: rebase and push min config as part of the full PF config
> ---
>  drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c | 26 ++++++++++++++++++++++
>  1 file changed, 26 insertions(+)
> 
> diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c b/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c
> index 55afc5b06371..86dade6f1083 100644
> --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c
> +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c
> @@ -341,6 +341,17 @@ static int pf_push_full_vf_config(struct xe_gt *gt, unsigned int vfid)
>  	}
>  	xe_gt_assert(gt, num_dwords <= max_cfg_dwords);
>  
> +	if (vfid == PFID) {
> +		u64 ggtt_start = xe_wopcm_size(gt_to_xe(gt));
> +		u64 ggtt_size = gt_to_tile(gt)->mem.ggtt->size - ggtt_start;
> +
> +		/* plain PF config data will never include a real GGTT region */
> +		xe_gt_assert(gt, !encode_config_ggtt(cfg + num_dwords, config, true));
> +
> +		/* fake PF GGTT config covers full GGTT range except reserved WOPCM */
> +		num_dwords += encode_ggtt(cfg + num_dwords, ggtt_start, ggtt_size, true);
> +	}
> +
>  	num_klvs = xe_guc_klv_count(cfg, num_dwords);
>  	err = pf_push_vf_buf_klvs(gt, vfid, num_klvs, buf, num_dwords);
>  
> @@ -2375,6 +2386,20 @@ int xe_gt_sriov_pf_config_restore(struct xe_gt *gt, unsigned int vfid,
>  	return err;
>  }
>  
> +static void pf_prepare_self_config(struct xe_gt *gt)
> +{
> +	struct xe_gt_sriov_config *config = pf_pick_vf_config(gt, PFID);
> +
> +	/*
> +	 * We want PF to be allowed to use all of context ID, doorbells IDs
> +	 * and whole usable GGTT area. While we can store ctxs/dbs numbers
> +	 * directly in the config structure, can't do the same with the GGTT
> +	 * configuration, so let it be prepared on demand while pushing KLVs.
> +	 */
> +	config->num_ctxs = GUC_ID_MAX;
> +	config->num_dbs = GUC_NUM_DOORBELLS;
> +}
> +
>  static int pf_push_self_config(struct xe_gt *gt)
>  {
>  	int err;
> @@ -2418,6 +2443,7 @@ int xe_gt_sriov_pf_config_init(struct xe_gt *gt)
>  	xe_gt_assert(gt, IS_SRIOV_PF(xe));
>  
>  	mutex_lock(xe_gt_sriov_pf_master_mutex(gt));
> +	pf_prepare_self_config(gt);
>  	err = pf_push_self_config(gt);
>  	mutex_unlock(xe_gt_sriov_pf_master_mutex(gt));

LGTM:
Reviewed-by: Piotr Piórkowski <piotr.piorkowski at intel.com>
>  
> -- 
> 2.47.1
> 

-- 


More information about the Intel-xe mailing list