Skip to content

Commit

Permalink
Enable PXP virtualization in kernel
Browse files Browse the repository at this point in the history
enabled PXP virtualization in i915, add virtio pxp device to realize
PXP virtualization function.

Tracked-On: OAM-121827
Signed-off-by: Xue, Bosheng <[email protected]>
  • Loading branch information
bosheng1 committed Aug 20, 2024
1 parent 8c631d6 commit 6225346
Show file tree
Hide file tree
Showing 13 changed files with 1,541 additions and 9 deletions.
5 changes: 5 additions & 0 deletions drivers/gpu/drm/i915/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -369,10 +369,14 @@ i915-$(CONFIG_DRM_I915_PXP) += \
pxp/intel_pxp_cmd.o \
pxp/intel_pxp_debugfs.o \
pxp/intel_pxp_gsccs.o \
pxp/virt/intel_pxp_fe.o \
pxp/intel_pxp_irq.o \
pxp/intel_pxp_pm.o \
pxp/intel_pxp_session.o

virtio-pxp-y += \
pxp/virt/virtio_pxp.o

# Post-mortem debug and GPU hang state capture
i915-$(CONFIG_DRM_I915_CAPTURE_ERROR) += i915_gpu_error.o
i915-$(CONFIG_DRM_I915_SELFTEST) += \
Expand All @@ -399,6 +403,7 @@ include $(src)/gvt/Makefile

obj-$(CONFIG_DRM_I915) += i915.o
obj-$(CONFIG_DRM_I915_GVT_KVMGT) += kvmgt.o
obj-$(CONFIG_DRM_I915) += virtio-pxp.o

