#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"
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 |
.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);
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
+
+ xe_display_driver_set_hooks(driver);
- err = aperture_remove_conflicting_pci_devices(pdev, driver.name);
+ 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;
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);
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++;
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;
/*
}
}
+user_copy:
if (!copy_to_user(query_ptr, mem_regions, size))
ret = 0;
else