mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-25 05:00:48 -04:00
drm/xe/pf: Restrict device query responses in admin-only PF mode
When a PF is configured in admin-only mode, it is intended for management only and must not expose workload-facing capabilities to userspace. Limit the exposed ioctl set in admin-only PF mode to XE_DEVICE_QUERY and XE_OBSERVATION, and suppress capability-bearing query payloads so that the userspace cannot discover execution-related device details in this mode. Signed-off-by: Satyanarayana K V P <satyanarayana.k.v.p@intel.com> Cc: Michal Wajdeczko <michal.wajdeczko@intel.com> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com> Cc: Piotr Piórkowski <piotr.piorkowski@intel.com> Cc: Matthew Brost <matthew.brost@intel.com> Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com> Cc: Michał Winiarski <michal.winiarski@intel.com> Cc: Dunajski Bartosz <bartosz.dunajski@intel.com> Cc: Ashutosh Dixit <ashutosh.dixit@intel.com> Cc: dri-devel@lists.freedesktop.org Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Acked-by: Ashutosh Dixit <ashutosh.dixit@intel.com> Reviewed-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Link: https://patch.msgid.link/20260409154423.2499340-5-satyanarayana.k.v.p@intel.com
This commit is contained in:
committed by
Michal Wajdeczko
parent
6c84b49301
commit
d88c4bac8c
@@ -25,6 +25,7 @@
|
||||
#include "regs/xe_regs.h"
|
||||
#include "xe_bo.h"
|
||||
#include "xe_bo_evict.h"
|
||||
#include "xe_configfs.h"
|
||||
#include "xe_debugfs.h"
|
||||
#include "xe_defaults.h"
|
||||
#include "xe_devcoredump.h"
|
||||
@@ -390,7 +391,7 @@ bool xe_is_xe_file(const struct file *file)
|
||||
return file->f_op == &xe_driver_fops;
|
||||
}
|
||||
|
||||
static struct drm_driver driver = {
|
||||
static struct drm_driver regular_driver = {
|
||||
.driver_features =
|
||||
DRIVER_GEM |
|
||||
DRIVER_RENDER | DRIVER_SYNCOBJ |
|
||||
@@ -415,6 +416,39 @@ static struct drm_driver driver = {
|
||||
.patchlevel = DRIVER_PATCHLEVEL,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PCI_IOV
|
||||
static const struct drm_ioctl_desc xe_ioctls_admin_only[] = {
|
||||
DRM_IOCTL_DEF_DRV(XE_DEVICE_QUERY, xe_query_ioctl, DRM_RENDER_ALLOW),
|
||||
DRM_IOCTL_DEF_DRV(XE_OBSERVATION, xe_observation_ioctl, DRM_RENDER_ALLOW),
|
||||
};
|
||||
|
||||
static struct drm_driver admin_only_driver = {
|
||||
.driver_features =
|
||||
DRIVER_GEM | DRIVER_RENDER | DRIVER_GEM_GPUVA,
|
||||
.open = xe_file_open,
|
||||
.postclose = xe_file_close,
|
||||
.ioctls = xe_ioctls_admin_only,
|
||||
.num_ioctls = ARRAY_SIZE(xe_ioctls_admin_only),
|
||||
.fops = &xe_driver_fops,
|
||||
.name = DRIVER_NAME,
|
||||
.desc = DRIVER_DESC,
|
||||
.major = DRIVER_MAJOR,
|
||||
.minor = DRIVER_MINOR,
|
||||
.patchlevel = DRIVER_PATCHLEVEL,
|
||||
};
|
||||
|
||||
/**
|
||||
* xe_device_is_admin_only() - Check whether device is admin only or not.
|
||||
* @xe: the &xe_device to check
|
||||
*
|
||||
* Return: true if the device is admin only, false otherwise.
|
||||
*/
|
||||
bool xe_device_is_admin_only(const struct xe_device *xe)
|
||||
{
|
||||
return xe->drm.driver == &admin_only_driver;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void xe_device_destroy(struct drm_device *dev, void *dummy)
|
||||
{
|
||||
struct xe_device *xe = to_xe_device(dev);
|
||||
@@ -439,16 +473,26 @@ static void xe_device_destroy(struct drm_device *dev, void *dummy)
|
||||
struct xe_device *xe_device_create(struct pci_dev *pdev,
|
||||
const struct pci_device_id *ent)
|
||||
{
|
||||
struct drm_driver *driver = ®ular_driver;
|
||||
struct xe_device *xe;
|
||||
int err;
|
||||
|
||||
xe_display_driver_set_hooks(&driver);
|
||||
#ifdef CONFIG_PCI_IOV
|
||||
/*
|
||||
* Since XE device is not initialized yet, read from configfs
|
||||
* directly to decide whether we are in admin-only PF mode or not.
|
||||
*/
|
||||
if (xe_configfs_admin_only_pf(pdev))
|
||||
driver = &admin_only_driver;
|
||||
#endif
|
||||
|
||||
err = aperture_remove_conflicting_pci_devices(pdev, driver.name);
|
||||
xe_display_driver_set_hooks(driver);
|
||||
|
||||
err = aperture_remove_conflicting_pci_devices(pdev, driver->name);
|
||||
if (err)
|
||||
return ERR_PTR(err);
|
||||
|
||||
xe = devm_drm_dev_alloc(&pdev->dev, &driver, struct xe_device, drm);
|
||||
xe = devm_drm_dev_alloc(&pdev->dev, driver, struct xe_device, drm);
|
||||
if (IS_ERR(xe))
|
||||
return xe;
|
||||
|
||||
@@ -708,6 +752,11 @@ int xe_device_probe_early(struct xe_device *xe)
|
||||
|
||||
xe_sriov_probe_early(xe);
|
||||
|
||||
if (xe_device_is_admin_only(xe) && !IS_SRIOV_PF(xe)) {
|
||||
xe_err(xe, "Can't run Admin-only mode without SR-IOV PF mode!\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (IS_SRIOV_VF(xe))
|
||||
vf_update_device_info(xe);
|
||||
|
||||
|
||||
@@ -211,6 +211,15 @@ bool xe_is_xe_file(const struct file *file);
|
||||
|
||||
struct xe_vm *xe_device_asid_to_vm(struct xe_device *xe, u32 asid);
|
||||
|
||||
#ifdef CONFIG_PCI_IOV
|
||||
bool xe_device_is_admin_only(const struct xe_device *xe);
|
||||
#else
|
||||
static inline bool xe_device_is_admin_only(const struct xe_device *xe)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Occasionally it is seen that the G2H worker starts running after a delay of more than
|
||||
* a second even after being queued and activated by the Linux workqueue subsystem. This
|
||||
|
||||
@@ -1026,6 +1026,9 @@ bool xe_hw_engine_is_reserved(struct xe_hw_engine *hwe)
|
||||
struct xe_gt *gt = hwe->gt;
|
||||
struct xe_device *xe = gt_to_xe(gt);
|
||||
|
||||
if (xe_device_is_admin_only(xe))
|
||||
return true;
|
||||
|
||||
if (hwe->class == XE_ENGINE_CLASS_OTHER)
|
||||
return true;
|
||||
|
||||
|
||||
@@ -231,6 +231,9 @@ static size_t calc_mem_regions_size(struct xe_device *xe)
|
||||
u32 num_managers = 1;
|
||||
int i;
|
||||
|
||||
if (xe_device_is_admin_only(xe))
|
||||
return sizeof(struct drm_xe_query_mem_regions);
|
||||
|
||||
for (i = XE_PL_VRAM0; i <= XE_PL_VRAM1; ++i)
|
||||
if (ttm_manager_type(&xe->ttm, i))
|
||||
num_managers++;
|
||||
@@ -259,6 +262,9 @@ static int query_mem_regions(struct xe_device *xe,
|
||||
if (XE_IOCTL_DBG(xe, !mem_regions))
|
||||
return -ENOMEM;
|
||||
|
||||
if (xe_device_is_admin_only(xe))
|
||||
goto user_copy;
|
||||
|
||||
man = ttm_manager_type(&xe->ttm, XE_PL_TT);
|
||||
mem_regions->mem_regions[0].mem_class = DRM_XE_MEM_REGION_CLASS_SYSMEM;
|
||||
/*
|
||||
@@ -297,6 +303,7 @@ static int query_mem_regions(struct xe_device *xe,
|
||||
}
|
||||
}
|
||||
|
||||
user_copy:
|
||||
if (!copy_to_user(query_ptr, mem_regions, size))
|
||||
ret = 0;
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user