# kernel-doc test
#
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,8 @@ struct dma_buf *i915_gem_prime_export(struct drm_gem_object *gem_obj, int flags)
{
struct drm_i915_gem_object *obj = to_intel_bo(gem_obj);
DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
if (i915_gem_object_is_protected(obj))
gem_obj->protected = true;

exp_info.ops = &i915_dmabuf_ops;
exp_info.size = gem_obj->size;
Expand Down
46 changes: 42 additions & 4 deletions drivers/gpu/drm/i915/pxp/intel_pxp.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "intel_pxp_session.h"
#include "intel_pxp_tee.h"
#include "intel_pxp_types.h"
#include "virt/intel_pxp_fe.h"

/**
* DOC: PXP
Expand Down Expand Up @@ -49,16 +50,22 @@

bool intel_pxp_is_supported(const struct intel_pxp *pxp)
{
if (intel_pxp_is_in_vf(pxp))
return intel_pxp_fe_is_supported(pxp);
return IS_ENABLED(CONFIG_DRM_I915_PXP) && pxp;
}

bool intel_pxp_is_enabled(const struct intel_pxp *pxp)
{
if (intel_pxp_is_in_vf(pxp))
return intel_pxp_fe_is_enabled(pxp);
return IS_ENABLED(CONFIG_DRM_I915_PXP) && pxp && pxp->ce;
}

bool intel_pxp_is_active(const struct intel_pxp *pxp)
{
if (intel_pxp_is_in_vf(pxp))
return intel_pxp_fe_is_active(pxp);
return IS_ENABLED(CONFIG_DRM_I915_PXP) && pxp && pxp->arb_session.is_valid;
}

Expand Down Expand Up @@ -200,6 +207,8 @@ int intel_pxp_init(struct drm_i915_private *i915)
{
struct intel_gt *gt;
bool is_full_feature = false;
if (IS_SRIOV_VF(i915))
return intel_pxp_fe_init(i915);

if (intel_gt_is_wedged(to_gt(i915))) {
drm_err(&i915->drm, "Failed to init pxp due to not connected\n");
Expand Down Expand Up @@ -231,6 +240,7 @@ int intel_pxp_init(struct drm_i915_private *i915)
}

/* init common info used by all feature-mode usages*/
i915->pxp->vf = false;
i915->pxp->ctrl_gt = gt;
mutex_init(&i915->pxp->tee_mutex);

Expand All @@ -249,6 +259,8 @@ int intel_pxp_init(struct drm_i915_private *i915)

void intel_pxp_fini(struct drm_i915_private *i915)
{
if (IS_SRIOV_VF(i915))
return intel_pxp_fe_fini(i915);
if (!i915->pxp)
return;

Expand All @@ -269,6 +281,8 @@ void intel_pxp_fini(struct drm_i915_private *i915)

void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp)
{
if (intel_pxp_is_in_vf(pxp))
return intel_pxp_fe_mark_termination_in_progress(pxp);
pxp->hw_state_invalidated = true;
pxp->arb_session.is_valid = false;
pxp->arb_session.tag = 0;
Expand Down Expand Up @@ -304,6 +318,8 @@ static bool pxp_component_bound(struct intel_pxp *pxp)

int intel_pxp_get_backend_timeout_ms(struct intel_pxp *pxp)
{
if (intel_pxp_is_in_vf(pxp))
return intel_pxp_fe_get_backend_timeout_ms(pxp);
if (HAS_ENGINE(pxp->ctrl_gt, GSC0))
return GSCFW_MAX_ROUND_TRIP_LATENCY_MS;
else
Expand Down Expand Up @@ -362,8 +378,11 @@ static int __pxp_global_teardown_restart(struct intel_pxp *pxp)

void intel_pxp_end(struct intel_pxp *pxp)
{
struct drm_i915_private *i915 = pxp->ctrl_gt->i915;
struct drm_i915_private *i915;
intel_wakeref_t wakeref;
if (intel_pxp_is_in_vf(pxp))
return intel_pxp_fe_end(pxp);
i915 = pxp->ctrl_gt->i915;

if (!intel_pxp_is_enabled(pxp))
return;
Expand Down Expand Up @@ -407,6 +426,9 @@ static bool pxp_fw_dependencies_completed(struct intel_pxp *pxp)
*/
int intel_pxp_get_readiness_status(struct intel_pxp *pxp, int timeout_ms)
{
if (intel_pxp_is_in_vf(pxp))
return intel_pxp_fe_get_readiness_status(pxp, timeout_ms);

if (!intel_pxp_is_enabled(pxp)) {
drm_err(&pxp->ctrl_gt->i915->drm,
"Failed to get readiness due to PXP not enabled\n");
Expand Down Expand Up @@ -443,7 +465,8 @@ int intel_pxp_get_readiness_status(struct intel_pxp *pxp, int timeout_ms)
int intel_pxp_start(struct intel_pxp *pxp)
{
int ret = 0;

if (intel_pxp_is_in_vf(pxp))
return intel_pxp_fe_start(pxp);
ret = intel_pxp_get_readiness_status(pxp, PXP_READINESS_TIMEOUT);
if (ret < 0) {
drm_err(&pxp->ctrl_gt->i915->drm,
Expand Down Expand Up @@ -479,12 +502,16 @@ int intel_pxp_start(struct intel_pxp *pxp)

void intel_pxp_init_hw(struct intel_pxp *pxp)
{
if (intel_pxp_is_in_vf(pxp))
return intel_pxp_fe_init_hw(pxp);
kcr_pxp_enable(pxp);
intel_pxp_irq_enable(pxp);
}

void intel_pxp_fini_hw(struct intel_pxp *pxp)
{
if (intel_pxp_is_in_vf(pxp))
return intel_pxp_fe_fini_hw(pxp);
kcr_pxp_disable(pxp);
intel_pxp_irq_disable(pxp);
}
Expand All @@ -493,6 +520,9 @@ int intel_pxp_key_check(struct intel_pxp *pxp,
struct drm_i915_gem_object *obj,
bool assign)
{
if (intel_pxp_is_in_vf(pxp))
return intel_pxp_fe_key_check(pxp, obj, assign);

if (!intel_pxp_is_active(pxp)) {
return -ENODEV;
}
Expand Down Expand Up @@ -521,9 +551,12 @@ int intel_pxp_key_check(struct intel_pxp *pxp,

void intel_pxp_invalidate(struct intel_pxp *pxp)
{
struct drm_i915_private *i915 = pxp->ctrl_gt->i915;
struct drm_i915_private *i915;
struct i915_gem_context *ctx, *cn;

if (intel_pxp_is_in_vf(pxp))
i915 = pxp->fe.i915;
else
i915 = pxp->ctrl_gt->i915;
/* ban all contexts marked as protected */
spin_lock_irq(&i915->gem.contexts.lock);
list_for_each_entry_safe(ctx, cn, &i915->gem.contexts.list, link) {
Expand Down Expand Up @@ -838,6 +871,9 @@ int i915_pxp_ops_ioctl(struct drm_device *dev, void *data, struct drm_file *drmf
struct intel_pxp *pxp = i915->pxp;
intel_wakeref_t wakeref;

if(intel_pxp_is_in_vf(pxp))
return i915_pxp_fe_ops_ioctl(dev, data, drmfile);

if (!intel_pxp_is_enabled(pxp))
return -ENODEV;

Expand Down Expand Up @@ -903,6 +939,8 @@ int i915_pxp_ops_ioctl(struct drm_device *dev, void *data, struct drm_file *drmf

void intel_pxp_close(struct intel_pxp *pxp, struct drm_file *drmfile)
{
if (intel_pxp_is_in_vf(pxp))
return intel_pxp_fe_close(pxp, drmfile);
if (!intel_pxp_is_enabled(pxp) || !drmfile)
return;

Expand Down
11 changes: 8 additions & 3 deletions drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,10 @@ void intel_pxp_debugfs_register(struct intel_pxp *pxp)
if (!intel_pxp_is_supported(pxp))
return;

minor = pxp->ctrl_gt->i915->drm.primary;
if (pxp->vf)
minor = pxp->fe.i915->drm.primary;
else
minor = pxp->ctrl_gt->i915->drm.primary;
if (!minor->debugfs_root)
return;

Expand All @@ -86,6 +89,8 @@ void intel_pxp_debugfs_register(struct intel_pxp *pxp)
debugfs_create_file("info", 0444, pxproot,
pxp, &pxp_info_fops);

debugfs_create_file("terminate_state", 0644, pxproot,
pxp, &pxp_terminate_fops);

if (!pxp->vf)
debugfs_create_file("terminate_state", 0644, pxproot,
pxp, &pxp_terminate_fops);
}
9 changes: 9 additions & 0 deletions drivers/gpu/drm/i915/pxp/intel_pxp_pm.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "intel_pxp_pm.h"
#include "intel_pxp_session.h"
#include "intel_pxp_types.h"
#include "virt/intel_pxp_fe.h"

void intel_pxp_suspend_prepare(struct intel_pxp *pxp)
{
Expand All @@ -24,6 +25,8 @@ void intel_pxp_suspend_prepare(struct intel_pxp *pxp)
void intel_pxp_suspend(struct intel_pxp *pxp)
{
intel_wakeref_t wakeref;
if (intel_pxp_is_in_vf(pxp))
return intel_pxp_fe_suspend(pxp);

if (!intel_pxp_is_enabled(pxp))
return;
Expand Down Expand Up @@ -59,16 +62,22 @@ static void _pxp_resume(struct intel_pxp *pxp, bool take_wakeref)

void intel_pxp_resume_complete(struct intel_pxp *pxp)
{
if (intel_pxp_is_in_vf(pxp))
return intel_pxp_fe_resume_complete(pxp);
_pxp_resume(pxp, true);
}

void intel_pxp_runtime_resume(struct intel_pxp *pxp)
{
if (intel_pxp_is_in_vf(pxp))
return intel_pxp_fe_runtime_resume(pxp);
_pxp_resume(pxp, false);
}

void intel_pxp_runtime_suspend(struct intel_pxp *pxp)
{
if (intel_pxp_is_in_vf(pxp))
return intel_pxp_fe_runtime_suspend(pxp);
if (!intel_pxp_is_enabled(pxp))
return;

Expand Down
24 changes: 22 additions & 2 deletions drivers/gpu/drm/i915/pxp/intel_pxp_session.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,21 @@
#include "intel_pxp_types.h"
#include "intel_pxp_regs.h"

void intel_pxp_uevent(struct intel_pxp *pxp, int event)
{
struct intel_gt *gt = pxp->ctrl_gt;
struct drm_device *dev = &gt->i915->drm;
char event_str[25];
char *envp[2] = { event_str, NULL };

snprintf(event_str, ARRAY_SIZE(event_str),
"PXP_EVENT=%u", event);

DRM_DEBUG("generating pxp event :%d\n", event);

kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp);
}

static u8 get_next_instance_id(struct intel_pxp *pxp, u32 id)
{
u8 next_id = ++pxp->next_tag_id[id];
Expand Down Expand Up @@ -511,8 +526,10 @@ static void pxp_session_work(struct work_struct *work)

drm_dbg(&gt->i915->drm, "PXP: processing event-flags 0x%08x", events);

if (events & PXP_INVAL_REQUIRED)
if (events & PXP_INVAL_REQUIRED) {
intel_pxp_uevent(pxp, PXP_INVAL_REQUIRED);
intel_pxp_invalidate(pxp);
}

/*
* If we're processing an event while suspending then don't bother,
Expand All @@ -524,11 +541,14 @@ static void pxp_session_work(struct work_struct *work)

if (events & PXP_TERMINATION_REQUEST) {
events &= ~PXP_TERMINATION_COMPLETE;
intel_pxp_uevent(pxp, PXP_TERMINATION_REQUEST);
intel_pxp_terminate(pxp, true);
}

if (events & PXP_TERMINATION_COMPLETE)
if (events & PXP_TERMINATION_COMPLETE) {
intel_pxp_uevent(pxp, PXP_TERMINATION_COMPLETE);
pxp_terminate_complete(pxp);
}

intel_runtime_pm_put(gt->uncore->rpm, wakeref);
}
Expand Down
20 changes: 20 additions & 0 deletions drivers/gpu/drm/i915/pxp/intel_pxp_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <linux/mutex.h>
#include <linux/types.h>
#include <linux/workqueue.h>
#include "virt/virtpxp_drv.h"

struct drm_i915_private;

Expand Down Expand Up @@ -42,6 +43,23 @@ struct intel_pxp_session {
u32 tag;
};

struct intel_pxp_fe {
struct drm_i915_private *i915;
bool enabled;
bool active;
struct mutex session_mutex;
int device_idx;
int device_vfid;
int max_sessions;
int avail_sessions;
struct virtio_pxp *vpxp;
spinlock_t irq_lock;
struct intel_pxp_session hwdrm_sessions[INTEL_PXP_MAX_HWDRM_SESSIONS];
u32 key_instance;
struct work_struct session_work;
u32 session_events;
};

/**
* struct intel_pxp - pxp state
*/
Expand Down Expand Up @@ -165,6 +183,8 @@ struct intel_pxp {
#define PXP_TERMINATION_COMPLETE BIT(1)
#define PXP_INVAL_REQUIRED BIT(2)
#define PXP_EVENT_TYPE_IRQ BIT(3)
bool vf;
struct intel_pxp_fe fe;
};

#endif /* __INTEL_PXP_TYPES_H__ */
Loading

0 comments on commit 6225346

Please sign in to comment.