161 lines
5.0 KiB
C
161 lines
5.0 KiB
C
// SPDX-License-Identifier: MIT
|
|
/*
|
|
* Copyright © 2025 Intel Corporation
|
|
*/
|
|
|
|
#include <drm/drm_managed.h>
|
|
|
|
#include "regs/xe_gtt_defs.h"
|
|
|
|
#include "xe_assert.h"
|
|
#include "xe_ggtt.h"
|
|
#include "xe_sriov.h"
|
|
#include "xe_sriov_printk.h"
|
|
#include "xe_tile_sriov_vf.h"
|
|
#include "xe_wopcm.h"
|
|
|
|
/**
|
|
* DOC: GGTT nodes shifting during VF post-migration recovery
|
|
*
|
|
* The first fixup applied to the VF KMD structures as part of post-migration
|
|
* recovery is shifting nodes within &xe_ggtt instance. The nodes are moved
|
|
* from range previously assigned to this VF, into newly provisioned area.
|
|
*
|
|
* Below is a GGTT layout of example VF, with a certain address range assigned to
|
|
* said VF, and inaccessible areas above and below:
|
|
*
|
|
* 0 4GiB
|
|
* |<--------------------------- Total GGTT size ----------------------------->|
|
|
* WOPCM GUC_TOP
|
|
* |<-------------- Area mappable by xe_ggtt instance ---------------->|
|
|
*
|
|
* +---+---------------------------------+----------+----------------------+---+
|
|
* |\\\|/////////////////////////////////| VF mem |//////////////////////|\\\|
|
|
* +---+---------------------------------+----------+----------------------+---+
|
|
*
|
|
* Hardware enforced access rules before migration:
|
|
*
|
|
* |<------- inaccessible for VF ------->|<VF owned>|<-- inaccessible for VF ->|
|
|
*
|
|
* After the migration, GGTT area assigned to the VF might have shifted, either
|
|
* to lower or to higher address. But we expect the total size and extra areas to
|
|
* be identical, as migration can only happen between matching platforms.
|
|
* Below is an example of GGTT layout of the VF after migration. Content of the
|
|
* GGTT for VF has been moved to a new area, and we receive its address from GuC:
|
|
*
|
|
* +---+----------------------+----------+---------------------------------+---+
|
|
* |\\\|//////////////////////| VF mem |/////////////////////////////////|\\\|
|
|
* +---+----------------------+----------+---------------------------------+---+
|
|
*
|
|
* Hardware enforced access rules after migration:
|
|
*
|
|
* |<- inaccessible for VF -->|<VF owned>|<------- inaccessible for VF ------->|
|
|
*
|
|
* So the VF has a new slice of GGTT assigned, and during migration process, the
|
|
* memory content was copied to that new area. But the &xe_ggtt nodes are still
|
|
* tracking allocations using the old addresses. The nodes within VF owned area
|
|
* have to be shifted, and the start offset for GGTT adjusted.
|
|
*
|
|
* Due to use of GPU profiles, we do not expect the old and new GGTT areas to
|
|
* overlap; but our node shifting will fix addresses properly regardless.
|
|
*/
|
|
|
|
/**
|
|
* xe_tile_sriov_vf_lmem - VF LMEM configuration.
|
|
* @tile: the &xe_tile
|
|
*
|
|
* This function is for VF use only.
|
|
*
|
|
* Return: size of the LMEM assigned to VF.
|
|
*/
|
|
u64 xe_tile_sriov_vf_lmem(struct xe_tile *tile)
|
|
{
|
|
struct xe_tile_sriov_vf_selfconfig *config = &tile->sriov.vf.self_config;
|
|
|
|
xe_tile_assert(tile, IS_SRIOV_VF(tile_to_xe(tile)));
|
|
|
|
return config->lmem_size;
|
|
}
|
|
|
|
/**
|
|
* xe_tile_sriov_vf_lmem_store - Store VF LMEM configuration
|
|
* @tile: the &xe_tile
|
|
* @lmem_size: VF LMEM size to store
|
|
*
|
|
* This function is for VF use only.
|
|
*/
|
|
void xe_tile_sriov_vf_lmem_store(struct xe_tile *tile, u64 lmem_size)
|
|
{
|
|
struct xe_tile_sriov_vf_selfconfig *config = &tile->sriov.vf.self_config;
|
|
|
|
xe_tile_assert(tile, IS_SRIOV_VF(tile_to_xe(tile)));
|
|
|
|
config->lmem_size = lmem_size;
|
|
}
|
|
|
|
/**
|
|
* xe_tile_sriov_vf_ggtt - VF GGTT configuration.
|
|
* @tile: the &xe_tile
|
|
*
|
|
* This function is for VF use only.
|
|
*
|
|
* Return: size of the GGTT assigned to VF.
|
|
*/
|
|
u64 xe_tile_sriov_vf_ggtt(struct xe_tile *tile)
|
|
{
|
|
struct xe_tile_sriov_vf_selfconfig *config = &tile->sriov.vf.self_config;
|
|
|
|
xe_tile_assert(tile, IS_SRIOV_VF(tile_to_xe(tile)));
|
|
|
|
return config->ggtt_size;
|
|
}
|
|
|
|
/**
|
|
* xe_tile_sriov_vf_ggtt_store - Store VF GGTT configuration
|
|
* @tile: the &xe_tile
|
|
* @ggtt_size: VF GGTT size to store
|
|
*
|
|
* This function is for VF use only.
|
|
*/
|
|
void xe_tile_sriov_vf_ggtt_store(struct xe_tile *tile, u64 ggtt_size)
|
|
{
|
|
struct xe_tile_sriov_vf_selfconfig *config = &tile->sriov.vf.self_config;
|
|
|
|
xe_tile_assert(tile, IS_SRIOV_VF(tile_to_xe(tile)));
|
|
|
|
config->ggtt_size = ggtt_size;
|
|
}
|
|
|
|
/**
|
|
* xe_tile_sriov_vf_ggtt_base - VF GGTT base configuration.
|
|
* @tile: the &xe_tile
|
|
*
|
|
* This function is for VF use only.
|
|
*
|
|
* Return: base of the GGTT assigned to VF.
|
|
*/
|
|
u64 xe_tile_sriov_vf_ggtt_base(struct xe_tile *tile)
|
|
{
|
|
struct xe_tile_sriov_vf_selfconfig *config = &tile->sriov.vf.self_config;
|
|
|
|
xe_tile_assert(tile, IS_SRIOV_VF(tile_to_xe(tile)));
|
|
|
|
return READ_ONCE(config->ggtt_base);
|
|
}
|
|
|
|
/**
|
|
* xe_tile_sriov_vf_ggtt_base_store - Store VF GGTT base configuration
|
|
* @tile: the &xe_tile
|
|
* @ggtt_base: VF GGTT base to store
|
|
*
|
|
* This function is for VF use only.
|
|
*/
|
|
void xe_tile_sriov_vf_ggtt_base_store(struct xe_tile *tile, u64 ggtt_base)
|
|
{
|
|
struct xe_tile_sriov_vf_selfconfig *config = &tile->sriov.vf.self_config;
|
|
|
|
xe_tile_assert(tile, IS_SRIOV_VF(tile_to_xe(tile)));
|
|
|
|
WRITE_ONCE(config->ggtt_base, ggtt_base);
|
|
}
|