All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v6 00/15] drm/i915: Introduce Intel PXP
@ 2021-07-29  2:00 ` Daniele Ceraolo Spurio
  0 siblings, 0 replies; 64+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-07-29  2:00 UTC (permalink / raw)
  To: intel-gfx
  Cc: Alan Previn, Gaurav Kumar, dri-devel, Chris Wilson,
	Daniele Ceraolo Spurio, Jason Ekstrand, Rodrigo Vivi,
	Daniel Vetter, Juston Li

PXP (Protected Xe Path) is an i915 component, available on
GEN12+, that helps to establish the hardware protected session
and manage the status of the alive software session, as well
as its life cycle.

Very minimal changes from v5:

- Update mei_pxp match code to look the same as mei_hdcp (no
  functional/logical changes) and drop a couple of debug prints.

- Rebase on top of object create_ext changes (removal of vanilla_object).

Tested with: https://patchwork.freedesktop.org/series/87570/

Cc: Gaurav Kumar <kumar.gaurav@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Juston Li <juston.li@intel.com>
Cc: Alan Previn <alan.previn.teres.alexis@intel.com>
Cc: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Cc: Jason Ekstrand <jason@jlekstrand.net>
Cc: Daniel Vetter <daniel.vetter@intel.com>

Anshuman Gupta (2):
  drm/i915/pxp: Add plane decryption support
  drm/i915/pxp: black pixels on pxp disabled

Daniele Ceraolo Spurio (7):
  drm/i915/pxp: Define PXP component interface
  drm/i915/pxp: define PXP device flag and kconfig
  drm/i915/pxp: allocate a vcs context for pxp usage
  drm/i915/pxp: set KCR reg init
  drm/i915/pxp: interfaces for using protected objects
  drm/i915/pxp: start the arb session on demand
  drm/i915/pxp: enable PXP for integrated Gen12

Huang, Sean Z (5):
  drm/i915/pxp: Implement funcs to create the TEE channel
  drm/i915/pxp: Create the arbitrary session after boot
  drm/i915/pxp: Implement arb session teardown
  drm/i915/pxp: Implement PXP irq handler
  drm/i915/pxp: Enable PXP power management

Vitaly Lubart (1):
  mei: pxp: export pavp client to me client bus

 drivers/gpu/drm/i915/Kconfig                  |  11 +
 drivers/gpu/drm/i915/Makefile                 |   9 +
 .../gpu/drm/i915/display/intel_atomic_plane.c |  25 ++
 drivers/gpu/drm/i915/display/intel_display.c  |   4 +
 .../drm/i915/display/intel_display_types.h    |   6 +
 .../drm/i915/display/skl_universal_plane.c    |  49 +++-
 drivers/gpu/drm/i915/gem/i915_gem_context.c   |  68 ++++-
 drivers/gpu/drm/i915/gem/i915_gem_context.h   |  18 ++
 .../gpu/drm/i915/gem/i915_gem_context_types.h |   2 +
 drivers/gpu/drm/i915/gem/i915_gem_create.c    |  75 +++--
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c    |  42 ++-
 drivers/gpu/drm/i915/gem/i915_gem_object.c    |   6 +
 drivers/gpu/drm/i915/gem/i915_gem_object.h    |  12 +
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |   9 +
 drivers/gpu/drm/i915/gt/intel_engine.h        |   2 +
 drivers/gpu/drm/i915/gt/intel_gpu_commands.h  |  22 +-
 drivers/gpu/drm/i915/gt/intel_gt.c            |   5 +
 drivers/gpu/drm/i915/gt/intel_gt_irq.c        |   7 +
 drivers/gpu/drm/i915/gt/intel_gt_pm.c         |  15 +-
 drivers/gpu/drm/i915/gt/intel_gt_types.h      |   3 +
 drivers/gpu/drm/i915/i915_drv.c               |   2 +
 drivers/gpu/drm/i915/i915_drv.h               |   4 +
 drivers/gpu/drm/i915/i915_pci.c               |   2 +
 drivers/gpu/drm/i915/i915_reg.h               |  48 ++++
 drivers/gpu/drm/i915/intel_device_info.h      |   1 +
 drivers/gpu/drm/i915/pxp/intel_pxp.c          | 268 ++++++++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp.h          |  67 +++++
 drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c      | 141 +++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h      |  15 +
 drivers/gpu/drm/i915/pxp/intel_pxp_irq.c      | 100 +++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_irq.h      |  32 +++
 drivers/gpu/drm/i915/pxp/intel_pxp_pm.c       |  40 +++
 drivers/gpu/drm/i915/pxp/intel_pxp_pm.h       |  23 ++
 drivers/gpu/drm/i915/pxp/intel_pxp_session.c  | 172 +++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_session.h  |  15 +
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c      | 170 +++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.h      |  17 ++
 .../drm/i915/pxp/intel_pxp_tee_interface.h    |  37 +++
 drivers/gpu/drm/i915/pxp/intel_pxp_types.h    |  55 ++++
 drivers/misc/mei/Kconfig                      |   2 +
 drivers/misc/mei/Makefile                     |   1 +
 drivers/misc/mei/pxp/Kconfig                  |  13 +
 drivers/misc/mei/pxp/Makefile                 |   7 +
 drivers/misc/mei/pxp/mei_pxp.c                | 229 +++++++++++++++
 drivers/misc/mei/pxp/mei_pxp.h                |  18 ++
 include/drm/i915_component.h                  |   1 +
 include/drm/i915_pxp_tee_interface.h          |  45 +++
 include/uapi/drm/i915_drm.h                   |  58 +++-
 48 files changed, 1940 insertions(+), 33 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp.c
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp.h
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_irq.h
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_pm.c
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_pm.h
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_session.c
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_session.h
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_tee.h
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_tee_interface.h
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_types.h
 create mode 100644 drivers/misc/mei/pxp/Kconfig
 create mode 100644 drivers/misc/mei/pxp/Makefile
 create mode 100644 drivers/misc/mei/pxp/mei_pxp.c
 create mode 100644 drivers/misc/mei/pxp/mei_pxp.h
 create mode 100644 include/drm/i915_pxp_tee_interface.h

-- 
2.32.0


^ permalink raw reply	[flat|nested] 64+ messages in thread

* [Intel-gfx] [PATCH v6 00/15] drm/i915: Introduce Intel PXP
@ 2021-07-29  2:00 ` Daniele Ceraolo Spurio
  0 siblings, 0 replies; 64+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-07-29  2:00 UTC (permalink / raw)
  To: intel-gfx
  Cc: Alan Previn, Gaurav Kumar, dri-devel, Chris Wilson, Daniel Vetter

PXP (Protected Xe Path) is an i915 component, available on
GEN12+, that helps to establish the hardware protected session
and manage the status of the alive software session, as well
as its life cycle.

Very minimal changes from v5:

- Update mei_pxp match code to look the same as mei_hdcp (no
  functional/logical changes) and drop a couple of debug prints.

- Rebase on top of object create_ext changes (removal of vanilla_object).

Tested with: https://patchwork.freedesktop.org/series/87570/

Cc: Gaurav Kumar <kumar.gaurav@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Juston Li <juston.li@intel.com>
Cc: Alan Previn <alan.previn.teres.alexis@intel.com>
Cc: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Cc: Jason Ekstrand <jason@jlekstrand.net>
Cc: Daniel Vetter <daniel.vetter@intel.com>

Anshuman Gupta (2):
  drm/i915/pxp: Add plane decryption support
  drm/i915/pxp: black pixels on pxp disabled

Daniele Ceraolo Spurio (7):
  drm/i915/pxp: Define PXP component interface
  drm/i915/pxp: define PXP device flag and kconfig
  drm/i915/pxp: allocate a vcs context for pxp usage
  drm/i915/pxp: set KCR reg init
  drm/i915/pxp: interfaces for using protected objects
  drm/i915/pxp: start the arb session on demand
  drm/i915/pxp: enable PXP for integrated Gen12

Huang, Sean Z (5):
  drm/i915/pxp: Implement funcs to create the TEE channel
  drm/i915/pxp: Create the arbitrary session after boot
  drm/i915/pxp: Implement arb session teardown
  drm/i915/pxp: Implement PXP irq handler
  drm/i915/pxp: Enable PXP power management

Vitaly Lubart (1):
  mei: pxp: export pavp client to me client bus

 drivers/gpu/drm/i915/Kconfig                  |  11 +
 drivers/gpu/drm/i915/Makefile                 |   9 +
 .../gpu/drm/i915/display/intel_atomic_plane.c |  25 ++
 drivers/gpu/drm/i915/display/intel_display.c  |   4 +
 .../drm/i915/display/intel_display_types.h    |   6 +
 .../drm/i915/display/skl_universal_plane.c    |  49 +++-
 drivers/gpu/drm/i915/gem/i915_gem_context.c   |  68 ++++-
 drivers/gpu/drm/i915/gem/i915_gem_context.h   |  18 ++
 .../gpu/drm/i915/gem/i915_gem_context_types.h |   2 +
 drivers/gpu/drm/i915/gem/i915_gem_create.c    |  75 +++--
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c    |  42 ++-
 drivers/gpu/drm/i915/gem/i915_gem_object.c    |   6 +
 drivers/gpu/drm/i915/gem/i915_gem_object.h    |  12 +
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |   9 +
 drivers/gpu/drm/i915/gt/intel_engine.h        |   2 +
 drivers/gpu/drm/i915/gt/intel_gpu_commands.h  |  22 +-
 drivers/gpu/drm/i915/gt/intel_gt.c            |   5 +
 drivers/gpu/drm/i915/gt/intel_gt_irq.c        |   7 +
 drivers/gpu/drm/i915/gt/intel_gt_pm.c         |  15 +-
 drivers/gpu/drm/i915/gt/intel_gt_types.h      |   3 +
 drivers/gpu/drm/i915/i915_drv.c               |   2 +
 drivers/gpu/drm/i915/i915_drv.h               |   4 +
 drivers/gpu/drm/i915/i915_pci.c               |   2 +
 drivers/gpu/drm/i915/i915_reg.h               |  48 ++++
 drivers/gpu/drm/i915/intel_device_info.h      |   1 +
 drivers/gpu/drm/i915/pxp/intel_pxp.c          | 268 ++++++++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp.h          |  67 +++++
 drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c      | 141 +++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h      |  15 +
 drivers/gpu/drm/i915/pxp/intel_pxp_irq.c      | 100 +++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_irq.h      |  32 +++
 drivers/gpu/drm/i915/pxp/intel_pxp_pm.c       |  40 +++
 drivers/gpu/drm/i915/pxp/intel_pxp_pm.h       |  23 ++
 drivers/gpu/drm/i915/pxp/intel_pxp_session.c  | 172 +++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_session.h  |  15 +
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c      | 170 +++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.h      |  17 ++
 .../drm/i915/pxp/intel_pxp_tee_interface.h    |  37 +++
 drivers/gpu/drm/i915/pxp/intel_pxp_types.h    |  55 ++++
 drivers/misc/mei/Kconfig                      |   2 +
 drivers/misc/mei/Makefile                     |   1 +
 drivers/misc/mei/pxp/Kconfig                  |  13 +
 drivers/misc/mei/pxp/Makefile                 |   7 +
 drivers/misc/mei/pxp/mei_pxp.c                | 229 +++++++++++++++
 drivers/misc/mei/pxp/mei_pxp.h                |  18 ++
 include/drm/i915_component.h                  |   1 +
 include/drm/i915_pxp_tee_interface.h          |  45 +++
 include/uapi/drm/i915_drm.h                   |  58 +++-
 48 files changed, 1940 insertions(+), 33 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp.c
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp.h
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_irq.h
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_pm.c
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_pm.h
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_session.c
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_session.h
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_tee.h
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_tee_interface.h
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_types.h
 create mode 100644 drivers/misc/mei/pxp/Kconfig
 create mode 100644 drivers/misc/mei/pxp/Makefile
 create mode 100644 drivers/misc/mei/pxp/mei_pxp.c
 create mode 100644 drivers/misc/mei/pxp/mei_pxp.h
 create mode 100644 include/drm/i915_pxp_tee_interface.h

-- 
2.32.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 64+ messages in thread

* [PATCH v6 01/15] drm/i915/pxp: Define PXP component interface
  2021-07-29  2:00 ` [Intel-gfx] " Daniele Ceraolo Spurio
@ 2021-07-29  2:00   ` Daniele Ceraolo Spurio
  -1 siblings, 0 replies; 64+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-07-29  2:00 UTC (permalink / raw)
  To: intel-gfx; +Cc: Daniele Ceraolo Spurio, dri-devel, Rodrigo Vivi

This will be used for communication between the i915 driver and the mei
one. Defining it in a stand-alone patch to avoid circualr dependedencies
between the patches modifying the 2 drivers.

Split out from an original patch from  Huang, Sean Z

v2: rename the component struct (Rodrigo)

Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
---
 include/drm/i915_component.h         |  1 +
 include/drm/i915_pxp_tee_interface.h | 45 ++++++++++++++++++++++++++++
 2 files changed, 46 insertions(+)
 create mode 100644 include/drm/i915_pxp_tee_interface.h

diff --git a/include/drm/i915_component.h b/include/drm/i915_component.h
index 55c3b123581b..c1e2a43d2d1e 100644
--- a/include/drm/i915_component.h
+++ b/include/drm/i915_component.h
@@ -29,6 +29,7 @@
 enum i915_component_type {
 	I915_COMPONENT_AUDIO = 1,
 	I915_COMPONENT_HDCP,
+	I915_COMPONENT_PXP
 };
 
 /* MAX_PORT is the number of port
diff --git a/include/drm/i915_pxp_tee_interface.h b/include/drm/i915_pxp_tee_interface.h
new file mode 100644
index 000000000000..09b8389152af
--- /dev/null
+++ b/include/drm/i915_pxp_tee_interface.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2020 Intel Corporation
+ *
+ * Authors:
+ * Vitaly Lubart <vitaly.lubart@intel.com>
+ */
+
+#ifndef _I915_PXP_TEE_INTERFACE_H_
+#define _I915_PXP_TEE_INTERFACE_H_
+
+#include <linux/mutex.h>
+#include <linux/device.h>
+
+/**
+ * struct i915_pxp_component_ops - ops for PXP services.
+ * @owner: Module providing the ops
+ * @send: sends data to PXP
+ * @receive: receives data from PXP
+ */
+struct i915_pxp_component_ops {
+	/**
+	 * @owner: owner of the module provding the ops
+	 */
+	struct module *owner;
+
+	int (*send)(struct device *dev, const void *message, size_t size);
+	int (*recv)(struct device *dev, void *buffer, size_t size);
+};
+
+/**
+ * struct i915_pxp_component - Used for communication between i915 and TEE
+ * drivers for the PXP services
+ * @tee_dev: device that provide the PXP service from TEE Bus.
+ * @pxp_ops: Ops implemented by TEE driver, used by i915 driver.
+ */
+struct i915_pxp_component {
+	struct device *tee_dev;
+	const struct i915_pxp_component_ops *ops;
+
+	/* To protect the above members. */
+	struct mutex mutex;
+};
+
+#endif /* _I915_TEE_PXP_INTERFACE_H_ */
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [Intel-gfx] [PATCH v6 01/15] drm/i915/pxp: Define PXP component interface
@ 2021-07-29  2:00   ` Daniele Ceraolo Spurio
  0 siblings, 0 replies; 64+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-07-29  2:00 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel

This will be used for communication between the i915 driver and the mei
one. Defining it in a stand-alone patch to avoid circualr dependedencies
between the patches modifying the 2 drivers.

Split out from an original patch from  Huang, Sean Z

v2: rename the component struct (Rodrigo)

Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
---
 include/drm/i915_component.h         |  1 +
 include/drm/i915_pxp_tee_interface.h | 45 ++++++++++++++++++++++++++++
 2 files changed, 46 insertions(+)
 create mode 100644 include/drm/i915_pxp_tee_interface.h

diff --git a/include/drm/i915_component.h b/include/drm/i915_component.h
index 55c3b123581b..c1e2a43d2d1e 100644
--- a/include/drm/i915_component.h
+++ b/include/drm/i915_component.h
@@ -29,6 +29,7 @@
 enum i915_component_type {
 	I915_COMPONENT_AUDIO = 1,
 	I915_COMPONENT_HDCP,
+	I915_COMPONENT_PXP
 };
 
 /* MAX_PORT is the number of port
diff --git a/include/drm/i915_pxp_tee_interface.h b/include/drm/i915_pxp_tee_interface.h
new file mode 100644
index 000000000000..09b8389152af
--- /dev/null
+++ b/include/drm/i915_pxp_tee_interface.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2020 Intel Corporation
+ *
+ * Authors:
+ * Vitaly Lubart <vitaly.lubart@intel.com>
+ */
+
+#ifndef _I915_PXP_TEE_INTERFACE_H_
+#define _I915_PXP_TEE_INTERFACE_H_
+
+#include <linux/mutex.h>
+#include <linux/device.h>
+
+/**
+ * struct i915_pxp_component_ops - ops for PXP services.
+ * @owner: Module providing the ops
+ * @send: sends data to PXP
+ * @receive: receives data from PXP
+ */
+struct i915_pxp_component_ops {
+	/**
+	 * @owner: owner of the module provding the ops
+	 */
+	struct module *owner;
+
+	int (*send)(struct device *dev, const void *message, size_t size);
+	int (*recv)(struct device *dev, void *buffer, size_t size);
+};
+
+/**
+ * struct i915_pxp_component - Used for communication between i915 and TEE
+ * drivers for the PXP services
+ * @tee_dev: device that provide the PXP service from TEE Bus.
+ * @pxp_ops: Ops implemented by TEE driver, used by i915 driver.
+ */
+struct i915_pxp_component {
+	struct device *tee_dev;
+	const struct i915_pxp_component_ops *ops;
+
+	/* To protect the above members. */
+	struct mutex mutex;
+};
+
+#endif /* _I915_TEE_PXP_INTERFACE_H_ */
-- 
2.32.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v6 02/15] mei: pxp: export pavp client to me client bus
  2021-07-29  2:00 ` [Intel-gfx] " Daniele Ceraolo Spurio
@ 2021-07-29  2:00   ` Daniele Ceraolo Spurio
  -1 siblings, 0 replies; 64+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-07-29  2:00 UTC (permalink / raw)
  To: intel-gfx
  Cc: Tomas Winkler, Daniele Ceraolo Spurio, Vitaly Lubart, dri-devel,
	Rodrigo Vivi

From: Vitaly Lubart <vitaly.lubart@intel.com>

Export PAVP client to work with i915 driver,
for binding it uses kernel component framework.

v2:drop debug prints, refactor match code to match mei_hdcp (Tomas)

Signed-off-by: Vitaly Lubart <vitaly.lubart@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> #v1
---
 drivers/misc/mei/Kconfig       |   2 +
 drivers/misc/mei/Makefile      |   1 +
 drivers/misc/mei/pxp/Kconfig   |  13 ++
 drivers/misc/mei/pxp/Makefile  |   7 +
 drivers/misc/mei/pxp/mei_pxp.c | 229 +++++++++++++++++++++++++++++++++
 drivers/misc/mei/pxp/mei_pxp.h |  18 +++
 6 files changed, 270 insertions(+)
 create mode 100644 drivers/misc/mei/pxp/Kconfig
 create mode 100644 drivers/misc/mei/pxp/Makefile
 create mode 100644 drivers/misc/mei/pxp/mei_pxp.c
 create mode 100644 drivers/misc/mei/pxp/mei_pxp.h

diff --git a/drivers/misc/mei/Kconfig b/drivers/misc/mei/Kconfig
index f5fd5b786607..0e0bcd0da852 100644
--- a/drivers/misc/mei/Kconfig
+++ b/drivers/misc/mei/Kconfig
@@ -47,3 +47,5 @@ config INTEL_MEI_TXE
 	  Intel Bay Trail
 
 source "drivers/misc/mei/hdcp/Kconfig"
+source "drivers/misc/mei/pxp/Kconfig"
+
diff --git a/drivers/misc/mei/Makefile b/drivers/misc/mei/Makefile
index f1c76f7ee804..d8e5165917f2 100644
--- a/drivers/misc/mei/Makefile
+++ b/drivers/misc/mei/Makefile
@@ -26,3 +26,4 @@ mei-$(CONFIG_EVENT_TRACING) += mei-trace.o
 CFLAGS_mei-trace.o = -I$(src)
 
 obj-$(CONFIG_INTEL_MEI_HDCP) += hdcp/
+obj-$(CONFIG_INTEL_MEI_PXP) += pxp/
diff --git a/drivers/misc/mei/pxp/Kconfig b/drivers/misc/mei/pxp/Kconfig
new file mode 100644
index 000000000000..4029b96afc04
--- /dev/null
+++ b/drivers/misc/mei/pxp/Kconfig
@@ -0,0 +1,13 @@
+
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2020, Intel Corporation. All rights reserved.
+#
+config INTEL_MEI_PXP
+	tristate "Intel PXP services of ME Interface"
+	select INTEL_MEI_ME
+	depends on DRM_I915
+	help
+	  MEI Support for PXP Services on Intel platforms.
+
+	  Enables the ME FW services required for PXP support through
+	  I915 display driver of Intel.
diff --git a/drivers/misc/mei/pxp/Makefile b/drivers/misc/mei/pxp/Makefile
new file mode 100644
index 000000000000..0329950d5794
--- /dev/null
+++ b/drivers/misc/mei/pxp/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright (c) 2020, Intel Corporation. All rights reserved.
+#
+# Makefile - PXP client driver for Intel MEI Bus Driver.
+
+obj-$(CONFIG_INTEL_MEI_PXP) += mei_pxp.o
diff --git a/drivers/misc/mei/pxp/mei_pxp.c b/drivers/misc/mei/pxp/mei_pxp.c
new file mode 100644
index 000000000000..f7380d387bab
--- /dev/null
+++ b/drivers/misc/mei/pxp/mei_pxp.c
@@ -0,0 +1,229 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright © 2020 - 2021 Intel Corporation
+ */
+
+/**
+ * DOC: MEI_PXP Client Driver
+ *
+ * The mei_pxp driver acts as a translation layer between PXP
+ * protocol  implementer (I915) and ME FW by translating PXP
+ * negotiation messages to ME FW command payloads and vice versa.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/uuid.h>
+#include <linux/mei_cl_bus.h>
+#include <linux/component.h>
+#include <drm/drm_connector.h>
+#include <drm/i915_component.h>
+#include <drm/i915_pxp_tee_interface.h>
+
+#include "mei_pxp.h"
+
+/**
+ * mei_pxp_send_message() - Sends a PXP message to ME FW.
+ * @dev: device corresponding to the mei_cl_device
+ * @message: a message buffer to send
+ * @size: size of the message
+ * Return: 0 on Success, <0 on Failure
+ */
+static int
+mei_pxp_send_message(struct device *dev, const void *message, size_t size)
+{
+	struct mei_cl_device *cldev;
+	ssize_t byte;
+
+	if (!dev || !message)
+		return -EINVAL;
+
+	cldev = to_mei_cl_device(dev);
+
+	/* temporary drop const qualifier till the API is fixed */
+	byte = mei_cldev_send(cldev, (u8 *)message, size);
+	if (byte < 0) {
+		dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte);
+		return byte;
+	}
+
+	return 0;
+}
+
+/**
+ * mei_pxp_receive_message() - Receives a PXP message from ME FW.
+ * @dev: device corresponding to the mei_cl_device
+ * @buffer: a message buffer to contain the received message
+ * @size: size of the buffer
+ * Return: bytes sent on Success, <0 on Failure
+ */
+static int
+mei_pxp_receive_message(struct device *dev, void *buffer, size_t size)
+{
+	struct mei_cl_device *cldev;
+	ssize_t byte;
+
+	if (!dev || !buffer)
+		return -EINVAL;
+
+	cldev = to_mei_cl_device(dev);
+
+	byte = mei_cldev_recv(cldev, buffer, size);
+	if (byte < 0) {
+		dev_dbg(dev, "mei_cldev_recv failed. %zd\n", byte);
+		return byte;
+	}
+
+	return byte;
+}
+
+static const struct i915_pxp_component_ops mei_pxp_ops = {
+	.owner = THIS_MODULE,
+	.send = mei_pxp_send_message,
+	.recv = mei_pxp_receive_message,
+};
+
+static int mei_component_master_bind(struct device *dev)
+{
+	struct mei_cl_device *cldev = to_mei_cl_device(dev);
+	struct i915_pxp_component *comp_master = mei_cldev_get_drvdata(cldev);
+	int ret;
+
+	comp_master->ops = &mei_pxp_ops;
+	comp_master->tee_dev = dev;
+	ret = component_bind_all(dev, comp_master);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static void mei_component_master_unbind(struct device *dev)
+{
+	struct mei_cl_device *cldev = to_mei_cl_device(dev);
+	struct i915_pxp_component *comp_master = mei_cldev_get_drvdata(cldev);
+
+	component_unbind_all(dev, comp_master);
+}
+
+static const struct component_master_ops mei_component_master_ops = {
+	.bind = mei_component_master_bind,
+	.unbind = mei_component_master_unbind,
+};
+
+/**
+ * mei_pxp_component_match - compare function for matching mei pxp.
+ *
+ *    The function checks if the driver is i915, the subcomponent is PXP
+ *    and the grand parent of pxp and the parent of i915 are the same
+ *    PCH device.
+ *
+ * @dev: master device
+ * @subcomponent: subcomponent to match (I915_COMPONENT_PXP)
+ * @data: compare data (mei pxp device)
+ *
+ * Return:
+ * * 1 - if components match
+ * * 0 - otherwise
+ */
+static int mei_pxp_component_match(struct device *dev, int subcomponent,
+				   void *data)
+{
+	struct device *base = data;
+
+	if (strcmp(dev->driver->name, "i915") ||
+	    subcomponent != I915_COMPONENT_PXP)
+		return 0;
+
+	base = base->parent;
+	if (!base)
+		return 0;
+
+	base = base->parent;
+	dev = dev->parent;
+
+	return (base && dev && dev == base);
+}
+
+static int mei_pxp_probe(struct mei_cl_device *cldev,
+			 const struct mei_cl_device_id *id)
+{
+	struct i915_pxp_component *comp_master;
+	struct component_match *master_match;
+	int ret;
+
+	ret = mei_cldev_enable(cldev);
+	if (ret < 0) {
+		dev_err(&cldev->dev, "mei_cldev_enable Failed. %d\n", ret);
+		goto enable_err_exit;
+	}
+
+	comp_master = kzalloc(sizeof(*comp_master), GFP_KERNEL);
+	if (!comp_master) {
+		ret = -ENOMEM;
+		goto err_exit;
+	}
+
+	master_match = NULL;
+	component_match_add_typed(&cldev->dev, &master_match,
+				  mei_pxp_component_match, &cldev->dev);
+	if (IS_ERR_OR_NULL(master_match)) {
+		ret = -ENOMEM;
+		goto err_exit;
+	}
+
+	mei_cldev_set_drvdata(cldev, comp_master);
+	ret = component_master_add_with_match(&cldev->dev,
+					      &mei_component_master_ops,
+					      master_match);
+	if (ret < 0) {
+		dev_err(&cldev->dev, "Master comp add failed %d\n", ret);
+		goto err_exit;
+	}
+
+	return 0;
+
+err_exit:
+	mei_cldev_set_drvdata(cldev, NULL);
+	kfree(comp_master);
+	mei_cldev_disable(cldev);
+enable_err_exit:
+	return ret;
+}
+
+static void mei_pxp_remove(struct mei_cl_device *cldev)
+{
+	struct i915_pxp_component *comp_master = mei_cldev_get_drvdata(cldev);
+	int ret;
+
+	component_master_del(&cldev->dev, &mei_component_master_ops);
+	kfree(comp_master);
+	mei_cldev_set_drvdata(cldev, NULL);
+
+	ret = mei_cldev_disable(cldev);
+	if (ret)
+		dev_warn(&cldev->dev, "mei_cldev_disable() failed\n");
+}
+
+/* fbf6fcf1-96cf-4e2e-a6a6-1bab8cbe36b1 : PAVP GUID*/
+#define MEI_GUID_PXP GUID_INIT(0xfbf6fcf1, 0x96cf, 0x4e2e, 0xA6, \
+			       0xa6, 0x1b, 0xab, 0x8c, 0xbe, 0x36, 0xb1)
+
+static struct mei_cl_device_id mei_pxp_tbl[] = {
+	{ .uuid = MEI_GUID_PXP, .version = MEI_CL_VERSION_ANY },
+	{ }
+};
+MODULE_DEVICE_TABLE(mei, mei_pxp_tbl);
+
+static struct mei_cl_driver mei_pxp_driver = {
+	.id_table = mei_pxp_tbl,
+	.name = KBUILD_MODNAME,
+	.probe = mei_pxp_probe,
+	.remove	= mei_pxp_remove,
+};
+
+module_mei_cl_driver(mei_pxp_driver);
+
+MODULE_AUTHOR("Intel Corporation");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("MEI PXP");
diff --git a/drivers/misc/mei/pxp/mei_pxp.h b/drivers/misc/mei/pxp/mei_pxp.h
new file mode 100644
index 000000000000..e7b15373fefd
--- /dev/null
+++ b/drivers/misc/mei/pxp/mei_pxp.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright © 2020 Intel Corporation
+ *
+ * Authors:
+ * Vitaly Lubart <vitaly.lubart@intel.com>
+ */
+
+#ifndef __MEI_PXP_H__
+#define __MEI_PXP_H__
+
+/* me_pxp_status: Enumeration of all PXP Status Codes */
+enum me_pxp_status {
+	ME_PXP_STATUS_SUCCESS			= 0x0000,
+
+};
+
+#endif /* __MEI_PXP_H__ */
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [Intel-gfx] [PATCH v6 02/15] mei: pxp: export pavp client to me client bus
@ 2021-07-29  2:00   ` Daniele Ceraolo Spurio
  0 siblings, 0 replies; 64+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-07-29  2:00 UTC (permalink / raw)
  To: intel-gfx; +Cc: Tomas Winkler, Vitaly Lubart, dri-devel

From: Vitaly Lubart <vitaly.lubart@intel.com>

Export PAVP client to work with i915 driver,
for binding it uses kernel component framework.

v2:drop debug prints, refactor match code to match mei_hdcp (Tomas)

Signed-off-by: Vitaly Lubart <vitaly.lubart@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> #v1
---
 drivers/misc/mei/Kconfig       |   2 +
 drivers/misc/mei/Makefile      |   1 +
 drivers/misc/mei/pxp/Kconfig   |  13 ++
 drivers/misc/mei/pxp/Makefile  |   7 +
 drivers/misc/mei/pxp/mei_pxp.c | 229 +++++++++++++++++++++++++++++++++
 drivers/misc/mei/pxp/mei_pxp.h |  18 +++
 6 files changed, 270 insertions(+)
 create mode 100644 drivers/misc/mei/pxp/Kconfig
 create mode 100644 drivers/misc/mei/pxp/Makefile
 create mode 100644 drivers/misc/mei/pxp/mei_pxp.c
 create mode 100644 drivers/misc/mei/pxp/mei_pxp.h

diff --git a/drivers/misc/mei/Kconfig b/drivers/misc/mei/Kconfig
index f5fd5b786607..0e0bcd0da852 100644
--- a/drivers/misc/mei/Kconfig
+++ b/drivers/misc/mei/Kconfig
@@ -47,3 +47,5 @@ config INTEL_MEI_TXE
 	  Intel Bay Trail
 
 source "drivers/misc/mei/hdcp/Kconfig"
+source "drivers/misc/mei/pxp/Kconfig"
+
diff --git a/drivers/misc/mei/Makefile b/drivers/misc/mei/Makefile
index f1c76f7ee804..d8e5165917f2 100644
--- a/drivers/misc/mei/Makefile
+++ b/drivers/misc/mei/Makefile
@@ -26,3 +26,4 @@ mei-$(CONFIG_EVENT_TRACING) += mei-trace.o
 CFLAGS_mei-trace.o = -I$(src)
 
 obj-$(CONFIG_INTEL_MEI_HDCP) += hdcp/
+obj-$(CONFIG_INTEL_MEI_PXP) += pxp/
diff --git a/drivers/misc/mei/pxp/Kconfig b/drivers/misc/mei/pxp/Kconfig
new file mode 100644
index 000000000000..4029b96afc04
--- /dev/null
+++ b/drivers/misc/mei/pxp/Kconfig
@@ -0,0 +1,13 @@
+
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2020, Intel Corporation. All rights reserved.
+#
+config INTEL_MEI_PXP
+	tristate "Intel PXP services of ME Interface"
+	select INTEL_MEI_ME
+	depends on DRM_I915
+	help
+	  MEI Support for PXP Services on Intel platforms.
+
+	  Enables the ME FW services required for PXP support through
+	  I915 display driver of Intel.
diff --git a/drivers/misc/mei/pxp/Makefile b/drivers/misc/mei/pxp/Makefile
new file mode 100644
index 000000000000..0329950d5794
--- /dev/null
+++ b/drivers/misc/mei/pxp/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright (c) 2020, Intel Corporation. All rights reserved.
+#
+# Makefile - PXP client driver for Intel MEI Bus Driver.
+
+obj-$(CONFIG_INTEL_MEI_PXP) += mei_pxp.o
diff --git a/drivers/misc/mei/pxp/mei_pxp.c b/drivers/misc/mei/pxp/mei_pxp.c
new file mode 100644
index 000000000000..f7380d387bab
--- /dev/null
+++ b/drivers/misc/mei/pxp/mei_pxp.c
@@ -0,0 +1,229 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright © 2020 - 2021 Intel Corporation
+ */
+
+/**
+ * DOC: MEI_PXP Client Driver
+ *
+ * The mei_pxp driver acts as a translation layer between PXP
+ * protocol  implementer (I915) and ME FW by translating PXP
+ * negotiation messages to ME FW command payloads and vice versa.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/uuid.h>
+#include <linux/mei_cl_bus.h>
+#include <linux/component.h>
+#include <drm/drm_connector.h>
+#include <drm/i915_component.h>
+#include <drm/i915_pxp_tee_interface.h>
+
+#include "mei_pxp.h"
+
+/**
+ * mei_pxp_send_message() - Sends a PXP message to ME FW.
+ * @dev: device corresponding to the mei_cl_device
+ * @message: a message buffer to send
+ * @size: size of the message
+ * Return: 0 on Success, <0 on Failure
+ */
+static int
+mei_pxp_send_message(struct device *dev, const void *message, size_t size)
+{
+	struct mei_cl_device *cldev;
+	ssize_t byte;
+
+	if (!dev || !message)
+		return -EINVAL;
+
+	cldev = to_mei_cl_device(dev);
+
+	/* temporary drop const qualifier till the API is fixed */
+	byte = mei_cldev_send(cldev, (u8 *)message, size);
+	if (byte < 0) {
+		dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte);
+		return byte;
+	}
+
+	return 0;
+}
+
+/**
+ * mei_pxp_receive_message() - Receives a PXP message from ME FW.
+ * @dev: device corresponding to the mei_cl_device
+ * @buffer: a message buffer to contain the received message
+ * @size: size of the buffer
+ * Return: bytes sent on Success, <0 on Failure
+ */
+static int
+mei_pxp_receive_message(struct device *dev, void *buffer, size_t size)
+{
+	struct mei_cl_device *cldev;
+	ssize_t byte;
+
+	if (!dev || !buffer)
+		return -EINVAL;
+
+	cldev = to_mei_cl_device(dev);
+
+	byte = mei_cldev_recv(cldev, buffer, size);
+	if (byte < 0) {
+		dev_dbg(dev, "mei_cldev_recv failed. %zd\n", byte);
+		return byte;
+	}
+
+	return byte;
+}
+
+static const struct i915_pxp_component_ops mei_pxp_ops = {
+	.owner = THIS_MODULE,
+	.send = mei_pxp_send_message,
+	.recv = mei_pxp_receive_message,
+};
+
+static int mei_component_master_bind(struct device *dev)
+{
+	struct mei_cl_device *cldev = to_mei_cl_device(dev);
+	struct i915_pxp_component *comp_master = mei_cldev_get_drvdata(cldev);
+	int ret;
+
+	comp_master->ops = &mei_pxp_ops;
+	comp_master->tee_dev = dev;
+	ret = component_bind_all(dev, comp_master);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static void mei_component_master_unbind(struct device *dev)
+{
+	struct mei_cl_device *cldev = to_mei_cl_device(dev);
+	struct i915_pxp_component *comp_master = mei_cldev_get_drvdata(cldev);
+
+	component_unbind_all(dev, comp_master);
+}
+
+static const struct component_master_ops mei_component_master_ops = {
+	.bind = mei_component_master_bind,
+	.unbind = mei_component_master_unbind,
+};
+
+/**
+ * mei_pxp_component_match - compare function for matching mei pxp.
+ *
+ *    The function checks if the driver is i915, the subcomponent is PXP
+ *    and the grand parent of pxp and the parent of i915 are the same
+ *    PCH device.
+ *
+ * @dev: master device
+ * @subcomponent: subcomponent to match (I915_COMPONENT_PXP)
+ * @data: compare data (mei pxp device)
+ *
+ * Return:
+ * * 1 - if components match
+ * * 0 - otherwise
+ */
+static int mei_pxp_component_match(struct device *dev, int subcomponent,
+				   void *data)
+{
+	struct device *base = data;
+
+	if (strcmp(dev->driver->name, "i915") ||
+	    subcomponent != I915_COMPONENT_PXP)
+		return 0;
+
+	base = base->parent;
+	if (!base)
+		return 0;
+
+	base = base->parent;
+	dev = dev->parent;
+
+	return (base && dev && dev == base);
+}
+
+static int mei_pxp_probe(struct mei_cl_device *cldev,
+			 const struct mei_cl_device_id *id)
+{
+	struct i915_pxp_component *comp_master;
+	struct component_match *master_match;
+	int ret;
+
+	ret = mei_cldev_enable(cldev);
+	if (ret < 0) {
+		dev_err(&cldev->dev, "mei_cldev_enable Failed. %d\n", ret);
+		goto enable_err_exit;
+	}
+
+	comp_master = kzalloc(sizeof(*comp_master), GFP_KERNEL);
+	if (!comp_master) {
+		ret = -ENOMEM;
+		goto err_exit;
+	}
+
+	master_match = NULL;
+	component_match_add_typed(&cldev->dev, &master_match,
+				  mei_pxp_component_match, &cldev->dev);
+	if (IS_ERR_OR_NULL(master_match)) {
+		ret = -ENOMEM;
+		goto err_exit;
+	}
+
+	mei_cldev_set_drvdata(cldev, comp_master);
+	ret = component_master_add_with_match(&cldev->dev,
+					      &mei_component_master_ops,
+					      master_match);
+	if (ret < 0) {
+		dev_err(&cldev->dev, "Master comp add failed %d\n", ret);
+		goto err_exit;
+	}
+
+	return 0;
+
+err_exit:
+	mei_cldev_set_drvdata(cldev, NULL);
+	kfree(comp_master);
+	mei_cldev_disable(cldev);
+enable_err_exit:
+	return ret;
+}
+
+static void mei_pxp_remove(struct mei_cl_device *cldev)
+{
+	struct i915_pxp_component *comp_master = mei_cldev_get_drvdata(cldev);
+	int ret;
+
+	component_master_del(&cldev->dev, &mei_component_master_ops);
+	kfree(comp_master);
+	mei_cldev_set_drvdata(cldev, NULL);
+
+	ret = mei_cldev_disable(cldev);
+	if (ret)
+		dev_warn(&cldev->dev, "mei_cldev_disable() failed\n");
+}
+
+/* fbf6fcf1-96cf-4e2e-a6a6-1bab8cbe36b1 : PAVP GUID*/
+#define MEI_GUID_PXP GUID_INIT(0xfbf6fcf1, 0x96cf, 0x4e2e, 0xA6, \
+			       0xa6, 0x1b, 0xab, 0x8c, 0xbe, 0x36, 0xb1)
+
+static struct mei_cl_device_id mei_pxp_tbl[] = {
+	{ .uuid = MEI_GUID_PXP, .version = MEI_CL_VERSION_ANY },
+	{ }
+};
+MODULE_DEVICE_TABLE(mei, mei_pxp_tbl);
+
+static struct mei_cl_driver mei_pxp_driver = {
+	.id_table = mei_pxp_tbl,
+	.name = KBUILD_MODNAME,
+	.probe = mei_pxp_probe,
+	.remove	= mei_pxp_remove,
+};
+
+module_mei_cl_driver(mei_pxp_driver);
+
+MODULE_AUTHOR("Intel Corporation");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("MEI PXP");
diff --git a/drivers/misc/mei/pxp/mei_pxp.h b/drivers/misc/mei/pxp/mei_pxp.h
new file mode 100644
index 000000000000..e7b15373fefd
--- /dev/null
+++ b/drivers/misc/mei/pxp/mei_pxp.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright © 2020 Intel Corporation
+ *
+ * Authors:
+ * Vitaly Lubart <vitaly.lubart@intel.com>
+ */
+
+#ifndef __MEI_PXP_H__
+#define __MEI_PXP_H__
+
+/* me_pxp_status: Enumeration of all PXP Status Codes */
+enum me_pxp_status {
+	ME_PXP_STATUS_SUCCESS			= 0x0000,
+
+};
+
+#endif /* __MEI_PXP_H__ */
-- 
2.32.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v6 03/15] drm/i915/pxp: define PXP device flag and kconfig
  2021-07-29  2:00 ` [Intel-gfx] " Daniele Ceraolo Spurio
@ 2021-07-29  2:00   ` Daniele Ceraolo Spurio
  -1 siblings, 0 replies; 64+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-07-29  2:00 UTC (permalink / raw)
  To: intel-gfx; +Cc: Daniele Ceraolo Spurio, dri-devel, Rodrigo Vivi

Ahead of the PXP implementation, define the relevant define flag and
kconfig option.

v2: flip kconfig default to N. Some machines have IFWIs that do not
support PXP, so we need it to be an opt-in until we add support to query
the caps from the mei device.

Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
---
 drivers/gpu/drm/i915/Kconfig             | 11 +++++++++++
 drivers/gpu/drm/i915/i915_drv.h          |  4 ++++
 drivers/gpu/drm/i915/intel_device_info.h |  1 +
 3 files changed, 16 insertions(+)

diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
index f960f5d7664e..5987c3d5d9fb 100644
--- a/drivers/gpu/drm/i915/Kconfig
+++ b/drivers/gpu/drm/i915/Kconfig
@@ -131,6 +131,17 @@ config DRM_I915_GVT_KVMGT
 	  Choose this option if you want to enable KVMGT support for
 	  Intel GVT-g.
 
+config DRM_I915_PXP
+	bool "Enable Intel PXP support for Intel Gen12+ platform"
+	depends on DRM_I915
+	depends on INTEL_MEI && INTEL_MEI_PXP
+	default n
+	help
+	  PXP (Protected Xe Path) is an i915 component, available on GEN12+
+	  GPUs, that helps to establish the hardware protected session and
+	  manage the status of the alive software session, as well as its life
+	  cycle.
+
 menu "drm/i915 Debugging"
 depends on DRM_I915
 depends on EXPERT
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 70bef688c6da..fa2bb791bcaa 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1724,6 +1724,10 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
 
 #define HAS_VRR(i915)	(GRAPHICS_VER(i915) >= 12)
 
+#define HAS_PXP(dev_priv) (IS_ENABLED(CONFIG_DRM_I915_PXP) && \
+			   INTEL_INFO(dev_priv)->has_pxp) && \
+			   VDBOX_MASK(&dev_priv->gt)
+
 /* Only valid when HAS_DISPLAY() is true */
 #define INTEL_DISPLAY_ENABLED(dev_priv) \
 	(drm_WARN_ON(&(dev_priv)->drm, !HAS_DISPLAY(dev_priv)), !(dev_priv)->params.disable_display)
diff --git a/drivers/gpu/drm/i915/intel_device_info.h b/drivers/gpu/drm/i915/intel_device_info.h
index 121d6d9afd3a..e896dd60579b 100644
--- a/drivers/gpu/drm/i915/intel_device_info.h
+++ b/drivers/gpu/drm/i915/intel_device_info.h
@@ -134,6 +134,7 @@ enum intel_ppgtt_type {
 	func(has_logical_ring_contexts); \
 	func(has_logical_ring_elsq); \
 	func(has_pooled_eu); \
+	func(has_pxp); \
 	func(has_rc6); \
 	func(has_rc6p); \
 	func(has_rps); \
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [Intel-gfx] [PATCH v6 03/15] drm/i915/pxp: define PXP device flag and kconfig
@ 2021-07-29  2:00   ` Daniele Ceraolo Spurio
  0 siblings, 0 replies; 64+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-07-29  2:00 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel

Ahead of the PXP implementation, define the relevant define flag and
kconfig option.

v2: flip kconfig default to N. Some machines have IFWIs that do not
support PXP, so we need it to be an opt-in until we add support to query
the caps from the mei device.

Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
---
 drivers/gpu/drm/i915/Kconfig             | 11 +++++++++++
 drivers/gpu/drm/i915/i915_drv.h          |  4 ++++
 drivers/gpu/drm/i915/intel_device_info.h |  1 +
 3 files changed, 16 insertions(+)

diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
index f960f5d7664e..5987c3d5d9fb 100644
--- a/drivers/gpu/drm/i915/Kconfig
+++ b/drivers/gpu/drm/i915/Kconfig
@@ -131,6 +131,17 @@ config DRM_I915_GVT_KVMGT
 	  Choose this option if you want to enable KVMGT support for
 	  Intel GVT-g.
 
+config DRM_I915_PXP
+	bool "Enable Intel PXP support for Intel Gen12+ platform"
+	depends on DRM_I915
+	depends on INTEL_MEI && INTEL_MEI_PXP
+	default n
+	help
+	  PXP (Protected Xe Path) is an i915 component, available on GEN12+
+	  GPUs, that helps to establish the hardware protected session and
+	  manage the status of the alive software session, as well as its life
+	  cycle.
+
 menu "drm/i915 Debugging"
 depends on DRM_I915
 depends on EXPERT
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 70bef688c6da..fa2bb791bcaa 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1724,6 +1724,10 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
 
 #define HAS_VRR(i915)	(GRAPHICS_VER(i915) >= 12)
 
+#define HAS_PXP(dev_priv) (IS_ENABLED(CONFIG_DRM_I915_PXP) && \
+			   INTEL_INFO(dev_priv)->has_pxp) && \
+			   VDBOX_MASK(&dev_priv->gt)
+
 /* Only valid when HAS_DISPLAY() is true */
 #define INTEL_DISPLAY_ENABLED(dev_priv) \
 	(drm_WARN_ON(&(dev_priv)->drm, !HAS_DISPLAY(dev_priv)), !(dev_priv)->params.disable_display)
diff --git a/drivers/gpu/drm/i915/intel_device_info.h b/drivers/gpu/drm/i915/intel_device_info.h
index 121d6d9afd3a..e896dd60579b 100644
--- a/drivers/gpu/drm/i915/intel_device_info.h
+++ b/drivers/gpu/drm/i915/intel_device_info.h
@@ -134,6 +134,7 @@ enum intel_ppgtt_type {
 	func(has_logical_ring_contexts); \
 	func(has_logical_ring_elsq); \
 	func(has_pooled_eu); \
+	func(has_pxp); \
 	func(has_rc6); \
 	func(has_rc6p); \
 	func(has_rps); \
-- 
2.32.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v6 04/15] drm/i915/pxp: allocate a vcs context for pxp usage
  2021-07-29  2:00 ` [Intel-gfx] " Daniele Ceraolo Spurio
@ 2021-07-29  2:00   ` Daniele Ceraolo Spurio
  -1 siblings, 0 replies; 64+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-07-29  2:00 UTC (permalink / raw)
  To: intel-gfx; +Cc: Rodrigo Vivi, Daniele Ceraolo Spurio, dri-devel, Chris Wilson

The context is required to send the session termination commands to the
VCS, which will be implemented in a follow-up patch. We can also use the
presence of the context as a check of pxp initialization completion.

v2: use perma-pinned context (Chris)
v3: rename pinned_context functions (Chris)
v4: split export of pinned_context functions to a separate patch (Rodrigo)

Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
---
 drivers/gpu/drm/i915/Makefile              |  4 ++
 drivers/gpu/drm/i915/gt/intel_engine.h     |  2 +
 drivers/gpu/drm/i915/gt/intel_gt.c         |  5 ++
 drivers/gpu/drm/i915/gt/intel_gt_types.h   |  3 ++
 drivers/gpu/drm/i915/pxp/intel_pxp.c       | 62 ++++++++++++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp.h       | 35 ++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_types.h | 15 ++++++
 7 files changed, 126 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp.c
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp.h
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_types.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index a985c92c8c19..4adb5e726794 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -275,6 +275,10 @@ i915-y += \
 
 i915-y += i915_perf.o
 
+# Protected execution platform (PXP) support
+i915-$(CONFIG_DRM_I915_PXP) += \
+	pxp/intel_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) += \
diff --git a/drivers/gpu/drm/i915/gt/intel_engine.h b/drivers/gpu/drm/i915/gt/intel_engine.h
index c2a5640ae055..66d674b362ed 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine.h
@@ -175,6 +175,8 @@ intel_write_status_page(struct intel_engine_cs *engine, int reg, u32 value)
 #define I915_GEM_HWS_SEQNO		0x40
 #define I915_GEM_HWS_SEQNO_ADDR		(I915_GEM_HWS_SEQNO * sizeof(u32))
 #define I915_GEM_HWS_MIGRATE		(0x42 * sizeof(u32))
+#define I915_GEM_HWS_PXP		0x60
+#define I915_GEM_HWS_PXP_ADDR		(I915_GEM_HWS_PXP * sizeof(u32))
 #define I915_GEM_HWS_SCRATCH		0x80
 
 #define I915_HWS_CSB_BUF0_INDEX		0x10
diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c
index a64aa43f7cd9..fc73a4ef067f 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt.c
@@ -21,6 +21,7 @@
 #include "intel_uncore.h"
 #include "intel_pm.h"
 #include "shmem_utils.h"
+#include "pxp/intel_pxp.h"
 
 void intel_gt_init_early(struct intel_gt *gt, struct drm_i915_private *i915)
 {
@@ -662,6 +663,8 @@ int intel_gt_init(struct intel_gt *gt)
 
 	intel_migrate_init(&gt->migrate, gt);
 
+	intel_pxp_init(&gt->pxp);
+
 	goto out_fw;
 err_gt:
 	__intel_gt_disable(gt);
@@ -697,6 +700,8 @@ void intel_gt_driver_unregister(struct intel_gt *gt)
 
 	intel_rps_driver_unregister(&gt->rps);
 
+	intel_pxp_fini(&gt->pxp);
+
 	/*
 	 * Upon unregistering the device to prevent any new users, cancel
 	 * all in-flight requests so that we can quickly unbind the active
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_types.h b/drivers/gpu/drm/i915/gt/intel_gt_types.h
index 97a5075288d2..b5f7b1b32ac9 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_types.h
@@ -26,6 +26,7 @@
 #include "intel_rps_types.h"
 #include "intel_migrate_types.h"
 #include "intel_wakeref.h"
+#include "pxp/intel_pxp_types.h"
 
 struct drm_i915_private;
 struct i915_ggtt;
@@ -185,6 +186,8 @@ struct intel_gt {
 		/* Slice/subslice/EU info */
 		struct sseu_dev_info sseu;
 	} info;
+
+	struct intel_pxp pxp;
 };
 
 enum intel_gt_scratch_field {
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
new file mode 100644
index 000000000000..7b2053902146
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright(c) 2020 Intel Corporation.
+ */
+#include "intel_pxp.h"
+#include "gt/intel_context.h"
+#include "i915_drv.h"
+
+static int create_vcs_context(struct intel_pxp *pxp)
+{
+	static struct lock_class_key pxp_lock;
+	struct intel_gt *gt = pxp_to_gt(pxp);
+	struct intel_engine_cs *engine;
+	struct intel_context *ce;
+
+	/*
+	 * Find the first VCS engine present. We're guaranteed there is one
+	 * if we're in this function due to the check in has_pxp
+	 */
+	for (engine = gt->engine_class[VIDEO_DECODE_CLASS][0]; !engine; engine++);
+	GEM_BUG_ON(!engine || engine->class != VIDEO_DECODE_CLASS);
+
+	ce = intel_engine_create_pinned_context(engine, engine->gt->vm, SZ_4K,
+						I915_GEM_HWS_PXP_ADDR,
+						&pxp_lock, "pxp_context");
+	if (IS_ERR(ce)) {
+		drm_err(&gt->i915->drm, "failed to create VCS ctx for PXP\n");
+		return PTR_ERR(ce);
+	}
+
+	pxp->ce = ce;
+
+	return 0;
+}
+
+static void destroy_vcs_context(struct intel_pxp *pxp)
+{
+	intel_engine_destroy_pinned_context(fetch_and_zero(&pxp->ce));
+}
+
+void intel_pxp_init(struct intel_pxp *pxp)
+{
+	struct intel_gt *gt = pxp_to_gt(pxp);
+	int ret;
+
+	if (!HAS_PXP(gt->i915))
+		return;
+
+	ret = create_vcs_context(pxp);
+	if (ret)
+		return;
+
+	drm_info(&gt->i915->drm, "Protected Xe Path (PXP) protected content support initialized\n");
+}
+
+void intel_pxp_fini(struct intel_pxp *pxp)
+{
+	if (!intel_pxp_is_enabled(pxp))
+		return;
+
+	destroy_vcs_context(pxp);
+}
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
new file mode 100644
index 000000000000..e87550fb9821
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright(c) 2020, Intel Corporation. All rights reserved.
+ */
+
+#ifndef __INTEL_PXP_H__
+#define __INTEL_PXP_H__
+
+#include "gt/intel_gt_types.h"
+#include "intel_pxp_types.h"
+
+static inline struct intel_gt *pxp_to_gt(const struct intel_pxp *pxp)
+{
+	return container_of(pxp, struct intel_gt, pxp);
+}
+
+static inline bool intel_pxp_is_enabled(const struct intel_pxp *pxp)
+{
+	return pxp->ce;
+}
+
+#ifdef CONFIG_DRM_I915_PXP
+void intel_pxp_init(struct intel_pxp *pxp);
+void intel_pxp_fini(struct intel_pxp *pxp);
+#else
+static inline void intel_pxp_init(struct intel_pxp *pxp)
+{
+}
+
+static inline void intel_pxp_fini(struct intel_pxp *pxp)
+{
+}
+#endif
+
+#endif /* __INTEL_PXP_H__ */
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
new file mode 100644
index 000000000000..bd12c520e60a
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright(c) 2020, Intel Corporation. All rights reserved.
+ */
+
+#ifndef __INTEL_PXP_TYPES_H__
+#define __INTEL_PXP_TYPES_H__
+
+struct intel_context;
+
+struct intel_pxp {
+	struct intel_context *ce;
+};
+
+#endif /* __INTEL_PXP_TYPES_H__ */
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [Intel-gfx] [PATCH v6 04/15] drm/i915/pxp: allocate a vcs context for pxp usage
@ 2021-07-29  2:00   ` Daniele Ceraolo Spurio
  0 siblings, 0 replies; 64+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-07-29  2:00 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Chris Wilson

The context is required to send the session termination commands to the
VCS, which will be implemented in a follow-up patch. We can also use the
presence of the context as a check of pxp initialization completion.

v2: use perma-pinned context (Chris)
v3: rename pinned_context functions (Chris)
v4: split export of pinned_context functions to a separate patch (Rodrigo)

Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
---
 drivers/gpu/drm/i915/Makefile              |  4 ++
 drivers/gpu/drm/i915/gt/intel_engine.h     |  2 +
 drivers/gpu/drm/i915/gt/intel_gt.c         |  5 ++
 drivers/gpu/drm/i915/gt/intel_gt_types.h   |  3 ++
 drivers/gpu/drm/i915/pxp/intel_pxp.c       | 62 ++++++++++++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp.h       | 35 ++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_types.h | 15 ++++++
 7 files changed, 126 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp.c
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp.h
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_types.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index a985c92c8c19..4adb5e726794 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -275,6 +275,10 @@ i915-y += \
 
 i915-y += i915_perf.o
 
+# Protected execution platform (PXP) support
+i915-$(CONFIG_DRM_I915_PXP) += \
+	pxp/intel_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) += \
diff --git a/drivers/gpu/drm/i915/gt/intel_engine.h b/drivers/gpu/drm/i915/gt/intel_engine.h
index c2a5640ae055..66d674b362ed 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine.h
@@ -175,6 +175,8 @@ intel_write_status_page(struct intel_engine_cs *engine, int reg, u32 value)
 #define I915_GEM_HWS_SEQNO		0x40
 #define I915_GEM_HWS_SEQNO_ADDR		(I915_GEM_HWS_SEQNO * sizeof(u32))
 #define I915_GEM_HWS_MIGRATE		(0x42 * sizeof(u32))
+#define I915_GEM_HWS_PXP		0x60
+#define I915_GEM_HWS_PXP_ADDR		(I915_GEM_HWS_PXP * sizeof(u32))
 #define I915_GEM_HWS_SCRATCH		0x80
 
 #define I915_HWS_CSB_BUF0_INDEX		0x10
diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c
index a64aa43f7cd9..fc73a4ef067f 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt.c
@@ -21,6 +21,7 @@
 #include "intel_uncore.h"
 #include "intel_pm.h"
 #include "shmem_utils.h"
+#include "pxp/intel_pxp.h"
 
 void intel_gt_init_early(struct intel_gt *gt, struct drm_i915_private *i915)
 {
@@ -662,6 +663,8 @@ int intel_gt_init(struct intel_gt *gt)
 
 	intel_migrate_init(&gt->migrate, gt);
 
+	intel_pxp_init(&gt->pxp);
+
 	goto out_fw;
 err_gt:
 	__intel_gt_disable(gt);
@@ -697,6 +700,8 @@ void intel_gt_driver_unregister(struct intel_gt *gt)
 
 	intel_rps_driver_unregister(&gt->rps);
 
+	intel_pxp_fini(&gt->pxp);
+
 	/*
 	 * Upon unregistering the device to prevent any new users, cancel
 	 * all in-flight requests so that we can quickly unbind the active
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_types.h b/drivers/gpu/drm/i915/gt/intel_gt_types.h
index 97a5075288d2..b5f7b1b32ac9 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_types.h
@@ -26,6 +26,7 @@
 #include "intel_rps_types.h"
 #include "intel_migrate_types.h"
 #include "intel_wakeref.h"
+#include "pxp/intel_pxp_types.h"
 
 struct drm_i915_private;
 struct i915_ggtt;
@@ -185,6 +186,8 @@ struct intel_gt {
 		/* Slice/subslice/EU info */
 		struct sseu_dev_info sseu;
 	} info;
+
+	struct intel_pxp pxp;
 };
 
 enum intel_gt_scratch_field {
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
new file mode 100644
index 000000000000..7b2053902146
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright(c) 2020 Intel Corporation.
+ */
+#include "intel_pxp.h"
+#include "gt/intel_context.h"
+#include "i915_drv.h"
+
+static int create_vcs_context(struct intel_pxp *pxp)
+{
+	static struct lock_class_key pxp_lock;
+	struct intel_gt *gt = pxp_to_gt(pxp);
+	struct intel_engine_cs *engine;
+	struct intel_context *ce;
+
+	/*
+	 * Find the first VCS engine present. We're guaranteed there is one
+	 * if we're in this function due to the check in has_pxp
+	 */
+	for (engine = gt->engine_class[VIDEO_DECODE_CLASS][0]; !engine; engine++);
+	GEM_BUG_ON(!engine || engine->class != VIDEO_DECODE_CLASS);
+
+	ce = intel_engine_create_pinned_context(engine, engine->gt->vm, SZ_4K,
+						I915_GEM_HWS_PXP_ADDR,
+						&pxp_lock, "pxp_context");
+	if (IS_ERR(ce)) {
+		drm_err(&gt->i915->drm, "failed to create VCS ctx for PXP\n");
+		return PTR_ERR(ce);
+	}
+
+	pxp->ce = ce;
+
+	return 0;
+}
+
+static void destroy_vcs_context(struct intel_pxp *pxp)
+{
+	intel_engine_destroy_pinned_context(fetch_and_zero(&pxp->ce));
+}
+
+void intel_pxp_init(struct intel_pxp *pxp)
+{
+	struct intel_gt *gt = pxp_to_gt(pxp);
+	int ret;
+
+	if (!HAS_PXP(gt->i915))
+		return;
+
+	ret = create_vcs_context(pxp);
+	if (ret)
+		return;
+
+	drm_info(&gt->i915->drm, "Protected Xe Path (PXP) protected content support initialized\n");
+}
+
+void intel_pxp_fini(struct intel_pxp *pxp)
+{
+	if (!intel_pxp_is_enabled(pxp))
+		return;
+
+	destroy_vcs_context(pxp);
+}
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
new file mode 100644
index 000000000000..e87550fb9821
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright(c) 2020, Intel Corporation. All rights reserved.
+ */
+
+#ifndef __INTEL_PXP_H__
+#define __INTEL_PXP_H__
+
+#include "gt/intel_gt_types.h"
+#include "intel_pxp_types.h"
+
+static inline struct intel_gt *pxp_to_gt(const struct intel_pxp *pxp)
+{
+	return container_of(pxp, struct intel_gt, pxp);
+}
+
+static inline bool intel_pxp_is_enabled(const struct intel_pxp *pxp)
+{
+	return pxp->ce;
+}
+
+#ifdef CONFIG_DRM_I915_PXP
+void intel_pxp_init(struct intel_pxp *pxp);
+void intel_pxp_fini(struct intel_pxp *pxp);
+#else
+static inline void intel_pxp_init(struct intel_pxp *pxp)
+{
+}
+
+static inline void intel_pxp_fini(struct intel_pxp *pxp)
+{
+}
+#endif
+
+#endif /* __INTEL_PXP_H__ */
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
new file mode 100644
index 000000000000..bd12c520e60a
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright(c) 2020, Intel Corporation. All rights reserved.
+ */
+
+#ifndef __INTEL_PXP_TYPES_H__
+#define __INTEL_PXP_TYPES_H__
+
+struct intel_context;
+
+struct intel_pxp {
+	struct intel_context *ce;
+};
+
+#endif /* __INTEL_PXP_TYPES_H__ */
-- 
2.32.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v6 05/15] drm/i915/pxp: Implement funcs to create the TEE channel
  2021-07-29  2:00 ` [Intel-gfx] " Daniele Ceraolo Spurio
@ 2021-07-29  2:00   ` Daniele Ceraolo Spurio
  -1 siblings, 0 replies; 64+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-07-29  2:00 UTC (permalink / raw)
  To: intel-gfx
  Cc: Huang, Sean Z, dri-devel, Chris Wilson, Daniele Ceraolo Spurio,
	Huang, Rodrigo Vivi

From: "Huang, Sean Z" <sean.z.huang@intel.com>

Implement the funcs to create the TEE channel, so kernel can
send the TEE commands directly to TEE for creating the arbitrary
(default) session.

v2: fix locking, don't pollute dev_priv (Chris)

v3: wait for mei PXP component to be bound.

v4: drop the wait, as the component might be bound after i915 load
completes. We'll instead check when sending a tee message.

Signed-off-by: Huang, Sean Z <sean.z.huang@intel.com>
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
---
 drivers/gpu/drm/i915/Makefile              |  3 +-
 drivers/gpu/drm/i915/pxp/intel_pxp.c       | 13 ++++
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c   | 77 ++++++++++++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.h   | 14 ++++
 drivers/gpu/drm/i915/pxp/intel_pxp_types.h |  3 +
 5 files changed, 109 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_tee.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 4adb5e726794..db6889c7474b 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -277,7 +277,8 @@ i915-y += i915_perf.o
 
 # Protected execution platform (PXP) support
 i915-$(CONFIG_DRM_I915_PXP) += \
-	pxp/intel_pxp.o
+	pxp/intel_pxp.o \
+	pxp/intel_pxp_tee.o
 
 # Post-mortem debug and GPU hang state capture
 i915-$(CONFIG_DRM_I915_CAPTURE_ERROR) += i915_gpu_error.o
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index 7b2053902146..400deaea2d8a 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -3,6 +3,7 @@
  * Copyright(c) 2020 Intel Corporation.
  */
 #include "intel_pxp.h"
+#include "intel_pxp_tee.h"
 #include "gt/intel_context.h"
 #include "i915_drv.h"
 
@@ -50,7 +51,16 @@ void intel_pxp_init(struct intel_pxp *pxp)
 	if (ret)
 		return;
 
+	ret = intel_pxp_tee_component_init(pxp);
+	if (ret)
+		goto out_context;
+
 	drm_info(&gt->i915->drm, "Protected Xe Path (PXP) protected content support initialized\n");
+
+	return;
+
+out_context:
+	destroy_vcs_context(pxp);
 }
 
 void intel_pxp_fini(struct intel_pxp *pxp)
@@ -58,5 +68,8 @@ void intel_pxp_fini(struct intel_pxp *pxp)
 	if (!intel_pxp_is_enabled(pxp))
 		return;
 
+	intel_pxp_tee_component_fini(pxp);
+
 	destroy_vcs_context(pxp);
+
 }
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
new file mode 100644
index 000000000000..21916ec0f6ff
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright(c) 2020 Intel Corporation.
+ */
+
+#include <linux/component.h>
+#include "drm/i915_pxp_tee_interface.h"
+#include "drm/i915_component.h"
+#include "i915_drv.h"
+#include "intel_pxp.h"
+#include "intel_pxp_tee.h"
+
+static inline struct intel_pxp *i915_dev_to_pxp(struct device *i915_kdev)
+{
+	return &kdev_to_i915(i915_kdev)->gt.pxp;
+}
+
+/**
+ * i915_pxp_tee_component_bind - bind function to pass the function pointers to pxp_tee
+ * @i915_kdev: pointer to i915 kernel device
+ * @tee_kdev: pointer to tee kernel device
+ * @data: pointer to pxp_tee_master containing the function pointers
+ *
+ * This bind function is called during the system boot or resume from system sleep.
+ *
+ * Return: return 0 if successful.
+ */
+static int i915_pxp_tee_component_bind(struct device *i915_kdev,
+				       struct device *tee_kdev, void *data)
+{
+	struct intel_pxp *pxp = i915_dev_to_pxp(i915_kdev);
+
+	pxp->pxp_component = data;
+	pxp->pxp_component->tee_dev = tee_kdev;
+
+	return 0;
+}
+
+static void i915_pxp_tee_component_unbind(struct device *i915_kdev,
+					  struct device *tee_kdev, void *data)
+{
+	struct intel_pxp *pxp = i915_dev_to_pxp(i915_kdev);
+
+	pxp->pxp_component = NULL;
+}
+
+static const struct component_ops i915_pxp_tee_component_ops = {
+	.bind   = i915_pxp_tee_component_bind,
+	.unbind = i915_pxp_tee_component_unbind,
+};
+
+int intel_pxp_tee_component_init(struct intel_pxp *pxp)
+{
+	int ret;
+	struct intel_gt *gt = pxp_to_gt(pxp);
+	struct drm_i915_private *i915 = gt->i915;
+
+	ret = component_add_typed(i915->drm.dev, &i915_pxp_tee_component_ops,
+				  I915_COMPONENT_PXP);
+	if (ret < 0) {
+		drm_err(&i915->drm, "Failed to add PXP component (%d)\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+void intel_pxp_tee_component_fini(struct intel_pxp *pxp)
+{
+	struct intel_gt *gt = pxp_to_gt(pxp);
+	struct drm_i915_private *i915 = gt->i915;
+
+	if (!pxp->pxp_component)
+		return;
+
+	component_del(i915->drm.dev, &i915_pxp_tee_component_ops);
+}
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.h b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.h
new file mode 100644
index 000000000000..23d050a5d3e7
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright(c) 2020, Intel Corporation. All rights reserved.
+ */
+
+#ifndef __INTEL_PXP_TEE_H__
+#define __INTEL_PXP_TEE_H__
+
+#include "intel_pxp.h"
+
+int intel_pxp_tee_component_init(struct intel_pxp *pxp);
+void intel_pxp_tee_component_fini(struct intel_pxp *pxp);
+
+#endif /* __INTEL_PXP_TEE_H__ */
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
index bd12c520e60a..3e95d21513e8 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
@@ -7,8 +7,11 @@
 #define __INTEL_PXP_TYPES_H__
 
 struct intel_context;
+struct i915_pxp_component;
 
 struct intel_pxp {
+	struct i915_pxp_component *pxp_component;
+
 	struct intel_context *ce;
 };
 
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [Intel-gfx] [PATCH v6 05/15] drm/i915/pxp: Implement funcs to create the TEE channel
@ 2021-07-29  2:00   ` Daniele Ceraolo Spurio
  0 siblings, 0 replies; 64+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-07-29  2:00 UTC (permalink / raw)
  To: intel-gfx; +Cc: Huang, Sean Z, dri-devel, Chris Wilson, Huang

From: "Huang, Sean Z" <sean.z.huang@intel.com>

Implement the funcs to create the TEE channel, so kernel can
send the TEE commands directly to TEE for creating the arbitrary
(default) session.

v2: fix locking, don't pollute dev_priv (Chris)

v3: wait for mei PXP component to be bound.

v4: drop the wait, as the component might be bound after i915 load
completes. We'll instead check when sending a tee message.

Signed-off-by: Huang, Sean Z <sean.z.huang@intel.com>
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
---
 drivers/gpu/drm/i915/Makefile              |  3 +-
 drivers/gpu/drm/i915/pxp/intel_pxp.c       | 13 ++++
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c   | 77 ++++++++++++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.h   | 14 ++++
 drivers/gpu/drm/i915/pxp/intel_pxp_types.h |  3 +
 5 files changed, 109 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_tee.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 4adb5e726794..db6889c7474b 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -277,7 +277,8 @@ i915-y += i915_perf.o
 
 # Protected execution platform (PXP) support
 i915-$(CONFIG_DRM_I915_PXP) += \
-	pxp/intel_pxp.o
+	pxp/intel_pxp.o \
+	pxp/intel_pxp_tee.o
 
 # Post-mortem debug and GPU hang state capture
 i915-$(CONFIG_DRM_I915_CAPTURE_ERROR) += i915_gpu_error.o
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index 7b2053902146..400deaea2d8a 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -3,6 +3,7 @@
  * Copyright(c) 2020 Intel Corporation.
  */
 #include "intel_pxp.h"
+#include "intel_pxp_tee.h"
 #include "gt/intel_context.h"
 #include "i915_drv.h"
 
@@ -50,7 +51,16 @@ void intel_pxp_init(struct intel_pxp *pxp)
 	if (ret)
 		return;
 
+	ret = intel_pxp_tee_component_init(pxp);
+	if (ret)
+		goto out_context;
+
 	drm_info(&gt->i915->drm, "Protected Xe Path (PXP) protected content support initialized\n");
+
+	return;
+
+out_context:
+	destroy_vcs_context(pxp);
 }
 
 void intel_pxp_fini(struct intel_pxp *pxp)
@@ -58,5 +68,8 @@ void intel_pxp_fini(struct intel_pxp *pxp)
 	if (!intel_pxp_is_enabled(pxp))
 		return;
 
+	intel_pxp_tee_component_fini(pxp);
+
 	destroy_vcs_context(pxp);
+
 }
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
new file mode 100644
index 000000000000..21916ec0f6ff
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright(c) 2020 Intel Corporation.
+ */
+
+#include <linux/component.h>
+#include "drm/i915_pxp_tee_interface.h"
+#include "drm/i915_component.h"
+#include "i915_drv.h"
+#include "intel_pxp.h"
+#include "intel_pxp_tee.h"
+
+static inline struct intel_pxp *i915_dev_to_pxp(struct device *i915_kdev)
+{
+	return &kdev_to_i915(i915_kdev)->gt.pxp;
+}
+
+/**
+ * i915_pxp_tee_component_bind - bind function to pass the function pointers to pxp_tee
+ * @i915_kdev: pointer to i915 kernel device
+ * @tee_kdev: pointer to tee kernel device
+ * @data: pointer to pxp_tee_master containing the function pointers
+ *
+ * This bind function is called during the system boot or resume from system sleep.
+ *
+ * Return: return 0 if successful.
+ */
+static int i915_pxp_tee_component_bind(struct device *i915_kdev,
+				       struct device *tee_kdev, void *data)
+{
+	struct intel_pxp *pxp = i915_dev_to_pxp(i915_kdev);
+
+	pxp->pxp_component = data;
+	pxp->pxp_component->tee_dev = tee_kdev;
+
+	return 0;
+}
+
+static void i915_pxp_tee_component_unbind(struct device *i915_kdev,
+					  struct device *tee_kdev, void *data)
+{
+	struct intel_pxp *pxp = i915_dev_to_pxp(i915_kdev);
+
+	pxp->pxp_component = NULL;
+}
+
+static const struct component_ops i915_pxp_tee_component_ops = {
+	.bind   = i915_pxp_tee_component_bind,
+	.unbind = i915_pxp_tee_component_unbind,
+};
+
+int intel_pxp_tee_component_init(struct intel_pxp *pxp)
+{
+	int ret;
+	struct intel_gt *gt = pxp_to_gt(pxp);
+	struct drm_i915_private *i915 = gt->i915;
+
+	ret = component_add_typed(i915->drm.dev, &i915_pxp_tee_component_ops,
+				  I915_COMPONENT_PXP);
+	if (ret < 0) {
+		drm_err(&i915->drm, "Failed to add PXP component (%d)\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+void intel_pxp_tee_component_fini(struct intel_pxp *pxp)
+{
+	struct intel_gt *gt = pxp_to_gt(pxp);
+	struct drm_i915_private *i915 = gt->i915;
+
+	if (!pxp->pxp_component)
+		return;
+
+	component_del(i915->drm.dev, &i915_pxp_tee_component_ops);
+}
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.h b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.h
new file mode 100644
index 000000000000..23d050a5d3e7
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright(c) 2020, Intel Corporation. All rights reserved.
+ */
+
+#ifndef __INTEL_PXP_TEE_H__
+#define __INTEL_PXP_TEE_H__
+
+#include "intel_pxp.h"
+
+int intel_pxp_tee_component_init(struct intel_pxp *pxp);
+void intel_pxp_tee_component_fini(struct intel_pxp *pxp);
+
+#endif /* __INTEL_PXP_TEE_H__ */
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
index bd12c520e60a..3e95d21513e8 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
@@ -7,8 +7,11 @@
 #define __INTEL_PXP_TYPES_H__
 
 struct intel_context;
+struct i915_pxp_component;
 
 struct intel_pxp {
+	struct i915_pxp_component *pxp_component;
+
 	struct intel_context *ce;
 };
 
-- 
2.32.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v6 06/15] drm/i915/pxp: set KCR reg init
  2021-07-29  2:00 ` [Intel-gfx] " Daniele Ceraolo Spurio
@ 2021-07-29  2:00   ` Daniele Ceraolo Spurio
  -1 siblings, 0 replies; 64+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-07-29  2:00 UTC (permalink / raw)
  To: intel-gfx; +Cc: Sean Z, Daniele Ceraolo Spurio, Huang, dri-devel, Rodrigo Vivi

The setting is required by hardware to allow us doing further protection
operation such as sending commands to GPU or TEE. The register needs to
be re-programmed on resume, so for simplicitly we bundle the programming
with the component binding, which is automatically called on resume.

Further HW set-up operations will be added in the same location in
follow-up patches, so get ready for them by using a couple of
init/fini_hw wrappers instead of calling the KCR funcs directly.

v3: move programming to component binding function, rework commit msg

Signed-off-by: Huang, Sean Z <sean.z.huang@intel.com>
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
---
 drivers/gpu/drm/i915/pxp/intel_pxp.c     | 27 ++++++++++++++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp.h     |  3 +++
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c |  5 +++++
 3 files changed, 35 insertions(+)

diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index 400deaea2d8a..66a98feb33ab 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -7,6 +7,24 @@
 #include "gt/intel_context.h"
 #include "i915_drv.h"
 
+/* KCR register definitions */
+#define KCR_INIT _MMIO(0x320f0)
+
+/* Setting KCR Init bit is required after system boot */
+#define KCR_INIT_ALLOW_DISPLAY_ME_WRITES REG_BIT(14)
+
+static void kcr_pxp_enable(struct intel_gt *gt)
+{
+	intel_uncore_write(gt->uncore, KCR_INIT,
+			   _MASKED_BIT_ENABLE(KCR_INIT_ALLOW_DISPLAY_ME_WRITES));
+}
+
+static void kcr_pxp_disable(struct intel_gt *gt)
+{
+	intel_uncore_write(gt->uncore, KCR_INIT,
+			   _MASKED_BIT_DISABLE(KCR_INIT_ALLOW_DISPLAY_ME_WRITES));
+}
+
 static int create_vcs_context(struct intel_pxp *pxp)
 {
 	static struct lock_class_key pxp_lock;
@@ -71,5 +89,14 @@ void intel_pxp_fini(struct intel_pxp *pxp)
 	intel_pxp_tee_component_fini(pxp);
 
 	destroy_vcs_context(pxp);
+}
+
+void intel_pxp_init_hw(struct intel_pxp *pxp)
+{
+	kcr_pxp_enable(pxp_to_gt(pxp));
+}
 
+void intel_pxp_fini_hw(struct intel_pxp *pxp)
+{
+	kcr_pxp_disable(pxp_to_gt(pxp));
 }
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
index e87550fb9821..5427c3b28aa9 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
@@ -22,6 +22,9 @@ static inline bool intel_pxp_is_enabled(const struct intel_pxp *pxp)
 #ifdef CONFIG_DRM_I915_PXP
 void intel_pxp_init(struct intel_pxp *pxp);
 void intel_pxp_fini(struct intel_pxp *pxp);
+
+void intel_pxp_init_hw(struct intel_pxp *pxp);
+void intel_pxp_fini_hw(struct intel_pxp *pxp);
 #else
 static inline void intel_pxp_init(struct intel_pxp *pxp)
 {
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
index 21916ec0f6ff..33130fb7113b 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
@@ -33,6 +33,9 @@ static int i915_pxp_tee_component_bind(struct device *i915_kdev,
 	pxp->pxp_component = data;
 	pxp->pxp_component->tee_dev = tee_kdev;
 
+	/* the component is required to fully start the PXP HW */
+	intel_pxp_init_hw(pxp);
+
 	return 0;
 }
 
@@ -41,6 +44,8 @@ static void i915_pxp_tee_component_unbind(struct device *i915_kdev,
 {
 	struct intel_pxp *pxp = i915_dev_to_pxp(i915_kdev);
 
+	intel_pxp_fini_hw(pxp);
+
 	pxp->pxp_component = NULL;
 }
 
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [Intel-gfx] [PATCH v6 06/15] drm/i915/pxp: set KCR reg init
@ 2021-07-29  2:00   ` Daniele Ceraolo Spurio
  0 siblings, 0 replies; 64+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-07-29  2:00 UTC (permalink / raw)
  To: intel-gfx; +Cc: Sean Z, Huang, dri-devel

The setting is required by hardware to allow us doing further protection
operation such as sending commands to GPU or TEE. The register needs to
be re-programmed on resume, so for simplicitly we bundle the programming
with the component binding, which is automatically called on resume.

Further HW set-up operations will be added in the same location in
follow-up patches, so get ready for them by using a couple of
init/fini_hw wrappers instead of calling the KCR funcs directly.

v3: move programming to component binding function, rework commit msg

Signed-off-by: Huang, Sean Z <sean.z.huang@intel.com>
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
---
 drivers/gpu/drm/i915/pxp/intel_pxp.c     | 27 ++++++++++++++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp.h     |  3 +++
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c |  5 +++++
 3 files changed, 35 insertions(+)

diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index 400deaea2d8a..66a98feb33ab 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -7,6 +7,24 @@
 #include "gt/intel_context.h"
 #include "i915_drv.h"
 
+/* KCR register definitions */
+#define KCR_INIT _MMIO(0x320f0)
+
+/* Setting KCR Init bit is required after system boot */
+#define KCR_INIT_ALLOW_DISPLAY_ME_WRITES REG_BIT(14)
+
+static void kcr_pxp_enable(struct intel_gt *gt)
+{
+	intel_uncore_write(gt->uncore, KCR_INIT,
+			   _MASKED_BIT_ENABLE(KCR_INIT_ALLOW_DISPLAY_ME_WRITES));
+}
+
+static void kcr_pxp_disable(struct intel_gt *gt)
+{
+	intel_uncore_write(gt->uncore, KCR_INIT,
+			   _MASKED_BIT_DISABLE(KCR_INIT_ALLOW_DISPLAY_ME_WRITES));
+}
+
 static int create_vcs_context(struct intel_pxp *pxp)
 {
 	static struct lock_class_key pxp_lock;
@@ -71,5 +89,14 @@ void intel_pxp_fini(struct intel_pxp *pxp)
 	intel_pxp_tee_component_fini(pxp);
 
 	destroy_vcs_context(pxp);
+}
+
+void intel_pxp_init_hw(struct intel_pxp *pxp)
+{
+	kcr_pxp_enable(pxp_to_gt(pxp));
+}
 
+void intel_pxp_fini_hw(struct intel_pxp *pxp)
+{
+	kcr_pxp_disable(pxp_to_gt(pxp));
 }
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
index e87550fb9821..5427c3b28aa9 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
@@ -22,6 +22,9 @@ static inline bool intel_pxp_is_enabled(const struct intel_pxp *pxp)
 #ifdef CONFIG_DRM_I915_PXP
 void intel_pxp_init(struct intel_pxp *pxp);
 void intel_pxp_fini(struct intel_pxp *pxp);
+
+void intel_pxp_init_hw(struct intel_pxp *pxp);
+void intel_pxp_fini_hw(struct intel_pxp *pxp);
 #else
 static inline void intel_pxp_init(struct intel_pxp *pxp)
 {
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
index 21916ec0f6ff..33130fb7113b 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
@@ -33,6 +33,9 @@ static int i915_pxp_tee_component_bind(struct device *i915_kdev,
 	pxp->pxp_component = data;
 	pxp->pxp_component->tee_dev = tee_kdev;
 
+	/* the component is required to fully start the PXP HW */
+	intel_pxp_init_hw(pxp);
+
 	return 0;
 }
 
@@ -41,6 +44,8 @@ static void i915_pxp_tee_component_unbind(struct device *i915_kdev,
 {
 	struct intel_pxp *pxp = i915_dev_to_pxp(i915_kdev);
 
+	intel_pxp_fini_hw(pxp);
+
 	pxp->pxp_component = NULL;
 }
 
-- 
2.32.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v6 07/15] drm/i915/pxp: Create the arbitrary session after boot
  2021-07-29  2:00 ` [Intel-gfx] " Daniele Ceraolo Spurio
@ 2021-07-29  2:00   ` Daniele Ceraolo Spurio
  -1 siblings, 0 replies; 64+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-07-29  2:00 UTC (permalink / raw)
  To: intel-gfx
  Cc: Huang, Sean Z, dri-devel, Chris Wilson, Daniele Ceraolo Spurio,
	Huang, Rodrigo Vivi

From: "Huang, Sean Z" <sean.z.huang@intel.com>

Create the arbitrary session, with the fixed session id 0xf, after
system boot, for the case that application allocates the protected
buffer without establishing any protection session. Because the
hardware requires at least one alive session for protected buffer
creation. This arbitrary session will need to be re-created after
teardown or power event because hardware encryption key won't be
valid after such cases.

The session ID is exposed as part of the uapi so it can be used as part
of userspace commands.

v2: use gt->uncore->rpm (Chris)
v3: s/arb_is_in_play/arb_is_valid (Chris), move set-up to the new
    init_hw function
v4: move interface defs to separate header, set arb_is valid to false
    on fini (Rodrigo)
v5: handle async component binding

Signed-off-by: Huang, Sean Z <sean.z.huang@intel.com>
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
---
 drivers/gpu/drm/i915/Makefile                 |  1 +
 drivers/gpu/drm/i915/pxp/intel_pxp.c          |  7 ++
 drivers/gpu/drm/i915/pxp/intel_pxp.h          |  5 ++
 drivers/gpu/drm/i915/pxp/intel_pxp_session.c  | 74 ++++++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_session.h  | 15 ++++
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c      | 87 +++++++++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.h      |  3 +
 .../drm/i915/pxp/intel_pxp_tee_interface.h    | 37 ++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_types.h    | 12 +++
 include/uapi/drm/i915_drm.h                   |  3 +
 10 files changed, 244 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_session.c
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_session.h
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_tee_interface.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index db6889c7474b..278a11b991ab 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -278,6 +278,7 @@ i915-y += i915_perf.o
 # Protected execution platform (PXP) support
 i915-$(CONFIG_DRM_I915_PXP) += \
 	pxp/intel_pxp.o \
+	pxp/intel_pxp_session.o \
 	pxp/intel_pxp_tee.o
 
 # Post-mortem debug and GPU hang state capture
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index 66a98feb33ab..e1370f323126 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -3,6 +3,7 @@
  * Copyright(c) 2020 Intel Corporation.
  */
 #include "intel_pxp.h"
+#include "intel_pxp_session.h"
 #include "intel_pxp_tee.h"
 #include "gt/intel_context.h"
 #include "i915_drv.h"
@@ -65,6 +66,8 @@ void intel_pxp_init(struct intel_pxp *pxp)
 	if (!HAS_PXP(gt->i915))
 		return;
 
+	mutex_init(&pxp->tee_mutex);
+
 	ret = create_vcs_context(pxp);
 	if (ret)
 		return;
@@ -86,6 +89,8 @@ void intel_pxp_fini(struct intel_pxp *pxp)
 	if (!intel_pxp_is_enabled(pxp))
 		return;
 
+	pxp->arb_is_valid = false;
+
 	intel_pxp_tee_component_fini(pxp);
 
 	destroy_vcs_context(pxp);
@@ -94,6 +99,8 @@ void intel_pxp_fini(struct intel_pxp *pxp)
 void intel_pxp_init_hw(struct intel_pxp *pxp)
 {
 	kcr_pxp_enable(pxp_to_gt(pxp));
+
+	intel_pxp_create_arb_session(pxp);
 }
 
 void intel_pxp_fini_hw(struct intel_pxp *pxp)
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
index 5427c3b28aa9..8eeb65af78b1 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
@@ -19,6 +19,11 @@ static inline bool intel_pxp_is_enabled(const struct intel_pxp *pxp)
 	return pxp->ce;
 }
 
+static inline bool intel_pxp_is_active(const struct intel_pxp *pxp)
+{
+	return pxp->arb_is_valid;
+}
+
 #ifdef CONFIG_DRM_I915_PXP
 void intel_pxp_init(struct intel_pxp *pxp);
 void intel_pxp_fini(struct intel_pxp *pxp);
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
new file mode 100644
index 000000000000..3331868f354c
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright(c) 2020, Intel Corporation. All rights reserved.
+ */
+
+#include "drm/i915_drm.h"
+#include "i915_drv.h"
+
+#include "intel_pxp.h"
+#include "intel_pxp_session.h"
+#include "intel_pxp_tee.h"
+#include "intel_pxp_types.h"
+
+#define ARB_SESSION I915_PROTECTED_CONTENT_DEFAULT_SESSION /* shorter define */
+
+#define GEN12_KCR_SIP _MMIO(0x32260) /* KCR hwdrm session in play 0-31 */
+
+static bool intel_pxp_session_is_in_play(struct intel_pxp *pxp, u32 id)
+{
+	struct intel_gt *gt = pxp_to_gt(pxp);
+	intel_wakeref_t wakeref;
+	u32 sip = 0;
+
+	with_intel_runtime_pm(gt->uncore->rpm, wakeref)
+		sip = intel_uncore_read(gt->uncore, GEN12_KCR_SIP);
+
+	return sip & BIT(id);
+}
+
+static int pxp_wait_for_session_state(struct intel_pxp *pxp, u32 id, bool in_play)
+{
+	struct intel_gt *gt = pxp_to_gt(pxp);
+	intel_wakeref_t wakeref;
+	u32 mask = BIT(id);
+	int ret;
+
+	with_intel_runtime_pm(gt->uncore->rpm, wakeref)
+		ret = intel_wait_for_register(gt->uncore,
+					      GEN12_KCR_SIP,
+					      mask,
+					      in_play ? mask : 0,
+					      100);
+
+	return ret;
+}
+
+int intel_pxp_create_arb_session(struct intel_pxp *pxp)
+{
+	struct intel_gt *gt = pxp_to_gt(pxp);
+	int ret;
+
+	pxp->arb_is_valid = false;
+
+	if (intel_pxp_session_is_in_play(pxp, ARB_SESSION)) {
+		drm_err(&gt->i915->drm, "arb session already in play at creation time\n");
+		return -EEXIST;
+	}
+
+	ret = intel_pxp_tee_cmd_create_arb_session(pxp, ARB_SESSION);
+	if (ret) {
+		drm_err(&gt->i915->drm, "tee cmd for arb session creation failed\n");
+		return ret;
+	}
+
+	ret = pxp_wait_for_session_state(pxp, ARB_SESSION, true);
+	if (ret) {
+		drm_err(&gt->i915->drm, "arb session failed to go in play\n");
+		return ret;
+	}
+
+	pxp->arb_is_valid = true;
+
+	return 0;
+}
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.h b/drivers/gpu/drm/i915/pxp/intel_pxp_session.h
new file mode 100644
index 000000000000..316c3bebed9c
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright(c) 2020, Intel Corporation. All rights reserved.
+ */
+
+#ifndef __INTEL_PXP_SESSION_H__
+#define __INTEL_PXP_SESSION_H__
+
+#include <linux/types.h>
+
+struct intel_pxp;
+
+int intel_pxp_create_arb_session(struct intel_pxp *pxp);
+
+#endif /* __INTEL_PXP_SESSION_H__ */
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
index 33130fb7113b..3662bf67407a 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
@@ -8,13 +8,63 @@
 #include "drm/i915_component.h"
 #include "i915_drv.h"
 #include "intel_pxp.h"
+#include "intel_pxp_session.h"
 #include "intel_pxp_tee.h"
+#include "intel_pxp_tee_interface.h"
 
 static inline struct intel_pxp *i915_dev_to_pxp(struct device *i915_kdev)
 {
 	return &kdev_to_i915(i915_kdev)->gt.pxp;
 }
 
+static int intel_pxp_tee_io_message(struct intel_pxp *pxp,
+				    void *msg_in, u32 msg_in_size,
+				    void *msg_out, u32 msg_out_max_size,
+				    u32 *msg_out_rcv_size)
+{
+	struct drm_i915_private *i915 = pxp_to_gt(pxp)->i915;
+	struct i915_pxp_component *pxp_component = pxp->pxp_component;
+	int ret = 0;
+
+	mutex_lock(&pxp->tee_mutex);
+
+	/*
+	 * The binding of the component is asynchronous from i915 probe, so we
+	 * can't be sure it has happened.
+	 */
+	if (!pxp_component) {
+		ret = -ENODEV;
+		goto unlock;
+	}
+
+	ret = pxp_component->ops->send(pxp_component->tee_dev, msg_in, msg_in_size);
+	if (ret) {
+		drm_err(&i915->drm, "Failed to send PXP TEE message\n");
+		goto unlock;
+	}
+
+	ret = pxp_component->ops->recv(pxp_component->tee_dev, msg_out, msg_out_max_size);
+	if (ret < 0) {
+		drm_err(&i915->drm, "Failed to receive PXP TEE message\n");
+		goto unlock;
+	}
+
+	if (ret > msg_out_max_size) {
+		drm_err(&i915->drm,
+			"Failed to receive PXP TEE message due to unexpected output size\n");
+		ret = -ENOSPC;
+		goto unlock;
+	}
+
+	if (msg_out_rcv_size)
+		*msg_out_rcv_size = ret;
+
+	ret = 0;
+unlock:
+	mutex_unlock(&pxp->tee_mutex);
+	return ret;
+}
+
 /**
  * i915_pxp_tee_component_bind - bind function to pass the function pointers to pxp_tee
  * @i915_kdev: pointer to i915 kernel device
@@ -28,14 +78,24 @@ static inline struct intel_pxp *i915_dev_to_pxp(struct device *i915_kdev)
 static int i915_pxp_tee_component_bind(struct device *i915_kdev,
 				       struct device *tee_kdev, void *data)
 {
+	struct drm_i915_private *i915 = kdev_to_i915(i915_kdev);
 	struct intel_pxp *pxp = i915_dev_to_pxp(i915_kdev);
 
+	mutex_lock(&pxp->tee_mutex);
 	pxp->pxp_component = data;
 	pxp->pxp_component->tee_dev = tee_kdev;
+	mutex_unlock(&pxp->tee_mutex);
 
 	/* the component is required to fully start the PXP HW */
 	intel_pxp_init_hw(pxp);
 
+	if (!pxp->arb_is_valid) {
+		drm_err(&i915->drm, "Failed to create arb session during bind\n");
+		intel_pxp_fini_hw(pxp);
+		pxp->pxp_component = NULL;
+		return -EIO;
+	}
+
 	return 0;
 }
 
@@ -46,7 +106,9 @@ static void i915_pxp_tee_component_unbind(struct device *i915_kdev,
 
 	intel_pxp_fini_hw(pxp);
 
+	mutex_lock(&pxp->tee_mutex);
 	pxp->pxp_component = NULL;
+	mutex_unlock(&pxp->tee_mutex);
 }
 
 static const struct component_ops i915_pxp_tee_component_ops = {
@@ -80,3 +142,28 @@ void intel_pxp_tee_component_fini(struct intel_pxp *pxp)
 
 	component_del(i915->drm.dev, &i915_pxp_tee_component_ops);
 }
+
+int intel_pxp_tee_cmd_create_arb_session(struct intel_pxp *pxp,
+					 int arb_session_id)
+{
+	struct drm_i915_private *i915 = pxp_to_gt(pxp)->i915;
+	struct pxp_tee_create_arb_in msg_in = {0};
+	struct pxp_tee_create_arb_out msg_out = {0};
+	int ret;
+
+	msg_in.header.api_version = PXP_TEE_APIVER;
+	msg_in.header.command_id = PXP_TEE_ARB_CMDID;
+	msg_in.header.buffer_len = sizeof(msg_in) - sizeof(msg_in.header);
+	msg_in.protection_mode = PXP_TEE_ARB_PROTECTION_MODE;
+	msg_in.session_id = arb_session_id;
+
+	ret = intel_pxp_tee_io_message(pxp,
+				       &msg_in, sizeof(msg_in),
+				       &msg_out, sizeof(msg_out),
+				       NULL);
+
+	if (ret)
+		drm_err(&i915->drm, "Failed to send tee msg ret=[%d]\n", ret);
+
+	return ret;
+}
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.h b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.h
index 23d050a5d3e7..c136053ce340 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.h
@@ -11,4 +11,7 @@
 int intel_pxp_tee_component_init(struct intel_pxp *pxp);
 void intel_pxp_tee_component_fini(struct intel_pxp *pxp);
 
+int intel_pxp_tee_cmd_create_arb_session(struct intel_pxp *pxp,
+					 int arb_session_id);
+
 #endif /* __INTEL_PXP_TEE_H__ */
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee_interface.h b/drivers/gpu/drm/i915/pxp/intel_pxp_tee_interface.h
new file mode 100644
index 000000000000..1af6c0061e11
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee_interface.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright(c) 2020, Intel Corporation. All rights reserved.
+ */
+
+#ifndef __INTEL_PXP_TEE_INTERFACE_H__
+#define __INTEL_PXP_TEE_INTERFACE_H__
+
+#include <linux/types.h>
+
+#define PXP_TEE_APIVER 0x40002
+#define PXP_TEE_ARB_CMDID 0x1e
+#define PXP_TEE_ARB_PROTECTION_MODE 0x2
+
+/* PXP TEE message header */
+struct pxp_tee_cmd_header {
+	u32 api_version;
+	u32 command_id;
+	u32 status;
+	/* Length of the message (excluding the header) */
+	u32 buffer_len;
+} __packed;
+
+/* PXP TEE message input to create a arbitrary session */
+struct pxp_tee_create_arb_in {
+	struct pxp_tee_cmd_header header;
+	u32 protection_mode;
+	u32 session_id;
+} __packed;
+
+/* PXP TEE message output to create a arbitrary session */
+struct pxp_tee_create_arb_out {
+	struct pxp_tee_cmd_header header;
+} __packed;
+
+
+#endif /* __INTEL_PXP_TEE_INTERFACE_H__ */
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
index 3e95d21513e8..a4797a98c1f9 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
@@ -6,6 +6,9 @@
 #ifndef __INTEL_PXP_TYPES_H__
 #define __INTEL_PXP_TYPES_H__
 
+#include <linux/mutex.h>
+#include <linux/types.h>
+
 struct intel_context;
 struct i915_pxp_component;
 
@@ -13,6 +16,15 @@ struct intel_pxp {
 	struct i915_pxp_component *pxp_component;
 
 	struct intel_context *ce;
+
+	/*
+	 * After a teardown, the arb session can still be in play on the HW
+	 * even if the keys are gone, so we can't rely on the HW state of the
+	 * session to know if it's valid and need to track the status in SW.
+	 */
+	bool arb_is_valid;
+
+	struct mutex tee_mutex; /* protects the tee channel binding */
 };
 
 #endif /* __INTEL_PXP_TYPES_H__ */
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 7f13d241417f..4393eef59d9b 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -3018,6 +3018,9 @@ struct drm_i915_gem_create_ext_memory_regions {
 	__u64 regions;
 };
 
+/* ID of the protected content session managed by i915 when PXP is active */
+#define I915_PROTECTED_CONTENT_DEFAULT_SESSION 0xf
+
 #if defined(__cplusplus)
 }
 #endif
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [Intel-gfx] [PATCH v6 07/15] drm/i915/pxp: Create the arbitrary session after boot
@ 2021-07-29  2:00   ` Daniele Ceraolo Spurio
  0 siblings, 0 replies; 64+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-07-29  2:00 UTC (permalink / raw)
  To: intel-gfx; +Cc: Huang, Sean Z, dri-devel, Chris Wilson, Huang

From: "Huang, Sean Z" <sean.z.huang@intel.com>

Create the arbitrary session, with the fixed session id 0xf, after
system boot, for the case that application allocates the protected
buffer without establishing any protection session. Because the
hardware requires at least one alive session for protected buffer
creation. This arbitrary session will need to be re-created after
teardown or power event because hardware encryption key won't be
valid after such cases.

The session ID is exposed as part of the uapi so it can be used as part
of userspace commands.

v2: use gt->uncore->rpm (Chris)
v3: s/arb_is_in_play/arb_is_valid (Chris), move set-up to the new
    init_hw function
v4: move interface defs to separate header, set arb_is valid to false
    on fini (Rodrigo)
v5: handle async component binding

Signed-off-by: Huang, Sean Z <sean.z.huang@intel.com>
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
---
 drivers/gpu/drm/i915/Makefile                 |  1 +
 drivers/gpu/drm/i915/pxp/intel_pxp.c          |  7 ++
 drivers/gpu/drm/i915/pxp/intel_pxp.h          |  5 ++
 drivers/gpu/drm/i915/pxp/intel_pxp_session.c  | 74 ++++++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_session.h  | 15 ++++
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c      | 87 +++++++++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.h      |  3 +
 .../drm/i915/pxp/intel_pxp_tee_interface.h    | 37 ++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_types.h    | 12 +++
 include/uapi/drm/i915_drm.h                   |  3 +
 10 files changed, 244 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_session.c
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_session.h
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_tee_interface.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index db6889c7474b..278a11b991ab 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -278,6 +278,7 @@ i915-y += i915_perf.o
 # Protected execution platform (PXP) support
 i915-$(CONFIG_DRM_I915_PXP) += \
 	pxp/intel_pxp.o \
+	pxp/intel_pxp_session.o \
 	pxp/intel_pxp_tee.o
 
 # Post-mortem debug and GPU hang state capture
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index 66a98feb33ab..e1370f323126 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -3,6 +3,7 @@
  * Copyright(c) 2020 Intel Corporation.
  */
 #include "intel_pxp.h"
+#include "intel_pxp_session.h"
 #include "intel_pxp_tee.h"
 #include "gt/intel_context.h"
 #include "i915_drv.h"
@@ -65,6 +66,8 @@ void intel_pxp_init(struct intel_pxp *pxp)
 	if (!HAS_PXP(gt->i915))
 		return;
 
+	mutex_init(&pxp->tee_mutex);
+
 	ret = create_vcs_context(pxp);
 	if (ret)
 		return;
@@ -86,6 +89,8 @@ void intel_pxp_fini(struct intel_pxp *pxp)
 	if (!intel_pxp_is_enabled(pxp))
 		return;
 
+	pxp->arb_is_valid = false;
+
 	intel_pxp_tee_component_fini(pxp);
 
 	destroy_vcs_context(pxp);
@@ -94,6 +99,8 @@ void intel_pxp_fini(struct intel_pxp *pxp)
 void intel_pxp_init_hw(struct intel_pxp *pxp)
 {
 	kcr_pxp_enable(pxp_to_gt(pxp));
+
+	intel_pxp_create_arb_session(pxp);
 }
 
 void intel_pxp_fini_hw(struct intel_pxp *pxp)
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
index 5427c3b28aa9..8eeb65af78b1 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
@@ -19,6 +19,11 @@ static inline bool intel_pxp_is_enabled(const struct intel_pxp *pxp)
 	return pxp->ce;
 }
 
+static inline bool intel_pxp_is_active(const struct intel_pxp *pxp)
+{
+	return pxp->arb_is_valid;
+}
+
 #ifdef CONFIG_DRM_I915_PXP
 void intel_pxp_init(struct intel_pxp *pxp);
 void intel_pxp_fini(struct intel_pxp *pxp);
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
new file mode 100644
index 000000000000..3331868f354c
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright(c) 2020, Intel Corporation. All rights reserved.
+ */
+
+#include "drm/i915_drm.h"
+#include "i915_drv.h"
+
+#include "intel_pxp.h"
+#include "intel_pxp_session.h"
+#include "intel_pxp_tee.h"
+#include "intel_pxp_types.h"
+
+#define ARB_SESSION I915_PROTECTED_CONTENT_DEFAULT_SESSION /* shorter define */
+
+#define GEN12_KCR_SIP _MMIO(0x32260) /* KCR hwdrm session in play 0-31 */
+
+static bool intel_pxp_session_is_in_play(struct intel_pxp *pxp, u32 id)
+{
+	struct intel_gt *gt = pxp_to_gt(pxp);
+	intel_wakeref_t wakeref;
+	u32 sip = 0;
+
+	with_intel_runtime_pm(gt->uncore->rpm, wakeref)
+		sip = intel_uncore_read(gt->uncore, GEN12_KCR_SIP);
+
+	return sip & BIT(id);
+}
+
+static int pxp_wait_for_session_state(struct intel_pxp *pxp, u32 id, bool in_play)
+{
+	struct intel_gt *gt = pxp_to_gt(pxp);
+	intel_wakeref_t wakeref;
+	u32 mask = BIT(id);
+	int ret;
+
+	with_intel_runtime_pm(gt->uncore->rpm, wakeref)
+		ret = intel_wait_for_register(gt->uncore,
+					      GEN12_KCR_SIP,
+					      mask,
+					      in_play ? mask : 0,
+					      100);
+
+	return ret;
+}
+
+int intel_pxp_create_arb_session(struct intel_pxp *pxp)
+{
+	struct intel_gt *gt = pxp_to_gt(pxp);
+	int ret;
+
+	pxp->arb_is_valid = false;
+
+	if (intel_pxp_session_is_in_play(pxp, ARB_SESSION)) {
+		drm_err(&gt->i915->drm, "arb session already in play at creation time\n");
+		return -EEXIST;
+	}
+
+	ret = intel_pxp_tee_cmd_create_arb_session(pxp, ARB_SESSION);
+	if (ret) {
+		drm_err(&gt->i915->drm, "tee cmd for arb session creation failed\n");
+		return ret;
+	}
+
+	ret = pxp_wait_for_session_state(pxp, ARB_SESSION, true);
+	if (ret) {
+		drm_err(&gt->i915->drm, "arb session failed to go in play\n");
+		return ret;
+	}
+
+	pxp->arb_is_valid = true;
+
+	return 0;
+}
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.h b/drivers/gpu/drm/i915/pxp/intel_pxp_session.h
new file mode 100644
index 000000000000..316c3bebed9c
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright(c) 2020, Intel Corporation. All rights reserved.
+ */
+
+#ifndef __INTEL_PXP_SESSION_H__
+#define __INTEL_PXP_SESSION_H__
+
+#include <linux/types.h>
+
+struct intel_pxp;
+
+int intel_pxp_create_arb_session(struct intel_pxp *pxp);
+
+#endif /* __INTEL_PXP_SESSION_H__ */
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
index 33130fb7113b..3662bf67407a 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
@@ -8,13 +8,63 @@
 #include "drm/i915_component.h"
 #include "i915_drv.h"
 #include "intel_pxp.h"
+#include "intel_pxp_session.h"
 #include "intel_pxp_tee.h"
+#include "intel_pxp_tee_interface.h"
 
 static inline struct intel_pxp *i915_dev_to_pxp(struct device *i915_kdev)
 {
 	return &kdev_to_i915(i915_kdev)->gt.pxp;
 }
 
+static int intel_pxp_tee_io_message(struct intel_pxp *pxp,
+				    void *msg_in, u32 msg_in_size,
+				    void *msg_out, u32 msg_out_max_size,
+				    u32 *msg_out_rcv_size)
+{
+	struct drm_i915_private *i915 = pxp_to_gt(pxp)->i915;
+	struct i915_pxp_component *pxp_component = pxp->pxp_component;
+	int ret = 0;
+
+	mutex_lock(&pxp->tee_mutex);
+
+	/*
+	 * The binding of the component is asynchronous from i915 probe, so we
+	 * can't be sure it has happened.
+	 */
+	if (!pxp_component) {
+		ret = -ENODEV;
+		goto unlock;
+	}
+
+	ret = pxp_component->ops->send(pxp_component->tee_dev, msg_in, msg_in_size);
+	if (ret) {
+		drm_err(&i915->drm, "Failed to send PXP TEE message\n");
+		goto unlock;
+	}
+
+	ret = pxp_component->ops->recv(pxp_component->tee_dev, msg_out, msg_out_max_size);
+	if (ret < 0) {
+		drm_err(&i915->drm, "Failed to receive PXP TEE message\n");
+		goto unlock;
+	}
+
+	if (ret > msg_out_max_size) {
+		drm_err(&i915->drm,
+			"Failed to receive PXP TEE message due to unexpected output size\n");
+		ret = -ENOSPC;
+		goto unlock;
+	}
+
+	if (msg_out_rcv_size)
+		*msg_out_rcv_size = ret;
+
+	ret = 0;
+unlock:
+	mutex_unlock(&pxp->tee_mutex);
+	return ret;
+}
+
 /**
  * i915_pxp_tee_component_bind - bind function to pass the function pointers to pxp_tee
  * @i915_kdev: pointer to i915 kernel device
@@ -28,14 +78,24 @@ static inline struct intel_pxp *i915_dev_to_pxp(struct device *i915_kdev)
 static int i915_pxp_tee_component_bind(struct device *i915_kdev,
 				       struct device *tee_kdev, void *data)
 {
+	struct drm_i915_private *i915 = kdev_to_i915(i915_kdev);
 	struct intel_pxp *pxp = i915_dev_to_pxp(i915_kdev);
 
+	mutex_lock(&pxp->tee_mutex);
 	pxp->pxp_component = data;
 	pxp->pxp_component->tee_dev = tee_kdev;
+	mutex_unlock(&pxp->tee_mutex);
 
 	/* the component is required to fully start the PXP HW */
 	intel_pxp_init_hw(pxp);
 
+	if (!pxp->arb_is_valid) {
+		drm_err(&i915->drm, "Failed to create arb session during bind\n");
+		intel_pxp_fini_hw(pxp);
+		pxp->pxp_component = NULL;
+		return -EIO;
+	}
+
 	return 0;
 }
 
@@ -46,7 +106,9 @@ static void i915_pxp_tee_component_unbind(struct device *i915_kdev,
 
 	intel_pxp_fini_hw(pxp);
 
+	mutex_lock(&pxp->tee_mutex);
 	pxp->pxp_component = NULL;
+	mutex_unlock(&pxp->tee_mutex);
 }
 
 static const struct component_ops i915_pxp_tee_component_ops = {
@@ -80,3 +142,28 @@ void intel_pxp_tee_component_fini(struct intel_pxp *pxp)
 
 	component_del(i915->drm.dev, &i915_pxp_tee_component_ops);
 }
+
+int intel_pxp_tee_cmd_create_arb_session(struct intel_pxp *pxp,
+					 int arb_session_id)
+{
+	struct drm_i915_private *i915 = pxp_to_gt(pxp)->i915;
+	struct pxp_tee_create_arb_in msg_in = {0};
+	struct pxp_tee_create_arb_out msg_out = {0};
+	int ret;
+
+	msg_in.header.api_version = PXP_TEE_APIVER;
+	msg_in.header.command_id = PXP_TEE_ARB_CMDID;
+	msg_in.header.buffer_len = sizeof(msg_in) - sizeof(msg_in.header);
+	msg_in.protection_mode = PXP_TEE_ARB_PROTECTION_MODE;
+	msg_in.session_id = arb_session_id;
+
+	ret = intel_pxp_tee_io_message(pxp,
+				       &msg_in, sizeof(msg_in),
+				       &msg_out, sizeof(msg_out),
+				       NULL);
+
+	if (ret)
+		drm_err(&i915->drm, "Failed to send tee msg ret=[%d]\n", ret);
+
+	return ret;
+}
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.h b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.h
index 23d050a5d3e7..c136053ce340 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.h
@@ -11,4 +11,7 @@
 int intel_pxp_tee_component_init(struct intel_pxp *pxp);
 void intel_pxp_tee_component_fini(struct intel_pxp *pxp);
 
+int intel_pxp_tee_cmd_create_arb_session(struct intel_pxp *pxp,
+					 int arb_session_id);
+
 #endif /* __INTEL_PXP_TEE_H__ */
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee_interface.h b/drivers/gpu/drm/i915/pxp/intel_pxp_tee_interface.h
new file mode 100644
index 000000000000..1af6c0061e11
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee_interface.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright(c) 2020, Intel Corporation. All rights reserved.
+ */
+
+#ifndef __INTEL_PXP_TEE_INTERFACE_H__
+#define __INTEL_PXP_TEE_INTERFACE_H__
+
+#include <linux/types.h>
+
+#define PXP_TEE_APIVER 0x40002
+#define PXP_TEE_ARB_CMDID 0x1e
+#define PXP_TEE_ARB_PROTECTION_MODE 0x2
+
+/* PXP TEE message header */
+struct pxp_tee_cmd_header {
+	u32 api_version;
+	u32 command_id;
+	u32 status;
+	/* Length of the message (excluding the header) */
+	u32 buffer_len;
+} __packed;
+
+/* PXP TEE message input to create a arbitrary session */
+struct pxp_tee_create_arb_in {
+	struct pxp_tee_cmd_header header;
+	u32 protection_mode;
+	u32 session_id;
+} __packed;
+
+/* PXP TEE message output to create a arbitrary session */
+struct pxp_tee_create_arb_out {
+	struct pxp_tee_cmd_header header;
+} __packed;
+
+
+#endif /* __INTEL_PXP_TEE_INTERFACE_H__ */
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
index 3e95d21513e8..a4797a98c1f9 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
@@ -6,6 +6,9 @@
 #ifndef __INTEL_PXP_TYPES_H__
 #define __INTEL_PXP_TYPES_H__
 
+#include <linux/mutex.h>
+#include <linux/types.h>
+
 struct intel_context;
 struct i915_pxp_component;
 
@@ -13,6 +16,15 @@ struct intel_pxp {
 	struct i915_pxp_component *pxp_component;
 
 	struct intel_context *ce;
+
+	/*
+	 * After a teardown, the arb session can still be in play on the HW
+	 * even if the keys are gone, so we can't rely on the HW state of the
+	 * session to know if it's valid and need to track the status in SW.
+	 */
+	bool arb_is_valid;
+
+	struct mutex tee_mutex; /* protects the tee channel binding */
 };
 
 #endif /* __INTEL_PXP_TYPES_H__ */
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 7f13d241417f..4393eef59d9b 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -3018,6 +3018,9 @@ struct drm_i915_gem_create_ext_memory_regions {
 	__u64 regions;
 };
 
+/* ID of the protected content session managed by i915 when PXP is active */
+#define I915_PROTECTED_CONTENT_DEFAULT_SESSION 0xf
+
 #if defined(__cplusplus)
 }
 #endif
-- 
2.32.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v6 08/15] drm/i915/pxp: Implement arb session teardown
  2021-07-29  2:00 ` [Intel-gfx] " Daniele Ceraolo Spurio
@ 2021-07-29  2:00   ` Daniele Ceraolo Spurio
  -1 siblings, 0 replies; 64+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-07-29  2:00 UTC (permalink / raw)
  To: intel-gfx
  Cc: Huang, Sean Z, dri-devel, Chris Wilson, Daniele Ceraolo Spurio,
	Huang, Rodrigo Vivi

From: "Huang, Sean Z" <sean.z.huang@intel.com>

Teardown is triggered when the display topology changes and no
long meets the secure playback requirement, and hardware trashes
all the encryption keys for display. Additionally, we want to emit a
teardown operation to make sure we're clean on boot and resume

v2: emit in the ring, use high prio request (Chris)
v3: better defines, stalling flush, cleaned up and renamed submission
    funcs (Chris)

Signed-off-by: Huang, Sean Z <sean.z.huang@intel.com>
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
---
 drivers/gpu/drm/i915/Makefile                |   1 +
 drivers/gpu/drm/i915/gt/intel_gpu_commands.h |  22 ++-
 drivers/gpu/drm/i915/pxp/intel_pxp.c         |   7 +-
 drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c     | 141 +++++++++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h     |  15 ++
 drivers/gpu/drm/i915/pxp/intel_pxp_session.c |  29 ++++
 drivers/gpu/drm/i915/pxp/intel_pxp_session.h |   1 +
 7 files changed, 212 insertions(+), 4 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 278a11b991ab..e13bc803e5ce 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -278,6 +278,7 @@ i915-y += i915_perf.o
 # Protected execution platform (PXP) support
 i915-$(CONFIG_DRM_I915_PXP) += \
 	pxp/intel_pxp.o \
+	pxp/intel_pxp_cmd.o \
 	pxp/intel_pxp_session.o \
 	pxp/intel_pxp_tee.o
 
diff --git a/drivers/gpu/drm/i915/gt/intel_gpu_commands.h b/drivers/gpu/drm/i915/gt/intel_gpu_commands.h
index 1c3af0fc0456..ec2a0a566c40 100644
--- a/drivers/gpu/drm/i915/gt/intel_gpu_commands.h
+++ b/drivers/gpu/drm/i915/gt/intel_gpu_commands.h
@@ -28,10 +28,13 @@
 #define INSTR_26_TO_24_MASK	0x7000000
 #define   INSTR_26_TO_24_SHIFT	24
 
+#define __INSTR(client) ((client) << INSTR_CLIENT_SHIFT)
+
 /*
  * Memory interface instructions used by the kernel
  */
-#define MI_INSTR(opcode, flags) (((opcode) << 23) | (flags))
+#define MI_INSTR(opcode, flags) \
+	(__INSTR(INSTR_MI_CLIENT) | (opcode) << 23 | (flags))
 /* Many MI commands use bit 22 of the header dword for GGTT vs PPGTT */
 #define  MI_GLOBAL_GTT    (1<<22)
 
@@ -57,6 +60,7 @@
 #define MI_SUSPEND_FLUSH	MI_INSTR(0x0b, 0)
 #define   MI_SUSPEND_FLUSH_EN	(1<<0)
 #define MI_SET_APPID		MI_INSTR(0x0e, 0)
+#define   MI_SET_APPID_SESSION_ID(x)	((x) << 0)
 #define MI_OVERLAY_FLIP		MI_INSTR(0x11, 0)
 #define   MI_OVERLAY_CONTINUE	(0x0<<21)
 #define   MI_OVERLAY_ON		(0x1<<21)
@@ -146,6 +150,7 @@
 #define MI_STORE_REGISTER_MEM_GEN8   MI_INSTR(0x24, 2)
 #define   MI_SRM_LRM_GLOBAL_GTT		(1<<22)
 #define MI_FLUSH_DW		MI_INSTR(0x26, 1) /* for GEN6 */
+#define   MI_FLUSH_DW_PROTECTED_MEM_EN	(1<<22)
 #define   MI_FLUSH_DW_STORE_INDEX	(1<<21)
 #define   MI_INVALIDATE_TLB		(1<<18)
 #define   MI_FLUSH_DW_OP_STOREDW	(1<<14)
@@ -272,6 +277,19 @@
 #define   MI_MATH_REG_ZF		0x32
 #define   MI_MATH_REG_CF		0x33
 
+/*
+ * Media instructions used by the kernel
+ */
+#define MEDIA_INSTR(pipe, op, sub_op, flags) \
+	(__INSTR(INSTR_RC_CLIENT) | (pipe) << INSTR_SUBCLIENT_SHIFT | \
+	(op) << INSTR_26_TO_24_SHIFT | (sub_op) << 16 | (flags))
+
+#define MFX_WAIT				MEDIA_INSTR(1, 0, 0, 0)
+#define  MFX_WAIT_DW0_MFX_SYNC_CONTROL_FLAG	REG_BIT(8)
+#define  MFX_WAIT_DW0_PXP_SYNC_CONTROL_FLAG	REG_BIT(9)
+
+#define CRYPTO_KEY_EXCHANGE			MEDIA_INSTR(2, 6, 9, 0)
+
 /*
  * Commands used only by the command parser
  */
@@ -328,8 +346,6 @@
 #define GFX_OP_3DSTATE_BINDING_TABLE_EDIT_PS \
 	((0x3<<29)|(0x3<<27)|(0x0<<24)|(0x47<<16))
 
-#define MFX_WAIT  ((0x3<<29)|(0x1<<27)|(0x0<<16))
-
 #define COLOR_BLT     ((0x2<<29)|(0x40<<22))
 #define SRC_COPY_BLT  ((0x2<<29)|(0x43<<22))
 
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index e1370f323126..26176d43a02d 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -98,9 +98,14 @@ void intel_pxp_fini(struct intel_pxp *pxp)
 
 void intel_pxp_init_hw(struct intel_pxp *pxp)
 {
+	int ret;
+
 	kcr_pxp_enable(pxp_to_gt(pxp));
 
-	intel_pxp_create_arb_session(pxp);
+	/* always emit a full termination to clean the state */
+	ret = intel_pxp_terminate_arb_session_and_global(pxp);
+	if (!ret)
+		intel_pxp_create_arb_session(pxp);
 }
 
 void intel_pxp_fini_hw(struct intel_pxp *pxp)
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c
new file mode 100644
index 000000000000..80678dafde15
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c
@@ -0,0 +1,141 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright(c) 2020, Intel Corporation. All rights reserved.
+ */
+
+#include "intel_pxp.h"
+#include "intel_pxp_cmd.h"
+#include "intel_pxp_session.h"
+#include "gt/intel_context.h"
+#include "gt/intel_engine_pm.h"
+#include "gt/intel_gpu_commands.h"
+#include "gt/intel_ring.h"
+
+#include "i915_trace.h"
+
+/* stall until prior PXP and MFX/HCP/HUC objects are cmopleted */
+#define MFX_WAIT_PXP (MFX_WAIT | \
+		      MFX_WAIT_DW0_PXP_SYNC_CONTROL_FLAG | \
+		      MFX_WAIT_DW0_MFX_SYNC_CONTROL_FLAG)
+
+static u32 *pxp_emit_session_selection(u32 *cs, u32 idx)
+{
+	*cs++ = MFX_WAIT_PXP;
+
+	/* pxp off */
+	*cs++ = MI_FLUSH_DW;
+	*cs++ = 0;
+	*cs++ = 0;
+
+	/* select session */
+	*cs++ = MI_SET_APPID | MI_SET_APPID_SESSION_ID(idx);
+
+	*cs++ = MFX_WAIT_PXP;
+
+	/* pxp on */
+	*cs++ = MI_FLUSH_DW | MI_FLUSH_DW_PROTECTED_MEM_EN |
+		MI_FLUSH_DW_OP_STOREDW | MI_FLUSH_DW_STORE_INDEX;
+	*cs++ = I915_GEM_HWS_PXP_ADDR | MI_FLUSH_DW_USE_GTT;
+	*cs++ = 0;
+
+	*cs++ = MFX_WAIT_PXP;
+
+	return cs;
+}
+
+static u32 *pxp_emit_inline_termination(u32 *cs)
+{
+	/* session inline termination */
+	*cs++ = CRYPTO_KEY_EXCHANGE;
+	*cs++ = 0;
+
+	return cs;
+}
+
+static u32 *pxp_emit_session_termination(u32 *cs, u32 idx)
+{
+	cs = pxp_emit_session_selection(cs, idx);
+	cs = pxp_emit_inline_termination(cs);
+
+	return cs;
+}
+
+static u32 *pxp_emit_wait(u32 *cs)
+{
+	/* wait for cmds to go through */
+	*cs++ = MFX_WAIT_PXP;
+	*cs++ = 0;
+
+	return cs;
+}
+
+/*
+ * if we ever need to terminate more than one session, we can submit multiple
+ * selections and terminations back-to-back with a single wait at the end
+ */
+#define SELECTION_LEN 10
+#define TERMINATION_LEN 2
+#define SESSION_TERMINATION_LEN(x) ((SELECTION_LEN + TERMINATION_LEN) * (x))
+#define WAIT_LEN 2
+
+static void pxp_request_commit(struct i915_request *rq)
+{
+	struct i915_sched_attr attr = { .priority = I915_PRIORITY_MAX };
+	struct intel_timeline * const tl = i915_request_timeline(rq);
+
+	lockdep_unpin_lock(&tl->mutex, rq->cookie);
+
+	trace_i915_request_add(rq);
+	__i915_request_commit(rq);
+	__i915_request_queue(rq, &attr);
+
+	mutex_unlock(&tl->mutex);
+}
+
+int intel_pxp_terminate_session(struct intel_pxp *pxp, u32 id)
+{
+	struct i915_request *rq;
+	struct intel_context *ce = pxp->ce;
+	u32 *cs;
+	int err;
+
+	if (!intel_pxp_is_enabled(pxp))
+		return 0;
+
+	rq = i915_request_create(ce);
+	if (IS_ERR(rq))
+		return PTR_ERR(rq);
+
+	if (ce->engine->emit_init_breadcrumb) {
+		err = ce->engine->emit_init_breadcrumb(rq);
+		if (err)
+			goto out_rq;
+	}
+
+	cs = intel_ring_begin(rq, SESSION_TERMINATION_LEN(1) + WAIT_LEN);
+	if (IS_ERR(cs)) {
+		err = PTR_ERR(cs);
+		goto out_rq;
+	}
+
+	cs = pxp_emit_session_termination(cs, id);
+	cs = pxp_emit_wait(cs);
+
+	intel_ring_advance(rq, cs);
+
+out_rq:
+	i915_request_get(rq);
+
+	if (unlikely(err))
+		i915_request_set_error_once(rq, err);
+
+	pxp_request_commit(rq);
+
+	if (!err && i915_request_wait(rq, 0, HZ / 5) < 0)
+		err = -ETIME;
+
+	i915_request_put(rq);
+
+	return err;
+}
+
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h
new file mode 100644
index 000000000000..6d6299543578
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright(c) 2020, Intel Corporation. All rights reserved.
+ */
+
+#ifndef __INTEL_PXP_CMD_H__
+#define __INTEL_PXP_CMD_H__
+
+#include <linux/types.h>
+
+struct intel_pxp;
+
+int intel_pxp_terminate_session(struct intel_pxp *pxp, u32 idx);
+
+#endif /* __INTEL_PXP_CMD_H__ */
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
index 3331868f354c..b8e24adeb1f3 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
@@ -7,6 +7,7 @@
 #include "i915_drv.h"
 
 #include "intel_pxp.h"
+#include "intel_pxp_cmd.h"
 #include "intel_pxp_session.h"
 #include "intel_pxp_tee.h"
 #include "intel_pxp_types.h"
@@ -15,6 +16,9 @@
 
 #define GEN12_KCR_SIP _MMIO(0x32260) /* KCR hwdrm session in play 0-31 */
 
+/* PXP global terminate register for session termination */
+#define PXP_GLOBAL_TERMINATE _MMIO(0x320f8)
+
 static bool intel_pxp_session_is_in_play(struct intel_pxp *pxp, u32 id)
 {
 	struct intel_gt *gt = pxp_to_gt(pxp);
@@ -72,3 +76,28 @@ int intel_pxp_create_arb_session(struct intel_pxp *pxp)
 
 	return 0;
 }
+
+int intel_pxp_terminate_arb_session_and_global(struct intel_pxp *pxp)
+{
+	int ret;
+	struct intel_gt *gt = pxp_to_gt(pxp);
+
+	pxp->arb_is_valid = false;
+
+	/* terminate the hw sessions */
+	ret = intel_pxp_terminate_session(pxp, ARB_SESSION);
+	if (ret) {
+		drm_err(&gt->i915->drm, "Failed to submit session termination\n");
+		return ret;
+	}
+
+	ret = pxp_wait_for_session_state(pxp, ARB_SESSION, false);
+	if (ret) {
+		drm_err(&gt->i915->drm, "Session state did not clear\n");
+		return ret;
+	}
+
+	intel_uncore_write(gt->uncore, PXP_GLOBAL_TERMINATE, 1);
+
+	return ret;
+}
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.h b/drivers/gpu/drm/i915/pxp/intel_pxp_session.h
index 316c3bebed9c..7354314b1cc4 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.h
@@ -11,5 +11,6 @@
 struct intel_pxp;
 
 int intel_pxp_create_arb_session(struct intel_pxp *pxp);
+int intel_pxp_terminate_arb_session_and_global(struct intel_pxp *pxp);
 
 #endif /* __INTEL_PXP_SESSION_H__ */
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [Intel-gfx] [PATCH v6 08/15] drm/i915/pxp: Implement arb session teardown
@ 2021-07-29  2:00   ` Daniele Ceraolo Spurio
  0 siblings, 0 replies; 64+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-07-29  2:00 UTC (permalink / raw)
  To: intel-gfx; +Cc: Huang, Sean Z, dri-devel, Chris Wilson, Huang

From: "Huang, Sean Z" <sean.z.huang@intel.com>

Teardown is triggered when the display topology changes and no
long meets the secure playback requirement, and hardware trashes
all the encryption keys for display. Additionally, we want to emit a
teardown operation to make sure we're clean on boot and resume

v2: emit in the ring, use high prio request (Chris)
v3: better defines, stalling flush, cleaned up and renamed submission
    funcs (Chris)

Signed-off-by: Huang, Sean Z <sean.z.huang@intel.com>
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
---
 drivers/gpu/drm/i915/Makefile                |   1 +
 drivers/gpu/drm/i915/gt/intel_gpu_commands.h |  22 ++-
 drivers/gpu/drm/i915/pxp/intel_pxp.c         |   7 +-
 drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c     | 141 +++++++++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h     |  15 ++
 drivers/gpu/drm/i915/pxp/intel_pxp_session.c |  29 ++++
 drivers/gpu/drm/i915/pxp/intel_pxp_session.h |   1 +
 7 files changed, 212 insertions(+), 4 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 278a11b991ab..e13bc803e5ce 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -278,6 +278,7 @@ i915-y += i915_perf.o
 # Protected execution platform (PXP) support
 i915-$(CONFIG_DRM_I915_PXP) += \
 	pxp/intel_pxp.o \
+	pxp/intel_pxp_cmd.o \
 	pxp/intel_pxp_session.o \
 	pxp/intel_pxp_tee.o
 
diff --git a/drivers/gpu/drm/i915/gt/intel_gpu_commands.h b/drivers/gpu/drm/i915/gt/intel_gpu_commands.h
index 1c3af0fc0456..ec2a0a566c40 100644
--- a/drivers/gpu/drm/i915/gt/intel_gpu_commands.h
+++ b/drivers/gpu/drm/i915/gt/intel_gpu_commands.h
@@ -28,10 +28,13 @@
 #define INSTR_26_TO_24_MASK	0x7000000
 #define   INSTR_26_TO_24_SHIFT	24
 
+#define __INSTR(client) ((client) << INSTR_CLIENT_SHIFT)
+
 /*
  * Memory interface instructions used by the kernel
  */
-#define MI_INSTR(opcode, flags) (((opcode) << 23) | (flags))
+#define MI_INSTR(opcode, flags) \
+	(__INSTR(INSTR_MI_CLIENT) | (opcode) << 23 | (flags))
 /* Many MI commands use bit 22 of the header dword for GGTT vs PPGTT */
 #define  MI_GLOBAL_GTT    (1<<22)
 
@@ -57,6 +60,7 @@
 #define MI_SUSPEND_FLUSH	MI_INSTR(0x0b, 0)
 #define   MI_SUSPEND_FLUSH_EN	(1<<0)
 #define MI_SET_APPID		MI_INSTR(0x0e, 0)
+#define   MI_SET_APPID_SESSION_ID(x)	((x) << 0)
 #define MI_OVERLAY_FLIP		MI_INSTR(0x11, 0)
 #define   MI_OVERLAY_CONTINUE	(0x0<<21)
 #define   MI_OVERLAY_ON		(0x1<<21)
@@ -146,6 +150,7 @@
 #define MI_STORE_REGISTER_MEM_GEN8   MI_INSTR(0x24, 2)
 #define   MI_SRM_LRM_GLOBAL_GTT		(1<<22)
 #define MI_FLUSH_DW		MI_INSTR(0x26, 1) /* for GEN6 */
+#define   MI_FLUSH_DW_PROTECTED_MEM_EN	(1<<22)
 #define   MI_FLUSH_DW_STORE_INDEX	(1<<21)
 #define   MI_INVALIDATE_TLB		(1<<18)
 #define   MI_FLUSH_DW_OP_STOREDW	(1<<14)
@@ -272,6 +277,19 @@
 #define   MI_MATH_REG_ZF		0x32
 #define   MI_MATH_REG_CF		0x33
 
+/*
+ * Media instructions used by the kernel
+ */
+#define MEDIA_INSTR(pipe, op, sub_op, flags) \
+	(__INSTR(INSTR_RC_CLIENT) | (pipe) << INSTR_SUBCLIENT_SHIFT | \
+	(op) << INSTR_26_TO_24_SHIFT | (sub_op) << 16 | (flags))
+
+#define MFX_WAIT				MEDIA_INSTR(1, 0, 0, 0)
+#define  MFX_WAIT_DW0_MFX_SYNC_CONTROL_FLAG	REG_BIT(8)
+#define  MFX_WAIT_DW0_PXP_SYNC_CONTROL_FLAG	REG_BIT(9)
+
+#define CRYPTO_KEY_EXCHANGE			MEDIA_INSTR(2, 6, 9, 0)
+
 /*
  * Commands used only by the command parser
  */
@@ -328,8 +346,6 @@
 #define GFX_OP_3DSTATE_BINDING_TABLE_EDIT_PS \
 	((0x3<<29)|(0x3<<27)|(0x0<<24)|(0x47<<16))
 
-#define MFX_WAIT  ((0x3<<29)|(0x1<<27)|(0x0<<16))
-
 #define COLOR_BLT     ((0x2<<29)|(0x40<<22))
 #define SRC_COPY_BLT  ((0x2<<29)|(0x43<<22))
 
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index e1370f323126..26176d43a02d 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -98,9 +98,14 @@ void intel_pxp_fini(struct intel_pxp *pxp)
 
 void intel_pxp_init_hw(struct intel_pxp *pxp)
 {
+	int ret;
+
 	kcr_pxp_enable(pxp_to_gt(pxp));
 
-	intel_pxp_create_arb_session(pxp);
+	/* always emit a full termination to clean the state */
+	ret = intel_pxp_terminate_arb_session_and_global(pxp);
+	if (!ret)
+		intel_pxp_create_arb_session(pxp);
 }
 
 void intel_pxp_fini_hw(struct intel_pxp *pxp)
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c
new file mode 100644
index 000000000000..80678dafde15
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c
@@ -0,0 +1,141 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright(c) 2020, Intel Corporation. All rights reserved.
+ */
+
+#include "intel_pxp.h"
+#include "intel_pxp_cmd.h"
+#include "intel_pxp_session.h"
+#include "gt/intel_context.h"
+#include "gt/intel_engine_pm.h"
+#include "gt/intel_gpu_commands.h"
+#include "gt/intel_ring.h"
+
+#include "i915_trace.h"
+
+/* stall until prior PXP and MFX/HCP/HUC objects are cmopleted */
+#define MFX_WAIT_PXP (MFX_WAIT | \
+		      MFX_WAIT_DW0_PXP_SYNC_CONTROL_FLAG | \
+		      MFX_WAIT_DW0_MFX_SYNC_CONTROL_FLAG)
+
+static u32 *pxp_emit_session_selection(u32 *cs, u32 idx)
+{
+	*cs++ = MFX_WAIT_PXP;
+
+	/* pxp off */
+	*cs++ = MI_FLUSH_DW;
+	*cs++ = 0;
+	*cs++ = 0;
+
+	/* select session */
+	*cs++ = MI_SET_APPID | MI_SET_APPID_SESSION_ID(idx);
+
+	*cs++ = MFX_WAIT_PXP;
+
+	/* pxp on */
+	*cs++ = MI_FLUSH_DW | MI_FLUSH_DW_PROTECTED_MEM_EN |
+		MI_FLUSH_DW_OP_STOREDW | MI_FLUSH_DW_STORE_INDEX;
+	*cs++ = I915_GEM_HWS_PXP_ADDR | MI_FLUSH_DW_USE_GTT;
+	*cs++ = 0;
+
+	*cs++ = MFX_WAIT_PXP;
+
+	return cs;
+}
+
+static u32 *pxp_emit_inline_termination(u32 *cs)
+{
+	/* session inline termination */
+	*cs++ = CRYPTO_KEY_EXCHANGE;
+	*cs++ = 0;
+
+	return cs;
+}
+
+static u32 *pxp_emit_session_termination(u32 *cs, u32 idx)
+{
+	cs = pxp_emit_session_selection(cs, idx);
+	cs = pxp_emit_inline_termination(cs);
+
+	return cs;
+}
+
+static u32 *pxp_emit_wait(u32 *cs)
+{
+	/* wait for cmds to go through */
+	*cs++ = MFX_WAIT_PXP;
+	*cs++ = 0;
+
+	return cs;
+}
+
+/*
+ * if we ever need to terminate more than one session, we can submit multiple
+ * selections and terminations back-to-back with a single wait at the end
+ */
+#define SELECTION_LEN 10
+#define TERMINATION_LEN 2
+#define SESSION_TERMINATION_LEN(x) ((SELECTION_LEN + TERMINATION_LEN) * (x))
+#define WAIT_LEN 2
+
+static void pxp_request_commit(struct i915_request *rq)
+{
+	struct i915_sched_attr attr = { .priority = I915_PRIORITY_MAX };
+	struct intel_timeline * const tl = i915_request_timeline(rq);
+
+	lockdep_unpin_lock(&tl->mutex, rq->cookie);
+
+	trace_i915_request_add(rq);
+	__i915_request_commit(rq);
+	__i915_request_queue(rq, &attr);
+
+	mutex_unlock(&tl->mutex);
+}
+
+int intel_pxp_terminate_session(struct intel_pxp *pxp, u32 id)
+{
+	struct i915_request *rq;
+	struct intel_context *ce = pxp->ce;
+	u32 *cs;
+	int err;
+
+	if (!intel_pxp_is_enabled(pxp))
+		return 0;
+
+	rq = i915_request_create(ce);
+	if (IS_ERR(rq))
+		return PTR_ERR(rq);
+
+	if (ce->engine->emit_init_breadcrumb) {
+		err = ce->engine->emit_init_breadcrumb(rq);
+		if (err)
+			goto out_rq;
+	}
+
+	cs = intel_ring_begin(rq, SESSION_TERMINATION_LEN(1) + WAIT_LEN);
+	if (IS_ERR(cs)) {
+		err = PTR_ERR(cs);
+		goto out_rq;
+	}
+
+	cs = pxp_emit_session_termination(cs, id);
+	cs = pxp_emit_wait(cs);
+
+	intel_ring_advance(rq, cs);
+
+out_rq:
+	i915_request_get(rq);
+
+	if (unlikely(err))
+		i915_request_set_error_once(rq, err);
+
+	pxp_request_commit(rq);
+
+	if (!err && i915_request_wait(rq, 0, HZ / 5) < 0)
+		err = -ETIME;
+
+	i915_request_put(rq);
+
+	return err;
+}
+
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h
new file mode 100644
index 000000000000..6d6299543578
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright(c) 2020, Intel Corporation. All rights reserved.
+ */
+
+#ifndef __INTEL_PXP_CMD_H__
+#define __INTEL_PXP_CMD_H__
+
+#include <linux/types.h>
+
+struct intel_pxp;
+
+int intel_pxp_terminate_session(struct intel_pxp *pxp, u32 idx);
+
+#endif /* __INTEL_PXP_CMD_H__ */
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
index 3331868f354c..b8e24adeb1f3 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
@@ -7,6 +7,7 @@
 #include "i915_drv.h"
 
 #include "intel_pxp.h"
+#include "intel_pxp_cmd.h"
 #include "intel_pxp_session.h"
 #include "intel_pxp_tee.h"
 #include "intel_pxp_types.h"
@@ -15,6 +16,9 @@
 
 #define GEN12_KCR_SIP _MMIO(0x32260) /* KCR hwdrm session in play 0-31 */
 
+/* PXP global terminate register for session termination */
+#define PXP_GLOBAL_TERMINATE _MMIO(0x320f8)
+
 static bool intel_pxp_session_is_in_play(struct intel_pxp *pxp, u32 id)
 {
 	struct intel_gt *gt = pxp_to_gt(pxp);
@@ -72,3 +76,28 @@ int intel_pxp_create_arb_session(struct intel_pxp *pxp)
 
 	return 0;
 }
+
+int intel_pxp_terminate_arb_session_and_global(struct intel_pxp *pxp)
+{
+	int ret;
+	struct intel_gt *gt = pxp_to_gt(pxp);
+
+	pxp->arb_is_valid = false;
+
+	/* terminate the hw sessions */
+	ret = intel_pxp_terminate_session(pxp, ARB_SESSION);
+	if (ret) {
+		drm_err(&gt->i915->drm, "Failed to submit session termination\n");
+		return ret;
+	}
+
+	ret = pxp_wait_for_session_state(pxp, ARB_SESSION, false);
+	if (ret) {
+		drm_err(&gt->i915->drm, "Session state did not clear\n");
+		return ret;
+	}
+
+	intel_uncore_write(gt->uncore, PXP_GLOBAL_TERMINATE, 1);
+
+	return ret;
+}
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.h b/drivers/gpu/drm/i915/pxp/intel_pxp_session.h
index 316c3bebed9c..7354314b1cc4 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.h
@@ -11,5 +11,6 @@
 struct intel_pxp;
 
 int intel_pxp_create_arb_session(struct intel_pxp *pxp);
+int intel_pxp_terminate_arb_session_and_global(struct intel_pxp *pxp);
 
 #endif /* __INTEL_PXP_SESSION_H__ */
-- 
2.32.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v6 09/15] drm/i915/pxp: Implement PXP irq handler
  2021-07-29  2:00 ` [Intel-gfx] " Daniele Ceraolo Spurio
@ 2021-07-29  2:01   ` Daniele Ceraolo Spurio
  -1 siblings, 0 replies; 64+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-07-29  2:01 UTC (permalink / raw)
  To: intel-gfx
  Cc: Huang, Sean Z, dri-devel, Chris Wilson, Daniele Ceraolo Spurio,
	Huang, Rodrigo Vivi

From: "Huang, Sean Z" <sean.z.huang@intel.com>

The HW will generate a teardown interrupt when session termination is
required, which requires i915 to submit a terminating batch. Once the HW
is done with the termination it will generate another interrupt, at
which point it is safe to re-create the session.

Since the termination and re-creation flow is something we want to
trigger from the driver as well, use a common work function that can be
called both from the irq handler and from the driver set-up flows, which
has the addded benefit of allowing us to skip any extra locks because
the work itself serializes the operations.

v2: use struct completion instead of bool (Chris)
v3: drop locks, clean up functions and improve comments (Chris),
    move to common work function.
v4: improve comments, simplify wait logic (Rodrigo)
v5: unconditionally set interrupts, rename state_attacked var (Rodrigo)

Signed-off-by: Huang, Sean Z <sean.z.huang@intel.com>
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
---
 drivers/gpu/drm/i915/Makefile                |  1 +
 drivers/gpu/drm/i915/gt/intel_gt_irq.c       |  7 ++
 drivers/gpu/drm/i915/i915_reg.h              |  1 +
 drivers/gpu/drm/i915/pxp/intel_pxp.c         | 66 +++++++++++--
 drivers/gpu/drm/i915/pxp/intel_pxp.h         |  8 ++
 drivers/gpu/drm/i915/pxp/intel_pxp_irq.c     | 99 ++++++++++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_irq.h     | 32 +++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_session.c | 54 ++++++++++-
 drivers/gpu/drm/i915/pxp/intel_pxp_session.h |  5 +-
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c     |  8 +-
 drivers/gpu/drm/i915/pxp/intel_pxp_types.h   | 18 ++++
 11 files changed, 283 insertions(+), 16 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_irq.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index e13bc803e5ce..5dcdf5942d32 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -279,6 +279,7 @@ i915-y += i915_perf.o
 i915-$(CONFIG_DRM_I915_PXP) += \
 	pxp/intel_pxp.o \
 	pxp/intel_pxp_cmd.o \
+	pxp/intel_pxp_irq.o \
 	pxp/intel_pxp_session.o \
 	pxp/intel_pxp_tee.o
 
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_irq.c b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
index b2de83be4d97..699a74582d32 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_irq.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
@@ -13,6 +13,7 @@
 #include "intel_lrc_reg.h"
 #include "intel_uncore.h"
 #include "intel_rps.h"
+#include "pxp/intel_pxp_irq.h"
 
 static void guc_irq_handler(struct intel_guc *guc, u16 iir)
 {
@@ -64,6 +65,9 @@ gen11_other_irq_handler(struct intel_gt *gt, const u8 instance,
 	if (instance == OTHER_GTPM_INSTANCE)
 		return gen11_rps_irq_handler(&gt->rps, iir);
 
+	if (instance == OTHER_KCR_INSTANCE)
+		return intel_pxp_irq_handler(&gt->pxp, iir);
+
 	WARN_ONCE(1, "unhandled other interrupt instance=0x%x, iir=0x%x\n",
 		  instance, iir);
 }
@@ -196,6 +200,9 @@ void gen11_gt_irq_reset(struct intel_gt *gt)
 	intel_uncore_write(uncore, GEN11_GPM_WGBOXPERF_INTR_MASK,  ~0);
 	intel_uncore_write(uncore, GEN11_GUC_SG_INTR_ENABLE, 0);
 	intel_uncore_write(uncore, GEN11_GUC_SG_INTR_MASK,  ~0);
+
+	intel_uncore_write(uncore, GEN11_CRYPTO_RSVD_INTR_ENABLE, 0);
+	intel_uncore_write(uncore, GEN11_CRYPTO_RSVD_INTR_MASK,  ~0);
 }
 
 void gen11_gt_irq_postinstall(struct intel_gt *gt)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 70eed4fe3fe3..1a2a71916dfc 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -8086,6 +8086,7 @@ enum {
 /* irq instances for OTHER_CLASS */
 #define OTHER_GUC_INSTANCE	0
 #define OTHER_GTPM_INSTANCE	1
+#define OTHER_KCR_INSTANCE	4
 
 #define GEN11_INTR_IDENTITY_REG(x)	_MMIO(0x190060 + ((x) * 4))
 
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index 26176d43a02d..b0c7edc10cc3 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -2,7 +2,9 @@
 /*
  * Copyright(c) 2020 Intel Corporation.
  */
+#include <linux/workqueue.h>
 #include "intel_pxp.h"
+#include "intel_pxp_irq.h"
 #include "intel_pxp_session.h"
 #include "intel_pxp_tee.h"
 #include "gt/intel_context.h"
@@ -68,6 +70,16 @@ void intel_pxp_init(struct intel_pxp *pxp)
 
 	mutex_init(&pxp->tee_mutex);
 
+	/*
+	 * we'll use the completion to check if there is a termination pending,
+	 * so we start it as completed and we reinit it when a termination
+	 * is triggered.
+	 */
+	init_completion(&pxp->termination);
+	complete_all(&pxp->termination);
+
+	INIT_WORK(&pxp->session_work, intel_pxp_session_work);
+
 	ret = create_vcs_context(pxp);
 	if (ret)
 		return;
@@ -96,19 +108,61 @@ void intel_pxp_fini(struct intel_pxp *pxp)
 	destroy_vcs_context(pxp);
 }
 
-void intel_pxp_init_hw(struct intel_pxp *pxp)
+void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp)
 {
-	int ret;
+	pxp->arb_is_valid = false;
+	reinit_completion(&pxp->termination);
+}
+
+static void intel_pxp_queue_termination(struct intel_pxp *pxp)
+{
+	struct intel_gt *gt = pxp_to_gt(pxp);
+
+	/*
+	 * We want to get the same effect as if we received a termination
+	 * interrupt, so just pretend that we did.
+	 */
+	spin_lock_irq(&gt->irq_lock);
+	intel_pxp_mark_termination_in_progress(pxp);
+	pxp->session_events |= PXP_TERMINATION_REQUEST;
+	queue_work(system_unbound_wq, &pxp->session_work);
+	spin_unlock_irq(&gt->irq_lock);
+}
 
+/*
+ * the arb session is restarted from the irq work when we receive the
+ * termination completion interrupt
+ */
+int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp)
+{
+	if (!intel_pxp_is_enabled(pxp))
+		return 0;
+
+	if (!wait_for_completion_timeout(&pxp->termination,
+					 msecs_to_jiffies(100)))
+		return -ETIMEDOUT;
+
+	if (!pxp->arb_is_valid)
+		return -EIO;
+
+	return 0;
+}
+
+void intel_pxp_init_hw(struct intel_pxp *pxp)
+{
 	kcr_pxp_enable(pxp_to_gt(pxp));
+	intel_pxp_irq_enable(pxp);
 
-	/* always emit a full termination to clean the state */
-	ret = intel_pxp_terminate_arb_session_and_global(pxp);
-	if (!ret)
-		intel_pxp_create_arb_session(pxp);
+	/*
+	 * the session could've been attacked while we weren't loaded, so
+	 * handle it as if it was and re-create it.
+	 */
+	intel_pxp_queue_termination(pxp);
 }
 
 void intel_pxp_fini_hw(struct intel_pxp *pxp)
 {
 	kcr_pxp_disable(pxp_to_gt(pxp));
+
+	intel_pxp_irq_disable(pxp);
 }
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
index 8eeb65af78b1..074b3b980957 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
@@ -30,6 +30,9 @@ void intel_pxp_fini(struct intel_pxp *pxp);
 
 void intel_pxp_init_hw(struct intel_pxp *pxp);
 void intel_pxp_fini_hw(struct intel_pxp *pxp);
+
+void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp);
+int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp);
 #else
 static inline void intel_pxp_init(struct intel_pxp *pxp)
 {
@@ -38,6 +41,11 @@ static inline void intel_pxp_init(struct intel_pxp *pxp)
 static inline void intel_pxp_fini(struct intel_pxp *pxp)
 {
 }
+
+static inline int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp)
+{
+	return 0;
+}
 #endif
 
 #endif /* __INTEL_PXP_H__ */
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
new file mode 100644
index 000000000000..46eca1e81b9b
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright(c) 2020 Intel Corporation.
+ */
+#include <linux/workqueue.h>
+#include "intel_pxp.h"
+#include "intel_pxp_irq.h"
+#include "intel_pxp_session.h"
+#include "gt/intel_gt_irq.h"
+#include "i915_irq.h"
+#include "i915_reg.h"
+
+/**
+ * intel_pxp_irq_handler - Handles PXP interrupts.
+ * @pxp: pointer to pxp struct
+ * @iir: interrupt vector
+ */
+void intel_pxp_irq_handler(struct intel_pxp *pxp, u16 iir)
+{
+	struct intel_gt *gt = pxp_to_gt(pxp);
+
+	if (GEM_WARN_ON(!intel_pxp_is_enabled(pxp)))
+		return;
+
+	lockdep_assert_held(&gt->irq_lock);
+
+	if (unlikely(!iir))
+		return;
+
+	if (iir & (GEN12_DISPLAY_PXP_STATE_TERMINATED_INTERRUPT |
+		   GEN12_DISPLAY_APP_TERMINATED_PER_FW_REQ_INTERRUPT)) {
+		/* immediately mark PXP as inactive on termination */
+		intel_pxp_mark_termination_in_progress(pxp);
+		pxp->session_events |= PXP_TERMINATION_REQUEST;
+	}
+
+	if (iir & GEN12_DISPLAY_STATE_RESET_COMPLETE_INTERRUPT)
+		pxp->session_events |= PXP_TERMINATION_COMPLETE;
+
+	if (pxp->session_events)
+		queue_work(system_unbound_wq, &pxp->session_work);
+}
+
+static inline void __pxp_set_interrupts(struct intel_gt *gt, u32 interrupts)
+{
+	struct intel_uncore *uncore = gt->uncore;
+	const u32 mask = interrupts << 16;
+
+	intel_uncore_write(uncore, GEN11_CRYPTO_RSVD_INTR_ENABLE, mask);
+	intel_uncore_write(uncore, GEN11_CRYPTO_RSVD_INTR_MASK,  ~mask);
+}
+
+static inline void pxp_irq_reset(struct intel_gt *gt)
+{
+	spin_lock_irq(&gt->irq_lock);
+	gen11_gt_reset_one_iir(gt, 0, GEN11_KCR);
+	spin_unlock_irq(&gt->irq_lock);
+}
+
+void intel_pxp_irq_enable(struct intel_pxp *pxp)
+{
+	struct intel_gt *gt = pxp_to_gt(pxp);
+
+	spin_lock_irq(&gt->irq_lock);
+
+	if (!pxp->irq_enabled)
+		WARN_ON_ONCE(gen11_gt_reset_one_iir(gt, 0, GEN11_KCR));
+
+	__pxp_set_interrupts(gt, GEN12_PXP_INTERRUPTS);
+	pxp->irq_enabled = true;
+
+	spin_unlock_irq(&gt->irq_lock);
+}
+
+void intel_pxp_irq_disable(struct intel_pxp *pxp)
+{
+	struct intel_gt *gt = pxp_to_gt(pxp);
+
+	/*
+	 * We always need to submit a global termination when we re-enable the
+	 * interrupts, so there is no need to make sure that the session state
+	 * makes sense at the end of this function. Just make sure this is not
+	 * called in a path were the driver consider the session as valid and
+	 * doesn't call a termination on restart.
+	 */
+	GEM_WARN_ON(intel_pxp_is_active(pxp));
+
+	spin_lock_irq(&gt->irq_lock);
+
+	pxp->irq_enabled = false;
+	__pxp_set_interrupts(gt, 0);
+
+	spin_unlock_irq(&gt->irq_lock);
+	intel_synchronize_irq(gt->i915);
+
+	pxp_irq_reset(gt);
+
+	flush_work(&pxp->session_work);
+}
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_irq.h b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.h
new file mode 100644
index 000000000000..8b5793654844
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright(c) 2020, Intel Corporation. All rights reserved.
+ */
+
+#ifndef __INTEL_PXP_IRQ_H__
+#define __INTEL_PXP_IRQ_H__
+
+#include <linux/types.h>
+
+struct intel_pxp;
+
+#define GEN12_DISPLAY_PXP_STATE_TERMINATED_INTERRUPT BIT(1)
+#define GEN12_DISPLAY_APP_TERMINATED_PER_FW_REQ_INTERRUPT BIT(2)
+#define GEN12_DISPLAY_STATE_RESET_COMPLETE_INTERRUPT BIT(3)
+
+#define GEN12_PXP_INTERRUPTS \
+	(GEN12_DISPLAY_PXP_STATE_TERMINATED_INTERRUPT | \
+	 GEN12_DISPLAY_APP_TERMINATED_PER_FW_REQ_INTERRUPT | \
+	 GEN12_DISPLAY_STATE_RESET_COMPLETE_INTERRUPT)
+
+#ifdef CONFIG_DRM_I915_PXP
+void intel_pxp_irq_enable(struct intel_pxp *pxp);
+void intel_pxp_irq_disable(struct intel_pxp *pxp);
+void intel_pxp_irq_handler(struct intel_pxp *pxp, u16 iir);
+#else
+static inline void intel_pxp_irq_handler(struct intel_pxp *pxp, u16 iir)
+{
+}
+#endif
+
+#endif /* __INTEL_PXP_IRQ_H__ */
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
index b8e24adeb1f3..67c30e534d50 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
@@ -48,7 +48,7 @@ static int pxp_wait_for_session_state(struct intel_pxp *pxp, u32 id, bool in_pla
 	return ret;
 }
 
-int intel_pxp_create_arb_session(struct intel_pxp *pxp)
+static int pxp_create_arb_session(struct intel_pxp *pxp)
 {
 	struct intel_gt *gt = pxp_to_gt(pxp);
 	int ret;
@@ -77,12 +77,13 @@ int intel_pxp_create_arb_session(struct intel_pxp *pxp)
 	return 0;
 }
 
-int intel_pxp_terminate_arb_session_and_global(struct intel_pxp *pxp)
+static int pxp_terminate_arb_session_and_global(struct intel_pxp *pxp)
 {
 	int ret;
 	struct intel_gt *gt = pxp_to_gt(pxp);
 
-	pxp->arb_is_valid = false;
+	/* must mark termination in progress calling this function */
+	GEM_WARN_ON(pxp->arb_is_valid);
 
 	/* terminate the hw sessions */
 	ret = intel_pxp_terminate_session(pxp, ARB_SESSION);
@@ -101,3 +102,50 @@ int intel_pxp_terminate_arb_session_and_global(struct intel_pxp *pxp)
 
 	return ret;
 }
+
+static void pxp_terminate(struct intel_pxp *pxp)
+{
+	int ret;
+
+	pxp->hw_state_invalidated = true;
+
+	/*
+	 * if we fail to submit the termination there is no point in waiting for
+	 * it to complete. PXP will be marked as non-active until the next
+	 * termination is issued.
+	 */
+	ret = pxp_terminate_arb_session_and_global(pxp);
+	if (ret)
+		complete_all(&pxp->termination);
+}
+
+static void pxp_terminate_complete(struct intel_pxp *pxp)
+{
+	/* Re-create the arb session after teardown handle complete */
+	if (fetch_and_zero(&pxp->hw_state_invalidated))
+		pxp_create_arb_session(pxp);
+
+	complete_all(&pxp->termination);
+}
+
+void intel_pxp_session_work(struct work_struct *work)
+{
+	struct intel_pxp *pxp = container_of(work, typeof(*pxp), session_work);
+	struct intel_gt *gt = pxp_to_gt(pxp);
+	u32 events = 0;
+
+	spin_lock_irq(&gt->irq_lock);
+	events = fetch_and_zero(&pxp->session_events);
+	spin_unlock_irq(&gt->irq_lock);
+
+	if (!events)
+		return;
+
+	if (events & PXP_TERMINATION_REQUEST) {
+		events &= ~PXP_TERMINATION_COMPLETE;
+		pxp_terminate(pxp);
+	}
+
+	if (events & PXP_TERMINATION_COMPLETE)
+		pxp_terminate_complete(pxp);
+}
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.h b/drivers/gpu/drm/i915/pxp/intel_pxp_session.h
index 7354314b1cc4..ba4c9d2b94b7 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.h
@@ -8,9 +8,8 @@
 
 #include <linux/types.h>
 
-struct intel_pxp;
+struct work_struct;
 
-int intel_pxp_create_arb_session(struct intel_pxp *pxp);
-int intel_pxp_terminate_arb_session_and_global(struct intel_pxp *pxp);
+void intel_pxp_session_work(struct work_struct *work);
 
 #endif /* __INTEL_PXP_SESSION_H__ */
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
index 3662bf67407a..7693540dc1f9 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
@@ -80,6 +80,7 @@ static int i915_pxp_tee_component_bind(struct device *i915_kdev,
 {
 	struct drm_i915_private *i915 = kdev_to_i915(i915_kdev);
 	struct intel_pxp *pxp = i915_dev_to_pxp(i915_kdev);
+	int ret;
 
 	mutex_lock(&pxp->tee_mutex);
 	pxp->pxp_component = data;
@@ -88,15 +89,14 @@ static int i915_pxp_tee_component_bind(struct device *i915_kdev,
 
 	/* the component is required to fully start the PXP HW */
 	intel_pxp_init_hw(pxp);
-
-	if (!pxp->arb_is_valid) {
+	ret = intel_pxp_wait_for_arb_start(pxp);
+	if (ret) {
 		drm_err(&i915->drm, "Failed to create arb session during bind\n");
 		intel_pxp_fini_hw(pxp);
 		pxp->pxp_component = NULL;
-		return -EIO;
 	}
 
-	return 0;
+	return ret;
 }
 
 static void i915_pxp_tee_component_unbind(struct device *i915_kdev,
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
index a4797a98c1f9..475e3312c287 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
@@ -6,8 +6,10 @@
 #ifndef __INTEL_PXP_TYPES_H__
 #define __INTEL_PXP_TYPES_H__
 
+#include <linux/completion.h>
 #include <linux/mutex.h>
 #include <linux/types.h>
+#include <linux/workqueue.h>
 
 struct intel_context;
 struct i915_pxp_component;
@@ -25,6 +27,22 @@ struct intel_pxp {
 	bool arb_is_valid;
 
 	struct mutex tee_mutex; /* protects the tee channel binding */
+
+	/*
+	 * If the HW perceives an attack on the integrity of the encryption it
+	 * will invalidate the keys and expect SW to re-initialize the session.
+	 * We keep track of this state to make sure we only re-start the arb
+	 * session when required.
+	 */
+	bool hw_state_invalidated;
+
+	bool irq_enabled;
+	struct completion termination;
+
+	struct work_struct session_work;
+	u32 session_events; /* protected with gt->irq_lock */
+#define PXP_TERMINATION_REQUEST  BIT(0)
+#define PXP_TERMINATION_COMPLETE BIT(1)
 };
 
 #endif /* __INTEL_PXP_TYPES_H__ */
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [Intel-gfx] [PATCH v6 09/15] drm/i915/pxp: Implement PXP irq handler
@ 2021-07-29  2:01   ` Daniele Ceraolo Spurio
  0 siblings, 0 replies; 64+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-07-29  2:01 UTC (permalink / raw)
  To: intel-gfx; +Cc: Huang, Sean Z, dri-devel, Chris Wilson, Huang

From: "Huang, Sean Z" <sean.z.huang@intel.com>

The HW will generate a teardown interrupt when session termination is
required, which requires i915 to submit a terminating batch. Once the HW
is done with the termination it will generate another interrupt, at
which point it is safe to re-create the session.

Since the termination and re-creation flow is something we want to
trigger from the driver as well, use a common work function that can be
called both from the irq handler and from the driver set-up flows, which
has the addded benefit of allowing us to skip any extra locks because
the work itself serializes the operations.

v2: use struct completion instead of bool (Chris)
v3: drop locks, clean up functions and improve comments (Chris),
    move to common work function.
v4: improve comments, simplify wait logic (Rodrigo)
v5: unconditionally set interrupts, rename state_attacked var (Rodrigo)

Signed-off-by: Huang, Sean Z <sean.z.huang@intel.com>
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
---
 drivers/gpu/drm/i915/Makefile                |  1 +
 drivers/gpu/drm/i915/gt/intel_gt_irq.c       |  7 ++
 drivers/gpu/drm/i915/i915_reg.h              |  1 +
 drivers/gpu/drm/i915/pxp/intel_pxp.c         | 66 +++++++++++--
 drivers/gpu/drm/i915/pxp/intel_pxp.h         |  8 ++
 drivers/gpu/drm/i915/pxp/intel_pxp_irq.c     | 99 ++++++++++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_irq.h     | 32 +++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_session.c | 54 ++++++++++-
 drivers/gpu/drm/i915/pxp/intel_pxp_session.h |  5 +-
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c     |  8 +-
 drivers/gpu/drm/i915/pxp/intel_pxp_types.h   | 18 ++++
 11 files changed, 283 insertions(+), 16 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_irq.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index e13bc803e5ce..5dcdf5942d32 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -279,6 +279,7 @@ i915-y += i915_perf.o
 i915-$(CONFIG_DRM_I915_PXP) += \
 	pxp/intel_pxp.o \
 	pxp/intel_pxp_cmd.o \
+	pxp/intel_pxp_irq.o \
 	pxp/intel_pxp_session.o \
 	pxp/intel_pxp_tee.o
 
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_irq.c b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
index b2de83be4d97..699a74582d32 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_irq.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
@@ -13,6 +13,7 @@
 #include "intel_lrc_reg.h"
 #include "intel_uncore.h"
 #include "intel_rps.h"
+#include "pxp/intel_pxp_irq.h"
 
 static void guc_irq_handler(struct intel_guc *guc, u16 iir)
 {
@@ -64,6 +65,9 @@ gen11_other_irq_handler(struct intel_gt *gt, const u8 instance,
 	if (instance == OTHER_GTPM_INSTANCE)
 		return gen11_rps_irq_handler(&gt->rps, iir);
 
+	if (instance == OTHER_KCR_INSTANCE)
+		return intel_pxp_irq_handler(&gt->pxp, iir);
+
 	WARN_ONCE(1, "unhandled other interrupt instance=0x%x, iir=0x%x\n",
 		  instance, iir);
 }
@@ -196,6 +200,9 @@ void gen11_gt_irq_reset(struct intel_gt *gt)
 	intel_uncore_write(uncore, GEN11_GPM_WGBOXPERF_INTR_MASK,  ~0);
 	intel_uncore_write(uncore, GEN11_GUC_SG_INTR_ENABLE, 0);
 	intel_uncore_write(uncore, GEN11_GUC_SG_INTR_MASK,  ~0);
+
+	intel_uncore_write(uncore, GEN11_CRYPTO_RSVD_INTR_ENABLE, 0);
+	intel_uncore_write(uncore, GEN11_CRYPTO_RSVD_INTR_MASK,  ~0);
 }
 
 void gen11_gt_irq_postinstall(struct intel_gt *gt)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 70eed4fe3fe3..1a2a71916dfc 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -8086,6 +8086,7 @@ enum {
 /* irq instances for OTHER_CLASS */
 #define OTHER_GUC_INSTANCE	0
 #define OTHER_GTPM_INSTANCE	1
+#define OTHER_KCR_INSTANCE	4
 
 #define GEN11_INTR_IDENTITY_REG(x)	_MMIO(0x190060 + ((x) * 4))
 
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index 26176d43a02d..b0c7edc10cc3 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -2,7 +2,9 @@
 /*
  * Copyright(c) 2020 Intel Corporation.
  */
+#include <linux/workqueue.h>
 #include "intel_pxp.h"
+#include "intel_pxp_irq.h"
 #include "intel_pxp_session.h"
 #include "intel_pxp_tee.h"
 #include "gt/intel_context.h"
@@ -68,6 +70,16 @@ void intel_pxp_init(struct intel_pxp *pxp)
 
 	mutex_init(&pxp->tee_mutex);
 
+	/*
+	 * we'll use the completion to check if there is a termination pending,
+	 * so we start it as completed and we reinit it when a termination
+	 * is triggered.
+	 */
+	init_completion(&pxp->termination);
+	complete_all(&pxp->termination);
+
+	INIT_WORK(&pxp->session_work, intel_pxp_session_work);
+
 	ret = create_vcs_context(pxp);
 	if (ret)
 		return;
@@ -96,19 +108,61 @@ void intel_pxp_fini(struct intel_pxp *pxp)
 	destroy_vcs_context(pxp);
 }
 
-void intel_pxp_init_hw(struct intel_pxp *pxp)
+void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp)
 {
-	int ret;
+	pxp->arb_is_valid = false;
+	reinit_completion(&pxp->termination);
+}
+
+static void intel_pxp_queue_termination(struct intel_pxp *pxp)
+{
+	struct intel_gt *gt = pxp_to_gt(pxp);
+
+	/*
+	 * We want to get the same effect as if we received a termination
+	 * interrupt, so just pretend that we did.
+	 */
+	spin_lock_irq(&gt->irq_lock);
+	intel_pxp_mark_termination_in_progress(pxp);
+	pxp->session_events |= PXP_TERMINATION_REQUEST;
+	queue_work(system_unbound_wq, &pxp->session_work);
+	spin_unlock_irq(&gt->irq_lock);
+}
 
+/*
+ * the arb session is restarted from the irq work when we receive the
+ * termination completion interrupt
+ */
+int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp)
+{
+	if (!intel_pxp_is_enabled(pxp))
+		return 0;
+
+	if (!wait_for_completion_timeout(&pxp->termination,
+					 msecs_to_jiffies(100)))
+		return -ETIMEDOUT;
+
+	if (!pxp->arb_is_valid)
+		return -EIO;
+
+	return 0;
+}
+
+void intel_pxp_init_hw(struct intel_pxp *pxp)
+{
 	kcr_pxp_enable(pxp_to_gt(pxp));
+	intel_pxp_irq_enable(pxp);
 
-	/* always emit a full termination to clean the state */
-	ret = intel_pxp_terminate_arb_session_and_global(pxp);
-	if (!ret)
-		intel_pxp_create_arb_session(pxp);
+	/*
+	 * the session could've been attacked while we weren't loaded, so
+	 * handle it as if it was and re-create it.
+	 */
+	intel_pxp_queue_termination(pxp);
 }
 
 void intel_pxp_fini_hw(struct intel_pxp *pxp)
 {
 	kcr_pxp_disable(pxp_to_gt(pxp));
+
+	intel_pxp_irq_disable(pxp);
 }
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
index 8eeb65af78b1..074b3b980957 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
@@ -30,6 +30,9 @@ void intel_pxp_fini(struct intel_pxp *pxp);
 
 void intel_pxp_init_hw(struct intel_pxp *pxp);
 void intel_pxp_fini_hw(struct intel_pxp *pxp);
+
+void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp);
+int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp);
 #else
 static inline void intel_pxp_init(struct intel_pxp *pxp)
 {
@@ -38,6 +41,11 @@ static inline void intel_pxp_init(struct intel_pxp *pxp)
 static inline void intel_pxp_fini(struct intel_pxp *pxp)
 {
 }
+
+static inline int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp)
+{
+	return 0;
+}
 #endif
 
 #endif /* __INTEL_PXP_H__ */
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
new file mode 100644
index 000000000000..46eca1e81b9b
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright(c) 2020 Intel Corporation.
+ */
+#include <linux/workqueue.h>
+#include "intel_pxp.h"
+#include "intel_pxp_irq.h"
+#include "intel_pxp_session.h"
+#include "gt/intel_gt_irq.h"
+#include "i915_irq.h"
+#include "i915_reg.h"
+
+/**
+ * intel_pxp_irq_handler - Handles PXP interrupts.
+ * @pxp: pointer to pxp struct
+ * @iir: interrupt vector
+ */
+void intel_pxp_irq_handler(struct intel_pxp *pxp, u16 iir)
+{
+	struct intel_gt *gt = pxp_to_gt(pxp);
+
+	if (GEM_WARN_ON(!intel_pxp_is_enabled(pxp)))
+		return;
+
+	lockdep_assert_held(&gt->irq_lock);
+
+	if (unlikely(!iir))
+		return;
+
+	if (iir & (GEN12_DISPLAY_PXP_STATE_TERMINATED_INTERRUPT |
+		   GEN12_DISPLAY_APP_TERMINATED_PER_FW_REQ_INTERRUPT)) {
+		/* immediately mark PXP as inactive on termination */
+		intel_pxp_mark_termination_in_progress(pxp);
+		pxp->session_events |= PXP_TERMINATION_REQUEST;
+	}
+
+	if (iir & GEN12_DISPLAY_STATE_RESET_COMPLETE_INTERRUPT)
+		pxp->session_events |= PXP_TERMINATION_COMPLETE;
+
+	if (pxp->session_events)
+		queue_work(system_unbound_wq, &pxp->session_work);
+}
+
+static inline void __pxp_set_interrupts(struct intel_gt *gt, u32 interrupts)
+{
+	struct intel_uncore *uncore = gt->uncore;
+	const u32 mask = interrupts << 16;
+
+	intel_uncore_write(uncore, GEN11_CRYPTO_RSVD_INTR_ENABLE, mask);
+	intel_uncore_write(uncore, GEN11_CRYPTO_RSVD_INTR_MASK,  ~mask);
+}
+
+static inline void pxp_irq_reset(struct intel_gt *gt)
+{
+	spin_lock_irq(&gt->irq_lock);
+	gen11_gt_reset_one_iir(gt, 0, GEN11_KCR);
+	spin_unlock_irq(&gt->irq_lock);
+}
+
+void intel_pxp_irq_enable(struct intel_pxp *pxp)
+{
+	struct intel_gt *gt = pxp_to_gt(pxp);
+
+	spin_lock_irq(&gt->irq_lock);
+
+	if (!pxp->irq_enabled)
+		WARN_ON_ONCE(gen11_gt_reset_one_iir(gt, 0, GEN11_KCR));
+
+	__pxp_set_interrupts(gt, GEN12_PXP_INTERRUPTS);
+	pxp->irq_enabled = true;
+
+	spin_unlock_irq(&gt->irq_lock);
+}
+
+void intel_pxp_irq_disable(struct intel_pxp *pxp)
+{
+	struct intel_gt *gt = pxp_to_gt(pxp);
+
+	/*
+	 * We always need to submit a global termination when we re-enable the
+	 * interrupts, so there is no need to make sure that the session state
+	 * makes sense at the end of this function. Just make sure this is not
+	 * called in a path were the driver consider the session as valid and
+	 * doesn't call a termination on restart.
+	 */
+	GEM_WARN_ON(intel_pxp_is_active(pxp));
+
+	spin_lock_irq(&gt->irq_lock);
+
+	pxp->irq_enabled = false;
+	__pxp_set_interrupts(gt, 0);
+
+	spin_unlock_irq(&gt->irq_lock);
+	intel_synchronize_irq(gt->i915);
+
+	pxp_irq_reset(gt);
+
+	flush_work(&pxp->session_work);
+}
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_irq.h b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.h
new file mode 100644
index 000000000000..8b5793654844
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright(c) 2020, Intel Corporation. All rights reserved.
+ */
+
+#ifndef __INTEL_PXP_IRQ_H__
+#define __INTEL_PXP_IRQ_H__
+
+#include <linux/types.h>
+
+struct intel_pxp;
+
+#define GEN12_DISPLAY_PXP_STATE_TERMINATED_INTERRUPT BIT(1)
+#define GEN12_DISPLAY_APP_TERMINATED_PER_FW_REQ_INTERRUPT BIT(2)
+#define GEN12_DISPLAY_STATE_RESET_COMPLETE_INTERRUPT BIT(3)
+
+#define GEN12_PXP_INTERRUPTS \
+	(GEN12_DISPLAY_PXP_STATE_TERMINATED_INTERRUPT | \
+	 GEN12_DISPLAY_APP_TERMINATED_PER_FW_REQ_INTERRUPT | \
+	 GEN12_DISPLAY_STATE_RESET_COMPLETE_INTERRUPT)
+
+#ifdef CONFIG_DRM_I915_PXP
+void intel_pxp_irq_enable(struct intel_pxp *pxp);
+void intel_pxp_irq_disable(struct intel_pxp *pxp);
+void intel_pxp_irq_handler(struct intel_pxp *pxp, u16 iir);
+#else
+static inline void intel_pxp_irq_handler(struct intel_pxp *pxp, u16 iir)
+{
+}
+#endif
+
+#endif /* __INTEL_PXP_IRQ_H__ */
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
index b8e24adeb1f3..67c30e534d50 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
@@ -48,7 +48,7 @@ static int pxp_wait_for_session_state(struct intel_pxp *pxp, u32 id, bool in_pla
 	return ret;
 }
 
-int intel_pxp_create_arb_session(struct intel_pxp *pxp)
+static int pxp_create_arb_session(struct intel_pxp *pxp)
 {
 	struct intel_gt *gt = pxp_to_gt(pxp);
 	int ret;
@@ -77,12 +77,13 @@ int intel_pxp_create_arb_session(struct intel_pxp *pxp)
 	return 0;
 }
 
-int intel_pxp_terminate_arb_session_and_global(struct intel_pxp *pxp)
+static int pxp_terminate_arb_session_and_global(struct intel_pxp *pxp)
 {
 	int ret;
 	struct intel_gt *gt = pxp_to_gt(pxp);
 
-	pxp->arb_is_valid = false;
+	/* must mark termination in progress calling this function */
+	GEM_WARN_ON(pxp->arb_is_valid);
 
 	/* terminate the hw sessions */
 	ret = intel_pxp_terminate_session(pxp, ARB_SESSION);
@@ -101,3 +102,50 @@ int intel_pxp_terminate_arb_session_and_global(struct intel_pxp *pxp)
 
 	return ret;
 }
+
+static void pxp_terminate(struct intel_pxp *pxp)
+{
+	int ret;
+
+	pxp->hw_state_invalidated = true;
+
+	/*
+	 * if we fail to submit the termination there is no point in waiting for
+	 * it to complete. PXP will be marked as non-active until the next
+	 * termination is issued.
+	 */
+	ret = pxp_terminate_arb_session_and_global(pxp);
+	if (ret)
+		complete_all(&pxp->termination);
+}
+
+static void pxp_terminate_complete(struct intel_pxp *pxp)
+{
+	/* Re-create the arb session after teardown handle complete */
+	if (fetch_and_zero(&pxp->hw_state_invalidated))
+		pxp_create_arb_session(pxp);
+
+	complete_all(&pxp->termination);
+}
+
+void intel_pxp_session_work(struct work_struct *work)
+{
+	struct intel_pxp *pxp = container_of(work, typeof(*pxp), session_work);
+	struct intel_gt *gt = pxp_to_gt(pxp);
+	u32 events = 0;
+
+	spin_lock_irq(&gt->irq_lock);
+	events = fetch_and_zero(&pxp->session_events);
+	spin_unlock_irq(&gt->irq_lock);
+
+	if (!events)
+		return;
+
+	if (events & PXP_TERMINATION_REQUEST) {
+		events &= ~PXP_TERMINATION_COMPLETE;
+		pxp_terminate(pxp);
+	}
+
+	if (events & PXP_TERMINATION_COMPLETE)
+		pxp_terminate_complete(pxp);
+}
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.h b/drivers/gpu/drm/i915/pxp/intel_pxp_session.h
index 7354314b1cc4..ba4c9d2b94b7 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.h
@@ -8,9 +8,8 @@
 
 #include <linux/types.h>
 
-struct intel_pxp;
+struct work_struct;
 
-int intel_pxp_create_arb_session(struct intel_pxp *pxp);
-int intel_pxp_terminate_arb_session_and_global(struct intel_pxp *pxp);
+void intel_pxp_session_work(struct work_struct *work);
 
 #endif /* __INTEL_PXP_SESSION_H__ */
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
index 3662bf67407a..7693540dc1f9 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
@@ -80,6 +80,7 @@ static int i915_pxp_tee_component_bind(struct device *i915_kdev,
 {
 	struct drm_i915_private *i915 = kdev_to_i915(i915_kdev);
 	struct intel_pxp *pxp = i915_dev_to_pxp(i915_kdev);
+	int ret;
 
 	mutex_lock(&pxp->tee_mutex);
 	pxp->pxp_component = data;
@@ -88,15 +89,14 @@ static int i915_pxp_tee_component_bind(struct device *i915_kdev,
 
 	/* the component is required to fully start the PXP HW */
 	intel_pxp_init_hw(pxp);
-
-	if (!pxp->arb_is_valid) {
+	ret = intel_pxp_wait_for_arb_start(pxp);
+	if (ret) {
 		drm_err(&i915->drm, "Failed to create arb session during bind\n");
 		intel_pxp_fini_hw(pxp);
 		pxp->pxp_component = NULL;
-		return -EIO;
 	}
 
-	return 0;
+	return ret;
 }
 
 static void i915_pxp_tee_component_unbind(struct device *i915_kdev,
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
index a4797a98c1f9..475e3312c287 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
@@ -6,8 +6,10 @@
 #ifndef __INTEL_PXP_TYPES_H__
 #define __INTEL_PXP_TYPES_H__
 
+#include <linux/completion.h>
 #include <linux/mutex.h>
 #include <linux/types.h>
+#include <linux/workqueue.h>
 
 struct intel_context;
 struct i915_pxp_component;
@@ -25,6 +27,22 @@ struct intel_pxp {
 	bool arb_is_valid;
 
 	struct mutex tee_mutex; /* protects the tee channel binding */
+
+	/*
+	 * If the HW perceives an attack on the integrity of the encryption it
+	 * will invalidate the keys and expect SW to re-initialize the session.
+	 * We keep track of this state to make sure we only re-start the arb
+	 * session when required.
+	 */
+	bool hw_state_invalidated;
+
+	bool irq_enabled;
+	struct completion termination;
+
+	struct work_struct session_work;
+	u32 session_events; /* protected with gt->irq_lock */
+#define PXP_TERMINATION_REQUEST  BIT(0)
+#define PXP_TERMINATION_COMPLETE BIT(1)
 };
 
 #endif /* __INTEL_PXP_TYPES_H__ */
-- 
2.32.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v6 10/15] drm/i915/pxp: interfaces for using protected objects
  2021-07-29  2:00 ` [Intel-gfx] " Daniele Ceraolo Spurio
@ 2021-07-29  2:01   ` Daniele Ceraolo Spurio
  -1 siblings, 0 replies; 64+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-07-29  2:01 UTC (permalink / raw)
  To: intel-gfx
  Cc: Daniel Vetter, Chris Wilson, Daniele Ceraolo Spurio, dri-devel,
	Jason Ekstrand, Rodrigo Vivi, Bommu Krishnaiah

This api allow user mode to create protected buffers and to mark
contexts as making use of such objects. Only when using contexts
marked in such a way is the execution guaranteed to work as expected.

Contexts can only be marked as using protected content at creation time
(i.e. the parameter is immutable) and they must be both bannable and not
recoverable.

All protected objects and contexts that have backing storage will be
considered invalid when the PXP session is destroyed and all new
submissions using them will be rejected. All intel contexts within the
invalidated gem contexts will be marked banned. A new flag has been
added to the RESET_STATS ioctl to report the context invalidation to
userspace.

This patch was previously sent as 2 separate patches, which have been
squashed following a request to have all the uapi in a single patch.
I've retained the s-o-b from both.

v5: squash patches, rebase on proto_ctx, update kerneldoc

v6: rebase on obj create_ext changes

Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Cc: Jason Ekstrand <jason@jlekstrand.net>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> #v5
---
 drivers/gpu/drm/i915/gem/i915_gem_context.c   | 68 ++++++++++++--
 drivers/gpu/drm/i915/gem/i915_gem_context.h   | 18 ++++
 .../gpu/drm/i915/gem/i915_gem_context_types.h |  2 +
 drivers/gpu/drm/i915/gem/i915_gem_create.c    | 75 ++++++++++++----
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 40 ++++++++-
 drivers/gpu/drm/i915/gem/i915_gem_object.c    |  6 ++
 drivers/gpu/drm/i915/gem/i915_gem_object.h    | 12 +++
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |  9 ++
 drivers/gpu/drm/i915/pxp/intel_pxp.c          | 89 +++++++++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp.h          | 15 ++++
 drivers/gpu/drm/i915/pxp/intel_pxp_session.c  |  3 +
 drivers/gpu/drm/i915/pxp/intel_pxp_types.h    |  5 ++
 include/uapi/drm/i915_drm.h                   | 55 +++++++++++-
 13 files changed, 371 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c
index cff72679ad7c..0cd3e2d06188 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
@@ -77,6 +77,8 @@
 #include "gt/intel_gpu_commands.h"
 #include "gt/intel_ring.h"
 
+#include "pxp/intel_pxp.h"
+
 #include "i915_gem_context.h"
 #include "i915_trace.h"
 #include "i915_user_extensions.h"
@@ -241,6 +243,25 @@ static int proto_context_set_persistence(struct drm_i915_private *i915,
 	return 0;
 }
 
+static int proto_context_set_protected(struct drm_i915_private *i915,
+				       struct i915_gem_proto_context *pc,
+				       bool protected)
+{
+	int ret = 0;
+
+	if (!intel_pxp_is_enabled(&i915->gt.pxp))
+		ret = -ENODEV;
+	else if (!protected)
+		pc->user_flags &= ~BIT(UCONTEXT_PROTECTED);
+	else if ((pc->user_flags & BIT(UCONTEXT_RECOVERABLE)) ||
+		 !(pc->user_flags & BIT(UCONTEXT_BANNABLE)))
+		ret = -EPERM;
+	else
+		pc->user_flags |= BIT(UCONTEXT_PROTECTED);
+
+	return ret;
+}
+
 static struct i915_gem_proto_context *
 proto_context_create(struct drm_i915_private *i915, unsigned int flags)
 {
@@ -686,6 +707,8 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
 			ret = -EPERM;
 		else if (args->value)
 			pc->user_flags |= BIT(UCONTEXT_BANNABLE);
+		else if (pc->user_flags & BIT(UCONTEXT_PROTECTED))
+			ret = -EPERM;
 		else
 			pc->user_flags &= ~BIT(UCONTEXT_BANNABLE);
 		break;
@@ -693,10 +716,12 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
 	case I915_CONTEXT_PARAM_RECOVERABLE:
 		if (args->size)
 			ret = -EINVAL;
-		else if (args->value)
-			pc->user_flags |= BIT(UCONTEXT_RECOVERABLE);
-		else
+		else if (!args->value)
 			pc->user_flags &= ~BIT(UCONTEXT_RECOVERABLE);
+		else if (pc->user_flags & BIT(UCONTEXT_PROTECTED))
+			ret = -EPERM;
+		else
+			pc->user_flags |= BIT(UCONTEXT_RECOVERABLE);
 		break;
 
 	case I915_CONTEXT_PARAM_PRIORITY:
@@ -724,6 +749,11 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
 						    args->value);
 		break;
 
+	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
+		ret = proto_context_set_protected(fpriv->dev_priv, pc,
+						  args->value);
+		break;
+
 	case I915_CONTEXT_PARAM_NO_ZEROMAP:
 	case I915_CONTEXT_PARAM_BAN_PERIOD:
 	case I915_CONTEXT_PARAM_RINGSIZE:
@@ -1798,6 +1828,18 @@ static int set_priority(struct i915_gem_context *ctx,
 	return 0;
 }
 
+static int get_protected(struct i915_gem_context *ctx,
+			 struct drm_i915_gem_context_param *args)
+{
+	if (!intel_pxp_is_enabled(&ctx->i915->gt.pxp))
+		return -ENODEV;
+
+	args->size = 0;
+	args->value = i915_gem_context_uses_protected_content(ctx);
+
+	return 0;
+}
+
 static int ctx_setparam(struct drm_i915_file_private *fpriv,
 			struct i915_gem_context *ctx,
 			struct drm_i915_gem_context_param *args)
@@ -1821,6 +1863,8 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
 			ret = -EPERM;
 		else if (args->value)
 			i915_gem_context_set_bannable(ctx);
+		else if (i915_gem_context_uses_protected_content(ctx))
+			ret = -EPERM; /* can't clear this for protected contexts */
 		else
 			i915_gem_context_clear_bannable(ctx);
 		break;
@@ -1828,10 +1872,12 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
 	case I915_CONTEXT_PARAM_RECOVERABLE:
 		if (args->size)
 			ret = -EINVAL;
-		else if (args->value)
-			i915_gem_context_set_recoverable(ctx);
-		else
+		else if (!args->value)
 			i915_gem_context_clear_recoverable(ctx);
+		else if (i915_gem_context_uses_protected_content(ctx))
+			ret = -EPERM; /* can't set this for protected contexts */
+		else
+			i915_gem_context_set_recoverable(ctx);
 		break;
 
 	case I915_CONTEXT_PARAM_PRIORITY:
@@ -1846,6 +1892,7 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
 		ret = set_persistence(ctx, args);
 		break;
 
+	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
 	case I915_CONTEXT_PARAM_NO_ZEROMAP:
 	case I915_CONTEXT_PARAM_BAN_PERIOD:
 	case I915_CONTEXT_PARAM_RINGSIZE:
@@ -2174,6 +2221,10 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
 		args->value = i915_gem_context_is_persistent(ctx);
 		break;
 
+	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
+		ret = get_protected(ctx, args);
+		break;
+
 	case I915_CONTEXT_PARAM_NO_ZEROMAP:
 	case I915_CONTEXT_PARAM_BAN_PERIOD:
 	case I915_CONTEXT_PARAM_ENGINES:
@@ -2250,6 +2301,11 @@ int i915_gem_context_reset_stats_ioctl(struct drm_device *dev,
 	args->batch_active = atomic_read(&ctx->guilty_count);
 	args->batch_pending = atomic_read(&ctx->active_count);
 
+	/* re-use args->flags for output flags */
+	args->flags = 0;
+	if (i915_gem_context_invalidated(ctx))
+		args->flags |= I915_CONTEXT_INVALIDATED;
+
 	i915_gem_context_put(ctx);
 	return 0;
 }
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.h b/drivers/gpu/drm/i915/gem/i915_gem_context.h
index 18060536b0c2..d932a70122fa 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.h
@@ -108,6 +108,24 @@ i915_gem_context_clear_user_engines(struct i915_gem_context *ctx)
 	clear_bit(CONTEXT_USER_ENGINES, &ctx->flags);
 }
 
+static inline bool
+i915_gem_context_invalidated(const struct i915_gem_context *ctx)
+{
+	return test_bit(CONTEXT_INVALID, &ctx->flags);
+}
+
+static inline void
+i915_gem_context_set_invalid(struct i915_gem_context *ctx)
+{
+	set_bit(CONTEXT_INVALID, &ctx->flags);
+}
+
+static inline bool
+i915_gem_context_uses_protected_content(const struct i915_gem_context *ctx)
+{
+	return test_bit(UCONTEXT_PROTECTED, &ctx->user_flags);
+}
+
 /* i915_gem_context.c */
 void i915_gem_init__contexts(struct drm_i915_private *i915);
 
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
index 94c03a97cb77..1aa2290aa3c7 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
@@ -301,6 +301,7 @@ struct i915_gem_context {
 #define UCONTEXT_BANNABLE		2
 #define UCONTEXT_RECOVERABLE		3
 #define UCONTEXT_PERSISTENCE		4
+#define UCONTEXT_PROTECTED		5
 
 	/**
 	 * @flags: small set of booleans
@@ -308,6 +309,7 @@ struct i915_gem_context {
 	unsigned long flags;
 #define CONTEXT_CLOSED			0
 #define CONTEXT_USER_ENGINES		1
+#define CONTEXT_INVALID			2
 
 	/** @mutex: guards everything that isn't engines or handles_vma */
 	struct mutex mutex;
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c b/drivers/gpu/drm/i915/gem/i915_gem_create.c
index 23fee13a3384..0e48629316bb 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
@@ -6,6 +6,7 @@
 #include "gem/i915_gem_ioctls.h"
 #include "gem/i915_gem_lmem.h"
 #include "gem/i915_gem_region.h"
+#include "pxp/intel_pxp.h"
 
 #include "i915_drv.h"
 #include "i915_trace.h"
@@ -82,21 +83,11 @@ static int i915_gem_publish(struct drm_i915_gem_object *obj,
 	return 0;
 }
 
-/**
- * Creates a new object using the same path as DRM_I915_GEM_CREATE_EXT
- * @i915: i915 private
- * @size: size of the buffer, in bytes
- * @placements: possible placement regions, in priority order
- * @n_placements: number of possible placement regions
- *
- * This function is exposed primarily for selftests and does very little
- * error checking.  It is assumed that the set of placement regions has
- * already been verified to be valid.
- */
-struct drm_i915_gem_object *
-__i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
-			      struct intel_memory_region **placements,
-			      unsigned int n_placements)
+static struct drm_i915_gem_object *
+__i915_gem_object_create_user_ext(struct drm_i915_private *i915, u64 size,
+				  struct intel_memory_region **placements,
+				  unsigned int n_placements,
+				  unsigned int ext_flags)
 {
 	struct intel_memory_region *mr = placements[0];
 	struct drm_i915_gem_object *obj;
@@ -135,6 +126,12 @@ __i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
 
 	GEM_BUG_ON(size != obj->base.size);
 
+	/* Add any flag set by create_ext options */
+	flags |= ext_flags;
+
+	if (i915_gem_object_is_protected(obj))
+		intel_pxp_object_add(obj);
+
 	trace_i915_gem_object_create(obj);
 	return obj;
 
@@ -145,6 +142,26 @@ __i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
 	return ERR_PTR(ret);
 }
 
+/**
+ * Creates a new object using the same path as DRM_I915_GEM_CREATE_EXT
+ * @i915: i915 private
+ * @size: size of the buffer, in bytes
+ * @placements: possible placement regions, in priority order
+ * @n_placements: number of possible placement regions
+ *
+ * This function is exposed primarily for selftests and does very little
+ * error checking.  It is assumed that the set of placement regions has
+ * already been verified to be valid.
+ */
+struct drm_i915_gem_object *
+__i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
+			      struct intel_memory_region **placements,
+			      unsigned int n_placements)
+{
+	return __i915_gem_object_create_user_ext(i915, size, placements,
+						 n_placements, 0);
+}
+
 int
 i915_gem_dumb_create(struct drm_file *file,
 		     struct drm_device *dev,
@@ -224,6 +241,7 @@ struct create_ext {
 	struct drm_i915_private *i915;
 	struct intel_memory_region *placements[INTEL_REGION_UNKNOWN];
 	unsigned int n_placements;
+	unsigned long flags;
 };
 
 static void repr_placements(char *buf, size_t size,
@@ -356,8 +374,28 @@ static int ext_set_placements(struct i915_user_extension __user *base,
 	return set_placements(&ext, data);
 }
 
+static int ext_set_protected(struct i915_user_extension __user *base, void *data)
+{
+	struct drm_i915_gem_create_ext_protected_content ext;
+	struct create_ext *ext_data = data;
+
+	if (copy_from_user(&ext, base, sizeof(ext)))
+		return -EFAULT;
+
+	if (ext.flags)
+		return -EINVAL;
+
+	if (!intel_pxp_is_enabled(&ext_data->i915->gt.pxp))
+		return -ENODEV;
+
+	ext_data->flags |= I915_BO_PROTECTED;
+
+	return 0;
+}
+
 static const i915_user_extension_fn create_extensions[] = {
 	[I915_GEM_CREATE_EXT_MEMORY_REGIONS] = ext_set_placements,
+	[I915_GEM_CREATE_EXT_PROTECTED_CONTENT] = ext_set_protected,
 };
 
 /**
@@ -392,9 +430,10 @@ i915_gem_create_ext_ioctl(struct drm_device *dev, void *data,
 		ext_data.n_placements = 1;
 	}
 
-	obj = __i915_gem_object_create_user(i915, args->size,
-					    ext_data.placements,
-					    ext_data.n_placements);
+	obj = __i915_gem_object_create_user_ext(i915, args->size,
+						ext_data.placements,
+						ext_data.n_placements,
+						ext_data.flags);
 	if (IS_ERR(obj))
 		return PTR_ERR(obj);
 
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index 1ed7475de454..04f33d163340 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -21,6 +21,8 @@
 #include "gt/intel_gt_pm.h"
 #include "gt/intel_ring.h"
 
+#include "pxp/intel_pxp.h"
+
 #include "i915_drv.h"
 #include "i915_gem_clflush.h"
 #include "i915_gem_context.h"
@@ -751,6 +753,11 @@ static int eb_select_context(struct i915_execbuffer *eb)
 	if (unlikely(IS_ERR(ctx)))
 		return PTR_ERR(ctx);
 
+	if (i915_gem_context_invalidated(ctx)) {
+		i915_gem_context_put(ctx);
+		return -EACCES;
+	}
+
 	eb->gem_context = ctx;
 	if (rcu_access_pointer(ctx->vm))
 		eb->invalid_flags |= EXEC_OBJECT_NEEDS_GTT;
@@ -819,7 +826,7 @@ static struct i915_vma *eb_lookup_vma(struct i915_execbuffer *eb, u32 handle)
 	do {
 		struct drm_i915_gem_object *obj;
 		struct i915_vma *vma;
-		int err;
+		int err = 0;
 
 		rcu_read_lock();
 		vma = radix_tree_lookup(&eb->gem_context->handles_vma, handle);
@@ -833,6 +840,26 @@ static struct i915_vma *eb_lookup_vma(struct i915_execbuffer *eb, u32 handle)
 		if (unlikely(!obj))
 			return ERR_PTR(-ENOENT);
 
+		/*
+		 * If the user has opted-in for protected-object tracking, make
+		 * sure the object encryption can be used.
+		 * We only need to do this when the object is first used with
+		 * this context, because the context itself will be banned when
+		 * the protected objects become invalid.
+		 */
+		if (i915_gem_context_uses_protected_content(eb->gem_context) &&
+		    i915_gem_object_is_protected(obj)) {
+			if (!intel_pxp_is_active(&vm->gt->pxp))
+				err = -ENODEV;
+			else if (!i915_gem_object_has_valid_protection(obj))
+				err = -ENOEXEC;
+
+			if (err) {
+				i915_gem_object_put(obj);
+				return ERR_PTR(err);
+			}
+		}
+
 		vma = i915_vma_instance(obj, vm, NULL);
 		if (IS_ERR(vma)) {
 			i915_gem_object_put(obj);
@@ -2752,6 +2779,17 @@ eb_select_engine(struct i915_execbuffer *eb)
 
 	intel_gt_pm_get(ce->engine->gt);
 
+	if (i915_gem_context_uses_protected_content(eb->gem_context)) {
+		err = intel_pxp_wait_for_arb_start(&ce->engine->gt->pxp);
+		if (err)
+			goto err;
+
+		if (i915_gem_context_invalidated(eb->gem_context)) {
+			err = -EACCES;
+			goto err;
+		}
+	}
+
 	if (!test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
 		err = intel_context_alloc_state(ce);
 		if (err)
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c
index 6fb9afb65034..658a42a7fa07 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
@@ -25,6 +25,7 @@
 #include <linux/sched/mm.h>
 
 #include "display/intel_frontbuffer.h"
+#include "pxp/intel_pxp.h"
 #include "i915_drv.h"
 #include "i915_gem_clflush.h"
 #include "i915_gem_context.h"
@@ -73,6 +74,8 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj,
 	INIT_LIST_HEAD(&obj->lut_list);
 	spin_lock_init(&obj->lut_lock);
 
+	INIT_LIST_HEAD(&obj->pxp_link);
+
 	spin_lock_init(&obj->mmo.lock);
 	obj->mmo.offsets = RB_ROOT;
 
@@ -231,6 +234,9 @@ void __i915_gem_free_object(struct drm_i915_gem_object *obj)
 		spin_unlock(&obj->vma.lock);
 	}
 
+	if (i915_gem_object_has_valid_protection(obj))
+		intel_pxp_object_remove(obj);
+
 	__i915_gem_object_free_mmaps(obj);
 
 	GEM_BUG_ON(!list_empty(&obj->lut_list));
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h
index 48112b9d76df..137ae2723514 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
@@ -269,6 +269,18 @@ i915_gem_object_clear_tiling_quirk(struct drm_i915_gem_object *obj)
 	clear_bit(I915_TILING_QUIRK_BIT, &obj->flags);
 }
 
+static inline bool
+i915_gem_object_is_protected(const struct drm_i915_gem_object *obj)
+{
+	return obj->flags & I915_BO_PROTECTED;
+}
+
+static inline bool
+i915_gem_object_has_valid_protection(const struct drm_i915_gem_object *obj)
+{
+	return i915_gem_object_is_protected(obj) && !list_empty(&obj->pxp_link);
+}
+
 static inline bool
 i915_gem_object_type_has(const struct drm_i915_gem_object *obj,
 			 unsigned long flags)
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
index 2471f36aaff3..38e4a190607a 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
@@ -298,6 +298,7 @@ struct drm_i915_gem_object {
 			     I915_BO_ALLOC_USER)
 #define I915_BO_READONLY         BIT(4)
 #define I915_TILING_QUIRK_BIT    5 /* unknown swizzling; do not release! */
+#define I915_BO_PROTECTED        BIT(6)
 
 	/**
 	 * @mem_flags - Mutable placement-related flags
@@ -537,6 +538,14 @@ struct drm_i915_gem_object {
 		bool created:1;
 	} ttm;
 
+	/*
+	 * When the PXP session is invalidated, we need to mark all protected
+	 * objects as invalid. To easily do so we add them all to a list. The
+	 * presence on the list is used to check if the encryption is valid or
+	 * not.
+	 */
+	struct list_head pxp_link;
+
 	/** Record of address bit 17 of each page at last unbind. */
 	unsigned long *bit_17;
 
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index b0c7edc10cc3..f418281e8c10 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -7,6 +7,7 @@
 #include "intel_pxp_irq.h"
 #include "intel_pxp_session.h"
 #include "intel_pxp_tee.h"
+#include "gem/i915_gem_context.h"
 #include "gt/intel_context.h"
 #include "i915_drv.h"
 
@@ -70,6 +71,9 @@ void intel_pxp_init(struct intel_pxp *pxp)
 
 	mutex_init(&pxp->tee_mutex);
 
+	spin_lock_init(&pxp->lock);
+	INIT_LIST_HEAD(&pxp->protected_objects);
+
 	/*
 	 * we'll use the completion to check if there is a termination pending,
 	 * so we start it as completed and we reinit it when a termination
@@ -166,3 +170,88 @@ void intel_pxp_fini_hw(struct intel_pxp *pxp)
 
 	intel_pxp_irq_disable(pxp);
 }
+
+int intel_pxp_object_add(struct drm_i915_gem_object *obj)
+{
+	struct intel_pxp *pxp = &to_i915(obj->base.dev)->gt.pxp;
+
+	if (!intel_pxp_is_enabled(pxp))
+		return -ENODEV;
+
+	if (!list_empty(&obj->pxp_link))
+		return -EEXIST;
+
+	spin_lock_irq(&pxp->lock);
+	list_add(&obj->pxp_link, &pxp->protected_objects);
+	spin_unlock_irq(&pxp->lock);
+
+	return 0;
+}
+
+void intel_pxp_object_remove(struct drm_i915_gem_object *obj)
+{
+	struct intel_pxp *pxp = &to_i915(obj->base.dev)->gt.pxp;
+
+	if (!intel_pxp_is_enabled(pxp))
+		return;
+
+	spin_lock_irq(&pxp->lock);
+	list_del_init(&obj->pxp_link);
+	spin_unlock_irq(&pxp->lock);
+}
+
+void intel_pxp_invalidate(struct intel_pxp *pxp)
+{
+	struct drm_i915_private *i915 = pxp_to_gt(pxp)->i915;
+	struct drm_i915_gem_object *obj, *tmp;
+	struct i915_gem_context *ctx, *cn;
+
+	/* delete objects that have been used with the invalidated session */
+	spin_lock_irq(&pxp->lock);
+	list_for_each_entry_safe(obj, tmp, &pxp->protected_objects, pxp_link) {
+		if (i915_gem_object_has_pages(obj))
+			list_del_init(&obj->pxp_link);
+	}
+	spin_unlock_irq(&pxp->lock);
+
+	/* 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) {
+		struct i915_gem_engines_iter it;
+		struct intel_context *ce;
+
+		if (!kref_get_unless_zero(&ctx->ref))
+			continue;
+
+		if (likely(!i915_gem_context_uses_protected_content(ctx)) ||
+		    i915_gem_context_invalidated(ctx)) {
+			i915_gem_context_put(ctx);
+			continue;
+		}
+
+		spin_unlock_irq(&i915->gem.contexts.lock);
+
+		/*
+		 * Note that by the time we get here the HW keys are already
+		 * long gone, so any batch using them that's already on the
+		 * engines is very likely a lost cause (and it has probably
+		 * already hung the engine). Therefore, we skip attempting to
+		 * pull the running context out of the HW and we prioritize
+		 * bringing the session back as soon as possible.
+		 */
+		for_each_gem_engine(ce, i915_gem_context_lock_engines(ctx), it) {
+			/* only invalidate if at least one ce was allocated */
+			if (test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
+				intel_context_set_banned(ce);
+				i915_gem_context_set_invalid(ctx);
+			}
+		}
+		i915_gem_context_unlock_engines(ctx);
+
+		spin_lock_irq(&i915->gem.contexts.lock);
+		list_safe_reset_next(ctx, cn, link);
+		i915_gem_context_put(ctx);
+	}
+	spin_unlock_irq(&i915->gem.contexts.lock);
+}
+
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
index 074b3b980957..4f7647f34153 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
@@ -9,6 +9,8 @@
 #include "gt/intel_gt_types.h"
 #include "intel_pxp_types.h"
 
+struct drm_i915_gem_object;
+
 static inline struct intel_gt *pxp_to_gt(const struct intel_pxp *pxp)
 {
 	return container_of(pxp, struct intel_gt, pxp);
@@ -33,6 +35,11 @@ void intel_pxp_fini_hw(struct intel_pxp *pxp);
 
 void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp);
 int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp);
+
+int intel_pxp_object_add(struct drm_i915_gem_object *obj);
+void intel_pxp_object_remove(struct drm_i915_gem_object *obj);
+
+void intel_pxp_invalidate(struct intel_pxp *pxp);
 #else
 static inline void intel_pxp_init(struct intel_pxp *pxp)
 {
@@ -46,6 +53,14 @@ static inline int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp)
 {
 	return 0;
 }
+
+static inline int intel_pxp_object_add(struct drm_i915_gem_object *obj)
+{
+	return 0;
+}
+static inline void intel_pxp_object_remove(struct drm_i915_gem_object *obj)
+{
+}
 #endif
 
 #endif /* __INTEL_PXP_H__ */
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
index 67c30e534d50..0edd563a653d 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
@@ -85,6 +85,9 @@ static int pxp_terminate_arb_session_and_global(struct intel_pxp *pxp)
 	/* must mark termination in progress calling this function */
 	GEM_WARN_ON(pxp->arb_is_valid);
 
+	/* invalidate protected objects */
+	intel_pxp_invalidate(pxp);
+
 	/* terminate the hw sessions */
 	ret = intel_pxp_terminate_session(pxp, ARB_SESSION);
 	if (ret) {
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
index 475e3312c287..be2bed3a2e4e 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
@@ -7,7 +7,9 @@
 #define __INTEL_PXP_TYPES_H__
 
 #include <linux/completion.h>
+#include <linux/list.h>
 #include <linux/mutex.h>
+#include <linux/spinlock.h>
 #include <linux/types.h>
 #include <linux/workqueue.h>
 
@@ -43,6 +45,9 @@ struct intel_pxp {
 	u32 session_events; /* protected with gt->irq_lock */
 #define PXP_TERMINATION_REQUEST  BIT(0)
 #define PXP_TERMINATION_COMPLETE BIT(1)
+
+	spinlock_t lock; /* protects the objects list */
+	struct list_head protected_objects;
 };
 
 #endif /* __INTEL_PXP_TYPES_H__ */
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 4393eef59d9b..2c9febdae6a5 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -1843,12 +1843,32 @@ struct drm_i915_gem_context_param {
  * attempted to use it, never re-use this context param number.
  */
 #define I915_CONTEXT_PARAM_RINGSIZE	0xc
+
+/*
+ * I915_CONTEXT_PARAM_PROTECTED_CONTENT:
+ *
+ * Mark that the context makes use of protected content, which will result
+ * in the context being invalidated when the protected content session is. The
+ * invalidation is reported back to userspace via the RESET_STATS ioctl (see
+ * relevant doc for details).
+ * This flag can only be set at context creation time and, when set to true,
+ * must be preceded by an explicit setting of I915_CONTEXT_PARAM_RECOVERABLE
+ * to false. This flag can't be set to true in conjunction with setting the
+ * I915_CONTEXT_PARAM_BANNABLE flag to false.
+ *
+ * In addition to the normal failure cases, setting this flag during context
+ * creation can result in the following errors:
+ *
+ * -ENODEV: feature not available
+ * -EPERM: trying to mark a recoverable or not bannable context as protected
+ */
+#define I915_CONTEXT_PARAM_PROTECTED_CONTENT    0xd
 /* Must be kept compact -- no holes and well documented */
 
 	__u64 value;
 };
 
-/*
+/**
  * Context SSEU programming
  *
  * It may be necessary for either functional or performance reason to configure
@@ -2181,6 +2201,12 @@ struct drm_i915_reg_read {
 struct drm_i915_reset_stats {
 	__u32 ctx_id;
 	__u32 flags;
+	/*
+	 * contexts marked as using protected content are invalidated when the
+	 * protected content session dies. Submission of invalidated contexts
+	 * is rejected with -EACCES.
+	 */
+#define I915_CONTEXT_INVALIDATED 0x1
 
 	/* All resets since boot/module reload, for all contexts */
 	__u32 reset_count;
@@ -2959,8 +2985,12 @@ struct drm_i915_gem_create_ext {
 	 *
 	 * For I915_GEM_CREATE_EXT_MEMORY_REGIONS usage see
 	 * struct drm_i915_gem_create_ext_memory_regions.
+	 *
+	 * For I915_GEM_CREATE_EXT_PROTECTED_CONTENT usage see
+	 * struct drm_i915_gem_create_ext_protected_content.
 	 */
 #define I915_GEM_CREATE_EXT_MEMORY_REGIONS 0
+#define I915_GEM_CREATE_EXT_PROTECTED_CONTENT 1
 	__u64 extensions;
 };
 
@@ -3018,6 +3048,29 @@ struct drm_i915_gem_create_ext_memory_regions {
 	__u64 regions;
 };
 
+/**
+ * struct drm_i915_gem_create_ext_protected_content - The
+ * I915_OBJECT_PARAM_PROTECTED_CONTENT extension.
+ *
+ * If this extension is provided, buffer contents are expected to be protected
+ * by PXP encryption and require decryption for scan out and processing. This
+ * is only possible on platforms that have PXP enabled, on all other scenarios
+ * using this extension will cause the ioctl to fail and return -ENODEV. The
+ * flags parameter is reserved for future expansion and must currently be set
+ * to zero.
+ *
+ * The buffer contents are considered invalid after a PXP session teardown.
+ *
+ * The encryption is guaranteed to be processed correctly only if the object
+ * is submitted with a context created using the
+ * I915_CONTEXT_PARAM_PROTECTED_CONTENT flag. This will also enable extra checks
+ * at submission time on the validity of the objects involved.
+ */
+struct drm_i915_gem_create_ext_protected_content {
+	struct i915_user_extension base;
+	__u32 flags;
+};
+
 /* ID of the protected content session managed by i915 when PXP is active */
 #define I915_PROTECTED_CONTENT_DEFAULT_SESSION 0xf
 
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [Intel-gfx] [PATCH v6 10/15] drm/i915/pxp: interfaces for using protected objects
@ 2021-07-29  2:01   ` Daniele Ceraolo Spurio
  0 siblings, 0 replies; 64+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-07-29  2:01 UTC (permalink / raw)
  To: intel-gfx; +Cc: Daniel Vetter, Chris Wilson, dri-devel, Bommu Krishnaiah

This api allow user mode to create protected buffers and to mark
contexts as making use of such objects. Only when using contexts
marked in such a way is the execution guaranteed to work as expected.

Contexts can only be marked as using protected content at creation time
(i.e. the parameter is immutable) and they must be both bannable and not
recoverable.

All protected objects and contexts that have backing storage will be
considered invalid when the PXP session is destroyed and all new
submissions using them will be rejected. All intel contexts within the
invalidated gem contexts will be marked banned. A new flag has been
added to the RESET_STATS ioctl to report the context invalidation to
userspace.

This patch was previously sent as 2 separate patches, which have been
squashed following a request to have all the uapi in a single patch.
I've retained the s-o-b from both.

v5: squash patches, rebase on proto_ctx, update kerneldoc

v6: rebase on obj create_ext changes

Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Cc: Jason Ekstrand <jason@jlekstrand.net>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> #v5
---
 drivers/gpu/drm/i915/gem/i915_gem_context.c   | 68 ++++++++++++--
 drivers/gpu/drm/i915/gem/i915_gem_context.h   | 18 ++++
 .../gpu/drm/i915/gem/i915_gem_context_types.h |  2 +
 drivers/gpu/drm/i915/gem/i915_gem_create.c    | 75 ++++++++++++----
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 40 ++++++++-
 drivers/gpu/drm/i915/gem/i915_gem_object.c    |  6 ++
 drivers/gpu/drm/i915/gem/i915_gem_object.h    | 12 +++
 .../gpu/drm/i915/gem/i915_gem_object_types.h  |  9 ++
 drivers/gpu/drm/i915/pxp/intel_pxp.c          | 89 +++++++++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp.h          | 15 ++++
 drivers/gpu/drm/i915/pxp/intel_pxp_session.c  |  3 +
 drivers/gpu/drm/i915/pxp/intel_pxp_types.h    |  5 ++
 include/uapi/drm/i915_drm.h                   | 55 +++++++++++-
 13 files changed, 371 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c
index cff72679ad7c..0cd3e2d06188 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
@@ -77,6 +77,8 @@
 #include "gt/intel_gpu_commands.h"
 #include "gt/intel_ring.h"
 
+#include "pxp/intel_pxp.h"
+
 #include "i915_gem_context.h"
 #include "i915_trace.h"
 #include "i915_user_extensions.h"
@@ -241,6 +243,25 @@ static int proto_context_set_persistence(struct drm_i915_private *i915,
 	return 0;
 }
 
+static int proto_context_set_protected(struct drm_i915_private *i915,
+				       struct i915_gem_proto_context *pc,
+				       bool protected)
+{
+	int ret = 0;
+
+	if (!intel_pxp_is_enabled(&i915->gt.pxp))
+		ret = -ENODEV;
+	else if (!protected)
+		pc->user_flags &= ~BIT(UCONTEXT_PROTECTED);
+	else if ((pc->user_flags & BIT(UCONTEXT_RECOVERABLE)) ||
+		 !(pc->user_flags & BIT(UCONTEXT_BANNABLE)))
+		ret = -EPERM;
+	else
+		pc->user_flags |= BIT(UCONTEXT_PROTECTED);
+
+	return ret;
+}
+
 static struct i915_gem_proto_context *
 proto_context_create(struct drm_i915_private *i915, unsigned int flags)
 {
@@ -686,6 +707,8 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
 			ret = -EPERM;
 		else if (args->value)
 			pc->user_flags |= BIT(UCONTEXT_BANNABLE);
+		else if (pc->user_flags & BIT(UCONTEXT_PROTECTED))
+			ret = -EPERM;
 		else
 			pc->user_flags &= ~BIT(UCONTEXT_BANNABLE);
 		break;
@@ -693,10 +716,12 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
 	case I915_CONTEXT_PARAM_RECOVERABLE:
 		if (args->size)
 			ret = -EINVAL;
-		else if (args->value)
-			pc->user_flags |= BIT(UCONTEXT_RECOVERABLE);
-		else
+		else if (!args->value)
 			pc->user_flags &= ~BIT(UCONTEXT_RECOVERABLE);
+		else if (pc->user_flags & BIT(UCONTEXT_PROTECTED))
+			ret = -EPERM;
+		else
+			pc->user_flags |= BIT(UCONTEXT_RECOVERABLE);
 		break;
 
 	case I915_CONTEXT_PARAM_PRIORITY:
@@ -724,6 +749,11 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
 						    args->value);
 		break;
 
+	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
+		ret = proto_context_set_protected(fpriv->dev_priv, pc,
+						  args->value);
+		break;
+
 	case I915_CONTEXT_PARAM_NO_ZEROMAP:
 	case I915_CONTEXT_PARAM_BAN_PERIOD:
 	case I915_CONTEXT_PARAM_RINGSIZE:
@@ -1798,6 +1828,18 @@ static int set_priority(struct i915_gem_context *ctx,
 	return 0;
 }
 
+static int get_protected(struct i915_gem_context *ctx,
+			 struct drm_i915_gem_context_param *args)
+{
+	if (!intel_pxp_is_enabled(&ctx->i915->gt.pxp))
+		return -ENODEV;
+
+	args->size = 0;
+	args->value = i915_gem_context_uses_protected_content(ctx);
+
+	return 0;
+}
+
 static int ctx_setparam(struct drm_i915_file_private *fpriv,
 			struct i915_gem_context *ctx,
 			struct drm_i915_gem_context_param *args)
@@ -1821,6 +1863,8 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
 			ret = -EPERM;
 		else if (args->value)
 			i915_gem_context_set_bannable(ctx);
+		else if (i915_gem_context_uses_protected_content(ctx))
+			ret = -EPERM; /* can't clear this for protected contexts */
 		else
 			i915_gem_context_clear_bannable(ctx);
 		break;
@@ -1828,10 +1872,12 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
 	case I915_CONTEXT_PARAM_RECOVERABLE:
 		if (args->size)
 			ret = -EINVAL;
-		else if (args->value)
-			i915_gem_context_set_recoverable(ctx);
-		else
+		else if (!args->value)
 			i915_gem_context_clear_recoverable(ctx);
+		else if (i915_gem_context_uses_protected_content(ctx))
+			ret = -EPERM; /* can't set this for protected contexts */
+		else
+			i915_gem_context_set_recoverable(ctx);
 		break;
 
 	case I915_CONTEXT_PARAM_PRIORITY:
@@ -1846,6 +1892,7 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
 		ret = set_persistence(ctx, args);
 		break;
 
+	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
 	case I915_CONTEXT_PARAM_NO_ZEROMAP:
 	case I915_CONTEXT_PARAM_BAN_PERIOD:
 	case I915_CONTEXT_PARAM_RINGSIZE:
@@ -2174,6 +2221,10 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
 		args->value = i915_gem_context_is_persistent(ctx);
 		break;
 
+	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
+		ret = get_protected(ctx, args);
+		break;
+
 	case I915_CONTEXT_PARAM_NO_ZEROMAP:
 	case I915_CONTEXT_PARAM_BAN_PERIOD:
 	case I915_CONTEXT_PARAM_ENGINES:
@@ -2250,6 +2301,11 @@ int i915_gem_context_reset_stats_ioctl(struct drm_device *dev,
 	args->batch_active = atomic_read(&ctx->guilty_count);
 	args->batch_pending = atomic_read(&ctx->active_count);
 
+	/* re-use args->flags for output flags */
+	args->flags = 0;
+	if (i915_gem_context_invalidated(ctx))
+		args->flags |= I915_CONTEXT_INVALIDATED;
+
 	i915_gem_context_put(ctx);
 	return 0;
 }
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.h b/drivers/gpu/drm/i915/gem/i915_gem_context.h
index 18060536b0c2..d932a70122fa 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.h
@@ -108,6 +108,24 @@ i915_gem_context_clear_user_engines(struct i915_gem_context *ctx)
 	clear_bit(CONTEXT_USER_ENGINES, &ctx->flags);
 }
 
+static inline bool
+i915_gem_context_invalidated(const struct i915_gem_context *ctx)
+{
+	return test_bit(CONTEXT_INVALID, &ctx->flags);
+}
+
+static inline void
+i915_gem_context_set_invalid(struct i915_gem_context *ctx)
+{
+	set_bit(CONTEXT_INVALID, &ctx->flags);
+}
+
+static inline bool
+i915_gem_context_uses_protected_content(const struct i915_gem_context *ctx)
+{
+	return test_bit(UCONTEXT_PROTECTED, &ctx->user_flags);
+}
+
 /* i915_gem_context.c */
 void i915_gem_init__contexts(struct drm_i915_private *i915);
 
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
index 94c03a97cb77..1aa2290aa3c7 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
@@ -301,6 +301,7 @@ struct i915_gem_context {
 #define UCONTEXT_BANNABLE		2
 #define UCONTEXT_RECOVERABLE		3
 #define UCONTEXT_PERSISTENCE		4
+#define UCONTEXT_PROTECTED		5
 
 	/**
 	 * @flags: small set of booleans
@@ -308,6 +309,7 @@ struct i915_gem_context {
 	unsigned long flags;
 #define CONTEXT_CLOSED			0
 #define CONTEXT_USER_ENGINES		1
+#define CONTEXT_INVALID			2
 
 	/** @mutex: guards everything that isn't engines or handles_vma */
 	struct mutex mutex;
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c b/drivers/gpu/drm/i915/gem/i915_gem_create.c
index 23fee13a3384..0e48629316bb 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
@@ -6,6 +6,7 @@
 #include "gem/i915_gem_ioctls.h"
 #include "gem/i915_gem_lmem.h"
 #include "gem/i915_gem_region.h"
+#include "pxp/intel_pxp.h"
 
 #include "i915_drv.h"
 #include "i915_trace.h"
@@ -82,21 +83,11 @@ static int i915_gem_publish(struct drm_i915_gem_object *obj,
 	return 0;
 }
 
-/**
- * Creates a new object using the same path as DRM_I915_GEM_CREATE_EXT
- * @i915: i915 private
- * @size: size of the buffer, in bytes
- * @placements: possible placement regions, in priority order
- * @n_placements: number of possible placement regions
- *
- * This function is exposed primarily for selftests and does very little
- * error checking.  It is assumed that the set of placement regions has
- * already been verified to be valid.
- */
-struct drm_i915_gem_object *
-__i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
-			      struct intel_memory_region **placements,
-			      unsigned int n_placements)
+static struct drm_i915_gem_object *
+__i915_gem_object_create_user_ext(struct drm_i915_private *i915, u64 size,
+				  struct intel_memory_region **placements,
+				  unsigned int n_placements,
+				  unsigned int ext_flags)
 {
 	struct intel_memory_region *mr = placements[0];
 	struct drm_i915_gem_object *obj;
@@ -135,6 +126,12 @@ __i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
 
 	GEM_BUG_ON(size != obj->base.size);
 
+	/* Add any flag set by create_ext options */
+	flags |= ext_flags;
+
+	if (i915_gem_object_is_protected(obj))
+		intel_pxp_object_add(obj);
+
 	trace_i915_gem_object_create(obj);
 	return obj;
 
@@ -145,6 +142,26 @@ __i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
 	return ERR_PTR(ret);
 }
 
+/**
+ * Creates a new object using the same path as DRM_I915_GEM_CREATE_EXT
+ * @i915: i915 private
+ * @size: size of the buffer, in bytes
+ * @placements: possible placement regions, in priority order
+ * @n_placements: number of possible placement regions
+ *
+ * This function is exposed primarily for selftests and does very little
+ * error checking.  It is assumed that the set of placement regions has
+ * already been verified to be valid.
+ */
+struct drm_i915_gem_object *
+__i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
+			      struct intel_memory_region **placements,
+			      unsigned int n_placements)
+{
+	return __i915_gem_object_create_user_ext(i915, size, placements,
+						 n_placements, 0);
+}
+
 int
 i915_gem_dumb_create(struct drm_file *file,
 		     struct drm_device *dev,
@@ -224,6 +241,7 @@ struct create_ext {
 	struct drm_i915_private *i915;
 	struct intel_memory_region *placements[INTEL_REGION_UNKNOWN];
 	unsigned int n_placements;
+	unsigned long flags;
 };
 
 static void repr_placements(char *buf, size_t size,
@@ -356,8 +374,28 @@ static int ext_set_placements(struct i915_user_extension __user *base,
 	return set_placements(&ext, data);
 }
 
+static int ext_set_protected(struct i915_user_extension __user *base, void *data)
+{
+	struct drm_i915_gem_create_ext_protected_content ext;
+	struct create_ext *ext_data = data;
+
+	if (copy_from_user(&ext, base, sizeof(ext)))
+		return -EFAULT;
+
+	if (ext.flags)
+		return -EINVAL;
+
+	if (!intel_pxp_is_enabled(&ext_data->i915->gt.pxp))
+		return -ENODEV;
+
+	ext_data->flags |= I915_BO_PROTECTED;
+
+	return 0;
+}
+
 static const i915_user_extension_fn create_extensions[] = {
 	[I915_GEM_CREATE_EXT_MEMORY_REGIONS] = ext_set_placements,
+	[I915_GEM_CREATE_EXT_PROTECTED_CONTENT] = ext_set_protected,
 };
 
 /**
@@ -392,9 +430,10 @@ i915_gem_create_ext_ioctl(struct drm_device *dev, void *data,
 		ext_data.n_placements = 1;
 	}
 
-	obj = __i915_gem_object_create_user(i915, args->size,
-					    ext_data.placements,
-					    ext_data.n_placements);
+	obj = __i915_gem_object_create_user_ext(i915, args->size,
+						ext_data.placements,
+						ext_data.n_placements,
+						ext_data.flags);
 	if (IS_ERR(obj))
 		return PTR_ERR(obj);
 
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index 1ed7475de454..04f33d163340 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -21,6 +21,8 @@
 #include "gt/intel_gt_pm.h"
 #include "gt/intel_ring.h"
 
+#include "pxp/intel_pxp.h"
+
 #include "i915_drv.h"
 #include "i915_gem_clflush.h"
 #include "i915_gem_context.h"
@@ -751,6 +753,11 @@ static int eb_select_context(struct i915_execbuffer *eb)
 	if (unlikely(IS_ERR(ctx)))
 		return PTR_ERR(ctx);
 
+	if (i915_gem_context_invalidated(ctx)) {
+		i915_gem_context_put(ctx);
+		return -EACCES;
+	}
+
 	eb->gem_context = ctx;
 	if (rcu_access_pointer(ctx->vm))
 		eb->invalid_flags |= EXEC_OBJECT_NEEDS_GTT;
@@ -819,7 +826,7 @@ static struct i915_vma *eb_lookup_vma(struct i915_execbuffer *eb, u32 handle)
 	do {
 		struct drm_i915_gem_object *obj;
 		struct i915_vma *vma;
-		int err;
+		int err = 0;
 
 		rcu_read_lock();
 		vma = radix_tree_lookup(&eb->gem_context->handles_vma, handle);
@@ -833,6 +840,26 @@ static struct i915_vma *eb_lookup_vma(struct i915_execbuffer *eb, u32 handle)
 		if (unlikely(!obj))
 			return ERR_PTR(-ENOENT);
 
+		/*
+		 * If the user has opted-in for protected-object tracking, make
+		 * sure the object encryption can be used.
+		 * We only need to do this when the object is first used with
+		 * this context, because the context itself will be banned when
+		 * the protected objects become invalid.
+		 */
+		if (i915_gem_context_uses_protected_content(eb->gem_context) &&
+		    i915_gem_object_is_protected(obj)) {
+			if (!intel_pxp_is_active(&vm->gt->pxp))
+				err = -ENODEV;
+			else if (!i915_gem_object_has_valid_protection(obj))
+				err = -ENOEXEC;
+
+			if (err) {
+				i915_gem_object_put(obj);
+				return ERR_PTR(err);
+			}
+		}
+
 		vma = i915_vma_instance(obj, vm, NULL);
 		if (IS_ERR(vma)) {
 			i915_gem_object_put(obj);
@@ -2752,6 +2779,17 @@ eb_select_engine(struct i915_execbuffer *eb)
 
 	intel_gt_pm_get(ce->engine->gt);
 
+	if (i915_gem_context_uses_protected_content(eb->gem_context)) {
+		err = intel_pxp_wait_for_arb_start(&ce->engine->gt->pxp);
+		if (err)
+			goto err;
+
+		if (i915_gem_context_invalidated(eb->gem_context)) {
+			err = -EACCES;
+			goto err;
+		}
+	}
+
 	if (!test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
 		err = intel_context_alloc_state(ce);
 		if (err)
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c
index 6fb9afb65034..658a42a7fa07 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
@@ -25,6 +25,7 @@
 #include <linux/sched/mm.h>
 
 #include "display/intel_frontbuffer.h"
+#include "pxp/intel_pxp.h"
 #include "i915_drv.h"
 #include "i915_gem_clflush.h"
 #include "i915_gem_context.h"
@@ -73,6 +74,8 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj,
 	INIT_LIST_HEAD(&obj->lut_list);
 	spin_lock_init(&obj->lut_lock);
 
+	INIT_LIST_HEAD(&obj->pxp_link);
+
 	spin_lock_init(&obj->mmo.lock);
 	obj->mmo.offsets = RB_ROOT;
 
@@ -231,6 +234,9 @@ void __i915_gem_free_object(struct drm_i915_gem_object *obj)
 		spin_unlock(&obj->vma.lock);
 	}
 
+	if (i915_gem_object_has_valid_protection(obj))
+		intel_pxp_object_remove(obj);
+
 	__i915_gem_object_free_mmaps(obj);
 
 	GEM_BUG_ON(!list_empty(&obj->lut_list));
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h
index 48112b9d76df..137ae2723514 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
@@ -269,6 +269,18 @@ i915_gem_object_clear_tiling_quirk(struct drm_i915_gem_object *obj)
 	clear_bit(I915_TILING_QUIRK_BIT, &obj->flags);
 }
 
+static inline bool
+i915_gem_object_is_protected(const struct drm_i915_gem_object *obj)
+{
+	return obj->flags & I915_BO_PROTECTED;
+}
+
+static inline bool
+i915_gem_object_has_valid_protection(const struct drm_i915_gem_object *obj)
+{
+	return i915_gem_object_is_protected(obj) && !list_empty(&obj->pxp_link);
+}
+
 static inline bool
 i915_gem_object_type_has(const struct drm_i915_gem_object *obj,
 			 unsigned long flags)
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
index 2471f36aaff3..38e4a190607a 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
@@ -298,6 +298,7 @@ struct drm_i915_gem_object {
 			     I915_BO_ALLOC_USER)
 #define I915_BO_READONLY         BIT(4)
 #define I915_TILING_QUIRK_BIT    5 /* unknown swizzling; do not release! */
+#define I915_BO_PROTECTED        BIT(6)
 
 	/**
 	 * @mem_flags - Mutable placement-related flags
@@ -537,6 +538,14 @@ struct drm_i915_gem_object {
 		bool created:1;
 	} ttm;
 
+	/*
+	 * When the PXP session is invalidated, we need to mark all protected
+	 * objects as invalid. To easily do so we add them all to a list. The
+	 * presence on the list is used to check if the encryption is valid or
+	 * not.
+	 */
+	struct list_head pxp_link;
+
 	/** Record of address bit 17 of each page at last unbind. */
 	unsigned long *bit_17;
 
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index b0c7edc10cc3..f418281e8c10 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -7,6 +7,7 @@
 #include "intel_pxp_irq.h"
 #include "intel_pxp_session.h"
 #include "intel_pxp_tee.h"
+#include "gem/i915_gem_context.h"
 #include "gt/intel_context.h"
 #include "i915_drv.h"
 
@@ -70,6 +71,9 @@ void intel_pxp_init(struct intel_pxp *pxp)
 
 	mutex_init(&pxp->tee_mutex);
 
+	spin_lock_init(&pxp->lock);
+	INIT_LIST_HEAD(&pxp->protected_objects);
+
 	/*
 	 * we'll use the completion to check if there is a termination pending,
 	 * so we start it as completed and we reinit it when a termination
@@ -166,3 +170,88 @@ void intel_pxp_fini_hw(struct intel_pxp *pxp)
 
 	intel_pxp_irq_disable(pxp);
 }
+
+int intel_pxp_object_add(struct drm_i915_gem_object *obj)
+{
+	struct intel_pxp *pxp = &to_i915(obj->base.dev)->gt.pxp;
+
+	if (!intel_pxp_is_enabled(pxp))
+		return -ENODEV;
+
+	if (!list_empty(&obj->pxp_link))
+		return -EEXIST;
+
+	spin_lock_irq(&pxp->lock);
+	list_add(&obj->pxp_link, &pxp->protected_objects);
+	spin_unlock_irq(&pxp->lock);
+
+	return 0;
+}
+
+void intel_pxp_object_remove(struct drm_i915_gem_object *obj)
+{
+	struct intel_pxp *pxp = &to_i915(obj->base.dev)->gt.pxp;
+
+	if (!intel_pxp_is_enabled(pxp))
+		return;
+
+	spin_lock_irq(&pxp->lock);
+	list_del_init(&obj->pxp_link);
+	spin_unlock_irq(&pxp->lock);
+}
+
+void intel_pxp_invalidate(struct intel_pxp *pxp)
+{
+	struct drm_i915_private *i915 = pxp_to_gt(pxp)->i915;
+	struct drm_i915_gem_object *obj, *tmp;
+	struct i915_gem_context *ctx, *cn;
+
+	/* delete objects that have been used with the invalidated session */
+	spin_lock_irq(&pxp->lock);
+	list_for_each_entry_safe(obj, tmp, &pxp->protected_objects, pxp_link) {
+		if (i915_gem_object_has_pages(obj))
+			list_del_init(&obj->pxp_link);
+	}
+	spin_unlock_irq(&pxp->lock);
+
+	/* 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) {
+		struct i915_gem_engines_iter it;
+		struct intel_context *ce;
+
+		if (!kref_get_unless_zero(&ctx->ref))
+			continue;
+
+		if (likely(!i915_gem_context_uses_protected_content(ctx)) ||
+		    i915_gem_context_invalidated(ctx)) {
+			i915_gem_context_put(ctx);
+			continue;
+		}
+
+		spin_unlock_irq(&i915->gem.contexts.lock);
+
+		/*
+		 * Note that by the time we get here the HW keys are already
+		 * long gone, so any batch using them that's already on the
+		 * engines is very likely a lost cause (and it has probably
+		 * already hung the engine). Therefore, we skip attempting to
+		 * pull the running context out of the HW and we prioritize
+		 * bringing the session back as soon as possible.
+		 */
+		for_each_gem_engine(ce, i915_gem_context_lock_engines(ctx), it) {
+			/* only invalidate if at least one ce was allocated */
+			if (test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
+				intel_context_set_banned(ce);
+				i915_gem_context_set_invalid(ctx);
+			}
+		}
+		i915_gem_context_unlock_engines(ctx);
+
+		spin_lock_irq(&i915->gem.contexts.lock);
+		list_safe_reset_next(ctx, cn, link);
+		i915_gem_context_put(ctx);
+	}
+	spin_unlock_irq(&i915->gem.contexts.lock);
+}
+
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
index 074b3b980957..4f7647f34153 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
@@ -9,6 +9,8 @@
 #include "gt/intel_gt_types.h"
 #include "intel_pxp_types.h"
 
+struct drm_i915_gem_object;
+
 static inline struct intel_gt *pxp_to_gt(const struct intel_pxp *pxp)
 {
 	return container_of(pxp, struct intel_gt, pxp);
@@ -33,6 +35,11 @@ void intel_pxp_fini_hw(struct intel_pxp *pxp);
 
 void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp);
 int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp);
+
+int intel_pxp_object_add(struct drm_i915_gem_object *obj);
+void intel_pxp_object_remove(struct drm_i915_gem_object *obj);
+
+void intel_pxp_invalidate(struct intel_pxp *pxp);
 #else
 static inline void intel_pxp_init(struct intel_pxp *pxp)
 {
@@ -46,6 +53,14 @@ static inline int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp)
 {
 	return 0;
 }
+
+static inline int intel_pxp_object_add(struct drm_i915_gem_object *obj)
+{
+	return 0;
+}
+static inline void intel_pxp_object_remove(struct drm_i915_gem_object *obj)
+{
+}
 #endif
 
 #endif /* __INTEL_PXP_H__ */
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
index 67c30e534d50..0edd563a653d 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
@@ -85,6 +85,9 @@ static int pxp_terminate_arb_session_and_global(struct intel_pxp *pxp)
 	/* must mark termination in progress calling this function */
 	GEM_WARN_ON(pxp->arb_is_valid);
 
+	/* invalidate protected objects */
+	intel_pxp_invalidate(pxp);
+
 	/* terminate the hw sessions */
 	ret = intel_pxp_terminate_session(pxp, ARB_SESSION);
 	if (ret) {
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
index 475e3312c287..be2bed3a2e4e 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
@@ -7,7 +7,9 @@
 #define __INTEL_PXP_TYPES_H__
 
 #include <linux/completion.h>
+#include <linux/list.h>
 #include <linux/mutex.h>
+#include <linux/spinlock.h>
 #include <linux/types.h>
 #include <linux/workqueue.h>
 
@@ -43,6 +45,9 @@ struct intel_pxp {
 	u32 session_events; /* protected with gt->irq_lock */
 #define PXP_TERMINATION_REQUEST  BIT(0)
 #define PXP_TERMINATION_COMPLETE BIT(1)
+
+	spinlock_t lock; /* protects the objects list */
+	struct list_head protected_objects;
 };
 
 #endif /* __INTEL_PXP_TYPES_H__ */
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 4393eef59d9b..2c9febdae6a5 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -1843,12 +1843,32 @@ struct drm_i915_gem_context_param {
  * attempted to use it, never re-use this context param number.
  */
 #define I915_CONTEXT_PARAM_RINGSIZE	0xc
+
+/*
+ * I915_CONTEXT_PARAM_PROTECTED_CONTENT:
+ *
+ * Mark that the context makes use of protected content, which will result
+ * in the context being invalidated when the protected content session is. The
+ * invalidation is reported back to userspace via the RESET_STATS ioctl (see
+ * relevant doc for details).
+ * This flag can only be set at context creation time and, when set to true,
+ * must be preceded by an explicit setting of I915_CONTEXT_PARAM_RECOVERABLE
+ * to false. This flag can't be set to true in conjunction with setting the
+ * I915_CONTEXT_PARAM_BANNABLE flag to false.
+ *
+ * In addition to the normal failure cases, setting this flag during context
+ * creation can result in the following errors:
+ *
+ * -ENODEV: feature not available
+ * -EPERM: trying to mark a recoverable or not bannable context as protected
+ */
+#define I915_CONTEXT_PARAM_PROTECTED_CONTENT    0xd
 /* Must be kept compact -- no holes and well documented */
 
 	__u64 value;
 };
 
-/*
+/**
  * Context SSEU programming
  *
  * It may be necessary for either functional or performance reason to configure
@@ -2181,6 +2201,12 @@ struct drm_i915_reg_read {
 struct drm_i915_reset_stats {
 	__u32 ctx_id;
 	__u32 flags;
+	/*
+	 * contexts marked as using protected content are invalidated when the
+	 * protected content session dies. Submission of invalidated contexts
+	 * is rejected with -EACCES.
+	 */
+#define I915_CONTEXT_INVALIDATED 0x1
 
 	/* All resets since boot/module reload, for all contexts */
 	__u32 reset_count;
@@ -2959,8 +2985,12 @@ struct drm_i915_gem_create_ext {
 	 *
 	 * For I915_GEM_CREATE_EXT_MEMORY_REGIONS usage see
 	 * struct drm_i915_gem_create_ext_memory_regions.
+	 *
+	 * For I915_GEM_CREATE_EXT_PROTECTED_CONTENT usage see
+	 * struct drm_i915_gem_create_ext_protected_content.
 	 */
 #define I915_GEM_CREATE_EXT_MEMORY_REGIONS 0
+#define I915_GEM_CREATE_EXT_PROTECTED_CONTENT 1
 	__u64 extensions;
 };
 
@@ -3018,6 +3048,29 @@ struct drm_i915_gem_create_ext_memory_regions {
 	__u64 regions;
 };
 
+/**
+ * struct drm_i915_gem_create_ext_protected_content - The
+ * I915_OBJECT_PARAM_PROTECTED_CONTENT extension.
+ *
+ * If this extension is provided, buffer contents are expected to be protected
+ * by PXP encryption and require decryption for scan out and processing. This
+ * is only possible on platforms that have PXP enabled, on all other scenarios
+ * using this extension will cause the ioctl to fail and return -ENODEV. The
+ * flags parameter is reserved for future expansion and must currently be set
+ * to zero.
+ *
+ * The buffer contents are considered invalid after a PXP session teardown.
+ *
+ * The encryption is guaranteed to be processed correctly only if the object
+ * is submitted with a context created using the
+ * I915_CONTEXT_PARAM_PROTECTED_CONTENT flag. This will also enable extra checks
+ * at submission time on the validity of the objects involved.
+ */
+struct drm_i915_gem_create_ext_protected_content {
+	struct i915_user_extension base;
+	__u32 flags;
+};
+
 /* ID of the protected content session managed by i915 when PXP is active */
 #define I915_PROTECTED_CONTENT_DEFAULT_SESSION 0xf
 
-- 
2.32.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v6 11/15] drm/i915/pxp: start the arb session on demand
  2021-07-29  2:00 ` [Intel-gfx] " Daniele Ceraolo Spurio
@ 2021-07-29  2:01   ` Daniele Ceraolo Spurio
  -1 siblings, 0 replies; 64+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-07-29  2:01 UTC (permalink / raw)
  To: intel-gfx; +Cc: Daniele Ceraolo Spurio, dri-devel, Rodrigo Vivi

Now that we can handle destruction and re-creation of the arb session,
we can postpone the start of the session to the first submission that
requires it, to avoid keeping it running with no user.

Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
---
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c    |  8 ++--
 drivers/gpu/drm/i915/pxp/intel_pxp.c          | 37 ++++++++++++-------
 drivers/gpu/drm/i915/pxp/intel_pxp.h          |  5 ++-
 drivers/gpu/drm/i915/pxp/intel_pxp_irq.c      |  2 +-
 drivers/gpu/drm/i915/pxp/intel_pxp_session.c  |  6 +--
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c      | 10 +----
 drivers/gpu/drm/i915/pxp/intel_pxp_types.h    |  2 +
 7 files changed, 39 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index 04f33d163340..862f887b1809 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -2780,9 +2780,11 @@ eb_select_engine(struct i915_execbuffer *eb)
 	intel_gt_pm_get(ce->engine->gt);
 
 	if (i915_gem_context_uses_protected_content(eb->gem_context)) {
-		err = intel_pxp_wait_for_arb_start(&ce->engine->gt->pxp);
-		if (err)
-			goto err;
+		if (!intel_pxp_is_active(&ce->engine->gt->pxp)) {
+			err = intel_pxp_start(&ce->engine->gt->pxp);
+			if (err)
+				goto err;
+		}
 
 		if (i915_gem_context_invalidated(eb->gem_context)) {
 			err = -EACCES;
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index f418281e8c10..31c8835eebb4 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -82,6 +82,7 @@ void intel_pxp_init(struct intel_pxp *pxp)
 	init_completion(&pxp->termination);
 	complete_all(&pxp->termination);
 
+	mutex_init(&pxp->arb_mutex);
 	INIT_WORK(&pxp->session_work, intel_pxp_session_work);
 
 	ret = create_vcs_context(pxp);
@@ -118,7 +119,7 @@ void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp)
 	reinit_completion(&pxp->termination);
 }
 
-static void intel_pxp_queue_termination(struct intel_pxp *pxp)
+static void pxp_queue_termination(struct intel_pxp *pxp)
 {
 	struct intel_gt *gt = pxp_to_gt(pxp);
 
@@ -137,31 +138,41 @@ static void intel_pxp_queue_termination(struct intel_pxp *pxp)
  * the arb session is restarted from the irq work when we receive the
  * termination completion interrupt
  */
-int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp)
+int intel_pxp_start(struct intel_pxp *pxp)
 {
+	int ret = 0;
+
 	if (!intel_pxp_is_enabled(pxp))
-		return 0;
+		return -ENODEV;
+
+	mutex_lock(&pxp->arb_mutex);
+
+	if (pxp->arb_is_valid)
+		goto unlock;
+
+	pxp_queue_termination(pxp);
 
 	if (!wait_for_completion_timeout(&pxp->termination,
-					 msecs_to_jiffies(100)))
-		return -ETIMEDOUT;
+					msecs_to_jiffies(100))) {
+		ret = -ETIMEDOUT;
+		goto unlock;
+	}
+
+	/* make sure the compiler doesn't optimize the double access */
+	barrier();
 
 	if (!pxp->arb_is_valid)
-		return -EIO;
+		ret = -EIO;
 
-	return 0;
+unlock:
+	mutex_unlock(&pxp->arb_mutex);
+	return ret;
 }
 
 void intel_pxp_init_hw(struct intel_pxp *pxp)
 {
 	kcr_pxp_enable(pxp_to_gt(pxp));
 	intel_pxp_irq_enable(pxp);
-
-	/*
-	 * the session could've been attacked while we weren't loaded, so
-	 * handle it as if it was and re-create it.
-	 */
-	intel_pxp_queue_termination(pxp);
 }
 
 void intel_pxp_fini_hw(struct intel_pxp *pxp)
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
index 4f7647f34153..382f7f069aca 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
@@ -34,7 +34,8 @@ void intel_pxp_init_hw(struct intel_pxp *pxp);
 void intel_pxp_fini_hw(struct intel_pxp *pxp);
 
 void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp);
-int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp);
+
+int intel_pxp_start(struct intel_pxp *pxp);
 
 int intel_pxp_object_add(struct drm_i915_gem_object *obj);
 void intel_pxp_object_remove(struct drm_i915_gem_object *obj);
@@ -49,7 +50,7 @@ static inline void intel_pxp_fini(struct intel_pxp *pxp)
 {
 }
 
-static inline int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp)
+static inline int intel_pxp_start(struct intel_pxp *pxp)
 {
 	return 0;
 }
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
index 46eca1e81b9b..340f20d130a8 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
@@ -31,7 +31,7 @@ void intel_pxp_irq_handler(struct intel_pxp *pxp, u16 iir)
 		   GEN12_DISPLAY_APP_TERMINATED_PER_FW_REQ_INTERRUPT)) {
 		/* immediately mark PXP as inactive on termination */
 		intel_pxp_mark_termination_in_progress(pxp);
-		pxp->session_events |= PXP_TERMINATION_REQUEST;
+		pxp->session_events |= PXP_TERMINATION_REQUEST | PXP_INVAL_REQUIRED;
 	}
 
 	if (iir & GEN12_DISPLAY_STATE_RESET_COMPLETE_INTERRUPT)
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
index 0edd563a653d..1f13e58d47f9 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
@@ -85,9 +85,6 @@ static int pxp_terminate_arb_session_and_global(struct intel_pxp *pxp)
 	/* must mark termination in progress calling this function */
 	GEM_WARN_ON(pxp->arb_is_valid);
 
-	/* invalidate protected objects */
-	intel_pxp_invalidate(pxp);
-
 	/* terminate the hw sessions */
 	ret = intel_pxp_terminate_session(pxp, ARB_SESSION);
 	if (ret) {
@@ -144,6 +141,9 @@ void intel_pxp_session_work(struct work_struct *work)
 	if (!events)
 		return;
 
+	if (events & PXP_INVAL_REQUIRED)
+		intel_pxp_invalidate(pxp);
+
 	if (events & PXP_TERMINATION_REQUEST) {
 		events &= ~PXP_TERMINATION_COMPLETE;
 		pxp_terminate(pxp);
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
index 7693540dc1f9..c0998047c1b6 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
@@ -78,9 +78,7 @@ static int intel_pxp_tee_io_message(struct intel_pxp *pxp,
 static int i915_pxp_tee_component_bind(struct device *i915_kdev,
 				       struct device *tee_kdev, void *data)
 {
-	struct drm_i915_private *i915 = kdev_to_i915(i915_kdev);
 	struct intel_pxp *pxp = i915_dev_to_pxp(i915_kdev);
-	int ret;
 
 	mutex_lock(&pxp->tee_mutex);
 	pxp->pxp_component = data;
@@ -89,14 +87,8 @@ static int i915_pxp_tee_component_bind(struct device *i915_kdev,
 
 	/* the component is required to fully start the PXP HW */
 	intel_pxp_init_hw(pxp);
-	ret = intel_pxp_wait_for_arb_start(pxp);
-	if (ret) {
-		drm_err(&i915->drm, "Failed to create arb session during bind\n");
-		intel_pxp_fini_hw(pxp);
-		pxp->pxp_component = NULL;
-	}
 
-	return ret;
+	return 0;
 }
 
 static void i915_pxp_tee_component_unbind(struct device *i915_kdev,
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
index be2bed3a2e4e..42601e6f51ee 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
@@ -26,6 +26,7 @@ struct intel_pxp {
 	 * even if the keys are gone, so we can't rely on the HW state of the
 	 * session to know if it's valid and need to track the status in SW.
 	 */
+	struct mutex arb_mutex; /* protects arb session start */
 	bool arb_is_valid;
 
 	struct mutex tee_mutex; /* protects the tee channel binding */
@@ -45,6 +46,7 @@ struct intel_pxp {
 	u32 session_events; /* protected with gt->irq_lock */
 #define PXP_TERMINATION_REQUEST  BIT(0)
 #define PXP_TERMINATION_COMPLETE BIT(1)
+#define PXP_INVAL_REQUIRED       BIT(2)
 
 	spinlock_t lock; /* protects the objects list */
 	struct list_head protected_objects;
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [Intel-gfx] [PATCH v6 11/15] drm/i915/pxp: start the arb session on demand
@ 2021-07-29  2:01   ` Daniele Ceraolo Spurio
  0 siblings, 0 replies; 64+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-07-29  2:01 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel

Now that we can handle destruction and re-creation of the arb session,
we can postpone the start of the session to the first submission that
requires it, to avoid keeping it running with no user.

Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
---
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c    |  8 ++--
 drivers/gpu/drm/i915/pxp/intel_pxp.c          | 37 ++++++++++++-------
 drivers/gpu/drm/i915/pxp/intel_pxp.h          |  5 ++-
 drivers/gpu/drm/i915/pxp/intel_pxp_irq.c      |  2 +-
 drivers/gpu/drm/i915/pxp/intel_pxp_session.c  |  6 +--
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c      | 10 +----
 drivers/gpu/drm/i915/pxp/intel_pxp_types.h    |  2 +
 7 files changed, 39 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index 04f33d163340..862f887b1809 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -2780,9 +2780,11 @@ eb_select_engine(struct i915_execbuffer *eb)
 	intel_gt_pm_get(ce->engine->gt);
 
 	if (i915_gem_context_uses_protected_content(eb->gem_context)) {
-		err = intel_pxp_wait_for_arb_start(&ce->engine->gt->pxp);
-		if (err)
-			goto err;
+		if (!intel_pxp_is_active(&ce->engine->gt->pxp)) {
+			err = intel_pxp_start(&ce->engine->gt->pxp);
+			if (err)
+				goto err;
+		}
 
 		if (i915_gem_context_invalidated(eb->gem_context)) {
 			err = -EACCES;
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index f418281e8c10..31c8835eebb4 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -82,6 +82,7 @@ void intel_pxp_init(struct intel_pxp *pxp)
 	init_completion(&pxp->termination);
 	complete_all(&pxp->termination);
 
+	mutex_init(&pxp->arb_mutex);
 	INIT_WORK(&pxp->session_work, intel_pxp_session_work);
 
 	ret = create_vcs_context(pxp);
@@ -118,7 +119,7 @@ void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp)
 	reinit_completion(&pxp->termination);
 }
 
-static void intel_pxp_queue_termination(struct intel_pxp *pxp)
+static void pxp_queue_termination(struct intel_pxp *pxp)
 {
 	struct intel_gt *gt = pxp_to_gt(pxp);
 
@@ -137,31 +138,41 @@ static void intel_pxp_queue_termination(struct intel_pxp *pxp)
  * the arb session is restarted from the irq work when we receive the
  * termination completion interrupt
  */
-int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp)
+int intel_pxp_start(struct intel_pxp *pxp)
 {
+	int ret = 0;
+
 	if (!intel_pxp_is_enabled(pxp))
-		return 0;
+		return -ENODEV;
+
+	mutex_lock(&pxp->arb_mutex);
+
+	if (pxp->arb_is_valid)
+		goto unlock;
+
+	pxp_queue_termination(pxp);
 
 	if (!wait_for_completion_timeout(&pxp->termination,
-					 msecs_to_jiffies(100)))
-		return -ETIMEDOUT;
+					msecs_to_jiffies(100))) {
+		ret = -ETIMEDOUT;
+		goto unlock;
+	}
+
+	/* make sure the compiler doesn't optimize the double access */
+	barrier();
 
 	if (!pxp->arb_is_valid)
-		return -EIO;
+		ret = -EIO;
 
-	return 0;
+unlock:
+	mutex_unlock(&pxp->arb_mutex);
+	return ret;
 }
 
 void intel_pxp_init_hw(struct intel_pxp *pxp)
 {
 	kcr_pxp_enable(pxp_to_gt(pxp));
 	intel_pxp_irq_enable(pxp);
-
-	/*
-	 * the session could've been attacked while we weren't loaded, so
-	 * handle it as if it was and re-create it.
-	 */
-	intel_pxp_queue_termination(pxp);
 }
 
 void intel_pxp_fini_hw(struct intel_pxp *pxp)
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
index 4f7647f34153..382f7f069aca 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
@@ -34,7 +34,8 @@ void intel_pxp_init_hw(struct intel_pxp *pxp);
 void intel_pxp_fini_hw(struct intel_pxp *pxp);
 
 void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp);
-int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp);
+
+int intel_pxp_start(struct intel_pxp *pxp);
 
 int intel_pxp_object_add(struct drm_i915_gem_object *obj);
 void intel_pxp_object_remove(struct drm_i915_gem_object *obj);
@@ -49,7 +50,7 @@ static inline void intel_pxp_fini(struct intel_pxp *pxp)
 {
 }
 
-static inline int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp)
+static inline int intel_pxp_start(struct intel_pxp *pxp)
 {
 	return 0;
 }
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
index 46eca1e81b9b..340f20d130a8 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
@@ -31,7 +31,7 @@ void intel_pxp_irq_handler(struct intel_pxp *pxp, u16 iir)
 		   GEN12_DISPLAY_APP_TERMINATED_PER_FW_REQ_INTERRUPT)) {
 		/* immediately mark PXP as inactive on termination */
 		intel_pxp_mark_termination_in_progress(pxp);
-		pxp->session_events |= PXP_TERMINATION_REQUEST;
+		pxp->session_events |= PXP_TERMINATION_REQUEST | PXP_INVAL_REQUIRED;
 	}
 
 	if (iir & GEN12_DISPLAY_STATE_RESET_COMPLETE_INTERRUPT)
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
index 0edd563a653d..1f13e58d47f9 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
@@ -85,9 +85,6 @@ static int pxp_terminate_arb_session_and_global(struct intel_pxp *pxp)
 	/* must mark termination in progress calling this function */
 	GEM_WARN_ON(pxp->arb_is_valid);
 
-	/* invalidate protected objects */
-	intel_pxp_invalidate(pxp);
-
 	/* terminate the hw sessions */
 	ret = intel_pxp_terminate_session(pxp, ARB_SESSION);
 	if (ret) {
@@ -144,6 +141,9 @@ void intel_pxp_session_work(struct work_struct *work)
 	if (!events)
 		return;
 
+	if (events & PXP_INVAL_REQUIRED)
+		intel_pxp_invalidate(pxp);
+
 	if (events & PXP_TERMINATION_REQUEST) {
 		events &= ~PXP_TERMINATION_COMPLETE;
 		pxp_terminate(pxp);
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
index 7693540dc1f9..c0998047c1b6 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
@@ -78,9 +78,7 @@ static int intel_pxp_tee_io_message(struct intel_pxp *pxp,
 static int i915_pxp_tee_component_bind(struct device *i915_kdev,
 				       struct device *tee_kdev, void *data)
 {
-	struct drm_i915_private *i915 = kdev_to_i915(i915_kdev);
 	struct intel_pxp *pxp = i915_dev_to_pxp(i915_kdev);
-	int ret;
 
 	mutex_lock(&pxp->tee_mutex);
 	pxp->pxp_component = data;
@@ -89,14 +87,8 @@ static int i915_pxp_tee_component_bind(struct device *i915_kdev,
 
 	/* the component is required to fully start the PXP HW */
 	intel_pxp_init_hw(pxp);
-	ret = intel_pxp_wait_for_arb_start(pxp);
-	if (ret) {
-		drm_err(&i915->drm, "Failed to create arb session during bind\n");
-		intel_pxp_fini_hw(pxp);
-		pxp->pxp_component = NULL;
-	}
 
-	return ret;
+	return 0;
 }
 
 static void i915_pxp_tee_component_unbind(struct device *i915_kdev,
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
index be2bed3a2e4e..42601e6f51ee 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
@@ -26,6 +26,7 @@ struct intel_pxp {
 	 * even if the keys are gone, so we can't rely on the HW state of the
 	 * session to know if it's valid and need to track the status in SW.
 	 */
+	struct mutex arb_mutex; /* protects arb session start */
 	bool arb_is_valid;
 
 	struct mutex tee_mutex; /* protects the tee channel binding */
@@ -45,6 +46,7 @@ struct intel_pxp {
 	u32 session_events; /* protected with gt->irq_lock */
 #define PXP_TERMINATION_REQUEST  BIT(0)
 #define PXP_TERMINATION_COMPLETE BIT(1)
+#define PXP_INVAL_REQUIRED       BIT(2)
 
 	spinlock_t lock; /* protects the objects list */
 	struct list_head protected_objects;
-- 
2.32.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v6 12/15] drm/i915/pxp: Enable PXP power management
  2021-07-29  2:00 ` [Intel-gfx] " Daniele Ceraolo Spurio
@ 2021-07-29  2:01   ` Daniele Ceraolo Spurio
  -1 siblings, 0 replies; 64+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-07-29  2:01 UTC (permalink / raw)
  To: intel-gfx
  Cc: Huang, Sean Z, dri-devel, Chris Wilson, Daniele Ceraolo Spurio,
	Huang, Rodrigo Vivi

From: "Huang, Sean Z" <sean.z.huang@intel.com>

During the power event S3+ sleep/resume, hardware will lose all the
encryption keys for every hardware session, even though the
session state might still be marked as alive after resume. Therefore,
we should consider the session as dead on suspend and invalidate all the
objects. The session will be automatically restarted on the first
protected submission on resume.

v2: runtime suspend also invalidates the keys
v3: fix return codes, simplify rpm ops (Chris), use the new worker func
v4: invalidate the objects on suspend, don't re-create the arb sesson on
resume (delayed to first submission).
v5: move irq changes back to irq patch (Rodrigo)

Signed-off-by: Huang, Sean Z <sean.z.huang@intel.com>
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
---
 drivers/gpu/drm/i915/Makefile                |  1 +
 drivers/gpu/drm/i915/gt/intel_gt_pm.c        | 15 +++++++-
 drivers/gpu/drm/i915/i915_drv.c              |  2 +
 drivers/gpu/drm/i915/pxp/intel_pxp_irq.c     |  1 +
 drivers/gpu/drm/i915/pxp/intel_pxp_pm.c      | 40 ++++++++++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_pm.h      | 23 +++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_session.c | 38 ++++++++++++++-----
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c     |  9 +++++
 8 files changed, 118 insertions(+), 11 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_pm.c
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_pm.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 5dcdf5942d32..4c1f1871b4b8 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -280,6 +280,7 @@ i915-$(CONFIG_DRM_I915_PXP) += \
 	pxp/intel_pxp.o \
 	pxp/intel_pxp_cmd.o \
 	pxp/intel_pxp_irq.o \
+	pxp/intel_pxp_pm.o \
 	pxp/intel_pxp_session.o \
 	pxp/intel_pxp_tee.o
 
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.c b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
index dea8e2479897..0fd1acab68c0 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_pm.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
@@ -18,6 +18,7 @@
 #include "intel_rc6.h"
 #include "intel_rps.h"
 #include "intel_wakeref.h"
+#include "pxp/intel_pxp_pm.h"
 
 static void user_forcewake(struct intel_gt *gt, bool suspend)
 {
@@ -262,6 +263,8 @@ int intel_gt_resume(struct intel_gt *gt)
 
 	intel_uc_resume(&gt->uc);
 
+	intel_pxp_resume(&gt->pxp);
+
 	user_forcewake(gt, false);
 
 out_fw:
@@ -296,6 +299,7 @@ void intel_gt_suspend_prepare(struct intel_gt *gt)
 	user_forcewake(gt, true);
 	wait_for_suspend(gt);
 
+	intel_pxp_suspend(&gt->pxp);
 	intel_uc_suspend(&gt->uc);
 }
 
@@ -346,6 +350,7 @@ void intel_gt_suspend_late(struct intel_gt *gt)
 
 void intel_gt_runtime_suspend(struct intel_gt *gt)
 {
+	intel_pxp_suspend(&gt->pxp);
 	intel_uc_runtime_suspend(&gt->uc);
 
 	GT_TRACE(gt, "\n");
@@ -353,11 +358,19 @@ void intel_gt_runtime_suspend(struct intel_gt *gt)
 
 int intel_gt_runtime_resume(struct intel_gt *gt)
 {
+	int ret;
+
 	GT_TRACE(gt, "\n");
 	intel_gt_init_swizzling(gt);
 	intel_ggtt_restore_fences(gt->ggtt);
 
-	return intel_uc_runtime_resume(&gt->uc);
+	ret = intel_uc_runtime_resume(&gt->uc);
+	if (ret)
+		return ret;
+
+	intel_pxp_resume(&gt->pxp);
+
+	return 0;
 }
 
 static ktime_t __intel_gt_get_awake_time(const struct intel_gt *gt)
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 59fb4c710c8c..d5bcc70a22d4 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -67,6 +67,8 @@
 #include "gt/intel_gt_pm.h"
 #include "gt/intel_rc6.h"
 
+#include "pxp/intel_pxp_pm.h"
+
 #include "i915_debugfs.h"
 #include "i915_drv.h"
 #include "i915_ioc32.h"
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
index 340f20d130a8..9e5847c653f2 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
@@ -9,6 +9,7 @@
 #include "gt/intel_gt_irq.h"
 #include "i915_irq.h"
 #include "i915_reg.h"
+#include "intel_runtime_pm.h"
 
 /**
  * intel_pxp_irq_handler - Handles PXP interrupts.
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c
new file mode 100644
index 000000000000..4507756b2977
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright(c) 2020 Intel Corporation.
+ */
+
+#include "intel_pxp.h"
+#include "intel_pxp_irq.h"
+#include "intel_pxp_pm.h"
+#include "intel_pxp_session.h"
+
+void intel_pxp_suspend(struct intel_pxp *pxp)
+{
+	if (!intel_pxp_is_enabled(pxp))
+		return;
+
+	pxp->arb_is_valid = false;
+
+	/* invalidate protected objects */
+	intel_pxp_invalidate(pxp);
+
+	intel_pxp_fini_hw(pxp);
+
+	pxp->hw_state_invalidated = false;
+}
+
+void intel_pxp_resume(struct intel_pxp *pxp)
+{
+	if (!intel_pxp_is_enabled(pxp))
+		return;
+
+	/*
+	 * The PXP component gets automatically unbound when we go into S3 and
+	 * re-bound after we come out, so in that scenario we can defer the
+	 * hw init to the bind call.
+	 */
+	if (!pxp->pxp_component)
+		return;
+
+	intel_pxp_init_hw(pxp);
+}
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_pm.h b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.h
new file mode 100644
index 000000000000..6f488789db6a
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright(c) 2020, Intel Corporation. All rights reserved.
+ */
+
+#ifndef __INTEL_PXP_PM_H__
+#define __INTEL_PXP_PM_H__
+
+#include "i915_drv.h"
+
+#ifdef CONFIG_DRM_I915_PXP
+void intel_pxp_suspend(struct intel_pxp *pxp);
+void intel_pxp_resume(struct intel_pxp *pxp);
+#else
+static inline void intel_pxp_suspend(struct intel_pxp *pxp)
+{
+}
+static inline void intel_pxp_resume(struct intel_pxp *pxp)
+{
+}
+#endif
+
+#endif /* __INTEL_PXP_PM_H__ */
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
index 1f13e58d47f9..79a84794e410 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
@@ -21,29 +21,36 @@
 
 static bool intel_pxp_session_is_in_play(struct intel_pxp *pxp, u32 id)
 {
-	struct intel_gt *gt = pxp_to_gt(pxp);
+	struct intel_uncore *uncore = pxp_to_gt(pxp)->uncore;
 	intel_wakeref_t wakeref;
 	u32 sip = 0;
 
-	with_intel_runtime_pm(gt->uncore->rpm, wakeref)
-		sip = intel_uncore_read(gt->uncore, GEN12_KCR_SIP);
+	/* if we're suspended the session is considered off */
+	with_intel_runtime_pm_if_in_use(uncore->rpm, wakeref)
+		sip = intel_uncore_read(uncore, GEN12_KCR_SIP);
 
 	return sip & BIT(id);
 }
 
 static int pxp_wait_for_session_state(struct intel_pxp *pxp, u32 id, bool in_play)
 {
-	struct intel_gt *gt = pxp_to_gt(pxp);
+	struct intel_uncore *uncore = pxp_to_gt(pxp)->uncore;
 	intel_wakeref_t wakeref;
 	u32 mask = BIT(id);
 	int ret;
 
-	with_intel_runtime_pm(gt->uncore->rpm, wakeref)
-		ret = intel_wait_for_register(gt->uncore,
-					      GEN12_KCR_SIP,
-					      mask,
-					      in_play ? mask : 0,
-					      100);
+	/* if we're suspended the session is considered off */
+	wakeref = intel_runtime_pm_get_if_in_use(uncore->rpm);
+	if (!wakeref)
+		return in_play ? -ENODEV : 0;
+
+	ret = intel_wait_for_register(uncore,
+				      GEN12_KCR_SIP,
+				      mask,
+				      in_play ? mask : 0,
+				      100);
+
+	intel_runtime_pm_put(uncore->rpm, wakeref);
 
 	return ret;
 }
@@ -132,6 +139,7 @@ void intel_pxp_session_work(struct work_struct *work)
 {
 	struct intel_pxp *pxp = container_of(work, typeof(*pxp), session_work);
 	struct intel_gt *gt = pxp_to_gt(pxp);
+	intel_wakeref_t wakeref;
 	u32 events = 0;
 
 	spin_lock_irq(&gt->irq_lock);
@@ -144,6 +152,14 @@ void intel_pxp_session_work(struct work_struct *work)
 	if (events & PXP_INVAL_REQUIRED)
 		intel_pxp_invalidate(pxp);
 
+	/*
+	 * If we're processing an event while suspending then don't bother,
+	 * we're going to re-init everything on resume anyway.
+	 */
+	wakeref = intel_runtime_pm_get_if_in_use(gt->uncore->rpm);
+	if (!wakeref)
+		return;
+
 	if (events & PXP_TERMINATION_REQUEST) {
 		events &= ~PXP_TERMINATION_COMPLETE;
 		pxp_terminate(pxp);
@@ -151,4 +167,6 @@ void intel_pxp_session_work(struct work_struct *work)
 
 	if (events & PXP_TERMINATION_COMPLETE)
 		pxp_terminate_complete(pxp);
+
+	intel_runtime_pm_put(gt->uncore->rpm, wakeref);
 }
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
index c0998047c1b6..b0094112b0d1 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
@@ -78,16 +78,25 @@ static int intel_pxp_tee_io_message(struct intel_pxp *pxp,
 static int i915_pxp_tee_component_bind(struct device *i915_kdev,
 				       struct device *tee_kdev, void *data)
 {
+	struct drm_i915_private *i915 = kdev_to_i915(i915_kdev);
 	struct intel_pxp *pxp = i915_dev_to_pxp(i915_kdev);
+	intel_wakeref_t wakeref;
 
 	mutex_lock(&pxp->tee_mutex);
 	pxp->pxp_component = data;
 	pxp->pxp_component->tee_dev = tee_kdev;
 	mutex_unlock(&pxp->tee_mutex);
 
+	/* if we are suspended, the HW will be re-initialized on resume */
+	wakeref = intel_runtime_pm_get_if_in_use(&i915->runtime_pm);
+	if (!wakeref)
+		return 0;
+
 	/* the component is required to fully start the PXP HW */
 	intel_pxp_init_hw(pxp);
 
+	intel_runtime_pm_put(&i915->runtime_pm, wakeref);
+
 	return 0;
 }
 
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [Intel-gfx] [PATCH v6 12/15] drm/i915/pxp: Enable PXP power management
@ 2021-07-29  2:01   ` Daniele Ceraolo Spurio
  0 siblings, 0 replies; 64+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-07-29  2:01 UTC (permalink / raw)
  To: intel-gfx; +Cc: Huang, Sean Z, dri-devel, Chris Wilson, Huang

From: "Huang, Sean Z" <sean.z.huang@intel.com>

During the power event S3+ sleep/resume, hardware will lose all the
encryption keys for every hardware session, even though the
session state might still be marked as alive after resume. Therefore,
we should consider the session as dead on suspend and invalidate all the
objects. The session will be automatically restarted on the first
protected submission on resume.

v2: runtime suspend also invalidates the keys
v3: fix return codes, simplify rpm ops (Chris), use the new worker func
v4: invalidate the objects on suspend, don't re-create the arb sesson on
resume (delayed to first submission).
v5: move irq changes back to irq patch (Rodrigo)

Signed-off-by: Huang, Sean Z <sean.z.huang@intel.com>
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
---
 drivers/gpu/drm/i915/Makefile                |  1 +
 drivers/gpu/drm/i915/gt/intel_gt_pm.c        | 15 +++++++-
 drivers/gpu/drm/i915/i915_drv.c              |  2 +
 drivers/gpu/drm/i915/pxp/intel_pxp_irq.c     |  1 +
 drivers/gpu/drm/i915/pxp/intel_pxp_pm.c      | 40 ++++++++++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_pm.h      | 23 +++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_session.c | 38 ++++++++++++++-----
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c     |  9 +++++
 8 files changed, 118 insertions(+), 11 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_pm.c
 create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_pm.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 5dcdf5942d32..4c1f1871b4b8 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -280,6 +280,7 @@ i915-$(CONFIG_DRM_I915_PXP) += \
 	pxp/intel_pxp.o \
 	pxp/intel_pxp_cmd.o \
 	pxp/intel_pxp_irq.o \
+	pxp/intel_pxp_pm.o \
 	pxp/intel_pxp_session.o \
 	pxp/intel_pxp_tee.o
 
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm.c b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
index dea8e2479897..0fd1acab68c0 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_pm.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
@@ -18,6 +18,7 @@
 #include "intel_rc6.h"
 #include "intel_rps.h"
 #include "intel_wakeref.h"
+#include "pxp/intel_pxp_pm.h"
 
 static void user_forcewake(struct intel_gt *gt, bool suspend)
 {
@@ -262,6 +263,8 @@ int intel_gt_resume(struct intel_gt *gt)
 
 	intel_uc_resume(&gt->uc);
 
+	intel_pxp_resume(&gt->pxp);
+
 	user_forcewake(gt, false);
 
 out_fw:
@@ -296,6 +299,7 @@ void intel_gt_suspend_prepare(struct intel_gt *gt)
 	user_forcewake(gt, true);
 	wait_for_suspend(gt);
 
+	intel_pxp_suspend(&gt->pxp);
 	intel_uc_suspend(&gt->uc);
 }
 
@@ -346,6 +350,7 @@ void intel_gt_suspend_late(struct intel_gt *gt)
 
 void intel_gt_runtime_suspend(struct intel_gt *gt)
 {
+	intel_pxp_suspend(&gt->pxp);
 	intel_uc_runtime_suspend(&gt->uc);
 
 	GT_TRACE(gt, "\n");
@@ -353,11 +358,19 @@ void intel_gt_runtime_suspend(struct intel_gt *gt)
 
 int intel_gt_runtime_resume(struct intel_gt *gt)
 {
+	int ret;
+
 	GT_TRACE(gt, "\n");
 	intel_gt_init_swizzling(gt);
 	intel_ggtt_restore_fences(gt->ggtt);
 
-	return intel_uc_runtime_resume(&gt->uc);
+	ret = intel_uc_runtime_resume(&gt->uc);
+	if (ret)
+		return ret;
+
+	intel_pxp_resume(&gt->pxp);
+
+	return 0;
 }
 
 static ktime_t __intel_gt_get_awake_time(const struct intel_gt *gt)
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 59fb4c710c8c..d5bcc70a22d4 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -67,6 +67,8 @@
 #include "gt/intel_gt_pm.h"
 #include "gt/intel_rc6.h"
 
+#include "pxp/intel_pxp_pm.h"
+
 #include "i915_debugfs.h"
 #include "i915_drv.h"
 #include "i915_ioc32.h"
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
index 340f20d130a8..9e5847c653f2 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
@@ -9,6 +9,7 @@
 #include "gt/intel_gt_irq.h"
 #include "i915_irq.h"
 #include "i915_reg.h"
+#include "intel_runtime_pm.h"
 
 /**
  * intel_pxp_irq_handler - Handles PXP interrupts.
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c
new file mode 100644
index 000000000000..4507756b2977
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright(c) 2020 Intel Corporation.
+ */
+
+#include "intel_pxp.h"
+#include "intel_pxp_irq.h"
+#include "intel_pxp_pm.h"
+#include "intel_pxp_session.h"
+
+void intel_pxp_suspend(struct intel_pxp *pxp)
+{
+	if (!intel_pxp_is_enabled(pxp))
+		return;
+
+	pxp->arb_is_valid = false;
+
+	/* invalidate protected objects */
+	intel_pxp_invalidate(pxp);
+
+	intel_pxp_fini_hw(pxp);
+
+	pxp->hw_state_invalidated = false;
+}
+
+void intel_pxp_resume(struct intel_pxp *pxp)
+{
+	if (!intel_pxp_is_enabled(pxp))
+		return;
+
+	/*
+	 * The PXP component gets automatically unbound when we go into S3 and
+	 * re-bound after we come out, so in that scenario we can defer the
+	 * hw init to the bind call.
+	 */
+	if (!pxp->pxp_component)
+		return;
+
+	intel_pxp_init_hw(pxp);
+}
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_pm.h b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.h
new file mode 100644
index 000000000000..6f488789db6a
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright(c) 2020, Intel Corporation. All rights reserved.
+ */
+
+#ifndef __INTEL_PXP_PM_H__
+#define __INTEL_PXP_PM_H__
+
+#include "i915_drv.h"
+
+#ifdef CONFIG_DRM_I915_PXP
+void intel_pxp_suspend(struct intel_pxp *pxp);
+void intel_pxp_resume(struct intel_pxp *pxp);
+#else
+static inline void intel_pxp_suspend(struct intel_pxp *pxp)
+{
+}
+static inline void intel_pxp_resume(struct intel_pxp *pxp)
+{
+}
+#endif
+
+#endif /* __INTEL_PXP_PM_H__ */
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
index 1f13e58d47f9..79a84794e410 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
@@ -21,29 +21,36 @@
 
 static bool intel_pxp_session_is_in_play(struct intel_pxp *pxp, u32 id)
 {
-	struct intel_gt *gt = pxp_to_gt(pxp);
+	struct intel_uncore *uncore = pxp_to_gt(pxp)->uncore;
 	intel_wakeref_t wakeref;
 	u32 sip = 0;
 
-	with_intel_runtime_pm(gt->uncore->rpm, wakeref)
-		sip = intel_uncore_read(gt->uncore, GEN12_KCR_SIP);
+	/* if we're suspended the session is considered off */
+	with_intel_runtime_pm_if_in_use(uncore->rpm, wakeref)
+		sip = intel_uncore_read(uncore, GEN12_KCR_SIP);
 
 	return sip & BIT(id);
 }
 
 static int pxp_wait_for_session_state(struct intel_pxp *pxp, u32 id, bool in_play)
 {
-	struct intel_gt *gt = pxp_to_gt(pxp);
+	struct intel_uncore *uncore = pxp_to_gt(pxp)->uncore;
 	intel_wakeref_t wakeref;
 	u32 mask = BIT(id);
 	int ret;
 
-	with_intel_runtime_pm(gt->uncore->rpm, wakeref)
-		ret = intel_wait_for_register(gt->uncore,
-					      GEN12_KCR_SIP,
-					      mask,
-					      in_play ? mask : 0,
-					      100);
+	/* if we're suspended the session is considered off */
+	wakeref = intel_runtime_pm_get_if_in_use(uncore->rpm);
+	if (!wakeref)
+		return in_play ? -ENODEV : 0;
+
+	ret = intel_wait_for_register(uncore,
+				      GEN12_KCR_SIP,
+				      mask,
+				      in_play ? mask : 0,
+				      100);
+
+	intel_runtime_pm_put(uncore->rpm, wakeref);
 
 	return ret;
 }
@@ -132,6 +139,7 @@ void intel_pxp_session_work(struct work_struct *work)
 {
 	struct intel_pxp *pxp = container_of(work, typeof(*pxp), session_work);
 	struct intel_gt *gt = pxp_to_gt(pxp);
+	intel_wakeref_t wakeref;
 	u32 events = 0;
 
 	spin_lock_irq(&gt->irq_lock);
@@ -144,6 +152,14 @@ void intel_pxp_session_work(struct work_struct *work)
 	if (events & PXP_INVAL_REQUIRED)
 		intel_pxp_invalidate(pxp);
 
+	/*
+	 * If we're processing an event while suspending then don't bother,
+	 * we're going to re-init everything on resume anyway.
+	 */
+	wakeref = intel_runtime_pm_get_if_in_use(gt->uncore->rpm);
+	if (!wakeref)
+		return;
+
 	if (events & PXP_TERMINATION_REQUEST) {
 		events &= ~PXP_TERMINATION_COMPLETE;
 		pxp_terminate(pxp);
@@ -151,4 +167,6 @@ void intel_pxp_session_work(struct work_struct *work)
 
 	if (events & PXP_TERMINATION_COMPLETE)
 		pxp_terminate_complete(pxp);
+
+	intel_runtime_pm_put(gt->uncore->rpm, wakeref);
 }
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
index c0998047c1b6..b0094112b0d1 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
@@ -78,16 +78,25 @@ static int intel_pxp_tee_io_message(struct intel_pxp *pxp,
 static int i915_pxp_tee_component_bind(struct device *i915_kdev,
 				       struct device *tee_kdev, void *data)
 {
+	struct drm_i915_private *i915 = kdev_to_i915(i915_kdev);
 	struct intel_pxp *pxp = i915_dev_to_pxp(i915_kdev);
+	intel_wakeref_t wakeref;
 
 	mutex_lock(&pxp->tee_mutex);
 	pxp->pxp_component = data;
 	pxp->pxp_component->tee_dev = tee_kdev;
 	mutex_unlock(&pxp->tee_mutex);
 
+	/* if we are suspended, the HW will be re-initialized on resume */
+	wakeref = intel_runtime_pm_get_if_in_use(&i915->runtime_pm);
+	if (!wakeref)
+		return 0;
+
 	/* the component is required to fully start the PXP HW */
 	intel_pxp_init_hw(pxp);
 
+	intel_runtime_pm_put(&i915->runtime_pm, wakeref);
+
 	return 0;
 }
 
-- 
2.32.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v6 13/15] drm/i915/pxp: Add plane decryption support
  2021-07-29  2:00 ` [Intel-gfx] " Daniele Ceraolo Spurio
@ 2021-07-29  2:01   ` Daniele Ceraolo Spurio
  -1 siblings, 0 replies; 64+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-07-29  2:01 UTC (permalink / raw)
  To: intel-gfx
  Cc: Anshuman Gupta, Huang Sean Z, dri-devel, Rodrigo Vivi,
	Daniele Ceraolo Spurio, Gaurav Kumar, Bommu Krishnaiah

From: Anshuman Gupta <anshuman.gupta@intel.com>

Add support to enable/disable PLANE_SURF Decryption Request bit.
It requires only to enable plane decryption support when following
condition met.
1. PXP session is enabled.
2. Buffer object is protected.

v2:
- Used gen fb obj user_flags instead gem_object_metadata. [Krishna]

v3:
- intel_pxp_gem_object_status() API changes.

v4: use intel_pxp_is_active (Daniele)

v5: rebase and use the new protected object status checker (Daniele)

v6: used plane state for plane_decryption to handle async flip
    as suggested by Ville.

v7: check pxp session while plane decrypt state computation. [Ville]
    removed pointless code. [Ville]

v8 (Daniele): update PXP check

Cc: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
Cc: Huang Sean Z <sean.z.huang@intel.com>
Cc: Gaurav Kumar <kumar.gaurav@intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Anshuman Gupta <anshuman.gupta@intel.com>
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
---
 .../gpu/drm/i915/display/intel_atomic_plane.c    | 16 ++++++++++++++++
 drivers/gpu/drm/i915/display/intel_display.c     |  4 ++++
 .../gpu/drm/i915/display/intel_display_types.h   |  3 +++
 .../gpu/drm/i915/display/skl_universal_plane.c   | 15 ++++++++++++---
 drivers/gpu/drm/i915/i915_reg.h                  |  1 +
 5 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index 47234d898549..3f605a666ea8 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -41,6 +41,7 @@
 #include "intel_display_types.h"
 #include "intel_pm.h"
 #include "intel_sprite.h"
+#include "pxp/intel_pxp.h"
 
 static void intel_plane_state_reset(struct intel_plane_state *plane_state,
 				    struct intel_plane *plane)
@@ -383,6 +384,14 @@ intel_crtc_get_plane(struct intel_crtc *crtc, enum plane_id plane_id)
 	return NULL;
 }
 
+static int bo_has_valid_encryption(const struct drm_i915_gem_object *obj)
+{
+	struct drm_i915_private *i915 = to_i915(obj->base.dev);
+
+	return i915_gem_object_has_valid_protection(obj) &&
+	       intel_pxp_is_active(&i915->gt.pxp);
+}
+
 int intel_plane_atomic_check(struct intel_atomic_state *state,
 			     struct intel_plane *plane)
 {
@@ -397,6 +406,7 @@ int intel_plane_atomic_check(struct intel_atomic_state *state,
 		intel_atomic_get_old_crtc_state(state, crtc);
 	struct intel_crtc_state *new_crtc_state =
 		intel_atomic_get_new_crtc_state(state, crtc);
+	const struct drm_framebuffer *fb;
 
 	if (new_crtc_state && new_crtc_state->bigjoiner_slave) {
 		struct intel_plane *master_plane =
@@ -413,6 +423,12 @@ int intel_plane_atomic_check(struct intel_atomic_state *state,
 					  new_master_plane_state,
 					  crtc);
 
+	fb = new_plane_state->hw.fb;
+	if (fb)
+		new_plane_state->decrypt = bo_has_valid_encryption(intel_fb_obj(fb));
+	else
+		new_plane_state->decrypt = old_plane_state->decrypt;
+
 	new_plane_state->uapi.visible = false;
 	if (!new_crtc_state)
 		return 0;
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 97a216edf600..eca645900770 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -9891,6 +9891,10 @@ static int intel_atomic_check_async(struct intel_atomic_state *state)
 			drm_dbg_kms(&i915->drm, "Color range cannot be changed in async flip\n");
 			return -EINVAL;
 		}
+
+		/* plane decryption is allow to change only in synchronous flips */
+		if (old_plane_state->decrypt != new_plane_state->decrypt)
+			return -EINVAL;
 	}
 
 	return 0;
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 34ec83fc7167..24f06cdf3340 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -629,6 +629,9 @@ struct intel_plane_state {
 
 	struct intel_fb_view view;
 
+	/* Plane pxp decryption state */
+	bool decrypt;
+
 	/* plane control register */
 	u32 ctl;
 
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index 3ad04bf2a0fd..06df634c216f 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -18,6 +18,7 @@
 #include "intel_sprite.h"
 #include "skl_scaler.h"
 #include "skl_universal_plane.h"
+#include "pxp/intel_pxp.h"
 
 static const u32 skl_plane_formats[] = {
 	DRM_FORMAT_C8,
@@ -1024,7 +1025,7 @@ skl_program_plane(struct intel_plane *plane,
 	u8 alpha = plane_state->hw.alpha >> 8;
 	u32 plane_color_ctl = 0, aux_dist = 0;
 	unsigned long irqflags;
-	u32 keymsk, keymax;
+	u32 keymsk, keymax, plane_surf;
 	u32 plane_ctl = plane_state->ctl;
 
 	plane_ctl |= skl_plane_ctl_crtc(crtc_state);
@@ -1113,8 +1114,16 @@ skl_program_plane(struct intel_plane *plane,
 	 * the control register just before the surface register.
 	 */
 	intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), plane_ctl);
-	intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id),
-			  intel_plane_ggtt_offset(plane_state) + surf_addr);
+	plane_surf = intel_plane_ggtt_offset(plane_state) + surf_addr;
+
+	/*
+	 * FIXME: pxp session invalidation can hit any time even at time of commit
+	 * or after the commit, display content will be garbage.
+	 */
+	if (plane_state->decrypt)
+		plane_surf |= PLANE_SURF_DECRYPT;
+
+	intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), plane_surf);
 
 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 1a2a71916dfc..4f4fdd59ecfc 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -7345,6 +7345,7 @@ enum {
 #define _PLANE_SURF_3(pipe)	_PIPE(pipe, _PLANE_SURF_3_A, _PLANE_SURF_3_B)
 #define PLANE_SURF(pipe, plane)	\
 	_MMIO_PLANE(plane, _PLANE_SURF_1(pipe), _PLANE_SURF_2(pipe))
+#define   PLANE_SURF_DECRYPT			REG_BIT(2)
 
 #define _PLANE_OFFSET_1_B			0x711a4
 #define _PLANE_OFFSET_2_B			0x712a4
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [Intel-gfx] [PATCH v6 13/15] drm/i915/pxp: Add plane decryption support
@ 2021-07-29  2:01   ` Daniele Ceraolo Spurio
  0 siblings, 0 replies; 64+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-07-29  2:01 UTC (permalink / raw)
  To: intel-gfx; +Cc: Huang Sean Z, dri-devel, Gaurav Kumar, Bommu Krishnaiah

From: Anshuman Gupta <anshuman.gupta@intel.com>

Add support to enable/disable PLANE_SURF Decryption Request bit.
It requires only to enable plane decryption support when following
condition met.
1. PXP session is enabled.
2. Buffer object is protected.

v2:
- Used gen fb obj user_flags instead gem_object_metadata. [Krishna]

v3:
- intel_pxp_gem_object_status() API changes.

v4: use intel_pxp_is_active (Daniele)

v5: rebase and use the new protected object status checker (Daniele)

v6: used plane state for plane_decryption to handle async flip
    as suggested by Ville.

v7: check pxp session while plane decrypt state computation. [Ville]
    removed pointless code. [Ville]

v8 (Daniele): update PXP check

Cc: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
Cc: Huang Sean Z <sean.z.huang@intel.com>
Cc: Gaurav Kumar <kumar.gaurav@intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Anshuman Gupta <anshuman.gupta@intel.com>
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
---
 .../gpu/drm/i915/display/intel_atomic_plane.c    | 16 ++++++++++++++++
 drivers/gpu/drm/i915/display/intel_display.c     |  4 ++++
 .../gpu/drm/i915/display/intel_display_types.h   |  3 +++
 .../gpu/drm/i915/display/skl_universal_plane.c   | 15 ++++++++++++---
 drivers/gpu/drm/i915/i915_reg.h                  |  1 +
 5 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index 47234d898549..3f605a666ea8 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -41,6 +41,7 @@
 #include "intel_display_types.h"
 #include "intel_pm.h"
 #include "intel_sprite.h"
+#include "pxp/intel_pxp.h"
 
 static void intel_plane_state_reset(struct intel_plane_state *plane_state,
 				    struct intel_plane *plane)
@@ -383,6 +384,14 @@ intel_crtc_get_plane(struct intel_crtc *crtc, enum plane_id plane_id)
 	return NULL;
 }
 
+static int bo_has_valid_encryption(const struct drm_i915_gem_object *obj)
+{
+	struct drm_i915_private *i915 = to_i915(obj->base.dev);
+
+	return i915_gem_object_has_valid_protection(obj) &&
+	       intel_pxp_is_active(&i915->gt.pxp);
+}
+
 int intel_plane_atomic_check(struct intel_atomic_state *state,
 			     struct intel_plane *plane)
 {
@@ -397,6 +406,7 @@ int intel_plane_atomic_check(struct intel_atomic_state *state,
 		intel_atomic_get_old_crtc_state(state, crtc);
 	struct intel_crtc_state *new_crtc_state =
 		intel_atomic_get_new_crtc_state(state, crtc);
+	const struct drm_framebuffer *fb;
 
 	if (new_crtc_state && new_crtc_state->bigjoiner_slave) {
 		struct intel_plane *master_plane =
@@ -413,6 +423,12 @@ int intel_plane_atomic_check(struct intel_atomic_state *state,
 					  new_master_plane_state,
 					  crtc);
 
+	fb = new_plane_state->hw.fb;
+	if (fb)
+		new_plane_state->decrypt = bo_has_valid_encryption(intel_fb_obj(fb));
+	else
+		new_plane_state->decrypt = old_plane_state->decrypt;
+
 	new_plane_state->uapi.visible = false;
 	if (!new_crtc_state)
 		return 0;
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 97a216edf600..eca645900770 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -9891,6 +9891,10 @@ static int intel_atomic_check_async(struct intel_atomic_state *state)
 			drm_dbg_kms(&i915->drm, "Color range cannot be changed in async flip\n");
 			return -EINVAL;
 		}
+
+		/* plane decryption is allow to change only in synchronous flips */
+		if (old_plane_state->decrypt != new_plane_state->decrypt)
+			return -EINVAL;
 	}
 
 	return 0;
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 34ec83fc7167..24f06cdf3340 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -629,6 +629,9 @@ struct intel_plane_state {
 
 	struct intel_fb_view view;
 
+	/* Plane pxp decryption state */
+	bool decrypt;
+
 	/* plane control register */
 	u32 ctl;
 
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index 3ad04bf2a0fd..06df634c216f 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -18,6 +18,7 @@
 #include "intel_sprite.h"
 #include "skl_scaler.h"
 #include "skl_universal_plane.h"
+#include "pxp/intel_pxp.h"
 
 static const u32 skl_plane_formats[] = {
 	DRM_FORMAT_C8,
@@ -1024,7 +1025,7 @@ skl_program_plane(struct intel_plane *plane,
 	u8 alpha = plane_state->hw.alpha >> 8;
 	u32 plane_color_ctl = 0, aux_dist = 0;
 	unsigned long irqflags;
-	u32 keymsk, keymax;
+	u32 keymsk, keymax, plane_surf;
 	u32 plane_ctl = plane_state->ctl;
 
 	plane_ctl |= skl_plane_ctl_crtc(crtc_state);
@@ -1113,8 +1114,16 @@ skl_program_plane(struct intel_plane *plane,
 	 * the control register just before the surface register.
 	 */
 	intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), plane_ctl);
-	intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id),
-			  intel_plane_ggtt_offset(plane_state) + surf_addr);
+	plane_surf = intel_plane_ggtt_offset(plane_state) + surf_addr;
+
+	/*
+	 * FIXME: pxp session invalidation can hit any time even at time of commit
+	 * or after the commit, display content will be garbage.
+	 */
+	if (plane_state->decrypt)
+		plane_surf |= PLANE_SURF_DECRYPT;
+
+	intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), plane_surf);
 
 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 1a2a71916dfc..4f4fdd59ecfc 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -7345,6 +7345,7 @@ enum {
 #define _PLANE_SURF_3(pipe)	_PIPE(pipe, _PLANE_SURF_3_A, _PLANE_SURF_3_B)
 #define PLANE_SURF(pipe, plane)	\
 	_MMIO_PLANE(plane, _PLANE_SURF_1(pipe), _PLANE_SURF_2(pipe))
+#define   PLANE_SURF_DECRYPT			REG_BIT(2)
 
 #define _PLANE_OFFSET_1_B			0x711a4
 #define _PLANE_OFFSET_2_B			0x712a4
-- 
2.32.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v6 14/15] drm/i915/pxp: black pixels on pxp disabled
  2021-07-29  2:00 ` [Intel-gfx] " Daniele Ceraolo Spurio
@ 2021-07-29  2:01   ` Daniele Ceraolo Spurio
  -1 siblings, 0 replies; 64+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-07-29  2:01 UTC (permalink / raw)
  To: intel-gfx
  Cc: Anshuman Gupta, Rodrigo Vivi, dri-devel, Daniele Ceraolo Spurio,
	Gaurav Kumar, Shankar Uma

From: Anshuman Gupta <anshuman.gupta@intel.com>

When protected sufaces has flipped and pxp session is disabled,
display black pixels by using plane color CTM correction.

v2:
- Display black pixels in async flip too.

v3:
- Removed the black pixels logic for async flip. [Ville]
- Used plane state to force black pixels. [Ville]

v4 (Daniele): update pxp_is_borked check.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Gaurav Kumar <kumar.gaurav@intel.com>
Cc: Shankar Uma <uma.shankar@intel.com>
Signed-off-by: Anshuman Gupta <anshuman.gupta@intel.com>
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
---
 .../gpu/drm/i915/display/intel_atomic_plane.c | 13 +++++-
 .../drm/i915/display/intel_display_types.h    |  3 ++
 .../drm/i915/display/skl_universal_plane.c    | 36 ++++++++++++++-
 drivers/gpu/drm/i915/i915_reg.h               | 46 +++++++++++++++++++
 4 files changed, 95 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index 3f605a666ea8..5dfb2b36d0f9 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -392,6 +392,11 @@ static int bo_has_valid_encryption(const struct drm_i915_gem_object *obj)
 	       intel_pxp_is_active(&i915->gt.pxp);
 }
 
+static bool pxp_is_borked(const struct drm_i915_gem_object *obj)
+{
+	return i915_gem_object_is_protected(obj) && !bo_has_valid_encryption(obj);
+}
+
 int intel_plane_atomic_check(struct intel_atomic_state *state,
 			     struct intel_plane *plane)
 {
@@ -424,10 +429,14 @@ int intel_plane_atomic_check(struct intel_atomic_state *state,
 					  crtc);
 
 	fb = new_plane_state->hw.fb;
-	if (fb)
+	if (fb) {
 		new_plane_state->decrypt = bo_has_valid_encryption(intel_fb_obj(fb));
-	else
+		new_plane_state->force_black = pxp_is_borked(intel_fb_obj(fb));
+
+	} else {
 		new_plane_state->decrypt = old_plane_state->decrypt;
+		new_plane_state->force_black = old_plane_state->force_black;
+	}
 
 	new_plane_state->uapi.visible = false;
 	if (!new_crtc_state)
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 24f06cdf3340..5481501cbc65 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -632,6 +632,9 @@ struct intel_plane_state {
 	/* Plane pxp decryption state */
 	bool decrypt;
 
+	/* Plane state to display black pixels when pxp is borked */
+	bool force_black;
+
 	/* plane control register */
 	u32 ctl;
 
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index 06df634c216f..d6673c8fdcd8 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -1002,6 +1002,33 @@ static u32 skl_surf_address(const struct intel_plane_state *plane_state,
 	}
 }
 
+static void intel_load_plane_csc_black(struct intel_plane *intel_plane)
+{
+	struct drm_i915_private *dev_priv = to_i915(intel_plane->base.dev);
+	enum pipe pipe = intel_plane->pipe;
+	enum plane_id plane = intel_plane->id;
+	u16 postoff = 0;
+
+	drm_dbg_kms(&dev_priv->drm, "plane color CTM to black  %s:%d\n",
+		    intel_plane->base.name, plane);
+	intel_de_write_fw(dev_priv, PLANE_CSC_COEFF(pipe, plane, 0), 0);
+	intel_de_write_fw(dev_priv, PLANE_CSC_COEFF(pipe, plane, 1), 0);
+
+	intel_de_write_fw(dev_priv, PLANE_CSC_COEFF(pipe, plane, 2), 0);
+	intel_de_write_fw(dev_priv, PLANE_CSC_COEFF(pipe, plane, 3), 0);
+
+	intel_de_write_fw(dev_priv, PLANE_CSC_COEFF(pipe, plane, 4), 0);
+	intel_de_write_fw(dev_priv, PLANE_CSC_COEFF(pipe, plane, 5), 0);
+
+	intel_de_write_fw(dev_priv, PLANE_CSC_PREOFF(pipe, plane, 0), 0);
+	intel_de_write_fw(dev_priv, PLANE_CSC_PREOFF(pipe, plane, 1), 0);
+	intel_de_write_fw(dev_priv, PLANE_CSC_PREOFF(pipe, plane, 2), 0);
+
+	intel_de_write_fw(dev_priv, PLANE_CSC_POSTOFF(pipe, plane, 0), postoff);
+	intel_de_write_fw(dev_priv, PLANE_CSC_POSTOFF(pipe, plane, 1), postoff);
+	intel_de_write_fw(dev_priv, PLANE_CSC_POSTOFF(pipe, plane, 2), postoff);
+}
+
 static void
 skl_program_plane(struct intel_plane *plane,
 		  const struct intel_crtc_state *crtc_state,
@@ -1115,14 +1142,21 @@ skl_program_plane(struct intel_plane *plane,
 	 */
 	intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), plane_ctl);
 	plane_surf = intel_plane_ggtt_offset(plane_state) + surf_addr;
+	plane_color_ctl = intel_de_read_fw(dev_priv, PLANE_COLOR_CTL(pipe, plane_id));
 
 	/*
 	 * FIXME: pxp session invalidation can hit any time even at time of commit
 	 * or after the commit, display content will be garbage.
 	 */
-	if (plane_state->decrypt)
+	if (plane_state->decrypt) {
 		plane_surf |= PLANE_SURF_DECRYPT;
+	} else if (plane_state->force_black) {
+		intel_load_plane_csc_black(plane);
+		plane_color_ctl |= PLANE_COLOR_PLANE_CSC_ENABLE;
+	}
 
+	intel_de_write_fw(dev_priv, PLANE_COLOR_CTL(pipe, plane_id),
+			  plane_color_ctl);
 	intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), plane_surf);
 
 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 4f4fdd59ecfc..76ec947b163d 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -7222,6 +7222,7 @@ enum {
 #define _PLANE_COLOR_CTL_3_A			0x703CC /* GLK+ */
 #define   PLANE_COLOR_PIPE_GAMMA_ENABLE		(1 << 30) /* Pre-ICL */
 #define   PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE	(1 << 28)
+#define   PLANE_COLOR_PLANE_CSC_ENABLE			REG_BIT(21) /* ICL+ */
 #define   PLANE_COLOR_INPUT_CSC_ENABLE		(1 << 20) /* ICL+ */
 #define   PLANE_COLOR_PIPE_CSC_ENABLE		(1 << 23) /* Pre-ICL */
 #define   PLANE_COLOR_CSC_MODE_BYPASS			(0 << 17)
@@ -11372,6 +11373,51 @@ enum skl_power_gate {
 					_PAL_PREC_MULTI_SEG_DATA_A, \
 					_PAL_PREC_MULTI_SEG_DATA_B)
 
+#define _MMIO_PLANE_GAMC(plane, i, a, b)  _MMIO(_PIPE(plane, a, b) + (i) * 4)
+
+/* Plane CSC Registers */
+#define _PLANE_CSC_RY_GY_1_A	0x70210
+#define _PLANE_CSC_RY_GY_2_A	0x70310
+
+#define _PLANE_CSC_RY_GY_1_B	0x71210
+#define _PLANE_CSC_RY_GY_2_B	0x71310
+
+#define _PLANE_CSC_RY_GY_1(pipe)	_PIPE(pipe, _PLANE_CSC_RY_GY_1_A, \
+					      _PLANE_CSC_RY_GY_1_B)
+#define _PLANE_CSC_RY_GY_2(pipe)	_PIPE(pipe, _PLANE_INPUT_CSC_RY_GY_2_A, \
+					      _PLANE_INPUT_CSC_RY_GY_2_B)
+#define PLANE_CSC_COEFF(pipe, plane, index)	_MMIO_PLANE(plane, \
+							    _PLANE_CSC_RY_GY_1(pipe) +  (index) * 4, \
+							    _PLANE_CSC_RY_GY_2(pipe) + (index) * 4)
+
+#define _PLANE_CSC_PREOFF_HI_1_A		0x70228
+#define _PLANE_CSC_PREOFF_HI_2_A		0x70328
+
+#define _PLANE_CSC_PREOFF_HI_1_B		0x71228
+#define _PLANE_CSC_PREOFF_HI_2_B		0x71328
+
+#define _PLANE_CSC_PREOFF_HI_1(pipe)	_PIPE(pipe, _PLANE_CSC_PREOFF_HI_1_A, \
+					      _PLANE_CSC_PREOFF_HI_1_B)
+#define _PLANE_CSC_PREOFF_HI_2(pipe)	_PIPE(pipe, _PLANE_CSC_PREOFF_HI_2_A, \
+					      _PLANE_CSC_PREOFF_HI_2_B)
+#define PLANE_CSC_PREOFF(pipe, plane, index)	_MMIO_PLANE(plane, _PLANE_CSC_PREOFF_HI_1(pipe) + \
+							    (index) * 4, _PLANE_CSC_PREOFF_HI_2(pipe) + \
+							    (index) * 4)
+
+#define _PLANE_CSC_POSTOFF_HI_1_A		0x70234
+#define _PLANE_CSC_POSTOFF_HI_2_A		0x70334
+
+#define _PLANE_CSC_POSTOFF_HI_1_B		0x71234
+#define _PLANE_CSC_POSTOFF_HI_2_B		0x71334
+
+#define _PLANE_CSC_POSTOFF_HI_1(pipe)	_PIPE(pipe, _PLANE_CSC_POSTOFF_HI_1_A, \
+					      _PLANE_CSC_POSTOFF_HI_1_B)
+#define _PLANE_CSC_POSTOFF_HI_2(pipe)	_PIPE(pipe, _PLANE_CSC_POSTOFF_HI_2_A, \
+					      _PLANE_CSC_POSTOFF_HI_2_B)
+#define PLANE_CSC_POSTOFF(pipe, plane, index)	_MMIO_PLANE(plane, _PLANE_CSC_POSTOFF_HI_1(pipe) + \
+							    (index) * 4, _PLANE_CSC_POSTOFF_HI_2(pipe) + \
+							    (index) * 4)
+
 /* pipe CSC & degamma/gamma LUTs on CHV */
 #define _CGM_PIPE_A_CSC_COEFF01	(VLV_DISPLAY_BASE + 0x67900)
 #define _CGM_PIPE_A_CSC_COEFF23	(VLV_DISPLAY_BASE + 0x67904)
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [Intel-gfx] [PATCH v6 14/15] drm/i915/pxp: black pixels on pxp disabled
@ 2021-07-29  2:01   ` Daniele Ceraolo Spurio
  0 siblings, 0 replies; 64+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-07-29  2:01 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel, Gaurav Kumar

From: Anshuman Gupta <anshuman.gupta@intel.com>

When protected sufaces has flipped and pxp session is disabled,
display black pixels by using plane color CTM correction.

v2:
- Display black pixels in async flip too.

v3:
- Removed the black pixels logic for async flip. [Ville]
- Used plane state to force black pixels. [Ville]

v4 (Daniele): update pxp_is_borked check.

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Gaurav Kumar <kumar.gaurav@intel.com>
Cc: Shankar Uma <uma.shankar@intel.com>
Signed-off-by: Anshuman Gupta <anshuman.gupta@intel.com>
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
---
 .../gpu/drm/i915/display/intel_atomic_plane.c | 13 +++++-
 .../drm/i915/display/intel_display_types.h    |  3 ++
 .../drm/i915/display/skl_universal_plane.c    | 36 ++++++++++++++-
 drivers/gpu/drm/i915/i915_reg.h               | 46 +++++++++++++++++++
 4 files changed, 95 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index 3f605a666ea8..5dfb2b36d0f9 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -392,6 +392,11 @@ static int bo_has_valid_encryption(const struct drm_i915_gem_object *obj)
 	       intel_pxp_is_active(&i915->gt.pxp);
 }
 
+static bool pxp_is_borked(const struct drm_i915_gem_object *obj)
+{
+	return i915_gem_object_is_protected(obj) && !bo_has_valid_encryption(obj);
+}
+
 int intel_plane_atomic_check(struct intel_atomic_state *state,
 			     struct intel_plane *plane)
 {
@@ -424,10 +429,14 @@ int intel_plane_atomic_check(struct intel_atomic_state *state,
 					  crtc);
 
 	fb = new_plane_state->hw.fb;
-	if (fb)
+	if (fb) {
 		new_plane_state->decrypt = bo_has_valid_encryption(intel_fb_obj(fb));
-	else
+		new_plane_state->force_black = pxp_is_borked(intel_fb_obj(fb));
+
+	} else {
 		new_plane_state->decrypt = old_plane_state->decrypt;
+		new_plane_state->force_black = old_plane_state->force_black;
+	}
 
 	new_plane_state->uapi.visible = false;
 	if (!new_crtc_state)
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 24f06cdf3340..5481501cbc65 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -632,6 +632,9 @@ struct intel_plane_state {
 	/* Plane pxp decryption state */
 	bool decrypt;
 
+	/* Plane state to display black pixels when pxp is borked */
+	bool force_black;
+
 	/* plane control register */
 	u32 ctl;
 
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index 06df634c216f..d6673c8fdcd8 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -1002,6 +1002,33 @@ static u32 skl_surf_address(const struct intel_plane_state *plane_state,
 	}
 }
 
+static void intel_load_plane_csc_black(struct intel_plane *intel_plane)
+{
+	struct drm_i915_private *dev_priv = to_i915(intel_plane->base.dev);
+	enum pipe pipe = intel_plane->pipe;
+	enum plane_id plane = intel_plane->id;
+	u16 postoff = 0;
+
+	drm_dbg_kms(&dev_priv->drm, "plane color CTM to black  %s:%d\n",
+		    intel_plane->base.name, plane);
+	intel_de_write_fw(dev_priv, PLANE_CSC_COEFF(pipe, plane, 0), 0);
+	intel_de_write_fw(dev_priv, PLANE_CSC_COEFF(pipe, plane, 1), 0);
+
+	intel_de_write_fw(dev_priv, PLANE_CSC_COEFF(pipe, plane, 2), 0);
+	intel_de_write_fw(dev_priv, PLANE_CSC_COEFF(pipe, plane, 3), 0);
+
+	intel_de_write_fw(dev_priv, PLANE_CSC_COEFF(pipe, plane, 4), 0);
+	intel_de_write_fw(dev_priv, PLANE_CSC_COEFF(pipe, plane, 5), 0);
+
+	intel_de_write_fw(dev_priv, PLANE_CSC_PREOFF(pipe, plane, 0), 0);
+	intel_de_write_fw(dev_priv, PLANE_CSC_PREOFF(pipe, plane, 1), 0);
+	intel_de_write_fw(dev_priv, PLANE_CSC_PREOFF(pipe, plane, 2), 0);
+
+	intel_de_write_fw(dev_priv, PLANE_CSC_POSTOFF(pipe, plane, 0), postoff);
+	intel_de_write_fw(dev_priv, PLANE_CSC_POSTOFF(pipe, plane, 1), postoff);
+	intel_de_write_fw(dev_priv, PLANE_CSC_POSTOFF(pipe, plane, 2), postoff);
+}
+
 static void
 skl_program_plane(struct intel_plane *plane,
 		  const struct intel_crtc_state *crtc_state,
@@ -1115,14 +1142,21 @@ skl_program_plane(struct intel_plane *plane,
 	 */
 	intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), plane_ctl);
 	plane_surf = intel_plane_ggtt_offset(plane_state) + surf_addr;
+	plane_color_ctl = intel_de_read_fw(dev_priv, PLANE_COLOR_CTL(pipe, plane_id));
 
 	/*
 	 * FIXME: pxp session invalidation can hit any time even at time of commit
 	 * or after the commit, display content will be garbage.
 	 */
-	if (plane_state->decrypt)
+	if (plane_state->decrypt) {
 		plane_surf |= PLANE_SURF_DECRYPT;
+	} else if (plane_state->force_black) {
+		intel_load_plane_csc_black(plane);
+		plane_color_ctl |= PLANE_COLOR_PLANE_CSC_ENABLE;
+	}
 
+	intel_de_write_fw(dev_priv, PLANE_COLOR_CTL(pipe, plane_id),
+			  plane_color_ctl);
 	intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), plane_surf);
 
 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 4f4fdd59ecfc..76ec947b163d 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -7222,6 +7222,7 @@ enum {
 #define _PLANE_COLOR_CTL_3_A			0x703CC /* GLK+ */
 #define   PLANE_COLOR_PIPE_GAMMA_ENABLE		(1 << 30) /* Pre-ICL */
 #define   PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE	(1 << 28)
+#define   PLANE_COLOR_PLANE_CSC_ENABLE			REG_BIT(21) /* ICL+ */
 #define   PLANE_COLOR_INPUT_CSC_ENABLE		(1 << 20) /* ICL+ */
 #define   PLANE_COLOR_PIPE_CSC_ENABLE		(1 << 23) /* Pre-ICL */
 #define   PLANE_COLOR_CSC_MODE_BYPASS			(0 << 17)
@@ -11372,6 +11373,51 @@ enum skl_power_gate {
 					_PAL_PREC_MULTI_SEG_DATA_A, \
 					_PAL_PREC_MULTI_SEG_DATA_B)
 
+#define _MMIO_PLANE_GAMC(plane, i, a, b)  _MMIO(_PIPE(plane, a, b) + (i) * 4)
+
+/* Plane CSC Registers */
+#define _PLANE_CSC_RY_GY_1_A	0x70210
+#define _PLANE_CSC_RY_GY_2_A	0x70310
+
+#define _PLANE_CSC_RY_GY_1_B	0x71210
+#define _PLANE_CSC_RY_GY_2_B	0x71310
+
+#define _PLANE_CSC_RY_GY_1(pipe)	_PIPE(pipe, _PLANE_CSC_RY_GY_1_A, \
+					      _PLANE_CSC_RY_GY_1_B)
+#define _PLANE_CSC_RY_GY_2(pipe)	_PIPE(pipe, _PLANE_INPUT_CSC_RY_GY_2_A, \
+					      _PLANE_INPUT_CSC_RY_GY_2_B)
+#define PLANE_CSC_COEFF(pipe, plane, index)	_MMIO_PLANE(plane, \
+							    _PLANE_CSC_RY_GY_1(pipe) +  (index) * 4, \
+							    _PLANE_CSC_RY_GY_2(pipe) + (index) * 4)
+
+#define _PLANE_CSC_PREOFF_HI_1_A		0x70228
+#define _PLANE_CSC_PREOFF_HI_2_A		0x70328
+
+#define _PLANE_CSC_PREOFF_HI_1_B		0x71228
+#define _PLANE_CSC_PREOFF_HI_2_B		0x71328
+
+#define _PLANE_CSC_PREOFF_HI_1(pipe)	_PIPE(pipe, _PLANE_CSC_PREOFF_HI_1_A, \
+					      _PLANE_CSC_PREOFF_HI_1_B)
+#define _PLANE_CSC_PREOFF_HI_2(pipe)	_PIPE(pipe, _PLANE_CSC_PREOFF_HI_2_A, \
+					      _PLANE_CSC_PREOFF_HI_2_B)
+#define PLANE_CSC_PREOFF(pipe, plane, index)	_MMIO_PLANE(plane, _PLANE_CSC_PREOFF_HI_1(pipe) + \
+							    (index) * 4, _PLANE_CSC_PREOFF_HI_2(pipe) + \
+							    (index) * 4)
+
+#define _PLANE_CSC_POSTOFF_HI_1_A		0x70234
+#define _PLANE_CSC_POSTOFF_HI_2_A		0x70334
+
+#define _PLANE_CSC_POSTOFF_HI_1_B		0x71234
+#define _PLANE_CSC_POSTOFF_HI_2_B		0x71334
+
+#define _PLANE_CSC_POSTOFF_HI_1(pipe)	_PIPE(pipe, _PLANE_CSC_POSTOFF_HI_1_A, \
+					      _PLANE_CSC_POSTOFF_HI_1_B)
+#define _PLANE_CSC_POSTOFF_HI_2(pipe)	_PIPE(pipe, _PLANE_CSC_POSTOFF_HI_2_A, \
+					      _PLANE_CSC_POSTOFF_HI_2_B)
+#define PLANE_CSC_POSTOFF(pipe, plane, index)	_MMIO_PLANE(plane, _PLANE_CSC_POSTOFF_HI_1(pipe) + \
+							    (index) * 4, _PLANE_CSC_POSTOFF_HI_2(pipe) + \
+							    (index) * 4)
+
 /* pipe CSC & degamma/gamma LUTs on CHV */
 #define _CGM_PIPE_A_CSC_COEFF01	(VLV_DISPLAY_BASE + 0x67900)
 #define _CGM_PIPE_A_CSC_COEFF23	(VLV_DISPLAY_BASE + 0x67904)
-- 
2.32.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [PATCH v6 15/15] drm/i915/pxp: enable PXP for integrated Gen12
  2021-07-29  2:00 ` [Intel-gfx] " Daniele Ceraolo Spurio
@ 2021-07-29  2:01   ` Daniele Ceraolo Spurio
  -1 siblings, 0 replies; 64+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-07-29  2:01 UTC (permalink / raw)
  To: intel-gfx; +Cc: Daniele Ceraolo Spurio, dri-devel, Rodrigo Vivi

Note that discrete cards can support PXP as well, but we haven't tested
on those yet so keeping it disabled for now.

Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
---
 drivers/gpu/drm/i915/i915_pci.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index 08651ca03478..f17f4bd2fd43 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -877,6 +877,7 @@ static const struct intel_device_info jsl_info = {
 	}, \
 	TGL_CURSOR_OFFSETS, \
 	.has_global_mocs = 1, \
+	.has_pxp = 1, \
 	.display.has_dsb = 1
 
 static const struct intel_device_info tgl_info = {
@@ -903,6 +904,7 @@ static const struct intel_device_info rkl_info = {
 #define DGFX_FEATURES \
 	.memory_regions = REGION_SMEM | REGION_LMEM | REGION_STOLEN_LMEM, \
 	.has_llc = 0, \
+	.has_pxp = 0, \
 	.has_snoop = 1, \
 	.is_dgfx = 1
 
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [Intel-gfx] [PATCH v6 15/15] drm/i915/pxp: enable PXP for integrated Gen12
@ 2021-07-29  2:01   ` Daniele Ceraolo Spurio
  0 siblings, 0 replies; 64+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-07-29  2:01 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel

Note that discrete cards can support PXP as well, but we haven't tested
on those yet so keeping it disabled for now.

Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
---
 drivers/gpu/drm/i915/i915_pci.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index 08651ca03478..f17f4bd2fd43 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -877,6 +877,7 @@ static const struct intel_device_info jsl_info = {
 	}, \
 	TGL_CURSOR_OFFSETS, \
 	.has_global_mocs = 1, \
+	.has_pxp = 1, \
 	.display.has_dsb = 1
 
 static const struct intel_device_info tgl_info = {
@@ -903,6 +904,7 @@ static const struct intel_device_info rkl_info = {
 #define DGFX_FEATURES \
 	.memory_regions = REGION_SMEM | REGION_LMEM | REGION_STOLEN_LMEM, \
 	.has_llc = 0, \
+	.has_pxp = 0, \
 	.has_snoop = 1, \
 	.is_dgfx = 1
 
-- 
2.32.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Introduce Intel PXP (rev2)
  2021-07-29  2:00 ` [Intel-gfx] " Daniele Ceraolo Spurio
                   ` (15 preceding siblings ...)
  (?)
@ 2021-07-29  3:16 ` Patchwork
  -1 siblings, 0 replies; 64+ messages in thread
From: Patchwork @ 2021-07-29  3:16 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: Introduce Intel PXP (rev2)
URL   : https://patchwork.freedesktop.org/series/90503/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
3eda4d7baf4a drm/i915/pxp: Define PXP component interface
-:31: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#31: 
new file mode 100644

total: 0 errors, 1 warnings, 0 checks, 52 lines checked
1ee35a3e836c mei: pxp: export pavp client to me client bus
-:36: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#36: 
new file mode 100644

total: 0 errors, 1 warnings, 0 checks, 276 lines checked
c61305748e40 drm/i915/pxp: define PXP device flag and kconfig
-:46: ERROR:COMPLEX_MACRO: Macros with complex values should be enclosed in parentheses
#46: FILE: drivers/gpu/drm/i915/i915_drv.h:1727:
+#define HAS_PXP(dev_priv) (IS_ENABLED(CONFIG_DRM_I915_PXP) && \
+			   INTEL_INFO(dev_priv)->has_pxp) && \
+			   VDBOX_MASK(&dev_priv->gt)

-:46: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'dev_priv' - possible side-effects?
#46: FILE: drivers/gpu/drm/i915/i915_drv.h:1727:
+#define HAS_PXP(dev_priv) (IS_ENABLED(CONFIG_DRM_I915_PXP) && \
+			   INTEL_INFO(dev_priv)->has_pxp) && \
+			   VDBOX_MASK(&dev_priv->gt)

total: 1 errors, 0 warnings, 1 checks, 34 lines checked
aa416e099e6f drm/i915/pxp: allocate a vcs context for pxp usage
-:98: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#98: 
new file mode 100644

-:122: ERROR:TRAILING_STATEMENTS: trailing statements should be on next line
#122: FILE: drivers/gpu/drm/i915/pxp/intel_pxp.c:20:
+	for (engine = gt->engine_class[VIDEO_DECODE_CLASS][0]; !engine; engine++);

total: 1 errors, 1 warnings, 0 checks, 168 lines checked
7ffdfca48a9e drm/i915/pxp: Implement funcs to create the TEE channel
-:75: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#75: 
new file mode 100644

total: 0 errors, 1 warnings, 0 checks, 142 lines checked
6f6679322f8d drm/i915/pxp: set KCR reg init
57f92b5ff2d8 drm/i915/pxp: Create the arbitrary session after boot
-:98: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#98: 
new file mode 100644

-:383: CHECK:LINE_SPACING: Please don't use multiple blank lines
#383: FILE: drivers/gpu/drm/i915/pxp/intel_pxp_tee_interface.h:36:
+
+

total: 0 errors, 1 warnings, 1 checks, 339 lines checked
26740ebc8086 drm/i915/pxp: Implement arb session teardown
-:63: CHECK:SPACING: spaces preferred around that '<<' (ctx:VxV)
#63: FILE: drivers/gpu/drm/i915/gt/intel_gpu_commands.h:153:
+#define   MI_FLUSH_DW_PROTECTED_MEM_EN	(1<<22)
                                       	  ^

-:117: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#117: 
new file mode 100644

total: 0 errors, 1 warnings, 1 checks, 283 lines checked
363a76eda1be drm/i915/pxp: Implement PXP irq handler
-:211: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#211: 
new file mode 100644

total: 0 errors, 1 warnings, 0 checks, 423 lines checked
89558164d429 drm/i915/pxp: interfaces for using protected objects
-:673: CHECK:LINE_SPACING: Please use a blank line after function/struct/union/enum declarations
#673: FILE: drivers/gpu/drm/i915/pxp/intel_pxp.h:61:
+}
+static inline void intel_pxp_object_remove(struct drm_i915_gem_object *obj)

total: 0 errors, 0 warnings, 1 checks, 676 lines checked
fe8ab2429443 drm/i915/pxp: start the arb session on demand
8ad86e692de6 drm/i915/pxp: Enable PXP power management
-:120: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#120: 
new file mode 100644

-:188: CHECK:LINE_SPACING: Please use a blank line after function/struct/union/enum declarations
#188: FILE: drivers/gpu/drm/i915/pxp/intel_pxp_pm.h:18:
+}
+static inline void intel_pxp_resume(struct intel_pxp *pxp)

total: 0 errors, 1 warnings, 1 checks, 232 lines checked
0f8e7697ee99 drm/i915/pxp: Add plane decryption support
9f4496a68386 drm/i915/pxp: black pixels on pxp disabled
-:165: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'pipe' - possible side-effects?
#165: FILE: drivers/gpu/drm/i915/i915_reg.h:11389:
+#define PLANE_CSC_COEFF(pipe, plane, index)	_MMIO_PLANE(plane, \
+							    _PLANE_CSC_RY_GY_1(pipe) +  (index) * 4, \
+							    _PLANE_CSC_RY_GY_2(pipe) + (index) * 4)

-:165: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'index' - possible side-effects?
#165: FILE: drivers/gpu/drm/i915/i915_reg.h:11389:
+#define PLANE_CSC_COEFF(pipe, plane, index)	_MMIO_PLANE(plane, \
+							    _PLANE_CSC_RY_GY_1(pipe) +  (index) * 4, \
+							    _PLANE_CSC_RY_GY_2(pipe) + (index) * 4)

-:166: WARNING:LONG_LINE: line length of 102 exceeds 100 columns
#166: FILE: drivers/gpu/drm/i915/i915_reg.h:11390:
+							    _PLANE_CSC_RY_GY_1(pipe) +  (index) * 4, \

-:179: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'pipe' - possible side-effects?
#179: FILE: drivers/gpu/drm/i915/i915_reg.h:11403:
+#define PLANE_CSC_PREOFF(pipe, plane, index)	_MMIO_PLANE(plane, _PLANE_CSC_PREOFF_HI_1(pipe) + \
+							    (index) * 4, _PLANE_CSC_PREOFF_HI_2(pipe) + \
+							    (index) * 4)

-:179: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'index' - possible side-effects?
#179: FILE: drivers/gpu/drm/i915/i915_reg.h:11403:
+#define PLANE_CSC_PREOFF(pipe, plane, index)	_MMIO_PLANE(plane, _PLANE_CSC_PREOFF_HI_1(pipe) + \
+							    (index) * 4, _PLANE_CSC_PREOFF_HI_2(pipe) + \
+							    (index) * 4)

-:180: WARNING:LONG_LINE: line length of 105 exceeds 100 columns
#180: FILE: drivers/gpu/drm/i915/i915_reg.h:11404:
+							    (index) * 4, _PLANE_CSC_PREOFF_HI_2(pipe) + \

-:193: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'pipe' - possible side-effects?
#193: FILE: drivers/gpu/drm/i915/i915_reg.h:11417:
+#define PLANE_CSC_POSTOFF(pipe, plane, index)	_MMIO_PLANE(plane, _PLANE_CSC_POSTOFF_HI_1(pipe) + \
+							    (index) * 4, _PLANE_CSC_POSTOFF_HI_2(pipe) + \
+							    (index) * 4)

-:193: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'index' - possible side-effects?
#193: FILE: drivers/gpu/drm/i915/i915_reg.h:11417:
+#define PLANE_CSC_POSTOFF(pipe, plane, index)	_MMIO_PLANE(plane, _PLANE_CSC_POSTOFF_HI_1(pipe) + \
+							    (index) * 4, _PLANE_CSC_POSTOFF_HI_2(pipe) + \
+							    (index) * 4)

-:194: WARNING:LONG_LINE: line length of 106 exceeds 100 columns
#194: FILE: drivers/gpu/drm/i915/i915_reg.h:11418:
+							    (index) * 4, _PLANE_CSC_POSTOFF_HI_2(pipe) + \

total: 0 errors, 3 warnings, 6 checks, 149 lines checked
8893b90612e6 drm/i915/pxp: enable PXP for integrated Gen12


_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 64+ messages in thread

* [Intel-gfx] ✗ Fi.CI.SPARSE: warning for drm/i915: Introduce Intel PXP (rev2)
  2021-07-29  2:00 ` [Intel-gfx] " Daniele Ceraolo Spurio
                   ` (16 preceding siblings ...)
  (?)
@ 2021-07-29  3:17 ` Patchwork
  -1 siblings, 0 replies; 64+ messages in thread
From: Patchwork @ 2021-07-29  3:17 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: Introduce Intel PXP (rev2)
URL   : https://patchwork.freedesktop.org/series/90503/
State : warning

== Summary ==

$ dim sparse --fast origin/drm-tip
Sparse version: v0.6.2
Fast mode used, each commit won't be checked separately.
-
+drivers/gpu/drm/i915/display/intel_display.c:1900:21:    expected struct i915_vma *[assigned] vma
+drivers/gpu/drm/i915/display/intel_display.c:1900:21:    got void [noderef] __iomem *[assigned] iomem
+drivers/gpu/drm/i915/display/intel_display.c:1900:21: warning: incorrect type in assignment (different address spaces)
+drivers/gpu/drm/i915/gem/i915_gem_context.c:1440:34:    expected struct i915_address_space *vm
+drivers/gpu/drm/i915/gem/i915_gem_context.c:1440:34:    got struct i915_address_space [noderef] __rcu *vm
+drivers/gpu/drm/i915/gem/i915_gem_context.c:1440:34: warning: incorrect type in argument 1 (different address spaces)
+drivers/gpu/drm/i915/gem/selftests/mock_context.c:43:25:    expected struct i915_address_space [noderef] __rcu *vm
+drivers/gpu/drm/i915/gem/selftests/mock_context.c:43:25:    got struct i915_address_space *
+drivers/gpu/drm/i915/gem/selftests/mock_context.c:43:25: warning: incorrect type in assignment (different address spaces)
+drivers/gpu/drm/i915/gem/selftests/mock_context.c:60:34:    expected struct i915_address_space *vm
+drivers/gpu/drm/i915/gem/selftests/mock_context.c:60:34:    got struct i915_address_space [noderef] __rcu *vm
+drivers/gpu/drm/i915/gem/selftests/mock_context.c:60:34: warning: incorrect type in argument 1 (different address spaces)
+drivers/gpu/drm/i915/gt/intel_engine_stats.h:27:9: warning: trying to copy expression type 31
+drivers/gpu/drm/i915/gt/intel_engine_stats.h:27:9: warning: trying to copy expression type 31
+drivers/gpu/drm/i915/gt/intel_engine_stats.h:27:9: warning: trying to copy expression type 31
+drivers/gpu/drm/i915/gt/intel_engine_stats.h:32:9: warning: trying to copy expression type 31
+drivers/gpu/drm/i915/gt/intel_engine_stats.h:32:9: warning: trying to copy expression type 31
+drivers/gpu/drm/i915/gt/intel_engine_stats.h:49:9: warning: trying to copy expression type 31
+drivers/gpu/drm/i915/gt/intel_engine_stats.h:49:9: warning: trying to copy expression type 31
+drivers/gpu/drm/i915/gt/intel_engine_stats.h:49:9: warning: trying to copy expression type 31
+drivers/gpu/drm/i915/gt/intel_engine_stats.h:56:9: warning: trying to copy expression type 31
+drivers/gpu/drm/i915/gt/intel_engine_stats.h:56:9: warning: trying to copy expression type 31
+drivers/gpu/drm/i915/gt/intel_reset.c:1392:5: warning: context imbalance in 'intel_gt_reset_trylock' - different lock contexts for basic block
+drivers/gpu/drm/i915/gt/intel_ring_submission.c:1268:24: warning: Using plain integer as NULL pointer
+drivers/gpu/drm/i915/i915_perf.c:1443:15: warning: memset with byte count of 16777216
+drivers/gpu/drm/i915/i915_perf.c:1497:15: warning: memset with byte count of 16777216
+./include/asm-generic/bitops/find.h:112:45: warning: shift count is negative (-262080)
+./include/asm-generic/bitops/find.h:32:31: warning: shift count is negative (-262080)
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'fwtable_read16' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'fwtable_read32' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'fwtable_read64' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'fwtable_read8' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'fwtable_write16' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'fwtable_write32' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'fwtable_write8' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen11_fwtable_read16' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen11_fwtable_read32' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen11_fwtable_read64' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen11_fwtable_read8' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen11_fwtable_write16' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen11_fwtable_write32' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen11_fwtable_write8' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen12_fwtable_read16' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen12_fwtable_read32' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen12_fwtable_read64' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen12_fwtable_read8' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen12_fwtable_write16' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen12_fwtable_write32' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen12_fwtable_write8' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen6_read16' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen6_read32' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen6_read64' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen6_read8' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen6_write16' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen6_write32' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen6_write8' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen8_write16' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen8_write32' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen8_write8' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'xehp_fwtable_write16' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'xehp_fwtable_write32' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'xehp_fwtable_write8' - different lock contexts for basic block
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined


_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 64+ messages in thread

* [Intel-gfx] ✗ Fi.CI.DOCS: warning for drm/i915: Introduce Intel PXP (rev2)
  2021-07-29  2:00 ` [Intel-gfx] " Daniele Ceraolo Spurio
                   ` (17 preceding siblings ...)
  (?)
@ 2021-07-29  3:21 ` Patchwork
  -1 siblings, 0 replies; 64+ messages in thread
From: Patchwork @ 2021-07-29  3:21 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: Introduce Intel PXP (rev2)
URL   : https://patchwork.freedesktop.org/series/90503/
State : warning

== Summary ==

$ make htmldocs 2>&1 > /dev/null | grep i915
./include/uapi/drm/i915_drm.h:1872: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
./include/uapi/drm/i915_drm.h:1872: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
./include/uapi/drm/i915_drm.h:1872: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
./include/uapi/drm/i915_drm.h:1872: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
./include/uapi/drm/i915_drm.h:3072: warning: Function parameter or member 'base' not described in 'drm_i915_gem_create_ext_protected_content'
./include/uapi/drm/i915_drm.h:3072: warning: Function parameter or member 'flags' not described in 'drm_i915_gem_create_ext_protected_content'


_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 64+ messages in thread

* [Intel-gfx] ✓ Fi.CI.BAT: success for drm/i915: Introduce Intel PXP (rev2)
  2021-07-29  2:00 ` [Intel-gfx] " Daniele Ceraolo Spurio
                   ` (18 preceding siblings ...)
  (?)
@ 2021-07-29  3:43 ` Patchwork
  -1 siblings, 0 replies; 64+ messages in thread
From: Patchwork @ 2021-07-29  3:43 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 3966 bytes --]

== Series Details ==

Series: drm/i915: Introduce Intel PXP (rev2)
URL   : https://patchwork.freedesktop.org/series/90503/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_10416 -> Patchwork_20735
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/index.html

Known issues
------------

  Here are the changes found in Patchwork_20735 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@amdgpu/amd_basic@semaphore:
    - fi-bdw-5557u:       NOTRUN -> [SKIP][1] ([fdo#109271]) +29 similar issues
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/fi-bdw-5557u/igt@amdgpu/amd_basic@semaphore.html

  * igt@core_hotunplug@unbind-rebind:
    - fi-bdw-5557u:       NOTRUN -> [WARN][2] ([i915#3718])
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/fi-bdw-5557u/igt@core_hotunplug@unbind-rebind.html

  * igt@i915_pm_rpm@basic-rte:
    - fi-bdw-5557u:       NOTRUN -> [FAIL][3] ([i915#579])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/fi-bdw-5557u/igt@i915_pm_rpm@basic-rte.html

  * igt@i915_selftest@live@late_gt_pm:
    - fi-bsw-nick:        [PASS][4] -> [DMESG-FAIL][5] ([i915#2927])
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/fi-bsw-nick/igt@i915_selftest@live@late_gt_pm.html
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/fi-bsw-nick/igt@i915_selftest@live@late_gt_pm.html

  * igt@kms_chamelium@dp-crc-fast:
    - fi-bdw-5557u:       NOTRUN -> [SKIP][6] ([fdo#109271] / [fdo#111827]) +8 similar issues
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/fi-bdw-5557u/igt@kms_chamelium@dp-crc-fast.html

  * igt@runner@aborted:
    - fi-bsw-nick:        NOTRUN -> [FAIL][7] ([fdo#109271] / [i915#1436])
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/fi-bsw-nick/igt@runner@aborted.html

  
  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#111827]: https://bugs.freedesktop.org/show_bug.cgi?id=111827
  [i915#1436]: https://gitlab.freedesktop.org/drm/intel/issues/1436
  [i915#2927]: https://gitlab.freedesktop.org/drm/intel/issues/2927
  [i915#3718]: https://gitlab.freedesktop.org/drm/intel/issues/3718
  [i915#579]: https://gitlab.freedesktop.org/drm/intel/issues/579


Participating hosts (40 -> 35)
------------------------------

  Missing    (5): fi-ilk-m540 fi-hsw-4200u fi-bsw-cyan fi-ctg-p8600 fi-bdw-samus 


Build changes
-------------

  * Linux: CI_DRM_10416 -> Patchwork_20735

  CI-20190529: 20190529
  CI_DRM_10416: 68506f9070522fa084cb3a8e5e0de44ee63b61ca @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_6155: 4b51398dcd7559012b85776e7353d516ff1e6ce6 @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
  Patchwork_20735: 8893b90612e65adef2c17852100f8eabe83e7724 @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

8893b90612e6 drm/i915/pxp: enable PXP for integrated Gen12
9f4496a68386 drm/i915/pxp: black pixels on pxp disabled
0f8e7697ee99 drm/i915/pxp: Add plane decryption support
8ad86e692de6 drm/i915/pxp: Enable PXP power management
fe8ab2429443 drm/i915/pxp: start the arb session on demand
89558164d429 drm/i915/pxp: interfaces for using protected objects
363a76eda1be drm/i915/pxp: Implement PXP irq handler
26740ebc8086 drm/i915/pxp: Implement arb session teardown
57f92b5ff2d8 drm/i915/pxp: Create the arbitrary session after boot
6f6679322f8d drm/i915/pxp: set KCR reg init
7ffdfca48a9e drm/i915/pxp: Implement funcs to create the TEE channel
aa416e099e6f drm/i915/pxp: allocate a vcs context for pxp usage
c61305748e40 drm/i915/pxp: define PXP device flag and kconfig
1ee35a3e836c mei: pxp: export pavp client to me client bus
3eda4d7baf4a drm/i915/pxp: Define PXP component interface

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/index.html

[-- Attachment #1.2: Type: text/html, Size: 4918 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 64+ messages in thread

* [Intel-gfx] ✓ Fi.CI.IGT: success for drm/i915: Introduce Intel PXP (rev2)
  2021-07-29  2:00 ` [Intel-gfx] " Daniele Ceraolo Spurio
                   ` (19 preceding siblings ...)
  (?)
@ 2021-07-29  9:55 ` Patchwork
  -1 siblings, 0 replies; 64+ messages in thread
From: Patchwork @ 2021-07-29  9:55 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 30258 bytes --]

== Series Details ==

Series: drm/i915: Introduce Intel PXP (rev2)
URL   : https://patchwork.freedesktop.org/series/90503/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_10416_full -> Patchwork_20735_full
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in Patchwork_20735_full:

### Piglit changes ###

#### Possible regressions ####

  * spec@arb_gpu_shader_int64@execution@conversion@geom-conversion-explicit-u64vec4-uvec4 (NEW):
    - {pig-icl-1065g7}:   NOTRUN -> [CRASH][1]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/pig-icl-1065g7/spec@arb_gpu_shader_int64@execution@conversion@geom-conversion-explicit-u64vec4-uvec4.html

  * spec@arb_gpu_shader_int64@execution@conversion@vert-conversion-implicit-i64vec2-dvec2 (NEW):
    - {pig-icl-1065g7}:   NOTRUN -> [INCOMPLETE][2] +7 similar issues
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/pig-icl-1065g7/spec@arb_gpu_shader_int64@execution@conversion@vert-conversion-implicit-i64vec2-dvec2.html

  
New tests
---------

  New tests have been introduced between CI_DRM_10416_full and Patchwork_20735_full:

### New Piglit tests (9) ###

  * spec@arb_gpu_shader_int64@execution@conversion@frag-conversion-implicit-u64vec4-dvec4:
    - Statuses : 1 incomplete(s)
    - Exec time: [0.0] s

  * spec@arb_gpu_shader_int64@execution@conversion@geom-conversion-explicit-u64vec4-uvec4:
    - Statuses : 1 crash(s)
    - Exec time: [0.95] s

  * spec@arb_gpu_shader_int64@execution@conversion@geom-conversion-implicit-u64vec2-dvec2:
    - Statuses : 1 incomplete(s)
    - Exec time: [0.0] s

  * spec@arb_gpu_shader_int64@execution@conversion@vert-conversion-explicit-bool-uint64_t:
    - Statuses : 1 incomplete(s)
    - Exec time: [0.0] s

  * spec@arb_gpu_shader_int64@execution@conversion@vert-conversion-explicit-u64vec3-bvec3:
    - Statuses : 1 incomplete(s)
    - Exec time: [0.0] s

  * spec@arb_gpu_shader_int64@execution@conversion@vert-conversion-implicit-i64vec2-dvec2:
    - Statuses : 1 incomplete(s)
    - Exec time: [0.0] s

  * spec@arb_gpu_shader_int64@execution@conversion@vert-conversion-implicit-i64vec4-dvec4:
    - Statuses : 1 incomplete(s)
    - Exec time: [0.0] s

  * spec@arb_gpu_shader_int64@execution@conversion@vert-conversion-implicit-i64vec4-u64vec4:
    - Statuses : 1 incomplete(s)
    - Exec time: [0.0] s

  * spec@arb_gpu_shader_int64@execution@conversion@vert-conversion-implicit-uint-uint64_t:
    - Statuses : 1 incomplete(s)
    - Exec time: [0.0] s

  

Known issues
------------

  Here are the changes found in Patchwork_20735_full that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@feature_discovery@display-3x:
    - shard-glk:          NOTRUN -> [SKIP][3] ([fdo#109271]) +39 similar issues
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-glk5/igt@feature_discovery@display-3x.html

  * igt@gem_ctx_persistence@process:
    - shard-snb:          NOTRUN -> [SKIP][4] ([fdo#109271] / [i915#1099]) +4 similar issues
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-snb5/igt@gem_ctx_persistence@process.html

  * igt@gem_exec_fair@basic-pace@vcs1:
    - shard-iclb:         NOTRUN -> [FAIL][5] ([i915#2842])
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-iclb4/igt@gem_exec_fair@basic-pace@vcs1.html

  * igt@gem_exec_fair@basic-throttle@rcs0:
    - shard-glk:          [PASS][6] -> [FAIL][7] ([i915#2842])
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-glk6/igt@gem_exec_fair@basic-throttle@rcs0.html
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-glk3/igt@gem_exec_fair@basic-throttle@rcs0.html
    - shard-iclb:         [PASS][8] -> [FAIL][9] ([i915#2849])
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-iclb3/igt@gem_exec_fair@basic-throttle@rcs0.html
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-iclb2/igt@gem_exec_fair@basic-throttle@rcs0.html

  * igt@gem_mmap_gtt@cpuset-big-copy-odd:
    - shard-iclb:         [PASS][10] -> [FAIL][11] ([i915#2428])
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-iclb2/igt@gem_mmap_gtt@cpuset-big-copy-odd.html
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-iclb7/igt@gem_mmap_gtt@cpuset-big-copy-odd.html
    - shard-glk:          [PASS][12] -> [FAIL][13] ([i915#1888] / [i915#307])
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-glk5/igt@gem_mmap_gtt@cpuset-big-copy-odd.html
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-glk1/igt@gem_mmap_gtt@cpuset-big-copy-odd.html

  * igt@gem_pread@exhaustion:
    - shard-snb:          NOTRUN -> [WARN][14] ([i915#2658])
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-snb2/igt@gem_pread@exhaustion.html

  * igt@gem_render_copy@linear-to-vebox-y-tiled:
    - shard-iclb:         NOTRUN -> [SKIP][15] ([i915#768])
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-iclb5/igt@gem_render_copy@linear-to-vebox-y-tiled.html

  * igt@gem_userptr_blits@dmabuf-sync:
    - shard-kbl:          NOTRUN -> [SKIP][16] ([fdo#109271] / [i915#3323])
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-kbl1/igt@gem_userptr_blits@dmabuf-sync.html
    - shard-apl:          NOTRUN -> [SKIP][17] ([fdo#109271] / [i915#3323])
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-apl8/igt@gem_userptr_blits@dmabuf-sync.html

  * igt@gem_userptr_blits@input-checking:
    - shard-snb:          NOTRUN -> [DMESG-WARN][18] ([i915#3002])
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-snb7/igt@gem_userptr_blits@input-checking.html

  * igt@i915_pm_rpm@basic-rte:
    - shard-kbl:          NOTRUN -> [FAIL][19] ([i915#579])
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-kbl7/igt@i915_pm_rpm@basic-rte.html
    - shard-glk:          NOTRUN -> [FAIL][20] ([i915#579])
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-glk5/igt@i915_pm_rpm@basic-rte.html

  * igt@i915_suspend@fence-restore-untiled:
    - shard-kbl:          NOTRUN -> [DMESG-WARN][21] ([i915#180])
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-kbl1/igt@i915_suspend@fence-restore-untiled.html

  * igt@kms_big_fb@x-tiled-32bpp-rotate-180:
    - shard-glk:          NOTRUN -> [DMESG-WARN][22] ([i915#118] / [i915#95])
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-glk5/igt@kms_big_fb@x-tiled-32bpp-rotate-180.html

  * igt@kms_big_fb@yf-tiled-max-hw-stride-32bpp-rotate-180-hflip:
    - shard-apl:          NOTRUN -> [SKIP][23] ([fdo#109271] / [i915#3777])
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-apl7/igt@kms_big_fb@yf-tiled-max-hw-stride-32bpp-rotate-180-hflip.html

  * igt@kms_big_fb@yf-tiled-max-hw-stride-64bpp-rotate-0:
    - shard-apl:          NOTRUN -> [SKIP][24] ([fdo#109271]) +224 similar issues
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-apl8/igt@kms_big_fb@yf-tiled-max-hw-stride-64bpp-rotate-0.html

  * igt@kms_chamelium@hdmi-crc-nonplanar-formats:
    - shard-glk:          NOTRUN -> [SKIP][25] ([fdo#109271] / [fdo#111827]) +3 similar issues
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-glk5/igt@kms_chamelium@hdmi-crc-nonplanar-formats.html
    - shard-kbl:          NOTRUN -> [SKIP][26] ([fdo#109271] / [fdo#111827]) +5 similar issues
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-kbl7/igt@kms_chamelium@hdmi-crc-nonplanar-formats.html

  * igt@kms_chamelium@vga-hpd-for-each-pipe:
    - shard-skl:          NOTRUN -> [SKIP][27] ([fdo#109271] / [fdo#111827]) +2 similar issues
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-skl10/igt@kms_chamelium@vga-hpd-for-each-pipe.html

  * igt@kms_color_chamelium@pipe-c-ctm-red-to-blue:
    - shard-snb:          NOTRUN -> [SKIP][28] ([fdo#109271] / [fdo#111827]) +15 similar issues
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-snb5/igt@kms_color_chamelium@pipe-c-ctm-red-to-blue.html

  * igt@kms_color_chamelium@pipe-d-ctm-limited-range:
    - shard-apl:          NOTRUN -> [SKIP][29] ([fdo#109271] / [fdo#111827]) +18 similar issues
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-apl7/igt@kms_color_chamelium@pipe-d-ctm-limited-range.html

  * igt@kms_content_protection@dp-mst-type-1:
    - shard-tglb:         NOTRUN -> [SKIP][30] ([i915#3116])
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-tglb3/igt@kms_content_protection@dp-mst-type-1.html

  * igt@kms_content_protection@legacy:
    - shard-kbl:          NOTRUN -> [TIMEOUT][31] ([i915#1319])
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-kbl7/igt@kms_content_protection@legacy.html

  * igt@kms_cursor_crc@pipe-a-cursor-max-size-sliding:
    - shard-iclb:         NOTRUN -> [SKIP][32] ([fdo#109278]) +4 similar issues
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-iclb5/igt@kms_cursor_crc@pipe-a-cursor-max-size-sliding.html

  * igt@kms_cursor_crc@pipe-c-cursor-max-size-sliding:
    - shard-tglb:         NOTRUN -> [SKIP][33] ([i915#3359]) +1 similar issue
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-tglb3/igt@kms_cursor_crc@pipe-c-cursor-max-size-sliding.html

  * igt@kms_flip@2x-dpms-vs-vblank-race:
    - shard-tglb:         NOTRUN -> [SKIP][34] ([fdo#111825]) +1 similar issue
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-tglb3/igt@kms_flip@2x-dpms-vs-vblank-race.html
    - shard-iclb:         NOTRUN -> [SKIP][35] ([fdo#109274])
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-iclb5/igt@kms_flip@2x-dpms-vs-vblank-race.html

  * igt@kms_flip@flip-vs-expired-vblank-interruptible@c-edp1:
    - shard-skl:          [PASS][36] -> [FAIL][37] ([i915#79])
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-skl5/igt@kms_flip@flip-vs-expired-vblank-interruptible@c-edp1.html
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-skl6/igt@kms_flip@flip-vs-expired-vblank-interruptible@c-edp1.html

  * igt@kms_flip@plain-flip-fb-recreate-interruptible@a-edp1:
    - shard-skl:          [PASS][38] -> [FAIL][39] ([i915#2122])
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-skl5/igt@kms_flip@plain-flip-fb-recreate-interruptible@a-edp1.html
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-skl6/igt@kms_flip@plain-flip-fb-recreate-interruptible@a-edp1.html

  * igt@kms_force_connector_basic@force-load-detect:
    - shard-tglb:         NOTRUN -> [SKIP][40] ([fdo#109285])
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-tglb1/igt@kms_force_connector_basic@force-load-detect.html

  * igt@kms_frontbuffer_tracking@fbc-2p-primscrn-spr-indfb-draw-blt:
    - shard-kbl:          NOTRUN -> [SKIP][41] ([fdo#109271]) +68 similar issues
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-kbl7/igt@kms_frontbuffer_tracking@fbc-2p-primscrn-spr-indfb-draw-blt.html

  * igt@kms_frontbuffer_tracking@fbc-2p-scndscrn-pri-indfb-draw-blt:
    - shard-skl:          NOTRUN -> [SKIP][42] ([fdo#109271]) +38 similar issues
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-skl10/igt@kms_frontbuffer_tracking@fbc-2p-scndscrn-pri-indfb-draw-blt.html

  * igt@kms_frontbuffer_tracking@fbcpsr-rgb101010-draw-blt:
    - shard-snb:          NOTRUN -> [SKIP][43] ([fdo#109271]) +276 similar issues
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-snb5/igt@kms_frontbuffer_tracking@fbcpsr-rgb101010-draw-blt.html

  * igt@kms_frontbuffer_tracking@psr-2p-scndscrn-cur-indfb-draw-pwrite:
    - shard-iclb:         NOTRUN -> [SKIP][44] ([fdo#109280])
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-iclb5/igt@kms_frontbuffer_tracking@psr-2p-scndscrn-cur-indfb-draw-pwrite.html

  * igt@kms_pipe_crc_basic@disable-crc-after-crtc-pipe-d:
    - shard-apl:          NOTRUN -> [SKIP][45] ([fdo#109271] / [i915#533]) +1 similar issue
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-apl2/igt@kms_pipe_crc_basic@disable-crc-after-crtc-pipe-d.html

  * igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a:
    - shard-kbl:          [PASS][46] -> [DMESG-WARN][47] ([i915#180]) +1 similar issue
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-kbl1/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a.html
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-kbl1/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a.html

  * igt@kms_plane@plane-panning-bottom-right-suspend@pipe-b-planes:
    - shard-apl:          [PASS][48] -> [DMESG-WARN][49] ([i915#180])
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-apl1/igt@kms_plane@plane-panning-bottom-right-suspend@pipe-b-planes.html
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-apl6/igt@kms_plane@plane-panning-bottom-right-suspend@pipe-b-planes.html

  * igt@kms_plane_alpha_blend@pipe-a-alpha-basic:
    - shard-apl:          NOTRUN -> [FAIL][50] ([fdo#108145] / [i915#265]) +1 similar issue
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-apl1/igt@kms_plane_alpha_blend@pipe-a-alpha-basic.html

  * igt@kms_plane_alpha_blend@pipe-b-alpha-transparent-fb:
    - shard-apl:          NOTRUN -> [FAIL][51] ([i915#265]) +1 similar issue
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-apl7/igt@kms_plane_alpha_blend@pipe-b-alpha-transparent-fb.html

  * igt@kms_plane_alpha_blend@pipe-b-coverage-vs-premult-vs-constant:
    - shard-iclb:         [PASS][52] -> [SKIP][53] ([fdo#109278])
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-iclb4/igt@kms_plane_alpha_blend@pipe-b-coverage-vs-premult-vs-constant.html
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-iclb2/igt@kms_plane_alpha_blend@pipe-b-coverage-vs-premult-vs-constant.html

  * igt@kms_plane_alpha_blend@pipe-c-alpha-transparent-fb:
    - shard-glk:          NOTRUN -> [FAIL][54] ([i915#265])
   [54]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-glk5/igt@kms_plane_alpha_blend@pipe-c-alpha-transparent-fb.html
    - shard-kbl:          NOTRUN -> [FAIL][55] ([i915#265])
   [55]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-kbl7/igt@kms_plane_alpha_blend@pipe-c-alpha-transparent-fb.html

  * igt@kms_psr2_sf@overlay-plane-update-sf-dmg-area-1:
    - shard-kbl:          NOTRUN -> [SKIP][56] ([fdo#109271] / [i915#658]) +1 similar issue
   [56]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-kbl7/igt@kms_psr2_sf@overlay-plane-update-sf-dmg-area-1.html
    - shard-glk:          NOTRUN -> [SKIP][57] ([fdo#109271] / [i915#658])
   [57]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-glk5/igt@kms_psr2_sf@overlay-plane-update-sf-dmg-area-1.html

  * igt@kms_psr2_sf@overlay-plane-update-sf-dmg-area-2:
    - shard-apl:          NOTRUN -> [SKIP][58] ([fdo#109271] / [i915#658]) +3 similar issues
   [58]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-apl7/igt@kms_psr2_sf@overlay-plane-update-sf-dmg-area-2.html

  * igt@kms_psr2_su@frontbuffer:
    - shard-iclb:         [PASS][59] -> [SKIP][60] ([fdo#109642] / [fdo#111068] / [i915#658])
   [59]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-iclb2/igt@kms_psr2_su@frontbuffer.html
   [60]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-iclb7/igt@kms_psr2_su@frontbuffer.html

  * igt@kms_psr@psr2_cursor_blt:
    - shard-iclb:         NOTRUN -> [SKIP][61] ([fdo#109441])
   [61]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-iclb5/igt@kms_psr@psr2_cursor_blt.html
    - shard-tglb:         NOTRUN -> [FAIL][62] ([i915#132] / [i915#3467])
   [62]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-tglb3/igt@kms_psr@psr2_cursor_blt.html

  * igt@kms_psr@psr2_primary_page_flip:
    - shard-iclb:         [PASS][63] -> [SKIP][64] ([fdo#109441]) +1 similar issue
   [63]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-iclb2/igt@kms_psr@psr2_primary_page_flip.html
   [64]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-iclb7/igt@kms_psr@psr2_primary_page_flip.html

  * igt@kms_selftest@all@damage_iter_no_damage:
    - shard-kbl:          NOTRUN -> [INCOMPLETE][65] ([i915#3871])
   [65]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-kbl4/igt@kms_selftest@all@damage_iter_no_damage.html

  * igt@kms_vblank@pipe-a-ts-continuation-suspend:
    - shard-apl:          [PASS][66] -> [DMESG-WARN][67] ([i915#180] / [i915#295])
   [66]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-apl6/igt@kms_vblank@pipe-a-ts-continuation-suspend.html
   [67]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-apl6/igt@kms_vblank@pipe-a-ts-continuation-suspend.html

  * igt@sysfs_clients@create:
    - shard-apl:          NOTRUN -> [SKIP][68] ([fdo#109271] / [i915#2994]) +1 similar issue
   [68]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-apl2/igt@sysfs_clients@create.html
    - shard-skl:          NOTRUN -> [SKIP][69] ([fdo#109271] / [i915#2994])
   [69]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-skl10/igt@sysfs_clients@create.html

  * igt@sysfs_clients@sema-25:
    - shard-kbl:          NOTRUN -> [SKIP][70] ([fdo#109271] / [i915#2994])
   [70]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-kbl7/igt@sysfs_clients@sema-25.html
    - shard-glk:          NOTRUN -> [SKIP][71] ([fdo#109271] / [i915#2994])
   [71]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-glk5/igt@sysfs_clients@sema-25.html

  
#### Possible fixes ####

  * igt@gem_exec_fair@basic-none-share@rcs0:
    - shard-iclb:         [FAIL][72] ([i915#2842]) -> [PASS][73]
   [72]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-iclb2/igt@gem_exec_fair@basic-none-share@rcs0.html
   [73]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-iclb7/igt@gem_exec_fair@basic-none-share@rcs0.html
    - {shard-rkl}:        [FAIL][74] ([i915#2842]) -> [PASS][75]
   [74]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-rkl-2/igt@gem_exec_fair@basic-none-share@rcs0.html
   [75]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-rkl-5/igt@gem_exec_fair@basic-none-share@rcs0.html

  * igt@gem_exec_fair@basic-none-vip@rcs0:
    - shard-kbl:          [FAIL][76] ([i915#2842]) -> [PASS][77] +2 similar issues
   [76]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-kbl2/igt@gem_exec_fair@basic-none-vip@rcs0.html
   [77]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-kbl6/igt@gem_exec_fair@basic-none-vip@rcs0.html

  * igt@gem_exec_fair@basic-pace-share@rcs0:
    - shard-glk:          [FAIL][78] ([i915#2842]) -> [PASS][79] +1 similar issue
   [78]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-glk8/igt@gem_exec_fair@basic-pace-share@rcs0.html
   [79]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-glk9/igt@gem_exec_fair@basic-pace-share@rcs0.html

  * igt@i915_pm_backlight@bad-brightness:
    - {shard-rkl}:        [SKIP][80] ([i915#3012]) -> [PASS][81]
   [80]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-rkl-5/igt@i915_pm_backlight@bad-brightness.html
   [81]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-rkl-6/igt@i915_pm_backlight@bad-brightness.html

  * igt@i915_pm_rpm@gem-evict-pwrite:
    - {shard-rkl}:        [SKIP][82] ([i915#3844] / [i915#579]) -> [PASS][83]
   [82]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-rkl-6/igt@i915_pm_rpm@gem-evict-pwrite.html
   [83]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-rkl-1/igt@i915_pm_rpm@gem-evict-pwrite.html

  * igt@i915_suspend@forcewake:
    - shard-kbl:          [DMESG-WARN][84] ([i915#180]) -> [PASS][85]
   [84]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-kbl1/igt@i915_suspend@forcewake.html
   [85]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-kbl4/igt@i915_suspend@forcewake.html

  * igt@kms_big_fb@x-tiled-8bpp-rotate-0:
    - {shard-rkl}:        [SKIP][86] ([i915#3638]) -> [PASS][87] +1 similar issue
   [86]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-rkl-2/igt@kms_big_fb@x-tiled-8bpp-rotate-0.html
   [87]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-rkl-6/igt@kms_big_fb@x-tiled-8bpp-rotate-0.html

  * igt@kms_big_fb@x-tiled-max-hw-stride-64bpp-rotate-0:
    - {shard-rkl}:        [SKIP][88] ([i915#3721]) -> [PASS][89] +2 similar issues
   [88]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-rkl-5/igt@kms_big_fb@x-tiled-max-hw-stride-64bpp-rotate-0.html
   [89]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-rkl-6/igt@kms_big_fb@x-tiled-max-hw-stride-64bpp-rotate-0.html

  * igt@kms_ccs@pipe-b-bad-aux-stride-y_tiled_gen12_rc_ccs:
    - {shard-rkl}:        [FAIL][90] ([i915#3678]) -> [PASS][91] +5 similar issues
   [90]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-rkl-5/igt@kms_ccs@pipe-b-bad-aux-stride-y_tiled_gen12_rc_ccs.html
   [91]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-rkl-6/igt@kms_ccs@pipe-b-bad-aux-stride-y_tiled_gen12_rc_ccs.html

  * igt@kms_color@pipe-c-ctm-max:
    - {shard-rkl}:        [SKIP][92] ([i915#1149] / [i915#1849]) -> [PASS][93] +3 similar issues
   [92]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-rkl-5/igt@kms_color@pipe-c-ctm-max.html
   [93]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-rkl-6/igt@kms_color@pipe-c-ctm-max.html

  * igt@kms_cursor_crc@pipe-a-cursor-128x42-offscreen:
    - {shard-rkl}:        [SKIP][94] ([fdo#112022]) -> [PASS][95] +9 similar issues
   [94]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-rkl-5/igt@kms_cursor_crc@pipe-a-cursor-128x42-offscreen.html
   [95]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-rkl-6/igt@kms_cursor_crc@pipe-a-cursor-128x42-offscreen.html

  * igt@kms_cursor_crc@pipe-a-cursor-64x21-onscreen:
    - shard-skl:          [FAIL][96] ([i915#3444]) -> [PASS][97]
   [96]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-skl1/igt@kms_cursor_crc@pipe-a-cursor-64x21-onscreen.html
   [97]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-skl4/igt@kms_cursor_crc@pipe-a-cursor-64x21-onscreen.html

  * igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions:
    - shard-skl:          [FAIL][98] ([i915#2346]) -> [PASS][99]
   [98]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-skl6/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions.html
   [99]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-skl4/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions.html

  * igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size:
    - shard-skl:          [FAIL][100] ([i915#2346] / [i915#533]) -> [PASS][101]
   [100]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-skl1/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size.html
   [101]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-skl10/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size.html

  * igt@kms_cursor_legacy@short-flip-after-cursor-toggle:
    - {shard-rkl}:        [SKIP][102] ([fdo#111825]) -> [PASS][103] +1 similar issue
   [102]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-rkl-2/igt@kms_cursor_legacy@short-flip-after-cursor-toggle.html
   [103]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-rkl-6/igt@kms_cursor_legacy@short-flip-after-cursor-toggle.html

  * igt@kms_dp_aux_dev:
    - {shard-rkl}:        [SKIP][104] ([i915#1257]) -> [PASS][105]
   [104]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-rkl-5/igt@kms_dp_aux_dev.html
   [105]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-rkl-6/igt@kms_dp_aux_dev.html

  * igt@kms_draw_crc@draw-method-xrgb2101010-render-untiled:
    - {shard-rkl}:        [SKIP][106] ([fdo#111314]) -> [PASS][107] +5 similar issues
   [106]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-rkl-5/igt@kms_draw_crc@draw-method-xrgb2101010-render-untiled.html
   [107]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-rkl-6/igt@kms_draw_crc@draw-method-xrgb2101010-render-untiled.html

  * igt@kms_frontbuffer_tracking@fbcpsr-rgb101010-draw-mmap-cpu:
    - {shard-rkl}:        [SKIP][108] ([i915#1849]) -> [PASS][109] +32 similar issues
   [108]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-rkl-5/igt@kms_frontbuffer_tracking@fbcpsr-rgb101010-draw-mmap-cpu.html
   [109]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-rkl-6/igt@kms_frontbuffer_tracking@fbcpsr-rgb101010-draw-mmap-cpu.html

  * igt@kms_plane_alpha_blend@pipe-b-coverage-7efc:
    - shard-skl:          [FAIL][110] ([fdo#108145] / [i915#265]) -> [PASS][111]
   [110]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-skl6/igt@kms_plane_alpha_blend@pipe-b-coverage-7efc.html
   [111]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-skl4/igt@kms_plane_alpha_blend@pipe-b-coverage-7efc.html

  * igt@kms_plane_multiple@atomic-pipe-c-tiling-y:
    - {shard-rkl}:        [SKIP][112] ([i915#1849] / [i915#3558]) -> [PASS][113]
   [112]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-rkl-5/igt@kms_plane_multiple@atomic-pipe-c-tiling-y.html
   [113]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-rkl-6/igt@kms_plane_multiple@atomic-pipe-c-tiling-y.html

  * igt@kms_plane_scaling@scaler-with-rotation@pipe-a-scaler-with-rotation:
    - shard-skl:          [DMESG-WARN][114] ([i915#1982]) -> [PASS][115]
   [114]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-skl8/igt@kms_plane_scaling@scaler-with-rotation@pipe-a-scaler-with-rotation.html
   [115]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-skl2/igt@kms_plane_scaling@scaler-with-rotation@pipe-a-scaler-with-rotation.html

  * igt@kms_psr@cursor_mmap_gtt:
    - {shard-rkl}:        [SKIP][116] ([i915#1072]) -> [PASS][117] +1 similar issue
   [116]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-rkl-5/igt@kms_psr@cursor_mmap_gtt.html
   [117]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-rkl-6/igt@kms_psr@cursor_mmap_gtt.html

  * igt@kms_psr@psr2_sprite_mmap_gtt:
    - shard-iclb:         [SKIP][118] ([fdo#109441]) -> [PASS][119] +1 similar issue
   [118]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-iclb3/igt@kms_psr@psr2_sprite_mmap_gtt.html
   [119]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-iclb2/igt@kms_psr@psr2_sprite_mmap_gtt.html

  * igt@kms_vblank@pipe-b-query-forked-busy-hang:
    - {shard-rkl}:        [SKIP][120] ([i915#1845]) -> [PASS][121] +19 similar issues
   [120]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-rkl-5/igt@kms_vblank@pipe-b-query-forked-busy-hang.html
   [121]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-rkl-6/igt@kms_vblank@pipe-b-query-forked-busy-hang.html

  * igt@perf@blocking-parameterized:
    - {shard-rkl}:        [FAIL][122] ([i915#3793]) -> [PASS][123]
   [122]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-rkl-5/igt@perf@blocking-parameterized.html
   [123]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-rkl-6/igt@perf@blocking-parameterized.html

  * igt@perf_pmu@rc6-suspend:
    - shard-kbl:          [INCOMPLETE][124] ([i915#155] / [i915#794]) -> [PASS][125]
   [124]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-kbl4/igt@perf_pmu@rc6-suspend.html
   [125]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-kbl1/igt@perf_pmu@rc6-suspend.html

  
#### Warnings ####

  * igt@i915_pm_dc@dc3co-vpb-simulation:
    - shard-iclb:         [SKIP][126] ([i915#588]) -> [SKIP][127] ([i915#658])
   [126]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-iclb2/igt@i915_pm_dc@dc3co-vpb-simulation.html
   [127]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-iclb7/igt@i915_pm_dc@dc3co-vpb-simulation.html

  * igt@i915_pm_rc6_residency@rc6-fence:
    - shard-iclb:         [WARN][128] ([i915#2684]) -> [WARN][129] ([i915#1804] / [i915#2684])
   [128]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-iclb5/igt@i915_pm_rc6_residency@rc6-fence.html
   [129]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-iclb6/igt@i915_pm_rc6_residency@rc6-fence.html

  * igt@kms_psr2_sf@overlay-primary-update-sf-dmg-area-3:
    - shard-iclb:         [SKIP][130] ([i915#658]) -> [SKIP][131] ([i915#2920]) +2 similar issues
   [130]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-iclb3/igt@kms_psr2_sf@overlay-primary-update-sf-dmg-area-3.html
   [131]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-iclb2/igt@kms_psr2_sf@overlay-primary-update-sf-dmg-area-3.html

  * igt@kms_psr2_sf@plane-move-sf-dmg-area-0:
    - shard-iclb:         [SKIP][132] ([i915#2920]) -> [SKIP][133] ([i915#658])
   [132]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10416/shard-iclb2/igt@kms_psr2_sf@plane-move-sf-dmg-area-0.html
   [133]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/shard-iclb7/igt@kms_psr2_sf@plane-move-sf-dmg-area-0.html

  * igt@runner@aborted:
    - shard-kbl:          ([FAIL][134], [FAIL][135], [FAIL][136], [FAIL][137]) ([fdo#109271] / [i915#1436] / [i915#180] / [i915#3002] / [i915#3363] / [i915#716]) -> ([FAIL][138], [FAIL][139], [FAIL][140], [FAIL][141], [FAIL][142], [FAIL][143], [FAIL][144]) ([fdo#109271] / [i915#1436] / [i915#180] / [i915#1814]

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20735/index.html

[-- Attachment #1.2: Type: text/html, Size: 33563 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v6 10/15] drm/i915/pxp: interfaces for using protected objects
  2021-07-29  2:01   ` [Intel-gfx] " Daniele Ceraolo Spurio
@ 2021-07-29 11:10     ` Rodrigo Vivi
  -1 siblings, 0 replies; 64+ messages in thread
From: Rodrigo Vivi @ 2021-07-29 11:10 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio, jason.ekstrand, Vetter, Daniel
  Cc: intel-gfx, Chris Wilson, dri-devel, Jason Ekstrand,
	Daniel Vetter, Bommu Krishnaiah

On Wed, Jul 28, 2021 at 07:01:01PM -0700, Daniele Ceraolo Spurio wrote:
> This api allow user mode to create protected buffers and to mark
> contexts as making use of such objects. Only when using contexts
> marked in such a way is the execution guaranteed to work as expected.
> 
> Contexts can only be marked as using protected content at creation time
> (i.e. the parameter is immutable) and they must be both bannable and not
> recoverable.
> 
> All protected objects and contexts that have backing storage will be
> considered invalid when the PXP session is destroyed and all new
> submissions using them will be rejected. All intel contexts within the
> invalidated gem contexts will be marked banned. A new flag has been
> added to the RESET_STATS ioctl to report the context invalidation to
> userspace.
> 
> This patch was previously sent as 2 separate patches, which have been
> squashed following a request to have all the uapi in a single patch.
> I've retained the s-o-b from both.
> 
> v5: squash patches, rebase on proto_ctx, update kerneldoc
> 
> v6: rebase on obj create_ext changes

The "rebase" word led me to think it was a small change caused
only by rebasing conflicts, but then I spotted something on
i915_gem_create.c that I didn't remember seeing before.

Since it took me a while to understand what was going on, let me
try to summarize to see if I got it right and to check
with others (Jason in special)
if we are aligned with the recent directions:

With the removal of the vanilla_object from the create_ext,
the addition of the flags was needed.

Then, instead of adding a new user_flags it adds the I915_BO_PROTECTED
to the existent flags (what is cleaner) but then it does

/* Add any flag set by create_ext options */
flags |= ext_flags;

on the new user_create_ext.

What shouldn't be a problem because the ext_flags is really only
the I915_BO_PROTECTED set by our new extension and immutable.

But I'm just trying to see if we are not opening any holes to accept
some undesired flags.

Apparently not.

Am I getting things right? Anything else we should check in here?

Thanks,
Rodrigo.

> 
> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
> Signed-off-by: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
> Cc: Jason Ekstrand <jason@jlekstrand.net>
> Cc: Daniel Vetter <daniel.vetter@intel.com>
> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> #v5
> ---
>  drivers/gpu/drm/i915/gem/i915_gem_context.c   | 68 ++++++++++++--
>  drivers/gpu/drm/i915/gem/i915_gem_context.h   | 18 ++++
>  .../gpu/drm/i915/gem/i915_gem_context_types.h |  2 +
>  drivers/gpu/drm/i915/gem/i915_gem_create.c    | 75 ++++++++++++----
>  .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 40 ++++++++-
>  drivers/gpu/drm/i915/gem/i915_gem_object.c    |  6 ++
>  drivers/gpu/drm/i915/gem/i915_gem_object.h    | 12 +++
>  .../gpu/drm/i915/gem/i915_gem_object_types.h  |  9 ++
>  drivers/gpu/drm/i915/pxp/intel_pxp.c          | 89 +++++++++++++++++++
>  drivers/gpu/drm/i915/pxp/intel_pxp.h          | 15 ++++
>  drivers/gpu/drm/i915/pxp/intel_pxp_session.c  |  3 +
>  drivers/gpu/drm/i915/pxp/intel_pxp_types.h    |  5 ++
>  include/uapi/drm/i915_drm.h                   | 55 +++++++++++-
>  13 files changed, 371 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> index cff72679ad7c..0cd3e2d06188 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> @@ -77,6 +77,8 @@
>  #include "gt/intel_gpu_commands.h"
>  #include "gt/intel_ring.h"
>  
> +#include "pxp/intel_pxp.h"
> +
>  #include "i915_gem_context.h"
>  #include "i915_trace.h"
>  #include "i915_user_extensions.h"
> @@ -241,6 +243,25 @@ static int proto_context_set_persistence(struct drm_i915_private *i915,
>  	return 0;
>  }
>  
> +static int proto_context_set_protected(struct drm_i915_private *i915,
> +				       struct i915_gem_proto_context *pc,
> +				       bool protected)
> +{
> +	int ret = 0;
> +
> +	if (!intel_pxp_is_enabled(&i915->gt.pxp))
> +		ret = -ENODEV;
> +	else if (!protected)
> +		pc->user_flags &= ~BIT(UCONTEXT_PROTECTED);
> +	else if ((pc->user_flags & BIT(UCONTEXT_RECOVERABLE)) ||
> +		 !(pc->user_flags & BIT(UCONTEXT_BANNABLE)))
> +		ret = -EPERM;
> +	else
> +		pc->user_flags |= BIT(UCONTEXT_PROTECTED);
> +
> +	return ret;
> +}
> +
>  static struct i915_gem_proto_context *
>  proto_context_create(struct drm_i915_private *i915, unsigned int flags)
>  {
> @@ -686,6 +707,8 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
>  			ret = -EPERM;
>  		else if (args->value)
>  			pc->user_flags |= BIT(UCONTEXT_BANNABLE);
> +		else if (pc->user_flags & BIT(UCONTEXT_PROTECTED))
> +			ret = -EPERM;
>  		else
>  			pc->user_flags &= ~BIT(UCONTEXT_BANNABLE);
>  		break;
> @@ -693,10 +716,12 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
>  	case I915_CONTEXT_PARAM_RECOVERABLE:
>  		if (args->size)
>  			ret = -EINVAL;
> -		else if (args->value)
> -			pc->user_flags |= BIT(UCONTEXT_RECOVERABLE);
> -		else
> +		else if (!args->value)
>  			pc->user_flags &= ~BIT(UCONTEXT_RECOVERABLE);
> +		else if (pc->user_flags & BIT(UCONTEXT_PROTECTED))
> +			ret = -EPERM;
> +		else
> +			pc->user_flags |= BIT(UCONTEXT_RECOVERABLE);
>  		break;
>  
>  	case I915_CONTEXT_PARAM_PRIORITY:
> @@ -724,6 +749,11 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
>  						    args->value);
>  		break;
>  
> +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
> +		ret = proto_context_set_protected(fpriv->dev_priv, pc,
> +						  args->value);
> +		break;
> +
>  	case I915_CONTEXT_PARAM_NO_ZEROMAP:
>  	case I915_CONTEXT_PARAM_BAN_PERIOD:
>  	case I915_CONTEXT_PARAM_RINGSIZE:
> @@ -1798,6 +1828,18 @@ static int set_priority(struct i915_gem_context *ctx,
>  	return 0;
>  }
>  
> +static int get_protected(struct i915_gem_context *ctx,
> +			 struct drm_i915_gem_context_param *args)
> +{
> +	if (!intel_pxp_is_enabled(&ctx->i915->gt.pxp))
> +		return -ENODEV;
> +
> +	args->size = 0;
> +	args->value = i915_gem_context_uses_protected_content(ctx);
> +
> +	return 0;
> +}
> +
>  static int ctx_setparam(struct drm_i915_file_private *fpriv,
>  			struct i915_gem_context *ctx,
>  			struct drm_i915_gem_context_param *args)
> @@ -1821,6 +1863,8 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
>  			ret = -EPERM;
>  		else if (args->value)
>  			i915_gem_context_set_bannable(ctx);
> +		else if (i915_gem_context_uses_protected_content(ctx))
> +			ret = -EPERM; /* can't clear this for protected contexts */
>  		else
>  			i915_gem_context_clear_bannable(ctx);
>  		break;
> @@ -1828,10 +1872,12 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
>  	case I915_CONTEXT_PARAM_RECOVERABLE:
>  		if (args->size)
>  			ret = -EINVAL;
> -		else if (args->value)
> -			i915_gem_context_set_recoverable(ctx);
> -		else
> +		else if (!args->value)
>  			i915_gem_context_clear_recoverable(ctx);
> +		else if (i915_gem_context_uses_protected_content(ctx))
> +			ret = -EPERM; /* can't set this for protected contexts */
> +		else
> +			i915_gem_context_set_recoverable(ctx);
>  		break;
>  
>  	case I915_CONTEXT_PARAM_PRIORITY:
> @@ -1846,6 +1892,7 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
>  		ret = set_persistence(ctx, args);
>  		break;
>  
> +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
>  	case I915_CONTEXT_PARAM_NO_ZEROMAP:
>  	case I915_CONTEXT_PARAM_BAN_PERIOD:
>  	case I915_CONTEXT_PARAM_RINGSIZE:
> @@ -2174,6 +2221,10 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
>  		args->value = i915_gem_context_is_persistent(ctx);
>  		break;
>  
> +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
> +		ret = get_protected(ctx, args);
> +		break;
> +
>  	case I915_CONTEXT_PARAM_NO_ZEROMAP:
>  	case I915_CONTEXT_PARAM_BAN_PERIOD:
>  	case I915_CONTEXT_PARAM_ENGINES:
> @@ -2250,6 +2301,11 @@ int i915_gem_context_reset_stats_ioctl(struct drm_device *dev,
>  	args->batch_active = atomic_read(&ctx->guilty_count);
>  	args->batch_pending = atomic_read(&ctx->active_count);
>  
> +	/* re-use args->flags for output flags */
> +	args->flags = 0;
> +	if (i915_gem_context_invalidated(ctx))
> +		args->flags |= I915_CONTEXT_INVALIDATED;
> +
>  	i915_gem_context_put(ctx);
>  	return 0;
>  }
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.h b/drivers/gpu/drm/i915/gem/i915_gem_context.h
> index 18060536b0c2..d932a70122fa 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_context.h
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.h
> @@ -108,6 +108,24 @@ i915_gem_context_clear_user_engines(struct i915_gem_context *ctx)
>  	clear_bit(CONTEXT_USER_ENGINES, &ctx->flags);
>  }
>  
> +static inline bool
> +i915_gem_context_invalidated(const struct i915_gem_context *ctx)
> +{
> +	return test_bit(CONTEXT_INVALID, &ctx->flags);
> +}
> +
> +static inline void
> +i915_gem_context_set_invalid(struct i915_gem_context *ctx)
> +{
> +	set_bit(CONTEXT_INVALID, &ctx->flags);
> +}
> +
> +static inline bool
> +i915_gem_context_uses_protected_content(const struct i915_gem_context *ctx)
> +{
> +	return test_bit(UCONTEXT_PROTECTED, &ctx->user_flags);
> +}
> +
>  /* i915_gem_context.c */
>  void i915_gem_init__contexts(struct drm_i915_private *i915);
>  
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
> index 94c03a97cb77..1aa2290aa3c7 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
> @@ -301,6 +301,7 @@ struct i915_gem_context {
>  #define UCONTEXT_BANNABLE		2
>  #define UCONTEXT_RECOVERABLE		3
>  #define UCONTEXT_PERSISTENCE		4
> +#define UCONTEXT_PROTECTED		5
>  
>  	/**
>  	 * @flags: small set of booleans
> @@ -308,6 +309,7 @@ struct i915_gem_context {
>  	unsigned long flags;
>  #define CONTEXT_CLOSED			0
>  #define CONTEXT_USER_ENGINES		1
> +#define CONTEXT_INVALID			2
>  
>  	/** @mutex: guards everything that isn't engines or handles_vma */
>  	struct mutex mutex;
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c b/drivers/gpu/drm/i915/gem/i915_gem_create.c
> index 23fee13a3384..0e48629316bb 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
> @@ -6,6 +6,7 @@
>  #include "gem/i915_gem_ioctls.h"
>  #include "gem/i915_gem_lmem.h"
>  #include "gem/i915_gem_region.h"
> +#include "pxp/intel_pxp.h"
>  
>  #include "i915_drv.h"
>  #include "i915_trace.h"
> @@ -82,21 +83,11 @@ static int i915_gem_publish(struct drm_i915_gem_object *obj,
>  	return 0;
>  }
>  
> -/**
> - * Creates a new object using the same path as DRM_I915_GEM_CREATE_EXT
> - * @i915: i915 private
> - * @size: size of the buffer, in bytes
> - * @placements: possible placement regions, in priority order
> - * @n_placements: number of possible placement regions
> - *
> - * This function is exposed primarily for selftests and does very little
> - * error checking.  It is assumed that the set of placement regions has
> - * already been verified to be valid.
> - */
> -struct drm_i915_gem_object *
> -__i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
> -			      struct intel_memory_region **placements,
> -			      unsigned int n_placements)
> +static struct drm_i915_gem_object *
> +__i915_gem_object_create_user_ext(struct drm_i915_private *i915, u64 size,
> +				  struct intel_memory_region **placements,
> +				  unsigned int n_placements,
> +				  unsigned int ext_flags)
>  {
>  	struct intel_memory_region *mr = placements[0];
>  	struct drm_i915_gem_object *obj;
> @@ -135,6 +126,12 @@ __i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
>  
>  	GEM_BUG_ON(size != obj->base.size);
>  
> +	/* Add any flag set by create_ext options */
> +	flags |= ext_flags;
> +
> +	if (i915_gem_object_is_protected(obj))
> +		intel_pxp_object_add(obj);
> +
>  	trace_i915_gem_object_create(obj);
>  	return obj;
>  
> @@ -145,6 +142,26 @@ __i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
>  	return ERR_PTR(ret);
>  }
>  
> +/**
> + * Creates a new object using the same path as DRM_I915_GEM_CREATE_EXT
> + * @i915: i915 private
> + * @size: size of the buffer, in bytes
> + * @placements: possible placement regions, in priority order
> + * @n_placements: number of possible placement regions
> + *
> + * This function is exposed primarily for selftests and does very little
> + * error checking.  It is assumed that the set of placement regions has
> + * already been verified to be valid.
> + */
> +struct drm_i915_gem_object *
> +__i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
> +			      struct intel_memory_region **placements,
> +			      unsigned int n_placements)
> +{
> +	return __i915_gem_object_create_user_ext(i915, size, placements,
> +						 n_placements, 0);
> +}
> +
>  int
>  i915_gem_dumb_create(struct drm_file *file,
>  		     struct drm_device *dev,
> @@ -224,6 +241,7 @@ struct create_ext {
>  	struct drm_i915_private *i915;
>  	struct intel_memory_region *placements[INTEL_REGION_UNKNOWN];
>  	unsigned int n_placements;
> +	unsigned long flags;
>  };
>  
>  static void repr_placements(char *buf, size_t size,
> @@ -356,8 +374,28 @@ static int ext_set_placements(struct i915_user_extension __user *base,
>  	return set_placements(&ext, data);
>  }
>  
> +static int ext_set_protected(struct i915_user_extension __user *base, void *data)
> +{
> +	struct drm_i915_gem_create_ext_protected_content ext;
> +	struct create_ext *ext_data = data;
> +
> +	if (copy_from_user(&ext, base, sizeof(ext)))
> +		return -EFAULT;
> +
> +	if (ext.flags)
> +		return -EINVAL;
> +
> +	if (!intel_pxp_is_enabled(&ext_data->i915->gt.pxp))
> +		return -ENODEV;
> +
> +	ext_data->flags |= I915_BO_PROTECTED;
> +
> +	return 0;
> +}
> +
>  static const i915_user_extension_fn create_extensions[] = {
>  	[I915_GEM_CREATE_EXT_MEMORY_REGIONS] = ext_set_placements,
> +	[I915_GEM_CREATE_EXT_PROTECTED_CONTENT] = ext_set_protected,
>  };
>  
>  /**
> @@ -392,9 +430,10 @@ i915_gem_create_ext_ioctl(struct drm_device *dev, void *data,
>  		ext_data.n_placements = 1;
>  	}
>  
> -	obj = __i915_gem_object_create_user(i915, args->size,
> -					    ext_data.placements,
> -					    ext_data.n_placements);
> +	obj = __i915_gem_object_create_user_ext(i915, args->size,
> +						ext_data.placements,
> +						ext_data.n_placements,
> +						ext_data.flags);
>  	if (IS_ERR(obj))
>  		return PTR_ERR(obj);
>  
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> index 1ed7475de454..04f33d163340 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> @@ -21,6 +21,8 @@
>  #include "gt/intel_gt_pm.h"
>  #include "gt/intel_ring.h"
>  
> +#include "pxp/intel_pxp.h"
> +
>  #include "i915_drv.h"
>  #include "i915_gem_clflush.h"
>  #include "i915_gem_context.h"
> @@ -751,6 +753,11 @@ static int eb_select_context(struct i915_execbuffer *eb)
>  	if (unlikely(IS_ERR(ctx)))
>  		return PTR_ERR(ctx);
>  
> +	if (i915_gem_context_invalidated(ctx)) {
> +		i915_gem_context_put(ctx);
> +		return -EACCES;
> +	}
> +
>  	eb->gem_context = ctx;
>  	if (rcu_access_pointer(ctx->vm))
>  		eb->invalid_flags |= EXEC_OBJECT_NEEDS_GTT;
> @@ -819,7 +826,7 @@ static struct i915_vma *eb_lookup_vma(struct i915_execbuffer *eb, u32 handle)
>  	do {
>  		struct drm_i915_gem_object *obj;
>  		struct i915_vma *vma;
> -		int err;
> +		int err = 0;
>  
>  		rcu_read_lock();
>  		vma = radix_tree_lookup(&eb->gem_context->handles_vma, handle);
> @@ -833,6 +840,26 @@ static struct i915_vma *eb_lookup_vma(struct i915_execbuffer *eb, u32 handle)
>  		if (unlikely(!obj))
>  			return ERR_PTR(-ENOENT);
>  
> +		/*
> +		 * If the user has opted-in for protected-object tracking, make
> +		 * sure the object encryption can be used.
> +		 * We only need to do this when the object is first used with
> +		 * this context, because the context itself will be banned when
> +		 * the protected objects become invalid.
> +		 */
> +		if (i915_gem_context_uses_protected_content(eb->gem_context) &&
> +		    i915_gem_object_is_protected(obj)) {
> +			if (!intel_pxp_is_active(&vm->gt->pxp))
> +				err = -ENODEV;
> +			else if (!i915_gem_object_has_valid_protection(obj))
> +				err = -ENOEXEC;
> +
> +			if (err) {
> +				i915_gem_object_put(obj);
> +				return ERR_PTR(err);
> +			}
> +		}
> +
>  		vma = i915_vma_instance(obj, vm, NULL);
>  		if (IS_ERR(vma)) {
>  			i915_gem_object_put(obj);
> @@ -2752,6 +2779,17 @@ eb_select_engine(struct i915_execbuffer *eb)
>  
>  	intel_gt_pm_get(ce->engine->gt);
>  
> +	if (i915_gem_context_uses_protected_content(eb->gem_context)) {
> +		err = intel_pxp_wait_for_arb_start(&ce->engine->gt->pxp);
> +		if (err)
> +			goto err;
> +
> +		if (i915_gem_context_invalidated(eb->gem_context)) {
> +			err = -EACCES;
> +			goto err;
> +		}
> +	}
> +
>  	if (!test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
>  		err = intel_context_alloc_state(ce);
>  		if (err)
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c
> index 6fb9afb65034..658a42a7fa07 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
> @@ -25,6 +25,7 @@
>  #include <linux/sched/mm.h>
>  
>  #include "display/intel_frontbuffer.h"
> +#include "pxp/intel_pxp.h"
>  #include "i915_drv.h"
>  #include "i915_gem_clflush.h"
>  #include "i915_gem_context.h"
> @@ -73,6 +74,8 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj,
>  	INIT_LIST_HEAD(&obj->lut_list);
>  	spin_lock_init(&obj->lut_lock);
>  
> +	INIT_LIST_HEAD(&obj->pxp_link);
> +
>  	spin_lock_init(&obj->mmo.lock);
>  	obj->mmo.offsets = RB_ROOT;
>  
> @@ -231,6 +234,9 @@ void __i915_gem_free_object(struct drm_i915_gem_object *obj)
>  		spin_unlock(&obj->vma.lock);
>  	}
>  
> +	if (i915_gem_object_has_valid_protection(obj))
> +		intel_pxp_object_remove(obj);
> +
>  	__i915_gem_object_free_mmaps(obj);
>  
>  	GEM_BUG_ON(!list_empty(&obj->lut_list));
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h
> index 48112b9d76df..137ae2723514 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
> @@ -269,6 +269,18 @@ i915_gem_object_clear_tiling_quirk(struct drm_i915_gem_object *obj)
>  	clear_bit(I915_TILING_QUIRK_BIT, &obj->flags);
>  }
>  
> +static inline bool
> +i915_gem_object_is_protected(const struct drm_i915_gem_object *obj)
> +{
> +	return obj->flags & I915_BO_PROTECTED;
> +}
> +
> +static inline bool
> +i915_gem_object_has_valid_protection(const struct drm_i915_gem_object *obj)
> +{
> +	return i915_gem_object_is_protected(obj) && !list_empty(&obj->pxp_link);
> +}
> +
>  static inline bool
>  i915_gem_object_type_has(const struct drm_i915_gem_object *obj,
>  			 unsigned long flags)
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> index 2471f36aaff3..38e4a190607a 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> @@ -298,6 +298,7 @@ struct drm_i915_gem_object {
>  			     I915_BO_ALLOC_USER)
>  #define I915_BO_READONLY         BIT(4)
>  #define I915_TILING_QUIRK_BIT    5 /* unknown swizzling; do not release! */
> +#define I915_BO_PROTECTED        BIT(6)
>  
>  	/**
>  	 * @mem_flags - Mutable placement-related flags
> @@ -537,6 +538,14 @@ struct drm_i915_gem_object {
>  		bool created:1;
>  	} ttm;
>  
> +	/*
> +	 * When the PXP session is invalidated, we need to mark all protected
> +	 * objects as invalid. To easily do so we add them all to a list. The
> +	 * presence on the list is used to check if the encryption is valid or
> +	 * not.
> +	 */
> +	struct list_head pxp_link;
> +
>  	/** Record of address bit 17 of each page at last unbind. */
>  	unsigned long *bit_17;
>  
> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
> index b0c7edc10cc3..f418281e8c10 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
> @@ -7,6 +7,7 @@
>  #include "intel_pxp_irq.h"
>  #include "intel_pxp_session.h"
>  #include "intel_pxp_tee.h"
> +#include "gem/i915_gem_context.h"
>  #include "gt/intel_context.h"
>  #include "i915_drv.h"
>  
> @@ -70,6 +71,9 @@ void intel_pxp_init(struct intel_pxp *pxp)
>  
>  	mutex_init(&pxp->tee_mutex);
>  
> +	spin_lock_init(&pxp->lock);
> +	INIT_LIST_HEAD(&pxp->protected_objects);
> +
>  	/*
>  	 * we'll use the completion to check if there is a termination pending,
>  	 * so we start it as completed and we reinit it when a termination
> @@ -166,3 +170,88 @@ void intel_pxp_fini_hw(struct intel_pxp *pxp)
>  
>  	intel_pxp_irq_disable(pxp);
>  }
> +
> +int intel_pxp_object_add(struct drm_i915_gem_object *obj)
> +{
> +	struct intel_pxp *pxp = &to_i915(obj->base.dev)->gt.pxp;
> +
> +	if (!intel_pxp_is_enabled(pxp))
> +		return -ENODEV;
> +
> +	if (!list_empty(&obj->pxp_link))
> +		return -EEXIST;
> +
> +	spin_lock_irq(&pxp->lock);
> +	list_add(&obj->pxp_link, &pxp->protected_objects);
> +	spin_unlock_irq(&pxp->lock);
> +
> +	return 0;
> +}
> +
> +void intel_pxp_object_remove(struct drm_i915_gem_object *obj)
> +{
> +	struct intel_pxp *pxp = &to_i915(obj->base.dev)->gt.pxp;
> +
> +	if (!intel_pxp_is_enabled(pxp))
> +		return;
> +
> +	spin_lock_irq(&pxp->lock);
> +	list_del_init(&obj->pxp_link);
> +	spin_unlock_irq(&pxp->lock);
> +}
> +
> +void intel_pxp_invalidate(struct intel_pxp *pxp)
> +{
> +	struct drm_i915_private *i915 = pxp_to_gt(pxp)->i915;
> +	struct drm_i915_gem_object *obj, *tmp;
> +	struct i915_gem_context *ctx, *cn;
> +
> +	/* delete objects that have been used with the invalidated session */
> +	spin_lock_irq(&pxp->lock);
> +	list_for_each_entry_safe(obj, tmp, &pxp->protected_objects, pxp_link) {
> +		if (i915_gem_object_has_pages(obj))
> +			list_del_init(&obj->pxp_link);
> +	}
> +	spin_unlock_irq(&pxp->lock);
> +
> +	/* 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) {
> +		struct i915_gem_engines_iter it;
> +		struct intel_context *ce;
> +
> +		if (!kref_get_unless_zero(&ctx->ref))
> +			continue;
> +
> +		if (likely(!i915_gem_context_uses_protected_content(ctx)) ||
> +		    i915_gem_context_invalidated(ctx)) {
> +			i915_gem_context_put(ctx);
> +			continue;
> +		}
> +
> +		spin_unlock_irq(&i915->gem.contexts.lock);
> +
> +		/*
> +		 * Note that by the time we get here the HW keys are already
> +		 * long gone, so any batch using them that's already on the
> +		 * engines is very likely a lost cause (and it has probably
> +		 * already hung the engine). Therefore, we skip attempting to
> +		 * pull the running context out of the HW and we prioritize
> +		 * bringing the session back as soon as possible.
> +		 */
> +		for_each_gem_engine(ce, i915_gem_context_lock_engines(ctx), it) {
> +			/* only invalidate if at least one ce was allocated */
> +			if (test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
> +				intel_context_set_banned(ce);
> +				i915_gem_context_set_invalid(ctx);
> +			}
> +		}
> +		i915_gem_context_unlock_engines(ctx);
> +
> +		spin_lock_irq(&i915->gem.contexts.lock);
> +		list_safe_reset_next(ctx, cn, link);
> +		i915_gem_context_put(ctx);
> +	}
> +	spin_unlock_irq(&i915->gem.contexts.lock);
> +}
> +
> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
> index 074b3b980957..4f7647f34153 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
> @@ -9,6 +9,8 @@
>  #include "gt/intel_gt_types.h"
>  #include "intel_pxp_types.h"
>  
> +struct drm_i915_gem_object;
> +
>  static inline struct intel_gt *pxp_to_gt(const struct intel_pxp *pxp)
>  {
>  	return container_of(pxp, struct intel_gt, pxp);
> @@ -33,6 +35,11 @@ void intel_pxp_fini_hw(struct intel_pxp *pxp);
>  
>  void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp);
>  int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp);
> +
> +int intel_pxp_object_add(struct drm_i915_gem_object *obj);
> +void intel_pxp_object_remove(struct drm_i915_gem_object *obj);
> +
> +void intel_pxp_invalidate(struct intel_pxp *pxp);
>  #else
>  static inline void intel_pxp_init(struct intel_pxp *pxp)
>  {
> @@ -46,6 +53,14 @@ static inline int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp)
>  {
>  	return 0;
>  }
> +
> +static inline int intel_pxp_object_add(struct drm_i915_gem_object *obj)
> +{
> +	return 0;
> +}
> +static inline void intel_pxp_object_remove(struct drm_i915_gem_object *obj)
> +{
> +}
>  #endif
>  
>  #endif /* __INTEL_PXP_H__ */
> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> index 67c30e534d50..0edd563a653d 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> @@ -85,6 +85,9 @@ static int pxp_terminate_arb_session_and_global(struct intel_pxp *pxp)
>  	/* must mark termination in progress calling this function */
>  	GEM_WARN_ON(pxp->arb_is_valid);
>  
> +	/* invalidate protected objects */
> +	intel_pxp_invalidate(pxp);
> +
>  	/* terminate the hw sessions */
>  	ret = intel_pxp_terminate_session(pxp, ARB_SESSION);
>  	if (ret) {
> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
> index 475e3312c287..be2bed3a2e4e 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
> @@ -7,7 +7,9 @@
>  #define __INTEL_PXP_TYPES_H__
>  
>  #include <linux/completion.h>
> +#include <linux/list.h>
>  #include <linux/mutex.h>
> +#include <linux/spinlock.h>
>  #include <linux/types.h>
>  #include <linux/workqueue.h>
>  
> @@ -43,6 +45,9 @@ struct intel_pxp {
>  	u32 session_events; /* protected with gt->irq_lock */
>  #define PXP_TERMINATION_REQUEST  BIT(0)
>  #define PXP_TERMINATION_COMPLETE BIT(1)
> +
> +	spinlock_t lock; /* protects the objects list */
> +	struct list_head protected_objects;
>  };
>  
>  #endif /* __INTEL_PXP_TYPES_H__ */
> diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
> index 4393eef59d9b..2c9febdae6a5 100644
> --- a/include/uapi/drm/i915_drm.h
> +++ b/include/uapi/drm/i915_drm.h
> @@ -1843,12 +1843,32 @@ struct drm_i915_gem_context_param {
>   * attempted to use it, never re-use this context param number.
>   */
>  #define I915_CONTEXT_PARAM_RINGSIZE	0xc
> +
> +/*
> + * I915_CONTEXT_PARAM_PROTECTED_CONTENT:
> + *
> + * Mark that the context makes use of protected content, which will result
> + * in the context being invalidated when the protected content session is. The
> + * invalidation is reported back to userspace via the RESET_STATS ioctl (see
> + * relevant doc for details).
> + * This flag can only be set at context creation time and, when set to true,
> + * must be preceded by an explicit setting of I915_CONTEXT_PARAM_RECOVERABLE
> + * to false. This flag can't be set to true in conjunction with setting the
> + * I915_CONTEXT_PARAM_BANNABLE flag to false.
> + *
> + * In addition to the normal failure cases, setting this flag during context
> + * creation can result in the following errors:
> + *
> + * -ENODEV: feature not available
> + * -EPERM: trying to mark a recoverable or not bannable context as protected
> + */
> +#define I915_CONTEXT_PARAM_PROTECTED_CONTENT    0xd
>  /* Must be kept compact -- no holes and well documented */
>  
>  	__u64 value;
>  };
>  
> -/*
> +/**
>   * Context SSEU programming
>   *
>   * It may be necessary for either functional or performance reason to configure
> @@ -2181,6 +2201,12 @@ struct drm_i915_reg_read {
>  struct drm_i915_reset_stats {
>  	__u32 ctx_id;
>  	__u32 flags;
> +	/*
> +	 * contexts marked as using protected content are invalidated when the
> +	 * protected content session dies. Submission of invalidated contexts
> +	 * is rejected with -EACCES.
> +	 */
> +#define I915_CONTEXT_INVALIDATED 0x1
>  
>  	/* All resets since boot/module reload, for all contexts */
>  	__u32 reset_count;
> @@ -2959,8 +2985,12 @@ struct drm_i915_gem_create_ext {
>  	 *
>  	 * For I915_GEM_CREATE_EXT_MEMORY_REGIONS usage see
>  	 * struct drm_i915_gem_create_ext_memory_regions.
> +	 *
> +	 * For I915_GEM_CREATE_EXT_PROTECTED_CONTENT usage see
> +	 * struct drm_i915_gem_create_ext_protected_content.
>  	 */
>  #define I915_GEM_CREATE_EXT_MEMORY_REGIONS 0
> +#define I915_GEM_CREATE_EXT_PROTECTED_CONTENT 1
>  	__u64 extensions;
>  };
>  
> @@ -3018,6 +3048,29 @@ struct drm_i915_gem_create_ext_memory_regions {
>  	__u64 regions;
>  };
>  
> +/**
> + * struct drm_i915_gem_create_ext_protected_content - The
> + * I915_OBJECT_PARAM_PROTECTED_CONTENT extension.
> + *
> + * If this extension is provided, buffer contents are expected to be protected
> + * by PXP encryption and require decryption for scan out and processing. This
> + * is only possible on platforms that have PXP enabled, on all other scenarios
> + * using this extension will cause the ioctl to fail and return -ENODEV. The
> + * flags parameter is reserved for future expansion and must currently be set
> + * to zero.
> + *
> + * The buffer contents are considered invalid after a PXP session teardown.
> + *
> + * The encryption is guaranteed to be processed correctly only if the object
> + * is submitted with a context created using the
> + * I915_CONTEXT_PARAM_PROTECTED_CONTENT flag. This will also enable extra checks
> + * at submission time on the validity of the objects involved.
> + */
> +struct drm_i915_gem_create_ext_protected_content {
> +	struct i915_user_extension base;
> +	__u32 flags;
> +};
> +
>  /* ID of the protected content session managed by i915 when PXP is active */
>  #define I915_PROTECTED_CONTENT_DEFAULT_SESSION 0xf
>  
> -- 
> 2.32.0
> 

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Intel-gfx] [PATCH v6 10/15] drm/i915/pxp: interfaces for using protected objects
@ 2021-07-29 11:10     ` Rodrigo Vivi
  0 siblings, 0 replies; 64+ messages in thread
From: Rodrigo Vivi @ 2021-07-29 11:10 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio, jason.ekstrand, Vetter, Daniel
  Cc: intel-gfx, Chris Wilson, dri-devel, Daniel Vetter, Bommu Krishnaiah

On Wed, Jul 28, 2021 at 07:01:01PM -0700, Daniele Ceraolo Spurio wrote:
> This api allow user mode to create protected buffers and to mark
> contexts as making use of such objects. Only when using contexts
> marked in such a way is the execution guaranteed to work as expected.
> 
> Contexts can only be marked as using protected content at creation time
> (i.e. the parameter is immutable) and they must be both bannable and not
> recoverable.
> 
> All protected objects and contexts that have backing storage will be
> considered invalid when the PXP session is destroyed and all new
> submissions using them will be rejected. All intel contexts within the
> invalidated gem contexts will be marked banned. A new flag has been
> added to the RESET_STATS ioctl to report the context invalidation to
> userspace.
> 
> This patch was previously sent as 2 separate patches, which have been
> squashed following a request to have all the uapi in a single patch.
> I've retained the s-o-b from both.
> 
> v5: squash patches, rebase on proto_ctx, update kerneldoc
> 
> v6: rebase on obj create_ext changes

The "rebase" word led me to think it was a small change caused
only by rebasing conflicts, but then I spotted something on
i915_gem_create.c that I didn't remember seeing before.

Since it took me a while to understand what was going on, let me
try to summarize to see if I got it right and to check
with others (Jason in special)
if we are aligned with the recent directions:

With the removal of the vanilla_object from the create_ext,
the addition of the flags was needed.

Then, instead of adding a new user_flags it adds the I915_BO_PROTECTED
to the existent flags (what is cleaner) but then it does

/* Add any flag set by create_ext options */
flags |= ext_flags;

on the new user_create_ext.

What shouldn't be a problem because the ext_flags is really only
the I915_BO_PROTECTED set by our new extension and immutable.

But I'm just trying to see if we are not opening any holes to accept
some undesired flags.

Apparently not.

Am I getting things right? Anything else we should check in here?

Thanks,
Rodrigo.

> 
> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
> Signed-off-by: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
> Cc: Jason Ekstrand <jason@jlekstrand.net>
> Cc: Daniel Vetter <daniel.vetter@intel.com>
> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> #v5
> ---
>  drivers/gpu/drm/i915/gem/i915_gem_context.c   | 68 ++++++++++++--
>  drivers/gpu/drm/i915/gem/i915_gem_context.h   | 18 ++++
>  .../gpu/drm/i915/gem/i915_gem_context_types.h |  2 +
>  drivers/gpu/drm/i915/gem/i915_gem_create.c    | 75 ++++++++++++----
>  .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 40 ++++++++-
>  drivers/gpu/drm/i915/gem/i915_gem_object.c    |  6 ++
>  drivers/gpu/drm/i915/gem/i915_gem_object.h    | 12 +++
>  .../gpu/drm/i915/gem/i915_gem_object_types.h  |  9 ++
>  drivers/gpu/drm/i915/pxp/intel_pxp.c          | 89 +++++++++++++++++++
>  drivers/gpu/drm/i915/pxp/intel_pxp.h          | 15 ++++
>  drivers/gpu/drm/i915/pxp/intel_pxp_session.c  |  3 +
>  drivers/gpu/drm/i915/pxp/intel_pxp_types.h    |  5 ++
>  include/uapi/drm/i915_drm.h                   | 55 +++++++++++-
>  13 files changed, 371 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> index cff72679ad7c..0cd3e2d06188 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> @@ -77,6 +77,8 @@
>  #include "gt/intel_gpu_commands.h"
>  #include "gt/intel_ring.h"
>  
> +#include "pxp/intel_pxp.h"
> +
>  #include "i915_gem_context.h"
>  #include "i915_trace.h"
>  #include "i915_user_extensions.h"
> @@ -241,6 +243,25 @@ static int proto_context_set_persistence(struct drm_i915_private *i915,
>  	return 0;
>  }
>  
> +static int proto_context_set_protected(struct drm_i915_private *i915,
> +				       struct i915_gem_proto_context *pc,
> +				       bool protected)
> +{
> +	int ret = 0;
> +
> +	if (!intel_pxp_is_enabled(&i915->gt.pxp))
> +		ret = -ENODEV;
> +	else if (!protected)
> +		pc->user_flags &= ~BIT(UCONTEXT_PROTECTED);
> +	else if ((pc->user_flags & BIT(UCONTEXT_RECOVERABLE)) ||
> +		 !(pc->user_flags & BIT(UCONTEXT_BANNABLE)))
> +		ret = -EPERM;
> +	else
> +		pc->user_flags |= BIT(UCONTEXT_PROTECTED);
> +
> +	return ret;
> +}
> +
>  static struct i915_gem_proto_context *
>  proto_context_create(struct drm_i915_private *i915, unsigned int flags)
>  {
> @@ -686,6 +707,8 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
>  			ret = -EPERM;
>  		else if (args->value)
>  			pc->user_flags |= BIT(UCONTEXT_BANNABLE);
> +		else if (pc->user_flags & BIT(UCONTEXT_PROTECTED))
> +			ret = -EPERM;
>  		else
>  			pc->user_flags &= ~BIT(UCONTEXT_BANNABLE);
>  		break;
> @@ -693,10 +716,12 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
>  	case I915_CONTEXT_PARAM_RECOVERABLE:
>  		if (args->size)
>  			ret = -EINVAL;
> -		else if (args->value)
> -			pc->user_flags |= BIT(UCONTEXT_RECOVERABLE);
> -		else
> +		else if (!args->value)
>  			pc->user_flags &= ~BIT(UCONTEXT_RECOVERABLE);
> +		else if (pc->user_flags & BIT(UCONTEXT_PROTECTED))
> +			ret = -EPERM;
> +		else
> +			pc->user_flags |= BIT(UCONTEXT_RECOVERABLE);
>  		break;
>  
>  	case I915_CONTEXT_PARAM_PRIORITY:
> @@ -724,6 +749,11 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
>  						    args->value);
>  		break;
>  
> +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
> +		ret = proto_context_set_protected(fpriv->dev_priv, pc,
> +						  args->value);
> +		break;
> +
>  	case I915_CONTEXT_PARAM_NO_ZEROMAP:
>  	case I915_CONTEXT_PARAM_BAN_PERIOD:
>  	case I915_CONTEXT_PARAM_RINGSIZE:
> @@ -1798,6 +1828,18 @@ static int set_priority(struct i915_gem_context *ctx,
>  	return 0;
>  }
>  
> +static int get_protected(struct i915_gem_context *ctx,
> +			 struct drm_i915_gem_context_param *args)
> +{
> +	if (!intel_pxp_is_enabled(&ctx->i915->gt.pxp))
> +		return -ENODEV;
> +
> +	args->size = 0;
> +	args->value = i915_gem_context_uses_protected_content(ctx);
> +
> +	return 0;
> +}
> +
>  static int ctx_setparam(struct drm_i915_file_private *fpriv,
>  			struct i915_gem_context *ctx,
>  			struct drm_i915_gem_context_param *args)
> @@ -1821,6 +1863,8 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
>  			ret = -EPERM;
>  		else if (args->value)
>  			i915_gem_context_set_bannable(ctx);
> +		else if (i915_gem_context_uses_protected_content(ctx))
> +			ret = -EPERM; /* can't clear this for protected contexts */
>  		else
>  			i915_gem_context_clear_bannable(ctx);
>  		break;
> @@ -1828,10 +1872,12 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
>  	case I915_CONTEXT_PARAM_RECOVERABLE:
>  		if (args->size)
>  			ret = -EINVAL;
> -		else if (args->value)
> -			i915_gem_context_set_recoverable(ctx);
> -		else
> +		else if (!args->value)
>  			i915_gem_context_clear_recoverable(ctx);
> +		else if (i915_gem_context_uses_protected_content(ctx))
> +			ret = -EPERM; /* can't set this for protected contexts */
> +		else
> +			i915_gem_context_set_recoverable(ctx);
>  		break;
>  
>  	case I915_CONTEXT_PARAM_PRIORITY:
> @@ -1846,6 +1892,7 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
>  		ret = set_persistence(ctx, args);
>  		break;
>  
> +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
>  	case I915_CONTEXT_PARAM_NO_ZEROMAP:
>  	case I915_CONTEXT_PARAM_BAN_PERIOD:
>  	case I915_CONTEXT_PARAM_RINGSIZE:
> @@ -2174,6 +2221,10 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
>  		args->value = i915_gem_context_is_persistent(ctx);
>  		break;
>  
> +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
> +		ret = get_protected(ctx, args);
> +		break;
> +
>  	case I915_CONTEXT_PARAM_NO_ZEROMAP:
>  	case I915_CONTEXT_PARAM_BAN_PERIOD:
>  	case I915_CONTEXT_PARAM_ENGINES:
> @@ -2250,6 +2301,11 @@ int i915_gem_context_reset_stats_ioctl(struct drm_device *dev,
>  	args->batch_active = atomic_read(&ctx->guilty_count);
>  	args->batch_pending = atomic_read(&ctx->active_count);
>  
> +	/* re-use args->flags for output flags */
> +	args->flags = 0;
> +	if (i915_gem_context_invalidated(ctx))
> +		args->flags |= I915_CONTEXT_INVALIDATED;
> +
>  	i915_gem_context_put(ctx);
>  	return 0;
>  }
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.h b/drivers/gpu/drm/i915/gem/i915_gem_context.h
> index 18060536b0c2..d932a70122fa 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_context.h
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.h
> @@ -108,6 +108,24 @@ i915_gem_context_clear_user_engines(struct i915_gem_context *ctx)
>  	clear_bit(CONTEXT_USER_ENGINES, &ctx->flags);
>  }
>  
> +static inline bool
> +i915_gem_context_invalidated(const struct i915_gem_context *ctx)
> +{
> +	return test_bit(CONTEXT_INVALID, &ctx->flags);
> +}
> +
> +static inline void
> +i915_gem_context_set_invalid(struct i915_gem_context *ctx)
> +{
> +	set_bit(CONTEXT_INVALID, &ctx->flags);
> +}
> +
> +static inline bool
> +i915_gem_context_uses_protected_content(const struct i915_gem_context *ctx)
> +{
> +	return test_bit(UCONTEXT_PROTECTED, &ctx->user_flags);
> +}
> +
>  /* i915_gem_context.c */
>  void i915_gem_init__contexts(struct drm_i915_private *i915);
>  
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
> index 94c03a97cb77..1aa2290aa3c7 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
> @@ -301,6 +301,7 @@ struct i915_gem_context {
>  #define UCONTEXT_BANNABLE		2
>  #define UCONTEXT_RECOVERABLE		3
>  #define UCONTEXT_PERSISTENCE		4
> +#define UCONTEXT_PROTECTED		5
>  
>  	/**
>  	 * @flags: small set of booleans
> @@ -308,6 +309,7 @@ struct i915_gem_context {
>  	unsigned long flags;
>  #define CONTEXT_CLOSED			0
>  #define CONTEXT_USER_ENGINES		1
> +#define CONTEXT_INVALID			2
>  
>  	/** @mutex: guards everything that isn't engines or handles_vma */
>  	struct mutex mutex;
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c b/drivers/gpu/drm/i915/gem/i915_gem_create.c
> index 23fee13a3384..0e48629316bb 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
> @@ -6,6 +6,7 @@
>  #include "gem/i915_gem_ioctls.h"
>  #include "gem/i915_gem_lmem.h"
>  #include "gem/i915_gem_region.h"
> +#include "pxp/intel_pxp.h"
>  
>  #include "i915_drv.h"
>  #include "i915_trace.h"
> @@ -82,21 +83,11 @@ static int i915_gem_publish(struct drm_i915_gem_object *obj,
>  	return 0;
>  }
>  
> -/**
> - * Creates a new object using the same path as DRM_I915_GEM_CREATE_EXT
> - * @i915: i915 private
> - * @size: size of the buffer, in bytes
> - * @placements: possible placement regions, in priority order
> - * @n_placements: number of possible placement regions
> - *
> - * This function is exposed primarily for selftests and does very little
> - * error checking.  It is assumed that the set of placement regions has
> - * already been verified to be valid.
> - */
> -struct drm_i915_gem_object *
> -__i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
> -			      struct intel_memory_region **placements,
> -			      unsigned int n_placements)
> +static struct drm_i915_gem_object *
> +__i915_gem_object_create_user_ext(struct drm_i915_private *i915, u64 size,
> +				  struct intel_memory_region **placements,
> +				  unsigned int n_placements,
> +				  unsigned int ext_flags)
>  {
>  	struct intel_memory_region *mr = placements[0];
>  	struct drm_i915_gem_object *obj;
> @@ -135,6 +126,12 @@ __i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
>  
>  	GEM_BUG_ON(size != obj->base.size);
>  
> +	/* Add any flag set by create_ext options */
> +	flags |= ext_flags;
> +
> +	if (i915_gem_object_is_protected(obj))
> +		intel_pxp_object_add(obj);
> +
>  	trace_i915_gem_object_create(obj);
>  	return obj;
>  
> @@ -145,6 +142,26 @@ __i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
>  	return ERR_PTR(ret);
>  }
>  
> +/**
> + * Creates a new object using the same path as DRM_I915_GEM_CREATE_EXT
> + * @i915: i915 private
> + * @size: size of the buffer, in bytes
> + * @placements: possible placement regions, in priority order
> + * @n_placements: number of possible placement regions
> + *
> + * This function is exposed primarily for selftests and does very little
> + * error checking.  It is assumed that the set of placement regions has
> + * already been verified to be valid.
> + */
> +struct drm_i915_gem_object *
> +__i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
> +			      struct intel_memory_region **placements,
> +			      unsigned int n_placements)
> +{
> +	return __i915_gem_object_create_user_ext(i915, size, placements,
> +						 n_placements, 0);
> +}
> +
>  int
>  i915_gem_dumb_create(struct drm_file *file,
>  		     struct drm_device *dev,
> @@ -224,6 +241,7 @@ struct create_ext {
>  	struct drm_i915_private *i915;
>  	struct intel_memory_region *placements[INTEL_REGION_UNKNOWN];
>  	unsigned int n_placements;
> +	unsigned long flags;
>  };
>  
>  static void repr_placements(char *buf, size_t size,
> @@ -356,8 +374,28 @@ static int ext_set_placements(struct i915_user_extension __user *base,
>  	return set_placements(&ext, data);
>  }
>  
> +static int ext_set_protected(struct i915_user_extension __user *base, void *data)
> +{
> +	struct drm_i915_gem_create_ext_protected_content ext;
> +	struct create_ext *ext_data = data;
> +
> +	if (copy_from_user(&ext, base, sizeof(ext)))
> +		return -EFAULT;
> +
> +	if (ext.flags)
> +		return -EINVAL;
> +
> +	if (!intel_pxp_is_enabled(&ext_data->i915->gt.pxp))
> +		return -ENODEV;
> +
> +	ext_data->flags |= I915_BO_PROTECTED;
> +
> +	return 0;
> +}
> +
>  static const i915_user_extension_fn create_extensions[] = {
>  	[I915_GEM_CREATE_EXT_MEMORY_REGIONS] = ext_set_placements,
> +	[I915_GEM_CREATE_EXT_PROTECTED_CONTENT] = ext_set_protected,
>  };
>  
>  /**
> @@ -392,9 +430,10 @@ i915_gem_create_ext_ioctl(struct drm_device *dev, void *data,
>  		ext_data.n_placements = 1;
>  	}
>  
> -	obj = __i915_gem_object_create_user(i915, args->size,
> -					    ext_data.placements,
> -					    ext_data.n_placements);
> +	obj = __i915_gem_object_create_user_ext(i915, args->size,
> +						ext_data.placements,
> +						ext_data.n_placements,
> +						ext_data.flags);
>  	if (IS_ERR(obj))
>  		return PTR_ERR(obj);
>  
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> index 1ed7475de454..04f33d163340 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> @@ -21,6 +21,8 @@
>  #include "gt/intel_gt_pm.h"
>  #include "gt/intel_ring.h"
>  
> +#include "pxp/intel_pxp.h"
> +
>  #include "i915_drv.h"
>  #include "i915_gem_clflush.h"
>  #include "i915_gem_context.h"
> @@ -751,6 +753,11 @@ static int eb_select_context(struct i915_execbuffer *eb)
>  	if (unlikely(IS_ERR(ctx)))
>  		return PTR_ERR(ctx);
>  
> +	if (i915_gem_context_invalidated(ctx)) {
> +		i915_gem_context_put(ctx);
> +		return -EACCES;
> +	}
> +
>  	eb->gem_context = ctx;
>  	if (rcu_access_pointer(ctx->vm))
>  		eb->invalid_flags |= EXEC_OBJECT_NEEDS_GTT;
> @@ -819,7 +826,7 @@ static struct i915_vma *eb_lookup_vma(struct i915_execbuffer *eb, u32 handle)
>  	do {
>  		struct drm_i915_gem_object *obj;
>  		struct i915_vma *vma;
> -		int err;
> +		int err = 0;
>  
>  		rcu_read_lock();
>  		vma = radix_tree_lookup(&eb->gem_context->handles_vma, handle);
> @@ -833,6 +840,26 @@ static struct i915_vma *eb_lookup_vma(struct i915_execbuffer *eb, u32 handle)
>  		if (unlikely(!obj))
>  			return ERR_PTR(-ENOENT);
>  
> +		/*
> +		 * If the user has opted-in for protected-object tracking, make
> +		 * sure the object encryption can be used.
> +		 * We only need to do this when the object is first used with
> +		 * this context, because the context itself will be banned when
> +		 * the protected objects become invalid.
> +		 */
> +		if (i915_gem_context_uses_protected_content(eb->gem_context) &&
> +		    i915_gem_object_is_protected(obj)) {
> +			if (!intel_pxp_is_active(&vm->gt->pxp))
> +				err = -ENODEV;
> +			else if (!i915_gem_object_has_valid_protection(obj))
> +				err = -ENOEXEC;
> +
> +			if (err) {
> +				i915_gem_object_put(obj);
> +				return ERR_PTR(err);
> +			}
> +		}
> +
>  		vma = i915_vma_instance(obj, vm, NULL);
>  		if (IS_ERR(vma)) {
>  			i915_gem_object_put(obj);
> @@ -2752,6 +2779,17 @@ eb_select_engine(struct i915_execbuffer *eb)
>  
>  	intel_gt_pm_get(ce->engine->gt);
>  
> +	if (i915_gem_context_uses_protected_content(eb->gem_context)) {
> +		err = intel_pxp_wait_for_arb_start(&ce->engine->gt->pxp);
> +		if (err)
> +			goto err;
> +
> +		if (i915_gem_context_invalidated(eb->gem_context)) {
> +			err = -EACCES;
> +			goto err;
> +		}
> +	}
> +
>  	if (!test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
>  		err = intel_context_alloc_state(ce);
>  		if (err)
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c
> index 6fb9afb65034..658a42a7fa07 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
> @@ -25,6 +25,7 @@
>  #include <linux/sched/mm.h>
>  
>  #include "display/intel_frontbuffer.h"
> +#include "pxp/intel_pxp.h"
>  #include "i915_drv.h"
>  #include "i915_gem_clflush.h"
>  #include "i915_gem_context.h"
> @@ -73,6 +74,8 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj,
>  	INIT_LIST_HEAD(&obj->lut_list);
>  	spin_lock_init(&obj->lut_lock);
>  
> +	INIT_LIST_HEAD(&obj->pxp_link);
> +
>  	spin_lock_init(&obj->mmo.lock);
>  	obj->mmo.offsets = RB_ROOT;
>  
> @@ -231,6 +234,9 @@ void __i915_gem_free_object(struct drm_i915_gem_object *obj)
>  		spin_unlock(&obj->vma.lock);
>  	}
>  
> +	if (i915_gem_object_has_valid_protection(obj))
> +		intel_pxp_object_remove(obj);
> +
>  	__i915_gem_object_free_mmaps(obj);
>  
>  	GEM_BUG_ON(!list_empty(&obj->lut_list));
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h
> index 48112b9d76df..137ae2723514 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
> @@ -269,6 +269,18 @@ i915_gem_object_clear_tiling_quirk(struct drm_i915_gem_object *obj)
>  	clear_bit(I915_TILING_QUIRK_BIT, &obj->flags);
>  }
>  
> +static inline bool
> +i915_gem_object_is_protected(const struct drm_i915_gem_object *obj)
> +{
> +	return obj->flags & I915_BO_PROTECTED;
> +}
> +
> +static inline bool
> +i915_gem_object_has_valid_protection(const struct drm_i915_gem_object *obj)
> +{
> +	return i915_gem_object_is_protected(obj) && !list_empty(&obj->pxp_link);
> +}
> +
>  static inline bool
>  i915_gem_object_type_has(const struct drm_i915_gem_object *obj,
>  			 unsigned long flags)
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> index 2471f36aaff3..38e4a190607a 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> @@ -298,6 +298,7 @@ struct drm_i915_gem_object {
>  			     I915_BO_ALLOC_USER)
>  #define I915_BO_READONLY         BIT(4)
>  #define I915_TILING_QUIRK_BIT    5 /* unknown swizzling; do not release! */
> +#define I915_BO_PROTECTED        BIT(6)
>  
>  	/**
>  	 * @mem_flags - Mutable placement-related flags
> @@ -537,6 +538,14 @@ struct drm_i915_gem_object {
>  		bool created:1;
>  	} ttm;
>  
> +	/*
> +	 * When the PXP session is invalidated, we need to mark all protected
> +	 * objects as invalid. To easily do so we add them all to a list. The
> +	 * presence on the list is used to check if the encryption is valid or
> +	 * not.
> +	 */
> +	struct list_head pxp_link;
> +
>  	/** Record of address bit 17 of each page at last unbind. */
>  	unsigned long *bit_17;
>  
> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
> index b0c7edc10cc3..f418281e8c10 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
> @@ -7,6 +7,7 @@
>  #include "intel_pxp_irq.h"
>  #include "intel_pxp_session.h"
>  #include "intel_pxp_tee.h"
> +#include "gem/i915_gem_context.h"
>  #include "gt/intel_context.h"
>  #include "i915_drv.h"
>  
> @@ -70,6 +71,9 @@ void intel_pxp_init(struct intel_pxp *pxp)
>  
>  	mutex_init(&pxp->tee_mutex);
>  
> +	spin_lock_init(&pxp->lock);
> +	INIT_LIST_HEAD(&pxp->protected_objects);
> +
>  	/*
>  	 * we'll use the completion to check if there is a termination pending,
>  	 * so we start it as completed and we reinit it when a termination
> @@ -166,3 +170,88 @@ void intel_pxp_fini_hw(struct intel_pxp *pxp)
>  
>  	intel_pxp_irq_disable(pxp);
>  }
> +
> +int intel_pxp_object_add(struct drm_i915_gem_object *obj)
> +{
> +	struct intel_pxp *pxp = &to_i915(obj->base.dev)->gt.pxp;
> +
> +	if (!intel_pxp_is_enabled(pxp))
> +		return -ENODEV;
> +
> +	if (!list_empty(&obj->pxp_link))
> +		return -EEXIST;
> +
> +	spin_lock_irq(&pxp->lock);
> +	list_add(&obj->pxp_link, &pxp->protected_objects);
> +	spin_unlock_irq(&pxp->lock);
> +
> +	return 0;
> +}
> +
> +void intel_pxp_object_remove(struct drm_i915_gem_object *obj)
> +{
> +	struct intel_pxp *pxp = &to_i915(obj->base.dev)->gt.pxp;
> +
> +	if (!intel_pxp_is_enabled(pxp))
> +		return;
> +
> +	spin_lock_irq(&pxp->lock);
> +	list_del_init(&obj->pxp_link);
> +	spin_unlock_irq(&pxp->lock);
> +}
> +
> +void intel_pxp_invalidate(struct intel_pxp *pxp)
> +{
> +	struct drm_i915_private *i915 = pxp_to_gt(pxp)->i915;
> +	struct drm_i915_gem_object *obj, *tmp;
> +	struct i915_gem_context *ctx, *cn;
> +
> +	/* delete objects that have been used with the invalidated session */
> +	spin_lock_irq(&pxp->lock);
> +	list_for_each_entry_safe(obj, tmp, &pxp->protected_objects, pxp_link) {
> +		if (i915_gem_object_has_pages(obj))
> +			list_del_init(&obj->pxp_link);
> +	}
> +	spin_unlock_irq(&pxp->lock);
> +
> +	/* 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) {
> +		struct i915_gem_engines_iter it;
> +		struct intel_context *ce;
> +
> +		if (!kref_get_unless_zero(&ctx->ref))
> +			continue;
> +
> +		if (likely(!i915_gem_context_uses_protected_content(ctx)) ||
> +		    i915_gem_context_invalidated(ctx)) {
> +			i915_gem_context_put(ctx);
> +			continue;
> +		}
> +
> +		spin_unlock_irq(&i915->gem.contexts.lock);
> +
> +		/*
> +		 * Note that by the time we get here the HW keys are already
> +		 * long gone, so any batch using them that's already on the
> +		 * engines is very likely a lost cause (and it has probably
> +		 * already hung the engine). Therefore, we skip attempting to
> +		 * pull the running context out of the HW and we prioritize
> +		 * bringing the session back as soon as possible.
> +		 */
> +		for_each_gem_engine(ce, i915_gem_context_lock_engines(ctx), it) {
> +			/* only invalidate if at least one ce was allocated */
> +			if (test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
> +				intel_context_set_banned(ce);
> +				i915_gem_context_set_invalid(ctx);
> +			}
> +		}
> +		i915_gem_context_unlock_engines(ctx);
> +
> +		spin_lock_irq(&i915->gem.contexts.lock);
> +		list_safe_reset_next(ctx, cn, link);
> +		i915_gem_context_put(ctx);
> +	}
> +	spin_unlock_irq(&i915->gem.contexts.lock);
> +}
> +
> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
> index 074b3b980957..4f7647f34153 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
> @@ -9,6 +9,8 @@
>  #include "gt/intel_gt_types.h"
>  #include "intel_pxp_types.h"
>  
> +struct drm_i915_gem_object;
> +
>  static inline struct intel_gt *pxp_to_gt(const struct intel_pxp *pxp)
>  {
>  	return container_of(pxp, struct intel_gt, pxp);
> @@ -33,6 +35,11 @@ void intel_pxp_fini_hw(struct intel_pxp *pxp);
>  
>  void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp);
>  int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp);
> +
> +int intel_pxp_object_add(struct drm_i915_gem_object *obj);
> +void intel_pxp_object_remove(struct drm_i915_gem_object *obj);
> +
> +void intel_pxp_invalidate(struct intel_pxp *pxp);
>  #else
>  static inline void intel_pxp_init(struct intel_pxp *pxp)
>  {
> @@ -46,6 +53,14 @@ static inline int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp)
>  {
>  	return 0;
>  }
> +
> +static inline int intel_pxp_object_add(struct drm_i915_gem_object *obj)
> +{
> +	return 0;
> +}
> +static inline void intel_pxp_object_remove(struct drm_i915_gem_object *obj)
> +{
> +}
>  #endif
>  
>  #endif /* __INTEL_PXP_H__ */
> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> index 67c30e534d50..0edd563a653d 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> @@ -85,6 +85,9 @@ static int pxp_terminate_arb_session_and_global(struct intel_pxp *pxp)
>  	/* must mark termination in progress calling this function */
>  	GEM_WARN_ON(pxp->arb_is_valid);
>  
> +	/* invalidate protected objects */
> +	intel_pxp_invalidate(pxp);
> +
>  	/* terminate the hw sessions */
>  	ret = intel_pxp_terminate_session(pxp, ARB_SESSION);
>  	if (ret) {
> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
> index 475e3312c287..be2bed3a2e4e 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
> @@ -7,7 +7,9 @@
>  #define __INTEL_PXP_TYPES_H__
>  
>  #include <linux/completion.h>
> +#include <linux/list.h>
>  #include <linux/mutex.h>
> +#include <linux/spinlock.h>
>  #include <linux/types.h>
>  #include <linux/workqueue.h>
>  
> @@ -43,6 +45,9 @@ struct intel_pxp {
>  	u32 session_events; /* protected with gt->irq_lock */
>  #define PXP_TERMINATION_REQUEST  BIT(0)
>  #define PXP_TERMINATION_COMPLETE BIT(1)
> +
> +	spinlock_t lock; /* protects the objects list */
> +	struct list_head protected_objects;
>  };
>  
>  #endif /* __INTEL_PXP_TYPES_H__ */
> diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
> index 4393eef59d9b..2c9febdae6a5 100644
> --- a/include/uapi/drm/i915_drm.h
> +++ b/include/uapi/drm/i915_drm.h
> @@ -1843,12 +1843,32 @@ struct drm_i915_gem_context_param {
>   * attempted to use it, never re-use this context param number.
>   */
>  #define I915_CONTEXT_PARAM_RINGSIZE	0xc
> +
> +/*
> + * I915_CONTEXT_PARAM_PROTECTED_CONTENT:
> + *
> + * Mark that the context makes use of protected content, which will result
> + * in the context being invalidated when the protected content session is. The
> + * invalidation is reported back to userspace via the RESET_STATS ioctl (see
> + * relevant doc for details).
> + * This flag can only be set at context creation time and, when set to true,
> + * must be preceded by an explicit setting of I915_CONTEXT_PARAM_RECOVERABLE
> + * to false. This flag can't be set to true in conjunction with setting the
> + * I915_CONTEXT_PARAM_BANNABLE flag to false.
> + *
> + * In addition to the normal failure cases, setting this flag during context
> + * creation can result in the following errors:
> + *
> + * -ENODEV: feature not available
> + * -EPERM: trying to mark a recoverable or not bannable context as protected
> + */
> +#define I915_CONTEXT_PARAM_PROTECTED_CONTENT    0xd
>  /* Must be kept compact -- no holes and well documented */
>  
>  	__u64 value;
>  };
>  
> -/*
> +/**
>   * Context SSEU programming
>   *
>   * It may be necessary for either functional or performance reason to configure
> @@ -2181,6 +2201,12 @@ struct drm_i915_reg_read {
>  struct drm_i915_reset_stats {
>  	__u32 ctx_id;
>  	__u32 flags;
> +	/*
> +	 * contexts marked as using protected content are invalidated when the
> +	 * protected content session dies. Submission of invalidated contexts
> +	 * is rejected with -EACCES.
> +	 */
> +#define I915_CONTEXT_INVALIDATED 0x1
>  
>  	/* All resets since boot/module reload, for all contexts */
>  	__u32 reset_count;
> @@ -2959,8 +2985,12 @@ struct drm_i915_gem_create_ext {
>  	 *
>  	 * For I915_GEM_CREATE_EXT_MEMORY_REGIONS usage see
>  	 * struct drm_i915_gem_create_ext_memory_regions.
> +	 *
> +	 * For I915_GEM_CREATE_EXT_PROTECTED_CONTENT usage see
> +	 * struct drm_i915_gem_create_ext_protected_content.
>  	 */
>  #define I915_GEM_CREATE_EXT_MEMORY_REGIONS 0
> +#define I915_GEM_CREATE_EXT_PROTECTED_CONTENT 1
>  	__u64 extensions;
>  };
>  
> @@ -3018,6 +3048,29 @@ struct drm_i915_gem_create_ext_memory_regions {
>  	__u64 regions;
>  };
>  
> +/**
> + * struct drm_i915_gem_create_ext_protected_content - The
> + * I915_OBJECT_PARAM_PROTECTED_CONTENT extension.
> + *
> + * If this extension is provided, buffer contents are expected to be protected
> + * by PXP encryption and require decryption for scan out and processing. This
> + * is only possible on platforms that have PXP enabled, on all other scenarios
> + * using this extension will cause the ioctl to fail and return -ENODEV. The
> + * flags parameter is reserved for future expansion and must currently be set
> + * to zero.
> + *
> + * The buffer contents are considered invalid after a PXP session teardown.
> + *
> + * The encryption is guaranteed to be processed correctly only if the object
> + * is submitted with a context created using the
> + * I915_CONTEXT_PARAM_PROTECTED_CONTENT flag. This will also enable extra checks
> + * at submission time on the validity of the objects involved.
> + */
> +struct drm_i915_gem_create_ext_protected_content {
> +	struct i915_user_extension base;
> +	__u32 flags;
> +};
> +
>  /* ID of the protected content session managed by i915 when PXP is active */
>  #define I915_PROTECTED_CONTENT_DEFAULT_SESSION 0xf
>  
> -- 
> 2.32.0
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v6 10/15] drm/i915/pxp: interfaces for using protected objects
  2021-07-29 11:10     ` [Intel-gfx] " Rodrigo Vivi
@ 2021-07-29 15:17       ` Daniele Ceraolo Spurio
  -1 siblings, 0 replies; 64+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-07-29 15:17 UTC (permalink / raw)
  To: Rodrigo Vivi, jason.ekstrand, Vetter, Daniel
  Cc: intel-gfx, Chris Wilson, dri-devel, Jason Ekstrand, Bommu Krishnaiah



On 7/29/2021 4:10 AM, Rodrigo Vivi wrote:
> On Wed, Jul 28, 2021 at 07:01:01PM -0700, Daniele Ceraolo Spurio wrote:
>> This api allow user mode to create protected buffers and to mark
>> contexts as making use of such objects. Only when using contexts
>> marked in such a way is the execution guaranteed to work as expected.
>>
>> Contexts can only be marked as using protected content at creation time
>> (i.e. the parameter is immutable) and they must be both bannable and not
>> recoverable.
>>
>> All protected objects and contexts that have backing storage will be
>> considered invalid when the PXP session is destroyed and all new
>> submissions using them will be rejected. All intel contexts within the
>> invalidated gem contexts will be marked banned. A new flag has been
>> added to the RESET_STATS ioctl to report the context invalidation to
>> userspace.
>>
>> This patch was previously sent as 2 separate patches, which have been
>> squashed following a request to have all the uapi in a single patch.
>> I've retained the s-o-b from both.
>>
>> v5: squash patches, rebase on proto_ctx, update kerneldoc
>>
>> v6: rebase on obj create_ext changes
> The "rebase" word led me to think it was a small change caused
> only by rebasing conflicts, but then I spotted something on
> i915_gem_create.c that I didn't remember seeing before.

Apologies for not being clear.

>
> Since it took me a while to understand what was going on, let me
> try to summarize to see if I got it right and to check
> with others (Jason in special)
> if we are aligned with the recent directions:
>
> With the removal of the vanilla_object from the create_ext,
> the addition of the flags was needed.

yes.

>
> Then, instead of adding a new user_flags it adds the I915_BO_PROTECTED
> to the existent flags (what is cleaner) but then it does
>
> /* Add any flag set by create_ext options */
> flags |= ext_flags;
>
> on the new user_create_ext.
>
> What shouldn't be a problem because the ext_flags is really only
> the I915_BO_PROTECTED set by our new extension and immutable.
>
> But I'm just trying to see if we are not opening any holes to accept
> some undesired flags.
>
> Apparently not.

ext_flags are not set directly by the user, but by the create_ext 
extension functions, based on the extensions the user has provided. This 
should allow the kernel to perform any required checks in the extension 
functions before setting the flag (like it happens in this case for the 
PXP option).

>
> Am I getting things right? Anything else we should check in here?

yup, got it right.

Daniele

>
> Thanks,
> Rodrigo.
>
>> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
>> Signed-off-by: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
>> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
>> Cc: Chris Wilson <chris@chris-wilson.co.uk>
>> Cc: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
>> Cc: Jason Ekstrand <jason@jlekstrand.net>
>> Cc: Daniel Vetter <daniel.vetter@intel.com>
>> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> #v5
>> ---
>>   drivers/gpu/drm/i915/gem/i915_gem_context.c   | 68 ++++++++++++--
>>   drivers/gpu/drm/i915/gem/i915_gem_context.h   | 18 ++++
>>   .../gpu/drm/i915/gem/i915_gem_context_types.h |  2 +
>>   drivers/gpu/drm/i915/gem/i915_gem_create.c    | 75 ++++++++++++----
>>   .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 40 ++++++++-
>>   drivers/gpu/drm/i915/gem/i915_gem_object.c    |  6 ++
>>   drivers/gpu/drm/i915/gem/i915_gem_object.h    | 12 +++
>>   .../gpu/drm/i915/gem/i915_gem_object_types.h  |  9 ++
>>   drivers/gpu/drm/i915/pxp/intel_pxp.c          | 89 +++++++++++++++++++
>>   drivers/gpu/drm/i915/pxp/intel_pxp.h          | 15 ++++
>>   drivers/gpu/drm/i915/pxp/intel_pxp_session.c  |  3 +
>>   drivers/gpu/drm/i915/pxp/intel_pxp_types.h    |  5 ++
>>   include/uapi/drm/i915_drm.h                   | 55 +++++++++++-
>>   13 files changed, 371 insertions(+), 26 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c
>> index cff72679ad7c..0cd3e2d06188 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
>> @@ -77,6 +77,8 @@
>>   #include "gt/intel_gpu_commands.h"
>>   #include "gt/intel_ring.h"
>>   
>> +#include "pxp/intel_pxp.h"
>> +
>>   #include "i915_gem_context.h"
>>   #include "i915_trace.h"
>>   #include "i915_user_extensions.h"
>> @@ -241,6 +243,25 @@ static int proto_context_set_persistence(struct drm_i915_private *i915,
>>   	return 0;
>>   }
>>   
>> +static int proto_context_set_protected(struct drm_i915_private *i915,
>> +				       struct i915_gem_proto_context *pc,
>> +				       bool protected)
>> +{
>> +	int ret = 0;
>> +
>> +	if (!intel_pxp_is_enabled(&i915->gt.pxp))
>> +		ret = -ENODEV;
>> +	else if (!protected)
>> +		pc->user_flags &= ~BIT(UCONTEXT_PROTECTED);
>> +	else if ((pc->user_flags & BIT(UCONTEXT_RECOVERABLE)) ||
>> +		 !(pc->user_flags & BIT(UCONTEXT_BANNABLE)))
>> +		ret = -EPERM;
>> +	else
>> +		pc->user_flags |= BIT(UCONTEXT_PROTECTED);
>> +
>> +	return ret;
>> +}
>> +
>>   static struct i915_gem_proto_context *
>>   proto_context_create(struct drm_i915_private *i915, unsigned int flags)
>>   {
>> @@ -686,6 +707,8 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
>>   			ret = -EPERM;
>>   		else if (args->value)
>>   			pc->user_flags |= BIT(UCONTEXT_BANNABLE);
>> +		else if (pc->user_flags & BIT(UCONTEXT_PROTECTED))
>> +			ret = -EPERM;
>>   		else
>>   			pc->user_flags &= ~BIT(UCONTEXT_BANNABLE);
>>   		break;
>> @@ -693,10 +716,12 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
>>   	case I915_CONTEXT_PARAM_RECOVERABLE:
>>   		if (args->size)
>>   			ret = -EINVAL;
>> -		else if (args->value)
>> -			pc->user_flags |= BIT(UCONTEXT_RECOVERABLE);
>> -		else
>> +		else if (!args->value)
>>   			pc->user_flags &= ~BIT(UCONTEXT_RECOVERABLE);
>> +		else if (pc->user_flags & BIT(UCONTEXT_PROTECTED))
>> +			ret = -EPERM;
>> +		else
>> +			pc->user_flags |= BIT(UCONTEXT_RECOVERABLE);
>>   		break;
>>   
>>   	case I915_CONTEXT_PARAM_PRIORITY:
>> @@ -724,6 +749,11 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
>>   						    args->value);
>>   		break;
>>   
>> +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
>> +		ret = proto_context_set_protected(fpriv->dev_priv, pc,
>> +						  args->value);
>> +		break;
>> +
>>   	case I915_CONTEXT_PARAM_NO_ZEROMAP:
>>   	case I915_CONTEXT_PARAM_BAN_PERIOD:
>>   	case I915_CONTEXT_PARAM_RINGSIZE:
>> @@ -1798,6 +1828,18 @@ static int set_priority(struct i915_gem_context *ctx,
>>   	return 0;
>>   }
>>   
>> +static int get_protected(struct i915_gem_context *ctx,
>> +			 struct drm_i915_gem_context_param *args)
>> +{
>> +	if (!intel_pxp_is_enabled(&ctx->i915->gt.pxp))
>> +		return -ENODEV;
>> +
>> +	args->size = 0;
>> +	args->value = i915_gem_context_uses_protected_content(ctx);
>> +
>> +	return 0;
>> +}
>> +
>>   static int ctx_setparam(struct drm_i915_file_private *fpriv,
>>   			struct i915_gem_context *ctx,
>>   			struct drm_i915_gem_context_param *args)
>> @@ -1821,6 +1863,8 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
>>   			ret = -EPERM;
>>   		else if (args->value)
>>   			i915_gem_context_set_bannable(ctx);
>> +		else if (i915_gem_context_uses_protected_content(ctx))
>> +			ret = -EPERM; /* can't clear this for protected contexts */
>>   		else
>>   			i915_gem_context_clear_bannable(ctx);
>>   		break;
>> @@ -1828,10 +1872,12 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
>>   	case I915_CONTEXT_PARAM_RECOVERABLE:
>>   		if (args->size)
>>   			ret = -EINVAL;
>> -		else if (args->value)
>> -			i915_gem_context_set_recoverable(ctx);
>> -		else
>> +		else if (!args->value)
>>   			i915_gem_context_clear_recoverable(ctx);
>> +		else if (i915_gem_context_uses_protected_content(ctx))
>> +			ret = -EPERM; /* can't set this for protected contexts */
>> +		else
>> +			i915_gem_context_set_recoverable(ctx);
>>   		break;
>>   
>>   	case I915_CONTEXT_PARAM_PRIORITY:
>> @@ -1846,6 +1892,7 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
>>   		ret = set_persistence(ctx, args);
>>   		break;
>>   
>> +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
>>   	case I915_CONTEXT_PARAM_NO_ZEROMAP:
>>   	case I915_CONTEXT_PARAM_BAN_PERIOD:
>>   	case I915_CONTEXT_PARAM_RINGSIZE:
>> @@ -2174,6 +2221,10 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
>>   		args->value = i915_gem_context_is_persistent(ctx);
>>   		break;
>>   
>> +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
>> +		ret = get_protected(ctx, args);
>> +		break;
>> +
>>   	case I915_CONTEXT_PARAM_NO_ZEROMAP:
>>   	case I915_CONTEXT_PARAM_BAN_PERIOD:
>>   	case I915_CONTEXT_PARAM_ENGINES:
>> @@ -2250,6 +2301,11 @@ int i915_gem_context_reset_stats_ioctl(struct drm_device *dev,
>>   	args->batch_active = atomic_read(&ctx->guilty_count);
>>   	args->batch_pending = atomic_read(&ctx->active_count);
>>   
>> +	/* re-use args->flags for output flags */
>> +	args->flags = 0;
>> +	if (i915_gem_context_invalidated(ctx))
>> +		args->flags |= I915_CONTEXT_INVALIDATED;
>> +
>>   	i915_gem_context_put(ctx);
>>   	return 0;
>>   }
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.h b/drivers/gpu/drm/i915/gem/i915_gem_context.h
>> index 18060536b0c2..d932a70122fa 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_context.h
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.h
>> @@ -108,6 +108,24 @@ i915_gem_context_clear_user_engines(struct i915_gem_context *ctx)
>>   	clear_bit(CONTEXT_USER_ENGINES, &ctx->flags);
>>   }
>>   
>> +static inline bool
>> +i915_gem_context_invalidated(const struct i915_gem_context *ctx)
>> +{
>> +	return test_bit(CONTEXT_INVALID, &ctx->flags);
>> +}
>> +
>> +static inline void
>> +i915_gem_context_set_invalid(struct i915_gem_context *ctx)
>> +{
>> +	set_bit(CONTEXT_INVALID, &ctx->flags);
>> +}
>> +
>> +static inline bool
>> +i915_gem_context_uses_protected_content(const struct i915_gem_context *ctx)
>> +{
>> +	return test_bit(UCONTEXT_PROTECTED, &ctx->user_flags);
>> +}
>> +
>>   /* i915_gem_context.c */
>>   void i915_gem_init__contexts(struct drm_i915_private *i915);
>>   
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
>> index 94c03a97cb77..1aa2290aa3c7 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
>> @@ -301,6 +301,7 @@ struct i915_gem_context {
>>   #define UCONTEXT_BANNABLE		2
>>   #define UCONTEXT_RECOVERABLE		3
>>   #define UCONTEXT_PERSISTENCE		4
>> +#define UCONTEXT_PROTECTED		5
>>   
>>   	/**
>>   	 * @flags: small set of booleans
>> @@ -308,6 +309,7 @@ struct i915_gem_context {
>>   	unsigned long flags;
>>   #define CONTEXT_CLOSED			0
>>   #define CONTEXT_USER_ENGINES		1
>> +#define CONTEXT_INVALID			2
>>   
>>   	/** @mutex: guards everything that isn't engines or handles_vma */
>>   	struct mutex mutex;
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c b/drivers/gpu/drm/i915/gem/i915_gem_create.c
>> index 23fee13a3384..0e48629316bb 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
>> @@ -6,6 +6,7 @@
>>   #include "gem/i915_gem_ioctls.h"
>>   #include "gem/i915_gem_lmem.h"
>>   #include "gem/i915_gem_region.h"
>> +#include "pxp/intel_pxp.h"
>>   
>>   #include "i915_drv.h"
>>   #include "i915_trace.h"
>> @@ -82,21 +83,11 @@ static int i915_gem_publish(struct drm_i915_gem_object *obj,
>>   	return 0;
>>   }
>>   
>> -/**
>> - * Creates a new object using the same path as DRM_I915_GEM_CREATE_EXT
>> - * @i915: i915 private
>> - * @size: size of the buffer, in bytes
>> - * @placements: possible placement regions, in priority order
>> - * @n_placements: number of possible placement regions
>> - *
>> - * This function is exposed primarily for selftests and does very little
>> - * error checking.  It is assumed that the set of placement regions has
>> - * already been verified to be valid.
>> - */
>> -struct drm_i915_gem_object *
>> -__i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
>> -			      struct intel_memory_region **placements,
>> -			      unsigned int n_placements)
>> +static struct drm_i915_gem_object *
>> +__i915_gem_object_create_user_ext(struct drm_i915_private *i915, u64 size,
>> +				  struct intel_memory_region **placements,
>> +				  unsigned int n_placements,
>> +				  unsigned int ext_flags)
>>   {
>>   	struct intel_memory_region *mr = placements[0];
>>   	struct drm_i915_gem_object *obj;
>> @@ -135,6 +126,12 @@ __i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
>>   
>>   	GEM_BUG_ON(size != obj->base.size);
>>   
>> +	/* Add any flag set by create_ext options */
>> +	flags |= ext_flags;
>> +
>> +	if (i915_gem_object_is_protected(obj))
>> +		intel_pxp_object_add(obj);
>> +
>>   	trace_i915_gem_object_create(obj);
>>   	return obj;
>>   
>> @@ -145,6 +142,26 @@ __i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
>>   	return ERR_PTR(ret);
>>   }
>>   
>> +/**
>> + * Creates a new object using the same path as DRM_I915_GEM_CREATE_EXT
>> + * @i915: i915 private
>> + * @size: size of the buffer, in bytes
>> + * @placements: possible placement regions, in priority order
>> + * @n_placements: number of possible placement regions
>> + *
>> + * This function is exposed primarily for selftests and does very little
>> + * error checking.  It is assumed that the set of placement regions has
>> + * already been verified to be valid.
>> + */
>> +struct drm_i915_gem_object *
>> +__i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
>> +			      struct intel_memory_region **placements,
>> +			      unsigned int n_placements)
>> +{
>> +	return __i915_gem_object_create_user_ext(i915, size, placements,
>> +						 n_placements, 0);
>> +}
>> +
>>   int
>>   i915_gem_dumb_create(struct drm_file *file,
>>   		     struct drm_device *dev,
>> @@ -224,6 +241,7 @@ struct create_ext {
>>   	struct drm_i915_private *i915;
>>   	struct intel_memory_region *placements[INTEL_REGION_UNKNOWN];
>>   	unsigned int n_placements;
>> +	unsigned long flags;
>>   };
>>   
>>   static void repr_placements(char *buf, size_t size,
>> @@ -356,8 +374,28 @@ static int ext_set_placements(struct i915_user_extension __user *base,
>>   	return set_placements(&ext, data);
>>   }
>>   
>> +static int ext_set_protected(struct i915_user_extension __user *base, void *data)
>> +{
>> +	struct drm_i915_gem_create_ext_protected_content ext;
>> +	struct create_ext *ext_data = data;
>> +
>> +	if (copy_from_user(&ext, base, sizeof(ext)))
>> +		return -EFAULT;
>> +
>> +	if (ext.flags)
>> +		return -EINVAL;
>> +
>> +	if (!intel_pxp_is_enabled(&ext_data->i915->gt.pxp))
>> +		return -ENODEV;
>> +
>> +	ext_data->flags |= I915_BO_PROTECTED;
>> +
>> +	return 0;
>> +}
>> +
>>   static const i915_user_extension_fn create_extensions[] = {
>>   	[I915_GEM_CREATE_EXT_MEMORY_REGIONS] = ext_set_placements,
>> +	[I915_GEM_CREATE_EXT_PROTECTED_CONTENT] = ext_set_protected,
>>   };
>>   
>>   /**
>> @@ -392,9 +430,10 @@ i915_gem_create_ext_ioctl(struct drm_device *dev, void *data,
>>   		ext_data.n_placements = 1;
>>   	}
>>   
>> -	obj = __i915_gem_object_create_user(i915, args->size,
>> -					    ext_data.placements,
>> -					    ext_data.n_placements);
>> +	obj = __i915_gem_object_create_user_ext(i915, args->size,
>> +						ext_data.placements,
>> +						ext_data.n_placements,
>> +						ext_data.flags);
>>   	if (IS_ERR(obj))
>>   		return PTR_ERR(obj);
>>   
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>> index 1ed7475de454..04f33d163340 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>> @@ -21,6 +21,8 @@
>>   #include "gt/intel_gt_pm.h"
>>   #include "gt/intel_ring.h"
>>   
>> +#include "pxp/intel_pxp.h"
>> +
>>   #include "i915_drv.h"
>>   #include "i915_gem_clflush.h"
>>   #include "i915_gem_context.h"
>> @@ -751,6 +753,11 @@ static int eb_select_context(struct i915_execbuffer *eb)
>>   	if (unlikely(IS_ERR(ctx)))
>>   		return PTR_ERR(ctx);
>>   
>> +	if (i915_gem_context_invalidated(ctx)) {
>> +		i915_gem_context_put(ctx);
>> +		return -EACCES;
>> +	}
>> +
>>   	eb->gem_context = ctx;
>>   	if (rcu_access_pointer(ctx->vm))
>>   		eb->invalid_flags |= EXEC_OBJECT_NEEDS_GTT;
>> @@ -819,7 +826,7 @@ static struct i915_vma *eb_lookup_vma(struct i915_execbuffer *eb, u32 handle)
>>   	do {
>>   		struct drm_i915_gem_object *obj;
>>   		struct i915_vma *vma;
>> -		int err;
>> +		int err = 0;
>>   
>>   		rcu_read_lock();
>>   		vma = radix_tree_lookup(&eb->gem_context->handles_vma, handle);
>> @@ -833,6 +840,26 @@ static struct i915_vma *eb_lookup_vma(struct i915_execbuffer *eb, u32 handle)
>>   		if (unlikely(!obj))
>>   			return ERR_PTR(-ENOENT);
>>   
>> +		/*
>> +		 * If the user has opted-in for protected-object tracking, make
>> +		 * sure the object encryption can be used.
>> +		 * We only need to do this when the object is first used with
>> +		 * this context, because the context itself will be banned when
>> +		 * the protected objects become invalid.
>> +		 */
>> +		if (i915_gem_context_uses_protected_content(eb->gem_context) &&
>> +		    i915_gem_object_is_protected(obj)) {
>> +			if (!intel_pxp_is_active(&vm->gt->pxp))
>> +				err = -ENODEV;
>> +			else if (!i915_gem_object_has_valid_protection(obj))
>> +				err = -ENOEXEC;
>> +
>> +			if (err) {
>> +				i915_gem_object_put(obj);
>> +				return ERR_PTR(err);
>> +			}
>> +		}
>> +
>>   		vma = i915_vma_instance(obj, vm, NULL);
>>   		if (IS_ERR(vma)) {
>>   			i915_gem_object_put(obj);
>> @@ -2752,6 +2779,17 @@ eb_select_engine(struct i915_execbuffer *eb)
>>   
>>   	intel_gt_pm_get(ce->engine->gt);
>>   
>> +	if (i915_gem_context_uses_protected_content(eb->gem_context)) {
>> +		err = intel_pxp_wait_for_arb_start(&ce->engine->gt->pxp);
>> +		if (err)
>> +			goto err;
>> +
>> +		if (i915_gem_context_invalidated(eb->gem_context)) {
>> +			err = -EACCES;
>> +			goto err;
>> +		}
>> +	}
>> +
>>   	if (!test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
>>   		err = intel_context_alloc_state(ce);
>>   		if (err)
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c
>> index 6fb9afb65034..658a42a7fa07 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
>> @@ -25,6 +25,7 @@
>>   #include <linux/sched/mm.h>
>>   
>>   #include "display/intel_frontbuffer.h"
>> +#include "pxp/intel_pxp.h"
>>   #include "i915_drv.h"
>>   #include "i915_gem_clflush.h"
>>   #include "i915_gem_context.h"
>> @@ -73,6 +74,8 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj,
>>   	INIT_LIST_HEAD(&obj->lut_list);
>>   	spin_lock_init(&obj->lut_lock);
>>   
>> +	INIT_LIST_HEAD(&obj->pxp_link);
>> +
>>   	spin_lock_init(&obj->mmo.lock);
>>   	obj->mmo.offsets = RB_ROOT;
>>   
>> @@ -231,6 +234,9 @@ void __i915_gem_free_object(struct drm_i915_gem_object *obj)
>>   		spin_unlock(&obj->vma.lock);
>>   	}
>>   
>> +	if (i915_gem_object_has_valid_protection(obj))
>> +		intel_pxp_object_remove(obj);
>> +
>>   	__i915_gem_object_free_mmaps(obj);
>>   
>>   	GEM_BUG_ON(!list_empty(&obj->lut_list));
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h
>> index 48112b9d76df..137ae2723514 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
>> @@ -269,6 +269,18 @@ i915_gem_object_clear_tiling_quirk(struct drm_i915_gem_object *obj)
>>   	clear_bit(I915_TILING_QUIRK_BIT, &obj->flags);
>>   }
>>   
>> +static inline bool
>> +i915_gem_object_is_protected(const struct drm_i915_gem_object *obj)
>> +{
>> +	return obj->flags & I915_BO_PROTECTED;
>> +}
>> +
>> +static inline bool
>> +i915_gem_object_has_valid_protection(const struct drm_i915_gem_object *obj)
>> +{
>> +	return i915_gem_object_is_protected(obj) && !list_empty(&obj->pxp_link);
>> +}
>> +
>>   static inline bool
>>   i915_gem_object_type_has(const struct drm_i915_gem_object *obj,
>>   			 unsigned long flags)
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
>> index 2471f36aaff3..38e4a190607a 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
>> @@ -298,6 +298,7 @@ struct drm_i915_gem_object {
>>   			     I915_BO_ALLOC_USER)
>>   #define I915_BO_READONLY         BIT(4)
>>   #define I915_TILING_QUIRK_BIT    5 /* unknown swizzling; do not release! */
>> +#define I915_BO_PROTECTED        BIT(6)
>>   
>>   	/**
>>   	 * @mem_flags - Mutable placement-related flags
>> @@ -537,6 +538,14 @@ struct drm_i915_gem_object {
>>   		bool created:1;
>>   	} ttm;
>>   
>> +	/*
>> +	 * When the PXP session is invalidated, we need to mark all protected
>> +	 * objects as invalid. To easily do so we add them all to a list. The
>> +	 * presence on the list is used to check if the encryption is valid or
>> +	 * not.
>> +	 */
>> +	struct list_head pxp_link;
>> +
>>   	/** Record of address bit 17 of each page at last unbind. */
>>   	unsigned long *bit_17;
>>   
>> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
>> index b0c7edc10cc3..f418281e8c10 100644
>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
>> @@ -7,6 +7,7 @@
>>   #include "intel_pxp_irq.h"
>>   #include "intel_pxp_session.h"
>>   #include "intel_pxp_tee.h"
>> +#include "gem/i915_gem_context.h"
>>   #include "gt/intel_context.h"
>>   #include "i915_drv.h"
>>   
>> @@ -70,6 +71,9 @@ void intel_pxp_init(struct intel_pxp *pxp)
>>   
>>   	mutex_init(&pxp->tee_mutex);
>>   
>> +	spin_lock_init(&pxp->lock);
>> +	INIT_LIST_HEAD(&pxp->protected_objects);
>> +
>>   	/*
>>   	 * we'll use the completion to check if there is a termination pending,
>>   	 * so we start it as completed and we reinit it when a termination
>> @@ -166,3 +170,88 @@ void intel_pxp_fini_hw(struct intel_pxp *pxp)
>>   
>>   	intel_pxp_irq_disable(pxp);
>>   }
>> +
>> +int intel_pxp_object_add(struct drm_i915_gem_object *obj)
>> +{
>> +	struct intel_pxp *pxp = &to_i915(obj->base.dev)->gt.pxp;
>> +
>> +	if (!intel_pxp_is_enabled(pxp))
>> +		return -ENODEV;
>> +
>> +	if (!list_empty(&obj->pxp_link))
>> +		return -EEXIST;
>> +
>> +	spin_lock_irq(&pxp->lock);
>> +	list_add(&obj->pxp_link, &pxp->protected_objects);
>> +	spin_unlock_irq(&pxp->lock);
>> +
>> +	return 0;
>> +}
>> +
>> +void intel_pxp_object_remove(struct drm_i915_gem_object *obj)
>> +{
>> +	struct intel_pxp *pxp = &to_i915(obj->base.dev)->gt.pxp;
>> +
>> +	if (!intel_pxp_is_enabled(pxp))
>> +		return;
>> +
>> +	spin_lock_irq(&pxp->lock);
>> +	list_del_init(&obj->pxp_link);
>> +	spin_unlock_irq(&pxp->lock);
>> +}
>> +
>> +void intel_pxp_invalidate(struct intel_pxp *pxp)
>> +{
>> +	struct drm_i915_private *i915 = pxp_to_gt(pxp)->i915;
>> +	struct drm_i915_gem_object *obj, *tmp;
>> +	struct i915_gem_context *ctx, *cn;
>> +
>> +	/* delete objects that have been used with the invalidated session */
>> +	spin_lock_irq(&pxp->lock);
>> +	list_for_each_entry_safe(obj, tmp, &pxp->protected_objects, pxp_link) {
>> +		if (i915_gem_object_has_pages(obj))
>> +			list_del_init(&obj->pxp_link);
>> +	}
>> +	spin_unlock_irq(&pxp->lock);
>> +
>> +	/* 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) {
>> +		struct i915_gem_engines_iter it;
>> +		struct intel_context *ce;
>> +
>> +		if (!kref_get_unless_zero(&ctx->ref))
>> +			continue;
>> +
>> +		if (likely(!i915_gem_context_uses_protected_content(ctx)) ||
>> +		    i915_gem_context_invalidated(ctx)) {
>> +			i915_gem_context_put(ctx);
>> +			continue;
>> +		}
>> +
>> +		spin_unlock_irq(&i915->gem.contexts.lock);
>> +
>> +		/*
>> +		 * Note that by the time we get here the HW keys are already
>> +		 * long gone, so any batch using them that's already on the
>> +		 * engines is very likely a lost cause (and it has probably
>> +		 * already hung the engine). Therefore, we skip attempting to
>> +		 * pull the running context out of the HW and we prioritize
>> +		 * bringing the session back as soon as possible.
>> +		 */
>> +		for_each_gem_engine(ce, i915_gem_context_lock_engines(ctx), it) {
>> +			/* only invalidate if at least one ce was allocated */
>> +			if (test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
>> +				intel_context_set_banned(ce);
>> +				i915_gem_context_set_invalid(ctx);
>> +			}
>> +		}
>> +		i915_gem_context_unlock_engines(ctx);
>> +
>> +		spin_lock_irq(&i915->gem.contexts.lock);
>> +		list_safe_reset_next(ctx, cn, link);
>> +		i915_gem_context_put(ctx);
>> +	}
>> +	spin_unlock_irq(&i915->gem.contexts.lock);
>> +}
>> +
>> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
>> index 074b3b980957..4f7647f34153 100644
>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
>> @@ -9,6 +9,8 @@
>>   #include "gt/intel_gt_types.h"
>>   #include "intel_pxp_types.h"
>>   
>> +struct drm_i915_gem_object;
>> +
>>   static inline struct intel_gt *pxp_to_gt(const struct intel_pxp *pxp)
>>   {
>>   	return container_of(pxp, struct intel_gt, pxp);
>> @@ -33,6 +35,11 @@ void intel_pxp_fini_hw(struct intel_pxp *pxp);
>>   
>>   void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp);
>>   int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp);
>> +
>> +int intel_pxp_object_add(struct drm_i915_gem_object *obj);
>> +void intel_pxp_object_remove(struct drm_i915_gem_object *obj);
>> +
>> +void intel_pxp_invalidate(struct intel_pxp *pxp);
>>   #else
>>   static inline void intel_pxp_init(struct intel_pxp *pxp)
>>   {
>> @@ -46,6 +53,14 @@ static inline int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp)
>>   {
>>   	return 0;
>>   }
>> +
>> +static inline int intel_pxp_object_add(struct drm_i915_gem_object *obj)
>> +{
>> +	return 0;
>> +}
>> +static inline void intel_pxp_object_remove(struct drm_i915_gem_object *obj)
>> +{
>> +}
>>   #endif
>>   
>>   #endif /* __INTEL_PXP_H__ */
>> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
>> index 67c30e534d50..0edd563a653d 100644
>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
>> @@ -85,6 +85,9 @@ static int pxp_terminate_arb_session_and_global(struct intel_pxp *pxp)
>>   	/* must mark termination in progress calling this function */
>>   	GEM_WARN_ON(pxp->arb_is_valid);
>>   
>> +	/* invalidate protected objects */
>> +	intel_pxp_invalidate(pxp);
>> +
>>   	/* terminate the hw sessions */
>>   	ret = intel_pxp_terminate_session(pxp, ARB_SESSION);
>>   	if (ret) {
>> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
>> index 475e3312c287..be2bed3a2e4e 100644
>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
>> @@ -7,7 +7,9 @@
>>   #define __INTEL_PXP_TYPES_H__
>>   
>>   #include <linux/completion.h>
>> +#include <linux/list.h>
>>   #include <linux/mutex.h>
>> +#include <linux/spinlock.h>
>>   #include <linux/types.h>
>>   #include <linux/workqueue.h>
>>   
>> @@ -43,6 +45,9 @@ struct intel_pxp {
>>   	u32 session_events; /* protected with gt->irq_lock */
>>   #define PXP_TERMINATION_REQUEST  BIT(0)
>>   #define PXP_TERMINATION_COMPLETE BIT(1)
>> +
>> +	spinlock_t lock; /* protects the objects list */
>> +	struct list_head protected_objects;
>>   };
>>   
>>   #endif /* __INTEL_PXP_TYPES_H__ */
>> diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
>> index 4393eef59d9b..2c9febdae6a5 100644
>> --- a/include/uapi/drm/i915_drm.h
>> +++ b/include/uapi/drm/i915_drm.h
>> @@ -1843,12 +1843,32 @@ struct drm_i915_gem_context_param {
>>    * attempted to use it, never re-use this context param number.
>>    */
>>   #define I915_CONTEXT_PARAM_RINGSIZE	0xc
>> +
>> +/*
>> + * I915_CONTEXT_PARAM_PROTECTED_CONTENT:
>> + *
>> + * Mark that the context makes use of protected content, which will result
>> + * in the context being invalidated when the protected content session is. The
>> + * invalidation is reported back to userspace via the RESET_STATS ioctl (see
>> + * relevant doc for details).
>> + * This flag can only be set at context creation time and, when set to true,
>> + * must be preceded by an explicit setting of I915_CONTEXT_PARAM_RECOVERABLE
>> + * to false. This flag can't be set to true in conjunction with setting the
>> + * I915_CONTEXT_PARAM_BANNABLE flag to false.
>> + *
>> + * In addition to the normal failure cases, setting this flag during context
>> + * creation can result in the following errors:
>> + *
>> + * -ENODEV: feature not available
>> + * -EPERM: trying to mark a recoverable or not bannable context as protected
>> + */
>> +#define I915_CONTEXT_PARAM_PROTECTED_CONTENT    0xd
>>   /* Must be kept compact -- no holes and well documented */
>>   
>>   	__u64 value;
>>   };
>>   
>> -/*
>> +/**
>>    * Context SSEU programming
>>    *
>>    * It may be necessary for either functional or performance reason to configure
>> @@ -2181,6 +2201,12 @@ struct drm_i915_reg_read {
>>   struct drm_i915_reset_stats {
>>   	__u32 ctx_id;
>>   	__u32 flags;
>> +	/*
>> +	 * contexts marked as using protected content are invalidated when the
>> +	 * protected content session dies. Submission of invalidated contexts
>> +	 * is rejected with -EACCES.
>> +	 */
>> +#define I915_CONTEXT_INVALIDATED 0x1
>>   
>>   	/* All resets since boot/module reload, for all contexts */
>>   	__u32 reset_count;
>> @@ -2959,8 +2985,12 @@ struct drm_i915_gem_create_ext {
>>   	 *
>>   	 * For I915_GEM_CREATE_EXT_MEMORY_REGIONS usage see
>>   	 * struct drm_i915_gem_create_ext_memory_regions.
>> +	 *
>> +	 * For I915_GEM_CREATE_EXT_PROTECTED_CONTENT usage see
>> +	 * struct drm_i915_gem_create_ext_protected_content.
>>   	 */
>>   #define I915_GEM_CREATE_EXT_MEMORY_REGIONS 0
>> +#define I915_GEM_CREATE_EXT_PROTECTED_CONTENT 1
>>   	__u64 extensions;
>>   };
>>   
>> @@ -3018,6 +3048,29 @@ struct drm_i915_gem_create_ext_memory_regions {
>>   	__u64 regions;
>>   };
>>   
>> +/**
>> + * struct drm_i915_gem_create_ext_protected_content - The
>> + * I915_OBJECT_PARAM_PROTECTED_CONTENT extension.
>> + *
>> + * If this extension is provided, buffer contents are expected to be protected
>> + * by PXP encryption and require decryption for scan out and processing. This
>> + * is only possible on platforms that have PXP enabled, on all other scenarios
>> + * using this extension will cause the ioctl to fail and return -ENODEV. The
>> + * flags parameter is reserved for future expansion and must currently be set
>> + * to zero.
>> + *
>> + * The buffer contents are considered invalid after a PXP session teardown.
>> + *
>> + * The encryption is guaranteed to be processed correctly only if the object
>> + * is submitted with a context created using the
>> + * I915_CONTEXT_PARAM_PROTECTED_CONTENT flag. This will also enable extra checks
>> + * at submission time on the validity of the objects involved.
>> + */
>> +struct drm_i915_gem_create_ext_protected_content {
>> +	struct i915_user_extension base;
>> +	__u32 flags;
>> +};
>> +
>>   /* ID of the protected content session managed by i915 when PXP is active */
>>   #define I915_PROTECTED_CONTENT_DEFAULT_SESSION 0xf
>>   
>> -- 
>> 2.32.0
>>


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Intel-gfx] [PATCH v6 10/15] drm/i915/pxp: interfaces for using protected objects
@ 2021-07-29 15:17       ` Daniele Ceraolo Spurio
  0 siblings, 0 replies; 64+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-07-29 15:17 UTC (permalink / raw)
  To: Rodrigo Vivi, jason.ekstrand, Vetter, Daniel
  Cc: intel-gfx, Chris Wilson, dri-devel, Bommu Krishnaiah



On 7/29/2021 4:10 AM, Rodrigo Vivi wrote:
> On Wed, Jul 28, 2021 at 07:01:01PM -0700, Daniele Ceraolo Spurio wrote:
>> This api allow user mode to create protected buffers and to mark
>> contexts as making use of such objects. Only when using contexts
>> marked in such a way is the execution guaranteed to work as expected.
>>
>> Contexts can only be marked as using protected content at creation time
>> (i.e. the parameter is immutable) and they must be both bannable and not
>> recoverable.
>>
>> All protected objects and contexts that have backing storage will be
>> considered invalid when the PXP session is destroyed and all new
>> submissions using them will be rejected. All intel contexts within the
>> invalidated gem contexts will be marked banned. A new flag has been
>> added to the RESET_STATS ioctl to report the context invalidation to
>> userspace.
>>
>> This patch was previously sent as 2 separate patches, which have been
>> squashed following a request to have all the uapi in a single patch.
>> I've retained the s-o-b from both.
>>
>> v5: squash patches, rebase on proto_ctx, update kerneldoc
>>
>> v6: rebase on obj create_ext changes
> The "rebase" word led me to think it was a small change caused
> only by rebasing conflicts, but then I spotted something on
> i915_gem_create.c that I didn't remember seeing before.

Apologies for not being clear.

>
> Since it took me a while to understand what was going on, let me
> try to summarize to see if I got it right and to check
> with others (Jason in special)
> if we are aligned with the recent directions:
>
> With the removal of the vanilla_object from the create_ext,
> the addition of the flags was needed.

yes.

>
> Then, instead of adding a new user_flags it adds the I915_BO_PROTECTED
> to the existent flags (what is cleaner) but then it does
>
> /* Add any flag set by create_ext options */
> flags |= ext_flags;
>
> on the new user_create_ext.
>
> What shouldn't be a problem because the ext_flags is really only
> the I915_BO_PROTECTED set by our new extension and immutable.
>
> But I'm just trying to see if we are not opening any holes to accept
> some undesired flags.
>
> Apparently not.

ext_flags are not set directly by the user, but by the create_ext 
extension functions, based on the extensions the user has provided. This 
should allow the kernel to perform any required checks in the extension 
functions before setting the flag (like it happens in this case for the 
PXP option).

>
> Am I getting things right? Anything else we should check in here?

yup, got it right.

Daniele

>
> Thanks,
> Rodrigo.
>
>> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
>> Signed-off-by: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
>> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
>> Cc: Chris Wilson <chris@chris-wilson.co.uk>
>> Cc: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
>> Cc: Jason Ekstrand <jason@jlekstrand.net>
>> Cc: Daniel Vetter <daniel.vetter@intel.com>
>> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> #v5
>> ---
>>   drivers/gpu/drm/i915/gem/i915_gem_context.c   | 68 ++++++++++++--
>>   drivers/gpu/drm/i915/gem/i915_gem_context.h   | 18 ++++
>>   .../gpu/drm/i915/gem/i915_gem_context_types.h |  2 +
>>   drivers/gpu/drm/i915/gem/i915_gem_create.c    | 75 ++++++++++++----
>>   .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 40 ++++++++-
>>   drivers/gpu/drm/i915/gem/i915_gem_object.c    |  6 ++
>>   drivers/gpu/drm/i915/gem/i915_gem_object.h    | 12 +++
>>   .../gpu/drm/i915/gem/i915_gem_object_types.h  |  9 ++
>>   drivers/gpu/drm/i915/pxp/intel_pxp.c          | 89 +++++++++++++++++++
>>   drivers/gpu/drm/i915/pxp/intel_pxp.h          | 15 ++++
>>   drivers/gpu/drm/i915/pxp/intel_pxp_session.c  |  3 +
>>   drivers/gpu/drm/i915/pxp/intel_pxp_types.h    |  5 ++
>>   include/uapi/drm/i915_drm.h                   | 55 +++++++++++-
>>   13 files changed, 371 insertions(+), 26 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c
>> index cff72679ad7c..0cd3e2d06188 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
>> @@ -77,6 +77,8 @@
>>   #include "gt/intel_gpu_commands.h"
>>   #include "gt/intel_ring.h"
>>   
>> +#include "pxp/intel_pxp.h"
>> +
>>   #include "i915_gem_context.h"
>>   #include "i915_trace.h"
>>   #include "i915_user_extensions.h"
>> @@ -241,6 +243,25 @@ static int proto_context_set_persistence(struct drm_i915_private *i915,
>>   	return 0;
>>   }
>>   
>> +static int proto_context_set_protected(struct drm_i915_private *i915,
>> +				       struct i915_gem_proto_context *pc,
>> +				       bool protected)
>> +{
>> +	int ret = 0;
>> +
>> +	if (!intel_pxp_is_enabled(&i915->gt.pxp))
>> +		ret = -ENODEV;
>> +	else if (!protected)
>> +		pc->user_flags &= ~BIT(UCONTEXT_PROTECTED);
>> +	else if ((pc->user_flags & BIT(UCONTEXT_RECOVERABLE)) ||
>> +		 !(pc->user_flags & BIT(UCONTEXT_BANNABLE)))
>> +		ret = -EPERM;
>> +	else
>> +		pc->user_flags |= BIT(UCONTEXT_PROTECTED);
>> +
>> +	return ret;
>> +}
>> +
>>   static struct i915_gem_proto_context *
>>   proto_context_create(struct drm_i915_private *i915, unsigned int flags)
>>   {
>> @@ -686,6 +707,8 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
>>   			ret = -EPERM;
>>   		else if (args->value)
>>   			pc->user_flags |= BIT(UCONTEXT_BANNABLE);
>> +		else if (pc->user_flags & BIT(UCONTEXT_PROTECTED))
>> +			ret = -EPERM;
>>   		else
>>   			pc->user_flags &= ~BIT(UCONTEXT_BANNABLE);
>>   		break;
>> @@ -693,10 +716,12 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
>>   	case I915_CONTEXT_PARAM_RECOVERABLE:
>>   		if (args->size)
>>   			ret = -EINVAL;
>> -		else if (args->value)
>> -			pc->user_flags |= BIT(UCONTEXT_RECOVERABLE);
>> -		else
>> +		else if (!args->value)
>>   			pc->user_flags &= ~BIT(UCONTEXT_RECOVERABLE);
>> +		else if (pc->user_flags & BIT(UCONTEXT_PROTECTED))
>> +			ret = -EPERM;
>> +		else
>> +			pc->user_flags |= BIT(UCONTEXT_RECOVERABLE);
>>   		break;
>>   
>>   	case I915_CONTEXT_PARAM_PRIORITY:
>> @@ -724,6 +749,11 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
>>   						    args->value);
>>   		break;
>>   
>> +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
>> +		ret = proto_context_set_protected(fpriv->dev_priv, pc,
>> +						  args->value);
>> +		break;
>> +
>>   	case I915_CONTEXT_PARAM_NO_ZEROMAP:
>>   	case I915_CONTEXT_PARAM_BAN_PERIOD:
>>   	case I915_CONTEXT_PARAM_RINGSIZE:
>> @@ -1798,6 +1828,18 @@ static int set_priority(struct i915_gem_context *ctx,
>>   	return 0;
>>   }
>>   
>> +static int get_protected(struct i915_gem_context *ctx,
>> +			 struct drm_i915_gem_context_param *args)
>> +{
>> +	if (!intel_pxp_is_enabled(&ctx->i915->gt.pxp))
>> +		return -ENODEV;
>> +
>> +	args->size = 0;
>> +	args->value = i915_gem_context_uses_protected_content(ctx);
>> +
>> +	return 0;
>> +}
>> +
>>   static int ctx_setparam(struct drm_i915_file_private *fpriv,
>>   			struct i915_gem_context *ctx,
>>   			struct drm_i915_gem_context_param *args)
>> @@ -1821,6 +1863,8 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
>>   			ret = -EPERM;
>>   		else if (args->value)
>>   			i915_gem_context_set_bannable(ctx);
>> +		else if (i915_gem_context_uses_protected_content(ctx))
>> +			ret = -EPERM; /* can't clear this for protected contexts */
>>   		else
>>   			i915_gem_context_clear_bannable(ctx);
>>   		break;
>> @@ -1828,10 +1872,12 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
>>   	case I915_CONTEXT_PARAM_RECOVERABLE:
>>   		if (args->size)
>>   			ret = -EINVAL;
>> -		else if (args->value)
>> -			i915_gem_context_set_recoverable(ctx);
>> -		else
>> +		else if (!args->value)
>>   			i915_gem_context_clear_recoverable(ctx);
>> +		else if (i915_gem_context_uses_protected_content(ctx))
>> +			ret = -EPERM; /* can't set this for protected contexts */
>> +		else
>> +			i915_gem_context_set_recoverable(ctx);
>>   		break;
>>   
>>   	case I915_CONTEXT_PARAM_PRIORITY:
>> @@ -1846,6 +1892,7 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
>>   		ret = set_persistence(ctx, args);
>>   		break;
>>   
>> +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
>>   	case I915_CONTEXT_PARAM_NO_ZEROMAP:
>>   	case I915_CONTEXT_PARAM_BAN_PERIOD:
>>   	case I915_CONTEXT_PARAM_RINGSIZE:
>> @@ -2174,6 +2221,10 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
>>   		args->value = i915_gem_context_is_persistent(ctx);
>>   		break;
>>   
>> +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
>> +		ret = get_protected(ctx, args);
>> +		break;
>> +
>>   	case I915_CONTEXT_PARAM_NO_ZEROMAP:
>>   	case I915_CONTEXT_PARAM_BAN_PERIOD:
>>   	case I915_CONTEXT_PARAM_ENGINES:
>> @@ -2250,6 +2301,11 @@ int i915_gem_context_reset_stats_ioctl(struct drm_device *dev,
>>   	args->batch_active = atomic_read(&ctx->guilty_count);
>>   	args->batch_pending = atomic_read(&ctx->active_count);
>>   
>> +	/* re-use args->flags for output flags */
>> +	args->flags = 0;
>> +	if (i915_gem_context_invalidated(ctx))
>> +		args->flags |= I915_CONTEXT_INVALIDATED;
>> +
>>   	i915_gem_context_put(ctx);
>>   	return 0;
>>   }
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.h b/drivers/gpu/drm/i915/gem/i915_gem_context.h
>> index 18060536b0c2..d932a70122fa 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_context.h
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.h
>> @@ -108,6 +108,24 @@ i915_gem_context_clear_user_engines(struct i915_gem_context *ctx)
>>   	clear_bit(CONTEXT_USER_ENGINES, &ctx->flags);
>>   }
>>   
>> +static inline bool
>> +i915_gem_context_invalidated(const struct i915_gem_context *ctx)
>> +{
>> +	return test_bit(CONTEXT_INVALID, &ctx->flags);
>> +}
>> +
>> +static inline void
>> +i915_gem_context_set_invalid(struct i915_gem_context *ctx)
>> +{
>> +	set_bit(CONTEXT_INVALID, &ctx->flags);
>> +}
>> +
>> +static inline bool
>> +i915_gem_context_uses_protected_content(const struct i915_gem_context *ctx)
>> +{
>> +	return test_bit(UCONTEXT_PROTECTED, &ctx->user_flags);
>> +}
>> +
>>   /* i915_gem_context.c */
>>   void i915_gem_init__contexts(struct drm_i915_private *i915);
>>   
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
>> index 94c03a97cb77..1aa2290aa3c7 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
>> @@ -301,6 +301,7 @@ struct i915_gem_context {
>>   #define UCONTEXT_BANNABLE		2
>>   #define UCONTEXT_RECOVERABLE		3
>>   #define UCONTEXT_PERSISTENCE		4
>> +#define UCONTEXT_PROTECTED		5
>>   
>>   	/**
>>   	 * @flags: small set of booleans
>> @@ -308,6 +309,7 @@ struct i915_gem_context {
>>   	unsigned long flags;
>>   #define CONTEXT_CLOSED			0
>>   #define CONTEXT_USER_ENGINES		1
>> +#define CONTEXT_INVALID			2
>>   
>>   	/** @mutex: guards everything that isn't engines or handles_vma */
>>   	struct mutex mutex;
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c b/drivers/gpu/drm/i915/gem/i915_gem_create.c
>> index 23fee13a3384..0e48629316bb 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
>> @@ -6,6 +6,7 @@
>>   #include "gem/i915_gem_ioctls.h"
>>   #include "gem/i915_gem_lmem.h"
>>   #include "gem/i915_gem_region.h"
>> +#include "pxp/intel_pxp.h"
>>   
>>   #include "i915_drv.h"
>>   #include "i915_trace.h"
>> @@ -82,21 +83,11 @@ static int i915_gem_publish(struct drm_i915_gem_object *obj,
>>   	return 0;
>>   }
>>   
>> -/**
>> - * Creates a new object using the same path as DRM_I915_GEM_CREATE_EXT
>> - * @i915: i915 private
>> - * @size: size of the buffer, in bytes
>> - * @placements: possible placement regions, in priority order
>> - * @n_placements: number of possible placement regions
>> - *
>> - * This function is exposed primarily for selftests and does very little
>> - * error checking.  It is assumed that the set of placement regions has
>> - * already been verified to be valid.
>> - */
>> -struct drm_i915_gem_object *
>> -__i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
>> -			      struct intel_memory_region **placements,
>> -			      unsigned int n_placements)
>> +static struct drm_i915_gem_object *
>> +__i915_gem_object_create_user_ext(struct drm_i915_private *i915, u64 size,
>> +				  struct intel_memory_region **placements,
>> +				  unsigned int n_placements,
>> +				  unsigned int ext_flags)
>>   {
>>   	struct intel_memory_region *mr = placements[0];
>>   	struct drm_i915_gem_object *obj;
>> @@ -135,6 +126,12 @@ __i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
>>   
>>   	GEM_BUG_ON(size != obj->base.size);
>>   
>> +	/* Add any flag set by create_ext options */
>> +	flags |= ext_flags;
>> +
>> +	if (i915_gem_object_is_protected(obj))
>> +		intel_pxp_object_add(obj);
>> +
>>   	trace_i915_gem_object_create(obj);
>>   	return obj;
>>   
>> @@ -145,6 +142,26 @@ __i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
>>   	return ERR_PTR(ret);
>>   }
>>   
>> +/**
>> + * Creates a new object using the same path as DRM_I915_GEM_CREATE_EXT
>> + * @i915: i915 private
>> + * @size: size of the buffer, in bytes
>> + * @placements: possible placement regions, in priority order
>> + * @n_placements: number of possible placement regions
>> + *
>> + * This function is exposed primarily for selftests and does very little
>> + * error checking.  It is assumed that the set of placement regions has
>> + * already been verified to be valid.
>> + */
>> +struct drm_i915_gem_object *
>> +__i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
>> +			      struct intel_memory_region **placements,
>> +			      unsigned int n_placements)
>> +{
>> +	return __i915_gem_object_create_user_ext(i915, size, placements,
>> +						 n_placements, 0);
>> +}
>> +
>>   int
>>   i915_gem_dumb_create(struct drm_file *file,
>>   		     struct drm_device *dev,
>> @@ -224,6 +241,7 @@ struct create_ext {
>>   	struct drm_i915_private *i915;
>>   	struct intel_memory_region *placements[INTEL_REGION_UNKNOWN];
>>   	unsigned int n_placements;
>> +	unsigned long flags;
>>   };
>>   
>>   static void repr_placements(char *buf, size_t size,
>> @@ -356,8 +374,28 @@ static int ext_set_placements(struct i915_user_extension __user *base,
>>   	return set_placements(&ext, data);
>>   }
>>   
>> +static int ext_set_protected(struct i915_user_extension __user *base, void *data)
>> +{
>> +	struct drm_i915_gem_create_ext_protected_content ext;
>> +	struct create_ext *ext_data = data;
>> +
>> +	if (copy_from_user(&ext, base, sizeof(ext)))
>> +		return -EFAULT;
>> +
>> +	if (ext.flags)
>> +		return -EINVAL;
>> +
>> +	if (!intel_pxp_is_enabled(&ext_data->i915->gt.pxp))
>> +		return -ENODEV;
>> +
>> +	ext_data->flags |= I915_BO_PROTECTED;
>> +
>> +	return 0;
>> +}
>> +
>>   static const i915_user_extension_fn create_extensions[] = {
>>   	[I915_GEM_CREATE_EXT_MEMORY_REGIONS] = ext_set_placements,
>> +	[I915_GEM_CREATE_EXT_PROTECTED_CONTENT] = ext_set_protected,
>>   };
>>   
>>   /**
>> @@ -392,9 +430,10 @@ i915_gem_create_ext_ioctl(struct drm_device *dev, void *data,
>>   		ext_data.n_placements = 1;
>>   	}
>>   
>> -	obj = __i915_gem_object_create_user(i915, args->size,
>> -					    ext_data.placements,
>> -					    ext_data.n_placements);
>> +	obj = __i915_gem_object_create_user_ext(i915, args->size,
>> +						ext_data.placements,
>> +						ext_data.n_placements,
>> +						ext_data.flags);
>>   	if (IS_ERR(obj))
>>   		return PTR_ERR(obj);
>>   
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>> index 1ed7475de454..04f33d163340 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>> @@ -21,6 +21,8 @@
>>   #include "gt/intel_gt_pm.h"
>>   #include "gt/intel_ring.h"
>>   
>> +#include "pxp/intel_pxp.h"
>> +
>>   #include "i915_drv.h"
>>   #include "i915_gem_clflush.h"
>>   #include "i915_gem_context.h"
>> @@ -751,6 +753,11 @@ static int eb_select_context(struct i915_execbuffer *eb)
>>   	if (unlikely(IS_ERR(ctx)))
>>   		return PTR_ERR(ctx);
>>   
>> +	if (i915_gem_context_invalidated(ctx)) {
>> +		i915_gem_context_put(ctx);
>> +		return -EACCES;
>> +	}
>> +
>>   	eb->gem_context = ctx;
>>   	if (rcu_access_pointer(ctx->vm))
>>   		eb->invalid_flags |= EXEC_OBJECT_NEEDS_GTT;
>> @@ -819,7 +826,7 @@ static struct i915_vma *eb_lookup_vma(struct i915_execbuffer *eb, u32 handle)
>>   	do {
>>   		struct drm_i915_gem_object *obj;
>>   		struct i915_vma *vma;
>> -		int err;
>> +		int err = 0;
>>   
>>   		rcu_read_lock();
>>   		vma = radix_tree_lookup(&eb->gem_context->handles_vma, handle);
>> @@ -833,6 +840,26 @@ static struct i915_vma *eb_lookup_vma(struct i915_execbuffer *eb, u32 handle)
>>   		if (unlikely(!obj))
>>   			return ERR_PTR(-ENOENT);
>>   
>> +		/*
>> +		 * If the user has opted-in for protected-object tracking, make
>> +		 * sure the object encryption can be used.
>> +		 * We only need to do this when the object is first used with
>> +		 * this context, because the context itself will be banned when
>> +		 * the protected objects become invalid.
>> +		 */
>> +		if (i915_gem_context_uses_protected_content(eb->gem_context) &&
>> +		    i915_gem_object_is_protected(obj)) {
>> +			if (!intel_pxp_is_active(&vm->gt->pxp))
>> +				err = -ENODEV;
>> +			else if (!i915_gem_object_has_valid_protection(obj))
>> +				err = -ENOEXEC;
>> +
>> +			if (err) {
>> +				i915_gem_object_put(obj);
>> +				return ERR_PTR(err);
>> +			}
>> +		}
>> +
>>   		vma = i915_vma_instance(obj, vm, NULL);
>>   		if (IS_ERR(vma)) {
>>   			i915_gem_object_put(obj);
>> @@ -2752,6 +2779,17 @@ eb_select_engine(struct i915_execbuffer *eb)
>>   
>>   	intel_gt_pm_get(ce->engine->gt);
>>   
>> +	if (i915_gem_context_uses_protected_content(eb->gem_context)) {
>> +		err = intel_pxp_wait_for_arb_start(&ce->engine->gt->pxp);
>> +		if (err)
>> +			goto err;
>> +
>> +		if (i915_gem_context_invalidated(eb->gem_context)) {
>> +			err = -EACCES;
>> +			goto err;
>> +		}
>> +	}
>> +
>>   	if (!test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
>>   		err = intel_context_alloc_state(ce);
>>   		if (err)
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c
>> index 6fb9afb65034..658a42a7fa07 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
>> @@ -25,6 +25,7 @@
>>   #include <linux/sched/mm.h>
>>   
>>   #include "display/intel_frontbuffer.h"
>> +#include "pxp/intel_pxp.h"
>>   #include "i915_drv.h"
>>   #include "i915_gem_clflush.h"
>>   #include "i915_gem_context.h"
>> @@ -73,6 +74,8 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj,
>>   	INIT_LIST_HEAD(&obj->lut_list);
>>   	spin_lock_init(&obj->lut_lock);
>>   
>> +	INIT_LIST_HEAD(&obj->pxp_link);
>> +
>>   	spin_lock_init(&obj->mmo.lock);
>>   	obj->mmo.offsets = RB_ROOT;
>>   
>> @@ -231,6 +234,9 @@ void __i915_gem_free_object(struct drm_i915_gem_object *obj)
>>   		spin_unlock(&obj->vma.lock);
>>   	}
>>   
>> +	if (i915_gem_object_has_valid_protection(obj))
>> +		intel_pxp_object_remove(obj);
>> +
>>   	__i915_gem_object_free_mmaps(obj);
>>   
>>   	GEM_BUG_ON(!list_empty(&obj->lut_list));
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h
>> index 48112b9d76df..137ae2723514 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
>> @@ -269,6 +269,18 @@ i915_gem_object_clear_tiling_quirk(struct drm_i915_gem_object *obj)
>>   	clear_bit(I915_TILING_QUIRK_BIT, &obj->flags);
>>   }
>>   
>> +static inline bool
>> +i915_gem_object_is_protected(const struct drm_i915_gem_object *obj)
>> +{
>> +	return obj->flags & I915_BO_PROTECTED;
>> +}
>> +
>> +static inline bool
>> +i915_gem_object_has_valid_protection(const struct drm_i915_gem_object *obj)
>> +{
>> +	return i915_gem_object_is_protected(obj) && !list_empty(&obj->pxp_link);
>> +}
>> +
>>   static inline bool
>>   i915_gem_object_type_has(const struct drm_i915_gem_object *obj,
>>   			 unsigned long flags)
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
>> index 2471f36aaff3..38e4a190607a 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
>> @@ -298,6 +298,7 @@ struct drm_i915_gem_object {
>>   			     I915_BO_ALLOC_USER)
>>   #define I915_BO_READONLY         BIT(4)
>>   #define I915_TILING_QUIRK_BIT    5 /* unknown swizzling; do not release! */
>> +#define I915_BO_PROTECTED        BIT(6)
>>   
>>   	/**
>>   	 * @mem_flags - Mutable placement-related flags
>> @@ -537,6 +538,14 @@ struct drm_i915_gem_object {
>>   		bool created:1;
>>   	} ttm;
>>   
>> +	/*
>> +	 * When the PXP session is invalidated, we need to mark all protected
>> +	 * objects as invalid. To easily do so we add them all to a list. The
>> +	 * presence on the list is used to check if the encryption is valid or
>> +	 * not.
>> +	 */
>> +	struct list_head pxp_link;
>> +
>>   	/** Record of address bit 17 of each page at last unbind. */
>>   	unsigned long *bit_17;
>>   
>> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
>> index b0c7edc10cc3..f418281e8c10 100644
>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
>> @@ -7,6 +7,7 @@
>>   #include "intel_pxp_irq.h"
>>   #include "intel_pxp_session.h"
>>   #include "intel_pxp_tee.h"
>> +#include "gem/i915_gem_context.h"
>>   #include "gt/intel_context.h"
>>   #include "i915_drv.h"
>>   
>> @@ -70,6 +71,9 @@ void intel_pxp_init(struct intel_pxp *pxp)
>>   
>>   	mutex_init(&pxp->tee_mutex);
>>   
>> +	spin_lock_init(&pxp->lock);
>> +	INIT_LIST_HEAD(&pxp->protected_objects);
>> +
>>   	/*
>>   	 * we'll use the completion to check if there is a termination pending,
>>   	 * so we start it as completed and we reinit it when a termination
>> @@ -166,3 +170,88 @@ void intel_pxp_fini_hw(struct intel_pxp *pxp)
>>   
>>   	intel_pxp_irq_disable(pxp);
>>   }
>> +
>> +int intel_pxp_object_add(struct drm_i915_gem_object *obj)
>> +{
>> +	struct intel_pxp *pxp = &to_i915(obj->base.dev)->gt.pxp;
>> +
>> +	if (!intel_pxp_is_enabled(pxp))
>> +		return -ENODEV;
>> +
>> +	if (!list_empty(&obj->pxp_link))
>> +		return -EEXIST;
>> +
>> +	spin_lock_irq(&pxp->lock);
>> +	list_add(&obj->pxp_link, &pxp->protected_objects);
>> +	spin_unlock_irq(&pxp->lock);
>> +
>> +	return 0;
>> +}
>> +
>> +void intel_pxp_object_remove(struct drm_i915_gem_object *obj)
>> +{
>> +	struct intel_pxp *pxp = &to_i915(obj->base.dev)->gt.pxp;
>> +
>> +	if (!intel_pxp_is_enabled(pxp))
>> +		return;
>> +
>> +	spin_lock_irq(&pxp->lock);
>> +	list_del_init(&obj->pxp_link);
>> +	spin_unlock_irq(&pxp->lock);
>> +}
>> +
>> +void intel_pxp_invalidate(struct intel_pxp *pxp)
>> +{
>> +	struct drm_i915_private *i915 = pxp_to_gt(pxp)->i915;
>> +	struct drm_i915_gem_object *obj, *tmp;
>> +	struct i915_gem_context *ctx, *cn;
>> +
>> +	/* delete objects that have been used with the invalidated session */
>> +	spin_lock_irq(&pxp->lock);
>> +	list_for_each_entry_safe(obj, tmp, &pxp->protected_objects, pxp_link) {
>> +		if (i915_gem_object_has_pages(obj))
>> +			list_del_init(&obj->pxp_link);
>> +	}
>> +	spin_unlock_irq(&pxp->lock);
>> +
>> +	/* 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) {
>> +		struct i915_gem_engines_iter it;
>> +		struct intel_context *ce;
>> +
>> +		if (!kref_get_unless_zero(&ctx->ref))
>> +			continue;
>> +
>> +		if (likely(!i915_gem_context_uses_protected_content(ctx)) ||
>> +		    i915_gem_context_invalidated(ctx)) {
>> +			i915_gem_context_put(ctx);
>> +			continue;
>> +		}
>> +
>> +		spin_unlock_irq(&i915->gem.contexts.lock);
>> +
>> +		/*
>> +		 * Note that by the time we get here the HW keys are already
>> +		 * long gone, so any batch using them that's already on the
>> +		 * engines is very likely a lost cause (and it has probably
>> +		 * already hung the engine). Therefore, we skip attempting to
>> +		 * pull the running context out of the HW and we prioritize
>> +		 * bringing the session back as soon as possible.
>> +		 */
>> +		for_each_gem_engine(ce, i915_gem_context_lock_engines(ctx), it) {
>> +			/* only invalidate if at least one ce was allocated */
>> +			if (test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
>> +				intel_context_set_banned(ce);
>> +				i915_gem_context_set_invalid(ctx);
>> +			}
>> +		}
>> +		i915_gem_context_unlock_engines(ctx);
>> +
>> +		spin_lock_irq(&i915->gem.contexts.lock);
>> +		list_safe_reset_next(ctx, cn, link);
>> +		i915_gem_context_put(ctx);
>> +	}
>> +	spin_unlock_irq(&i915->gem.contexts.lock);
>> +}
>> +
>> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
>> index 074b3b980957..4f7647f34153 100644
>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
>> @@ -9,6 +9,8 @@
>>   #include "gt/intel_gt_types.h"
>>   #include "intel_pxp_types.h"
>>   
>> +struct drm_i915_gem_object;
>> +
>>   static inline struct intel_gt *pxp_to_gt(const struct intel_pxp *pxp)
>>   {
>>   	return container_of(pxp, struct intel_gt, pxp);
>> @@ -33,6 +35,11 @@ void intel_pxp_fini_hw(struct intel_pxp *pxp);
>>   
>>   void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp);
>>   int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp);
>> +
>> +int intel_pxp_object_add(struct drm_i915_gem_object *obj);
>> +void intel_pxp_object_remove(struct drm_i915_gem_object *obj);
>> +
>> +void intel_pxp_invalidate(struct intel_pxp *pxp);
>>   #else
>>   static inline void intel_pxp_init(struct intel_pxp *pxp)
>>   {
>> @@ -46,6 +53,14 @@ static inline int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp)
>>   {
>>   	return 0;
>>   }
>> +
>> +static inline int intel_pxp_object_add(struct drm_i915_gem_object *obj)
>> +{
>> +	return 0;
>> +}
>> +static inline void intel_pxp_object_remove(struct drm_i915_gem_object *obj)
>> +{
>> +}
>>   #endif
>>   
>>   #endif /* __INTEL_PXP_H__ */
>> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
>> index 67c30e534d50..0edd563a653d 100644
>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
>> @@ -85,6 +85,9 @@ static int pxp_terminate_arb_session_and_global(struct intel_pxp *pxp)
>>   	/* must mark termination in progress calling this function */
>>   	GEM_WARN_ON(pxp->arb_is_valid);
>>   
>> +	/* invalidate protected objects */
>> +	intel_pxp_invalidate(pxp);
>> +
>>   	/* terminate the hw sessions */
>>   	ret = intel_pxp_terminate_session(pxp, ARB_SESSION);
>>   	if (ret) {
>> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
>> index 475e3312c287..be2bed3a2e4e 100644
>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
>> @@ -7,7 +7,9 @@
>>   #define __INTEL_PXP_TYPES_H__
>>   
>>   #include <linux/completion.h>
>> +#include <linux/list.h>
>>   #include <linux/mutex.h>
>> +#include <linux/spinlock.h>
>>   #include <linux/types.h>
>>   #include <linux/workqueue.h>
>>   
>> @@ -43,6 +45,9 @@ struct intel_pxp {
>>   	u32 session_events; /* protected with gt->irq_lock */
>>   #define PXP_TERMINATION_REQUEST  BIT(0)
>>   #define PXP_TERMINATION_COMPLETE BIT(1)
>> +
>> +	spinlock_t lock; /* protects the objects list */
>> +	struct list_head protected_objects;
>>   };
>>   
>>   #endif /* __INTEL_PXP_TYPES_H__ */
>> diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
>> index 4393eef59d9b..2c9febdae6a5 100644
>> --- a/include/uapi/drm/i915_drm.h
>> +++ b/include/uapi/drm/i915_drm.h
>> @@ -1843,12 +1843,32 @@ struct drm_i915_gem_context_param {
>>    * attempted to use it, never re-use this context param number.
>>    */
>>   #define I915_CONTEXT_PARAM_RINGSIZE	0xc
>> +
>> +/*
>> + * I915_CONTEXT_PARAM_PROTECTED_CONTENT:
>> + *
>> + * Mark that the context makes use of protected content, which will result
>> + * in the context being invalidated when the protected content session is. The
>> + * invalidation is reported back to userspace via the RESET_STATS ioctl (see
>> + * relevant doc for details).
>> + * This flag can only be set at context creation time and, when set to true,
>> + * must be preceded by an explicit setting of I915_CONTEXT_PARAM_RECOVERABLE
>> + * to false. This flag can't be set to true in conjunction with setting the
>> + * I915_CONTEXT_PARAM_BANNABLE flag to false.
>> + *
>> + * In addition to the normal failure cases, setting this flag during context
>> + * creation can result in the following errors:
>> + *
>> + * -ENODEV: feature not available
>> + * -EPERM: trying to mark a recoverable or not bannable context as protected
>> + */
>> +#define I915_CONTEXT_PARAM_PROTECTED_CONTENT    0xd
>>   /* Must be kept compact -- no holes and well documented */
>>   
>>   	__u64 value;
>>   };
>>   
>> -/*
>> +/**
>>    * Context SSEU programming
>>    *
>>    * It may be necessary for either functional or performance reason to configure
>> @@ -2181,6 +2201,12 @@ struct drm_i915_reg_read {
>>   struct drm_i915_reset_stats {
>>   	__u32 ctx_id;
>>   	__u32 flags;
>> +	/*
>> +	 * contexts marked as using protected content are invalidated when the
>> +	 * protected content session dies. Submission of invalidated contexts
>> +	 * is rejected with -EACCES.
>> +	 */
>> +#define I915_CONTEXT_INVALIDATED 0x1
>>   
>>   	/* All resets since boot/module reload, for all contexts */
>>   	__u32 reset_count;
>> @@ -2959,8 +2985,12 @@ struct drm_i915_gem_create_ext {
>>   	 *
>>   	 * For I915_GEM_CREATE_EXT_MEMORY_REGIONS usage see
>>   	 * struct drm_i915_gem_create_ext_memory_regions.
>> +	 *
>> +	 * For I915_GEM_CREATE_EXT_PROTECTED_CONTENT usage see
>> +	 * struct drm_i915_gem_create_ext_protected_content.
>>   	 */
>>   #define I915_GEM_CREATE_EXT_MEMORY_REGIONS 0
>> +#define I915_GEM_CREATE_EXT_PROTECTED_CONTENT 1
>>   	__u64 extensions;
>>   };
>>   
>> @@ -3018,6 +3048,29 @@ struct drm_i915_gem_create_ext_memory_regions {
>>   	__u64 regions;
>>   };
>>   
>> +/**
>> + * struct drm_i915_gem_create_ext_protected_content - The
>> + * I915_OBJECT_PARAM_PROTECTED_CONTENT extension.
>> + *
>> + * If this extension is provided, buffer contents are expected to be protected
>> + * by PXP encryption and require decryption for scan out and processing. This
>> + * is only possible on platforms that have PXP enabled, on all other scenarios
>> + * using this extension will cause the ioctl to fail and return -ENODEV. The
>> + * flags parameter is reserved for future expansion and must currently be set
>> + * to zero.
>> + *
>> + * The buffer contents are considered invalid after a PXP session teardown.
>> + *
>> + * The encryption is guaranteed to be processed correctly only if the object
>> + * is submitted with a context created using the
>> + * I915_CONTEXT_PARAM_PROTECTED_CONTENT flag. This will also enable extra checks
>> + * at submission time on the validity of the objects involved.
>> + */
>> +struct drm_i915_gem_create_ext_protected_content {
>> +	struct i915_user_extension base;
>> +	__u32 flags;
>> +};
>> +
>>   /* ID of the protected content session managed by i915 when PXP is active */
>>   #define I915_PROTECTED_CONTENT_DEFAULT_SESSION 0xf
>>   
>> -- 
>> 2.32.0
>>

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v6 10/15] drm/i915/pxp: interfaces for using protected objects
  2021-07-29 15:17       ` [Intel-gfx] " Daniele Ceraolo Spurio
@ 2021-07-29 20:40         ` Rodrigo Vivi
  -1 siblings, 0 replies; 64+ messages in thread
From: Rodrigo Vivi @ 2021-07-29 20:40 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio
  Cc: intel-gfx, dri-devel, Chris Wilson, jason.ekstrand,
	Jason Ekstrand, Bommu Krishnaiah, Vetter, Daniel

On Thu, Jul 29, 2021 at 08:17:44AM -0700, Daniele Ceraolo Spurio wrote:
> 
> 
> On 7/29/2021 4:10 AM, Rodrigo Vivi wrote:
> > On Wed, Jul 28, 2021 at 07:01:01PM -0700, Daniele Ceraolo Spurio wrote:
> > > This api allow user mode to create protected buffers and to mark
> > > contexts as making use of such objects. Only when using contexts
> > > marked in such a way is the execution guaranteed to work as expected.
> > > 
> > > Contexts can only be marked as using protected content at creation time
> > > (i.e. the parameter is immutable) and they must be both bannable and not
> > > recoverable.
> > > 
> > > All protected objects and contexts that have backing storage will be
> > > considered invalid when the PXP session is destroyed and all new
> > > submissions using them will be rejected. All intel contexts within the
> > > invalidated gem contexts will be marked banned. A new flag has been
> > > added to the RESET_STATS ioctl to report the context invalidation to
> > > userspace.
> > > 
> > > This patch was previously sent as 2 separate patches, which have been
> > > squashed following a request to have all the uapi in a single patch.
> > > I've retained the s-o-b from both.
> > > 
> > > v5: squash patches, rebase on proto_ctx, update kerneldoc
> > > 
> > > v6: rebase on obj create_ext changes
> > The "rebase" word led me to think it was a small change caused
> > only by rebasing conflicts, but then I spotted something on
> > i915_gem_create.c that I didn't remember seeing before.
> 
> Apologies for not being clear.
> 
> > 
> > Since it took me a while to understand what was going on, let me
> > try to summarize to see if I got it right and to check
> > with others (Jason in special)
> > if we are aligned with the recent directions:
> > 
> > With the removal of the vanilla_object from the create_ext,
> > the addition of the flags was needed.
> 
> yes.
> 
> > 
> > Then, instead of adding a new user_flags it adds the I915_BO_PROTECTED
> > to the existent flags (what is cleaner) but then it does
> > 
> > /* Add any flag set by create_ext options */
> > flags |= ext_flags;
> > 
> > on the new user_create_ext.
> > 
> > What shouldn't be a problem because the ext_flags is really only
> > the I915_BO_PROTECTED set by our new extension and immutable.
> > 
> > But I'm just trying to see if we are not opening any holes to accept
> > some undesired flags.
> > 
> > Apparently not.
> 
> ext_flags are not set directly by the user, but by the create_ext extension
> functions, based on the extensions the user has provided. This should allow
> the kernel to perform any required checks in the extension functions before
> setting the flag (like it happens in this case for the PXP option).
> 
> > 
> > Am I getting things right? Anything else we should check in here?
> 
> yup, got it right.

Great, thanks for confirming

so I'm okay with:

Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>


> 
> Daniele
> 
> > 
> > Thanks,
> > Rodrigo.
> > 
> > > Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
> > > Signed-off-by: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
> > > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > > Cc: Chris Wilson <chris@chris-wilson.co.uk>
> > > Cc: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
> > > Cc: Jason Ekstrand <jason@jlekstrand.net>
> > > Cc: Daniel Vetter <daniel.vetter@intel.com>
> > > Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> #v5
> > > ---
> > >   drivers/gpu/drm/i915/gem/i915_gem_context.c   | 68 ++++++++++++--
> > >   drivers/gpu/drm/i915/gem/i915_gem_context.h   | 18 ++++
> > >   .../gpu/drm/i915/gem/i915_gem_context_types.h |  2 +
> > >   drivers/gpu/drm/i915/gem/i915_gem_create.c    | 75 ++++++++++++----
> > >   .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 40 ++++++++-
> > >   drivers/gpu/drm/i915/gem/i915_gem_object.c    |  6 ++
> > >   drivers/gpu/drm/i915/gem/i915_gem_object.h    | 12 +++
> > >   .../gpu/drm/i915/gem/i915_gem_object_types.h  |  9 ++
> > >   drivers/gpu/drm/i915/pxp/intel_pxp.c          | 89 +++++++++++++++++++
> > >   drivers/gpu/drm/i915/pxp/intel_pxp.h          | 15 ++++
> > >   drivers/gpu/drm/i915/pxp/intel_pxp_session.c  |  3 +
> > >   drivers/gpu/drm/i915/pxp/intel_pxp_types.h    |  5 ++
> > >   include/uapi/drm/i915_drm.h                   | 55 +++++++++++-
> > >   13 files changed, 371 insertions(+), 26 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> > > index cff72679ad7c..0cd3e2d06188 100644
> > > --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
> > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> > > @@ -77,6 +77,8 @@
> > >   #include "gt/intel_gpu_commands.h"
> > >   #include "gt/intel_ring.h"
> > > +#include "pxp/intel_pxp.h"
> > > +
> > >   #include "i915_gem_context.h"
> > >   #include "i915_trace.h"
> > >   #include "i915_user_extensions.h"
> > > @@ -241,6 +243,25 @@ static int proto_context_set_persistence(struct drm_i915_private *i915,
> > >   	return 0;
> > >   }
> > > +static int proto_context_set_protected(struct drm_i915_private *i915,
> > > +				       struct i915_gem_proto_context *pc,
> > > +				       bool protected)
> > > +{
> > > +	int ret = 0;
> > > +
> > > +	if (!intel_pxp_is_enabled(&i915->gt.pxp))
> > > +		ret = -ENODEV;
> > > +	else if (!protected)
> > > +		pc->user_flags &= ~BIT(UCONTEXT_PROTECTED);
> > > +	else if ((pc->user_flags & BIT(UCONTEXT_RECOVERABLE)) ||
> > > +		 !(pc->user_flags & BIT(UCONTEXT_BANNABLE)))
> > > +		ret = -EPERM;
> > > +	else
> > > +		pc->user_flags |= BIT(UCONTEXT_PROTECTED);
> > > +
> > > +	return ret;
> > > +}
> > > +
> > >   static struct i915_gem_proto_context *
> > >   proto_context_create(struct drm_i915_private *i915, unsigned int flags)
> > >   {
> > > @@ -686,6 +707,8 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
> > >   			ret = -EPERM;
> > >   		else if (args->value)
> > >   			pc->user_flags |= BIT(UCONTEXT_BANNABLE);
> > > +		else if (pc->user_flags & BIT(UCONTEXT_PROTECTED))
> > > +			ret = -EPERM;
> > >   		else
> > >   			pc->user_flags &= ~BIT(UCONTEXT_BANNABLE);
> > >   		break;
> > > @@ -693,10 +716,12 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
> > >   	case I915_CONTEXT_PARAM_RECOVERABLE:
> > >   		if (args->size)
> > >   			ret = -EINVAL;
> > > -		else if (args->value)
> > > -			pc->user_flags |= BIT(UCONTEXT_RECOVERABLE);
> > > -		else
> > > +		else if (!args->value)
> > >   			pc->user_flags &= ~BIT(UCONTEXT_RECOVERABLE);
> > > +		else if (pc->user_flags & BIT(UCONTEXT_PROTECTED))
> > > +			ret = -EPERM;
> > > +		else
> > > +			pc->user_flags |= BIT(UCONTEXT_RECOVERABLE);
> > >   		break;
> > >   	case I915_CONTEXT_PARAM_PRIORITY:
> > > @@ -724,6 +749,11 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
> > >   						    args->value);
> > >   		break;
> > > +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
> > > +		ret = proto_context_set_protected(fpriv->dev_priv, pc,
> > > +						  args->value);
> > > +		break;
> > > +
> > >   	case I915_CONTEXT_PARAM_NO_ZEROMAP:
> > >   	case I915_CONTEXT_PARAM_BAN_PERIOD:
> > >   	case I915_CONTEXT_PARAM_RINGSIZE:
> > > @@ -1798,6 +1828,18 @@ static int set_priority(struct i915_gem_context *ctx,
> > >   	return 0;
> > >   }
> > > +static int get_protected(struct i915_gem_context *ctx,
> > > +			 struct drm_i915_gem_context_param *args)
> > > +{
> > > +	if (!intel_pxp_is_enabled(&ctx->i915->gt.pxp))
> > > +		return -ENODEV;
> > > +
> > > +	args->size = 0;
> > > +	args->value = i915_gem_context_uses_protected_content(ctx);
> > > +
> > > +	return 0;
> > > +}
> > > +
> > >   static int ctx_setparam(struct drm_i915_file_private *fpriv,
> > >   			struct i915_gem_context *ctx,
> > >   			struct drm_i915_gem_context_param *args)
> > > @@ -1821,6 +1863,8 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
> > >   			ret = -EPERM;
> > >   		else if (args->value)
> > >   			i915_gem_context_set_bannable(ctx);
> > > +		else if (i915_gem_context_uses_protected_content(ctx))
> > > +			ret = -EPERM; /* can't clear this for protected contexts */
> > >   		else
> > >   			i915_gem_context_clear_bannable(ctx);
> > >   		break;
> > > @@ -1828,10 +1872,12 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
> > >   	case I915_CONTEXT_PARAM_RECOVERABLE:
> > >   		if (args->size)
> > >   			ret = -EINVAL;
> > > -		else if (args->value)
> > > -			i915_gem_context_set_recoverable(ctx);
> > > -		else
> > > +		else if (!args->value)
> > >   			i915_gem_context_clear_recoverable(ctx);
> > > +		else if (i915_gem_context_uses_protected_content(ctx))
> > > +			ret = -EPERM; /* can't set this for protected contexts */
> > > +		else
> > > +			i915_gem_context_set_recoverable(ctx);
> > >   		break;
> > >   	case I915_CONTEXT_PARAM_PRIORITY:
> > > @@ -1846,6 +1892,7 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
> > >   		ret = set_persistence(ctx, args);
> > >   		break;
> > > +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
> > >   	case I915_CONTEXT_PARAM_NO_ZEROMAP:
> > >   	case I915_CONTEXT_PARAM_BAN_PERIOD:
> > >   	case I915_CONTEXT_PARAM_RINGSIZE:
> > > @@ -2174,6 +2221,10 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
> > >   		args->value = i915_gem_context_is_persistent(ctx);
> > >   		break;
> > > +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
> > > +		ret = get_protected(ctx, args);
> > > +		break;
> > > +
> > >   	case I915_CONTEXT_PARAM_NO_ZEROMAP:
> > >   	case I915_CONTEXT_PARAM_BAN_PERIOD:
> > >   	case I915_CONTEXT_PARAM_ENGINES:
> > > @@ -2250,6 +2301,11 @@ int i915_gem_context_reset_stats_ioctl(struct drm_device *dev,
> > >   	args->batch_active = atomic_read(&ctx->guilty_count);
> > >   	args->batch_pending = atomic_read(&ctx->active_count);
> > > +	/* re-use args->flags for output flags */
> > > +	args->flags = 0;
> > > +	if (i915_gem_context_invalidated(ctx))
> > > +		args->flags |= I915_CONTEXT_INVALIDATED;
> > > +
> > >   	i915_gem_context_put(ctx);
> > >   	return 0;
> > >   }
> > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.h b/drivers/gpu/drm/i915/gem/i915_gem_context.h
> > > index 18060536b0c2..d932a70122fa 100644
> > > --- a/drivers/gpu/drm/i915/gem/i915_gem_context.h
> > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.h
> > > @@ -108,6 +108,24 @@ i915_gem_context_clear_user_engines(struct i915_gem_context *ctx)
> > >   	clear_bit(CONTEXT_USER_ENGINES, &ctx->flags);
> > >   }
> > > +static inline bool
> > > +i915_gem_context_invalidated(const struct i915_gem_context *ctx)
> > > +{
> > > +	return test_bit(CONTEXT_INVALID, &ctx->flags);
> > > +}
> > > +
> > > +static inline void
> > > +i915_gem_context_set_invalid(struct i915_gem_context *ctx)
> > > +{
> > > +	set_bit(CONTEXT_INVALID, &ctx->flags);
> > > +}
> > > +
> > > +static inline bool
> > > +i915_gem_context_uses_protected_content(const struct i915_gem_context *ctx)
> > > +{
> > > +	return test_bit(UCONTEXT_PROTECTED, &ctx->user_flags);
> > > +}
> > > +
> > >   /* i915_gem_context.c */
> > >   void i915_gem_init__contexts(struct drm_i915_private *i915);
> > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
> > > index 94c03a97cb77..1aa2290aa3c7 100644
> > > --- a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
> > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
> > > @@ -301,6 +301,7 @@ struct i915_gem_context {
> > >   #define UCONTEXT_BANNABLE		2
> > >   #define UCONTEXT_RECOVERABLE		3
> > >   #define UCONTEXT_PERSISTENCE		4
> > > +#define UCONTEXT_PROTECTED		5
> > >   	/**
> > >   	 * @flags: small set of booleans
> > > @@ -308,6 +309,7 @@ struct i915_gem_context {
> > >   	unsigned long flags;
> > >   #define CONTEXT_CLOSED			0
> > >   #define CONTEXT_USER_ENGINES		1
> > > +#define CONTEXT_INVALID			2
> > >   	/** @mutex: guards everything that isn't engines or handles_vma */
> > >   	struct mutex mutex;
> > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c b/drivers/gpu/drm/i915/gem/i915_gem_create.c
> > > index 23fee13a3384..0e48629316bb 100644
> > > --- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
> > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
> > > @@ -6,6 +6,7 @@
> > >   #include "gem/i915_gem_ioctls.h"
> > >   #include "gem/i915_gem_lmem.h"
> > >   #include "gem/i915_gem_region.h"
> > > +#include "pxp/intel_pxp.h"
> > >   #include "i915_drv.h"
> > >   #include "i915_trace.h"
> > > @@ -82,21 +83,11 @@ static int i915_gem_publish(struct drm_i915_gem_object *obj,
> > >   	return 0;
> > >   }
> > > -/**
> > > - * Creates a new object using the same path as DRM_I915_GEM_CREATE_EXT
> > > - * @i915: i915 private
> > > - * @size: size of the buffer, in bytes
> > > - * @placements: possible placement regions, in priority order
> > > - * @n_placements: number of possible placement regions
> > > - *
> > > - * This function is exposed primarily for selftests and does very little
> > > - * error checking.  It is assumed that the set of placement regions has
> > > - * already been verified to be valid.
> > > - */
> > > -struct drm_i915_gem_object *
> > > -__i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
> > > -			      struct intel_memory_region **placements,
> > > -			      unsigned int n_placements)
> > > +static struct drm_i915_gem_object *
> > > +__i915_gem_object_create_user_ext(struct drm_i915_private *i915, u64 size,
> > > +				  struct intel_memory_region **placements,
> > > +				  unsigned int n_placements,
> > > +				  unsigned int ext_flags)
> > >   {
> > >   	struct intel_memory_region *mr = placements[0];
> > >   	struct drm_i915_gem_object *obj;
> > > @@ -135,6 +126,12 @@ __i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
> > >   	GEM_BUG_ON(size != obj->base.size);
> > > +	/* Add any flag set by create_ext options */
> > > +	flags |= ext_flags;
> > > +
> > > +	if (i915_gem_object_is_protected(obj))
> > > +		intel_pxp_object_add(obj);
> > > +
> > >   	trace_i915_gem_object_create(obj);
> > >   	return obj;
> > > @@ -145,6 +142,26 @@ __i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
> > >   	return ERR_PTR(ret);
> > >   }
> > > +/**
> > > + * Creates a new object using the same path as DRM_I915_GEM_CREATE_EXT
> > > + * @i915: i915 private
> > > + * @size: size of the buffer, in bytes
> > > + * @placements: possible placement regions, in priority order
> > > + * @n_placements: number of possible placement regions
> > > + *
> > > + * This function is exposed primarily for selftests and does very little
> > > + * error checking.  It is assumed that the set of placement regions has
> > > + * already been verified to be valid.
> > > + */
> > > +struct drm_i915_gem_object *
> > > +__i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
> > > +			      struct intel_memory_region **placements,
> > > +			      unsigned int n_placements)
> > > +{
> > > +	return __i915_gem_object_create_user_ext(i915, size, placements,
> > > +						 n_placements, 0);
> > > +}
> > > +
> > >   int
> > >   i915_gem_dumb_create(struct drm_file *file,
> > >   		     struct drm_device *dev,
> > > @@ -224,6 +241,7 @@ struct create_ext {
> > >   	struct drm_i915_private *i915;
> > >   	struct intel_memory_region *placements[INTEL_REGION_UNKNOWN];
> > >   	unsigned int n_placements;
> > > +	unsigned long flags;
> > >   };
> > >   static void repr_placements(char *buf, size_t size,
> > > @@ -356,8 +374,28 @@ static int ext_set_placements(struct i915_user_extension __user *base,
> > >   	return set_placements(&ext, data);
> > >   }
> > > +static int ext_set_protected(struct i915_user_extension __user *base, void *data)
> > > +{
> > > +	struct drm_i915_gem_create_ext_protected_content ext;
> > > +	struct create_ext *ext_data = data;
> > > +
> > > +	if (copy_from_user(&ext, base, sizeof(ext)))
> > > +		return -EFAULT;
> > > +
> > > +	if (ext.flags)
> > > +		return -EINVAL;
> > > +
> > > +	if (!intel_pxp_is_enabled(&ext_data->i915->gt.pxp))
> > > +		return -ENODEV;
> > > +
> > > +	ext_data->flags |= I915_BO_PROTECTED;
> > > +
> > > +	return 0;
> > > +}
> > > +
> > >   static const i915_user_extension_fn create_extensions[] = {
> > >   	[I915_GEM_CREATE_EXT_MEMORY_REGIONS] = ext_set_placements,
> > > +	[I915_GEM_CREATE_EXT_PROTECTED_CONTENT] = ext_set_protected,
> > >   };
> > >   /**
> > > @@ -392,9 +430,10 @@ i915_gem_create_ext_ioctl(struct drm_device *dev, void *data,
> > >   		ext_data.n_placements = 1;
> > >   	}
> > > -	obj = __i915_gem_object_create_user(i915, args->size,
> > > -					    ext_data.placements,
> > > -					    ext_data.n_placements);
> > > +	obj = __i915_gem_object_create_user_ext(i915, args->size,
> > > +						ext_data.placements,
> > > +						ext_data.n_placements,
> > > +						ext_data.flags);
> > >   	if (IS_ERR(obj))
> > >   		return PTR_ERR(obj);
> > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> > > index 1ed7475de454..04f33d163340 100644
> > > --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> > > @@ -21,6 +21,8 @@
> > >   #include "gt/intel_gt_pm.h"
> > >   #include "gt/intel_ring.h"
> > > +#include "pxp/intel_pxp.h"
> > > +
> > >   #include "i915_drv.h"
> > >   #include "i915_gem_clflush.h"
> > >   #include "i915_gem_context.h"
> > > @@ -751,6 +753,11 @@ static int eb_select_context(struct i915_execbuffer *eb)
> > >   	if (unlikely(IS_ERR(ctx)))
> > >   		return PTR_ERR(ctx);
> > > +	if (i915_gem_context_invalidated(ctx)) {
> > > +		i915_gem_context_put(ctx);
> > > +		return -EACCES;
> > > +	}
> > > +
> > >   	eb->gem_context = ctx;
> > >   	if (rcu_access_pointer(ctx->vm))
> > >   		eb->invalid_flags |= EXEC_OBJECT_NEEDS_GTT;
> > > @@ -819,7 +826,7 @@ static struct i915_vma *eb_lookup_vma(struct i915_execbuffer *eb, u32 handle)
> > >   	do {
> > >   		struct drm_i915_gem_object *obj;
> > >   		struct i915_vma *vma;
> > > -		int err;
> > > +		int err = 0;
> > >   		rcu_read_lock();
> > >   		vma = radix_tree_lookup(&eb->gem_context->handles_vma, handle);
> > > @@ -833,6 +840,26 @@ static struct i915_vma *eb_lookup_vma(struct i915_execbuffer *eb, u32 handle)
> > >   		if (unlikely(!obj))
> > >   			return ERR_PTR(-ENOENT);
> > > +		/*
> > > +		 * If the user has opted-in for protected-object tracking, make
> > > +		 * sure the object encryption can be used.
> > > +		 * We only need to do this when the object is first used with
> > > +		 * this context, because the context itself will be banned when
> > > +		 * the protected objects become invalid.
> > > +		 */
> > > +		if (i915_gem_context_uses_protected_content(eb->gem_context) &&
> > > +		    i915_gem_object_is_protected(obj)) {
> > > +			if (!intel_pxp_is_active(&vm->gt->pxp))
> > > +				err = -ENODEV;
> > > +			else if (!i915_gem_object_has_valid_protection(obj))
> > > +				err = -ENOEXEC;
> > > +
> > > +			if (err) {
> > > +				i915_gem_object_put(obj);
> > > +				return ERR_PTR(err);
> > > +			}
> > > +		}
> > > +
> > >   		vma = i915_vma_instance(obj, vm, NULL);
> > >   		if (IS_ERR(vma)) {
> > >   			i915_gem_object_put(obj);
> > > @@ -2752,6 +2779,17 @@ eb_select_engine(struct i915_execbuffer *eb)
> > >   	intel_gt_pm_get(ce->engine->gt);
> > > +	if (i915_gem_context_uses_protected_content(eb->gem_context)) {
> > > +		err = intel_pxp_wait_for_arb_start(&ce->engine->gt->pxp);
> > > +		if (err)
> > > +			goto err;
> > > +
> > > +		if (i915_gem_context_invalidated(eb->gem_context)) {
> > > +			err = -EACCES;
> > > +			goto err;
> > > +		}
> > > +	}
> > > +
> > >   	if (!test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
> > >   		err = intel_context_alloc_state(ce);
> > >   		if (err)
> > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c
> > > index 6fb9afb65034..658a42a7fa07 100644
> > > --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
> > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
> > > @@ -25,6 +25,7 @@
> > >   #include <linux/sched/mm.h>
> > >   #include "display/intel_frontbuffer.h"
> > > +#include "pxp/intel_pxp.h"
> > >   #include "i915_drv.h"
> > >   #include "i915_gem_clflush.h"
> > >   #include "i915_gem_context.h"
> > > @@ -73,6 +74,8 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj,
> > >   	INIT_LIST_HEAD(&obj->lut_list);
> > >   	spin_lock_init(&obj->lut_lock);
> > > +	INIT_LIST_HEAD(&obj->pxp_link);
> > > +
> > >   	spin_lock_init(&obj->mmo.lock);
> > >   	obj->mmo.offsets = RB_ROOT;
> > > @@ -231,6 +234,9 @@ void __i915_gem_free_object(struct drm_i915_gem_object *obj)
> > >   		spin_unlock(&obj->vma.lock);
> > >   	}
> > > +	if (i915_gem_object_has_valid_protection(obj))
> > > +		intel_pxp_object_remove(obj);
> > > +
> > >   	__i915_gem_object_free_mmaps(obj);
> > >   	GEM_BUG_ON(!list_empty(&obj->lut_list));
> > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h
> > > index 48112b9d76df..137ae2723514 100644
> > > --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
> > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
> > > @@ -269,6 +269,18 @@ i915_gem_object_clear_tiling_quirk(struct drm_i915_gem_object *obj)
> > >   	clear_bit(I915_TILING_QUIRK_BIT, &obj->flags);
> > >   }
> > > +static inline bool
> > > +i915_gem_object_is_protected(const struct drm_i915_gem_object *obj)
> > > +{
> > > +	return obj->flags & I915_BO_PROTECTED;
> > > +}
> > > +
> > > +static inline bool
> > > +i915_gem_object_has_valid_protection(const struct drm_i915_gem_object *obj)
> > > +{
> > > +	return i915_gem_object_is_protected(obj) && !list_empty(&obj->pxp_link);
> > > +}
> > > +
> > >   static inline bool
> > >   i915_gem_object_type_has(const struct drm_i915_gem_object *obj,
> > >   			 unsigned long flags)
> > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> > > index 2471f36aaff3..38e4a190607a 100644
> > > --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> > > @@ -298,6 +298,7 @@ struct drm_i915_gem_object {
> > >   			     I915_BO_ALLOC_USER)
> > >   #define I915_BO_READONLY         BIT(4)
> > >   #define I915_TILING_QUIRK_BIT    5 /* unknown swizzling; do not release! */
> > > +#define I915_BO_PROTECTED        BIT(6)
> > >   	/**
> > >   	 * @mem_flags - Mutable placement-related flags
> > > @@ -537,6 +538,14 @@ struct drm_i915_gem_object {
> > >   		bool created:1;
> > >   	} ttm;
> > > +	/*
> > > +	 * When the PXP session is invalidated, we need to mark all protected
> > > +	 * objects as invalid. To easily do so we add them all to a list. The
> > > +	 * presence on the list is used to check if the encryption is valid or
> > > +	 * not.
> > > +	 */
> > > +	struct list_head pxp_link;
> > > +
> > >   	/** Record of address bit 17 of each page at last unbind. */
> > >   	unsigned long *bit_17;
> > > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
> > > index b0c7edc10cc3..f418281e8c10 100644
> > > --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
> > > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
> > > @@ -7,6 +7,7 @@
> > >   #include "intel_pxp_irq.h"
> > >   #include "intel_pxp_session.h"
> > >   #include "intel_pxp_tee.h"
> > > +#include "gem/i915_gem_context.h"
> > >   #include "gt/intel_context.h"
> > >   #include "i915_drv.h"
> > > @@ -70,6 +71,9 @@ void intel_pxp_init(struct intel_pxp *pxp)
> > >   	mutex_init(&pxp->tee_mutex);
> > > +	spin_lock_init(&pxp->lock);
> > > +	INIT_LIST_HEAD(&pxp->protected_objects);
> > > +
> > >   	/*
> > >   	 * we'll use the completion to check if there is a termination pending,
> > >   	 * so we start it as completed and we reinit it when a termination
> > > @@ -166,3 +170,88 @@ void intel_pxp_fini_hw(struct intel_pxp *pxp)
> > >   	intel_pxp_irq_disable(pxp);
> > >   }
> > > +
> > > +int intel_pxp_object_add(struct drm_i915_gem_object *obj)
> > > +{
> > > +	struct intel_pxp *pxp = &to_i915(obj->base.dev)->gt.pxp;
> > > +
> > > +	if (!intel_pxp_is_enabled(pxp))
> > > +		return -ENODEV;
> > > +
> > > +	if (!list_empty(&obj->pxp_link))
> > > +		return -EEXIST;
> > > +
> > > +	spin_lock_irq(&pxp->lock);
> > > +	list_add(&obj->pxp_link, &pxp->protected_objects);
> > > +	spin_unlock_irq(&pxp->lock);
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +void intel_pxp_object_remove(struct drm_i915_gem_object *obj)
> > > +{
> > > +	struct intel_pxp *pxp = &to_i915(obj->base.dev)->gt.pxp;
> > > +
> > > +	if (!intel_pxp_is_enabled(pxp))
> > > +		return;
> > > +
> > > +	spin_lock_irq(&pxp->lock);
> > > +	list_del_init(&obj->pxp_link);
> > > +	spin_unlock_irq(&pxp->lock);
> > > +}
> > > +
> > > +void intel_pxp_invalidate(struct intel_pxp *pxp)
> > > +{
> > > +	struct drm_i915_private *i915 = pxp_to_gt(pxp)->i915;
> > > +	struct drm_i915_gem_object *obj, *tmp;
> > > +	struct i915_gem_context *ctx, *cn;
> > > +
> > > +	/* delete objects that have been used with the invalidated session */
> > > +	spin_lock_irq(&pxp->lock);
> > > +	list_for_each_entry_safe(obj, tmp, &pxp->protected_objects, pxp_link) {
> > > +		if (i915_gem_object_has_pages(obj))
> > > +			list_del_init(&obj->pxp_link);
> > > +	}
> > > +	spin_unlock_irq(&pxp->lock);
> > > +
> > > +	/* 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) {
> > > +		struct i915_gem_engines_iter it;
> > > +		struct intel_context *ce;
> > > +
> > > +		if (!kref_get_unless_zero(&ctx->ref))
> > > +			continue;
> > > +
> > > +		if (likely(!i915_gem_context_uses_protected_content(ctx)) ||
> > > +		    i915_gem_context_invalidated(ctx)) {
> > > +			i915_gem_context_put(ctx);
> > > +			continue;
> > > +		}
> > > +
> > > +		spin_unlock_irq(&i915->gem.contexts.lock);
> > > +
> > > +		/*
> > > +		 * Note that by the time we get here the HW keys are already
> > > +		 * long gone, so any batch using them that's already on the
> > > +		 * engines is very likely a lost cause (and it has probably
> > > +		 * already hung the engine). Therefore, we skip attempting to
> > > +		 * pull the running context out of the HW and we prioritize
> > > +		 * bringing the session back as soon as possible.
> > > +		 */
> > > +		for_each_gem_engine(ce, i915_gem_context_lock_engines(ctx), it) {
> > > +			/* only invalidate if at least one ce was allocated */
> > > +			if (test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
> > > +				intel_context_set_banned(ce);
> > > +				i915_gem_context_set_invalid(ctx);
> > > +			}
> > > +		}
> > > +		i915_gem_context_unlock_engines(ctx);
> > > +
> > > +		spin_lock_irq(&i915->gem.contexts.lock);
> > > +		list_safe_reset_next(ctx, cn, link);
> > > +		i915_gem_context_put(ctx);
> > > +	}
> > > +	spin_unlock_irq(&i915->gem.contexts.lock);
> > > +}
> > > +
> > > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
> > > index 074b3b980957..4f7647f34153 100644
> > > --- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
> > > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
> > > @@ -9,6 +9,8 @@
> > >   #include "gt/intel_gt_types.h"
> > >   #include "intel_pxp_types.h"
> > > +struct drm_i915_gem_object;
> > > +
> > >   static inline struct intel_gt *pxp_to_gt(const struct intel_pxp *pxp)
> > >   {
> > >   	return container_of(pxp, struct intel_gt, pxp);
> > > @@ -33,6 +35,11 @@ void intel_pxp_fini_hw(struct intel_pxp *pxp);
> > >   void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp);
> > >   int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp);
> > > +
> > > +int intel_pxp_object_add(struct drm_i915_gem_object *obj);
> > > +void intel_pxp_object_remove(struct drm_i915_gem_object *obj);
> > > +
> > > +void intel_pxp_invalidate(struct intel_pxp *pxp);
> > >   #else
> > >   static inline void intel_pxp_init(struct intel_pxp *pxp)
> > >   {
> > > @@ -46,6 +53,14 @@ static inline int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp)
> > >   {
> > >   	return 0;
> > >   }
> > > +
> > > +static inline int intel_pxp_object_add(struct drm_i915_gem_object *obj)
> > > +{
> > > +	return 0;
> > > +}
> > > +static inline void intel_pxp_object_remove(struct drm_i915_gem_object *obj)
> > > +{
> > > +}
> > >   #endif
> > >   #endif /* __INTEL_PXP_H__ */
> > > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> > > index 67c30e534d50..0edd563a653d 100644
> > > --- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> > > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> > > @@ -85,6 +85,9 @@ static int pxp_terminate_arb_session_and_global(struct intel_pxp *pxp)
> > >   	/* must mark termination in progress calling this function */
> > >   	GEM_WARN_ON(pxp->arb_is_valid);
> > > +	/* invalidate protected objects */
> > > +	intel_pxp_invalidate(pxp);
> > > +
> > >   	/* terminate the hw sessions */
> > >   	ret = intel_pxp_terminate_session(pxp, ARB_SESSION);
> > >   	if (ret) {
> > > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
> > > index 475e3312c287..be2bed3a2e4e 100644
> > > --- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
> > > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
> > > @@ -7,7 +7,9 @@
> > >   #define __INTEL_PXP_TYPES_H__
> > >   #include <linux/completion.h>
> > > +#include <linux/list.h>
> > >   #include <linux/mutex.h>
> > > +#include <linux/spinlock.h>
> > >   #include <linux/types.h>
> > >   #include <linux/workqueue.h>
> > > @@ -43,6 +45,9 @@ struct intel_pxp {
> > >   	u32 session_events; /* protected with gt->irq_lock */
> > >   #define PXP_TERMINATION_REQUEST  BIT(0)
> > >   #define PXP_TERMINATION_COMPLETE BIT(1)
> > > +
> > > +	spinlock_t lock; /* protects the objects list */
> > > +	struct list_head protected_objects;
> > >   };
> > >   #endif /* __INTEL_PXP_TYPES_H__ */
> > > diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
> > > index 4393eef59d9b..2c9febdae6a5 100644
> > > --- a/include/uapi/drm/i915_drm.h
> > > +++ b/include/uapi/drm/i915_drm.h
> > > @@ -1843,12 +1843,32 @@ struct drm_i915_gem_context_param {
> > >    * attempted to use it, never re-use this context param number.
> > >    */
> > >   #define I915_CONTEXT_PARAM_RINGSIZE	0xc
> > > +
> > > +/*
> > > + * I915_CONTEXT_PARAM_PROTECTED_CONTENT:
> > > + *
> > > + * Mark that the context makes use of protected content, which will result
> > > + * in the context being invalidated when the protected content session is. The
> > > + * invalidation is reported back to userspace via the RESET_STATS ioctl (see
> > > + * relevant doc for details).
> > > + * This flag can only be set at context creation time and, when set to true,
> > > + * must be preceded by an explicit setting of I915_CONTEXT_PARAM_RECOVERABLE
> > > + * to false. This flag can't be set to true in conjunction with setting the
> > > + * I915_CONTEXT_PARAM_BANNABLE flag to false.
> > > + *
> > > + * In addition to the normal failure cases, setting this flag during context
> > > + * creation can result in the following errors:
> > > + *
> > > + * -ENODEV: feature not available
> > > + * -EPERM: trying to mark a recoverable or not bannable context as protected
> > > + */
> > > +#define I915_CONTEXT_PARAM_PROTECTED_CONTENT    0xd
> > >   /* Must be kept compact -- no holes and well documented */
> > >   	__u64 value;
> > >   };
> > > -/*
> > > +/**
> > >    * Context SSEU programming
> > >    *
> > >    * It may be necessary for either functional or performance reason to configure
> > > @@ -2181,6 +2201,12 @@ struct drm_i915_reg_read {
> > >   struct drm_i915_reset_stats {
> > >   	__u32 ctx_id;
> > >   	__u32 flags;
> > > +	/*
> > > +	 * contexts marked as using protected content are invalidated when the
> > > +	 * protected content session dies. Submission of invalidated contexts
> > > +	 * is rejected with -EACCES.
> > > +	 */
> > > +#define I915_CONTEXT_INVALIDATED 0x1
> > >   	/* All resets since boot/module reload, for all contexts */
> > >   	__u32 reset_count;
> > > @@ -2959,8 +2985,12 @@ struct drm_i915_gem_create_ext {
> > >   	 *
> > >   	 * For I915_GEM_CREATE_EXT_MEMORY_REGIONS usage see
> > >   	 * struct drm_i915_gem_create_ext_memory_regions.
> > > +	 *
> > > +	 * For I915_GEM_CREATE_EXT_PROTECTED_CONTENT usage see
> > > +	 * struct drm_i915_gem_create_ext_protected_content.
> > >   	 */
> > >   #define I915_GEM_CREATE_EXT_MEMORY_REGIONS 0
> > > +#define I915_GEM_CREATE_EXT_PROTECTED_CONTENT 1
> > >   	__u64 extensions;
> > >   };
> > > @@ -3018,6 +3048,29 @@ struct drm_i915_gem_create_ext_memory_regions {
> > >   	__u64 regions;
> > >   };
> > > +/**
> > > + * struct drm_i915_gem_create_ext_protected_content - The
> > > + * I915_OBJECT_PARAM_PROTECTED_CONTENT extension.
> > > + *
> > > + * If this extension is provided, buffer contents are expected to be protected
> > > + * by PXP encryption and require decryption for scan out and processing. This
> > > + * is only possible on platforms that have PXP enabled, on all other scenarios
> > > + * using this extension will cause the ioctl to fail and return -ENODEV. The
> > > + * flags parameter is reserved for future expansion and must currently be set
> > > + * to zero.
> > > + *
> > > + * The buffer contents are considered invalid after a PXP session teardown.
> > > + *
> > > + * The encryption is guaranteed to be processed correctly only if the object
> > > + * is submitted with a context created using the
> > > + * I915_CONTEXT_PARAM_PROTECTED_CONTENT flag. This will also enable extra checks
> > > + * at submission time on the validity of the objects involved.
> > > + */
> > > +struct drm_i915_gem_create_ext_protected_content {
> > > +	struct i915_user_extension base;
> > > +	__u32 flags;
> > > +};
> > > +
> > >   /* ID of the protected content session managed by i915 when PXP is active */
> > >   #define I915_PROTECTED_CONTENT_DEFAULT_SESSION 0xf
> > > -- 
> > > 2.32.0
> > > 
> 

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Intel-gfx] [PATCH v6 10/15] drm/i915/pxp: interfaces for using protected objects
@ 2021-07-29 20:40         ` Rodrigo Vivi
  0 siblings, 0 replies; 64+ messages in thread
From: Rodrigo Vivi @ 2021-07-29 20:40 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio
  Cc: intel-gfx, dri-devel, Chris Wilson, jason.ekstrand,
	Bommu Krishnaiah, Vetter, Daniel

On Thu, Jul 29, 2021 at 08:17:44AM -0700, Daniele Ceraolo Spurio wrote:
> 
> 
> On 7/29/2021 4:10 AM, Rodrigo Vivi wrote:
> > On Wed, Jul 28, 2021 at 07:01:01PM -0700, Daniele Ceraolo Spurio wrote:
> > > This api allow user mode to create protected buffers and to mark
> > > contexts as making use of such objects. Only when using contexts
> > > marked in such a way is the execution guaranteed to work as expected.
> > > 
> > > Contexts can only be marked as using protected content at creation time
> > > (i.e. the parameter is immutable) and they must be both bannable and not
> > > recoverable.
> > > 
> > > All protected objects and contexts that have backing storage will be
> > > considered invalid when the PXP session is destroyed and all new
> > > submissions using them will be rejected. All intel contexts within the
> > > invalidated gem contexts will be marked banned. A new flag has been
> > > added to the RESET_STATS ioctl to report the context invalidation to
> > > userspace.
> > > 
> > > This patch was previously sent as 2 separate patches, which have been
> > > squashed following a request to have all the uapi in a single patch.
> > > I've retained the s-o-b from both.
> > > 
> > > v5: squash patches, rebase on proto_ctx, update kerneldoc
> > > 
> > > v6: rebase on obj create_ext changes
> > The "rebase" word led me to think it was a small change caused
> > only by rebasing conflicts, but then I spotted something on
> > i915_gem_create.c that I didn't remember seeing before.
> 
> Apologies for not being clear.
> 
> > 
> > Since it took me a while to understand what was going on, let me
> > try to summarize to see if I got it right and to check
> > with others (Jason in special)
> > if we are aligned with the recent directions:
> > 
> > With the removal of the vanilla_object from the create_ext,
> > the addition of the flags was needed.
> 
> yes.
> 
> > 
> > Then, instead of adding a new user_flags it adds the I915_BO_PROTECTED
> > to the existent flags (what is cleaner) but then it does
> > 
> > /* Add any flag set by create_ext options */
> > flags |= ext_flags;
> > 
> > on the new user_create_ext.
> > 
> > What shouldn't be a problem because the ext_flags is really only
> > the I915_BO_PROTECTED set by our new extension and immutable.
> > 
> > But I'm just trying to see if we are not opening any holes to accept
> > some undesired flags.
> > 
> > Apparently not.
> 
> ext_flags are not set directly by the user, but by the create_ext extension
> functions, based on the extensions the user has provided. This should allow
> the kernel to perform any required checks in the extension functions before
> setting the flag (like it happens in this case for the PXP option).
> 
> > 
> > Am I getting things right? Anything else we should check in here?
> 
> yup, got it right.

Great, thanks for confirming

so I'm okay with:

Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>


> 
> Daniele
> 
> > 
> > Thanks,
> > Rodrigo.
> > 
> > > Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
> > > Signed-off-by: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
> > > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > > Cc: Chris Wilson <chris@chris-wilson.co.uk>
> > > Cc: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
> > > Cc: Jason Ekstrand <jason@jlekstrand.net>
> > > Cc: Daniel Vetter <daniel.vetter@intel.com>
> > > Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> #v5
> > > ---
> > >   drivers/gpu/drm/i915/gem/i915_gem_context.c   | 68 ++++++++++++--
> > >   drivers/gpu/drm/i915/gem/i915_gem_context.h   | 18 ++++
> > >   .../gpu/drm/i915/gem/i915_gem_context_types.h |  2 +
> > >   drivers/gpu/drm/i915/gem/i915_gem_create.c    | 75 ++++++++++++----
> > >   .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 40 ++++++++-
> > >   drivers/gpu/drm/i915/gem/i915_gem_object.c    |  6 ++
> > >   drivers/gpu/drm/i915/gem/i915_gem_object.h    | 12 +++
> > >   .../gpu/drm/i915/gem/i915_gem_object_types.h  |  9 ++
> > >   drivers/gpu/drm/i915/pxp/intel_pxp.c          | 89 +++++++++++++++++++
> > >   drivers/gpu/drm/i915/pxp/intel_pxp.h          | 15 ++++
> > >   drivers/gpu/drm/i915/pxp/intel_pxp_session.c  |  3 +
> > >   drivers/gpu/drm/i915/pxp/intel_pxp_types.h    |  5 ++
> > >   include/uapi/drm/i915_drm.h                   | 55 +++++++++++-
> > >   13 files changed, 371 insertions(+), 26 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> > > index cff72679ad7c..0cd3e2d06188 100644
> > > --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
> > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> > > @@ -77,6 +77,8 @@
> > >   #include "gt/intel_gpu_commands.h"
> > >   #include "gt/intel_ring.h"
> > > +#include "pxp/intel_pxp.h"
> > > +
> > >   #include "i915_gem_context.h"
> > >   #include "i915_trace.h"
> > >   #include "i915_user_extensions.h"
> > > @@ -241,6 +243,25 @@ static int proto_context_set_persistence(struct drm_i915_private *i915,
> > >   	return 0;
> > >   }
> > > +static int proto_context_set_protected(struct drm_i915_private *i915,
> > > +				       struct i915_gem_proto_context *pc,
> > > +				       bool protected)
> > > +{
> > > +	int ret = 0;
> > > +
> > > +	if (!intel_pxp_is_enabled(&i915->gt.pxp))
> > > +		ret = -ENODEV;
> > > +	else if (!protected)
> > > +		pc->user_flags &= ~BIT(UCONTEXT_PROTECTED);
> > > +	else if ((pc->user_flags & BIT(UCONTEXT_RECOVERABLE)) ||
> > > +		 !(pc->user_flags & BIT(UCONTEXT_BANNABLE)))
> > > +		ret = -EPERM;
> > > +	else
> > > +		pc->user_flags |= BIT(UCONTEXT_PROTECTED);
> > > +
> > > +	return ret;
> > > +}
> > > +
> > >   static struct i915_gem_proto_context *
> > >   proto_context_create(struct drm_i915_private *i915, unsigned int flags)
> > >   {
> > > @@ -686,6 +707,8 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
> > >   			ret = -EPERM;
> > >   		else if (args->value)
> > >   			pc->user_flags |= BIT(UCONTEXT_BANNABLE);
> > > +		else if (pc->user_flags & BIT(UCONTEXT_PROTECTED))
> > > +			ret = -EPERM;
> > >   		else
> > >   			pc->user_flags &= ~BIT(UCONTEXT_BANNABLE);
> > >   		break;
> > > @@ -693,10 +716,12 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
> > >   	case I915_CONTEXT_PARAM_RECOVERABLE:
> > >   		if (args->size)
> > >   			ret = -EINVAL;
> > > -		else if (args->value)
> > > -			pc->user_flags |= BIT(UCONTEXT_RECOVERABLE);
> > > -		else
> > > +		else if (!args->value)
> > >   			pc->user_flags &= ~BIT(UCONTEXT_RECOVERABLE);
> > > +		else if (pc->user_flags & BIT(UCONTEXT_PROTECTED))
> > > +			ret = -EPERM;
> > > +		else
> > > +			pc->user_flags |= BIT(UCONTEXT_RECOVERABLE);
> > >   		break;
> > >   	case I915_CONTEXT_PARAM_PRIORITY:
> > > @@ -724,6 +749,11 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
> > >   						    args->value);
> > >   		break;
> > > +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
> > > +		ret = proto_context_set_protected(fpriv->dev_priv, pc,
> > > +						  args->value);
> > > +		break;
> > > +
> > >   	case I915_CONTEXT_PARAM_NO_ZEROMAP:
> > >   	case I915_CONTEXT_PARAM_BAN_PERIOD:
> > >   	case I915_CONTEXT_PARAM_RINGSIZE:
> > > @@ -1798,6 +1828,18 @@ static int set_priority(struct i915_gem_context *ctx,
> > >   	return 0;
> > >   }
> > > +static int get_protected(struct i915_gem_context *ctx,
> > > +			 struct drm_i915_gem_context_param *args)
> > > +{
> > > +	if (!intel_pxp_is_enabled(&ctx->i915->gt.pxp))
> > > +		return -ENODEV;
> > > +
> > > +	args->size = 0;
> > > +	args->value = i915_gem_context_uses_protected_content(ctx);
> > > +
> > > +	return 0;
> > > +}
> > > +
> > >   static int ctx_setparam(struct drm_i915_file_private *fpriv,
> > >   			struct i915_gem_context *ctx,
> > >   			struct drm_i915_gem_context_param *args)
> > > @@ -1821,6 +1863,8 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
> > >   			ret = -EPERM;
> > >   		else if (args->value)
> > >   			i915_gem_context_set_bannable(ctx);
> > > +		else if (i915_gem_context_uses_protected_content(ctx))
> > > +			ret = -EPERM; /* can't clear this for protected contexts */
> > >   		else
> > >   			i915_gem_context_clear_bannable(ctx);
> > >   		break;
> > > @@ -1828,10 +1872,12 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
> > >   	case I915_CONTEXT_PARAM_RECOVERABLE:
> > >   		if (args->size)
> > >   			ret = -EINVAL;
> > > -		else if (args->value)
> > > -			i915_gem_context_set_recoverable(ctx);
> > > -		else
> > > +		else if (!args->value)
> > >   			i915_gem_context_clear_recoverable(ctx);
> > > +		else if (i915_gem_context_uses_protected_content(ctx))
> > > +			ret = -EPERM; /* can't set this for protected contexts */
> > > +		else
> > > +			i915_gem_context_set_recoverable(ctx);
> > >   		break;
> > >   	case I915_CONTEXT_PARAM_PRIORITY:
> > > @@ -1846,6 +1892,7 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
> > >   		ret = set_persistence(ctx, args);
> > >   		break;
> > > +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
> > >   	case I915_CONTEXT_PARAM_NO_ZEROMAP:
> > >   	case I915_CONTEXT_PARAM_BAN_PERIOD:
> > >   	case I915_CONTEXT_PARAM_RINGSIZE:
> > > @@ -2174,6 +2221,10 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
> > >   		args->value = i915_gem_context_is_persistent(ctx);
> > >   		break;
> > > +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
> > > +		ret = get_protected(ctx, args);
> > > +		break;
> > > +
> > >   	case I915_CONTEXT_PARAM_NO_ZEROMAP:
> > >   	case I915_CONTEXT_PARAM_BAN_PERIOD:
> > >   	case I915_CONTEXT_PARAM_ENGINES:
> > > @@ -2250,6 +2301,11 @@ int i915_gem_context_reset_stats_ioctl(struct drm_device *dev,
> > >   	args->batch_active = atomic_read(&ctx->guilty_count);
> > >   	args->batch_pending = atomic_read(&ctx->active_count);
> > > +	/* re-use args->flags for output flags */
> > > +	args->flags = 0;
> > > +	if (i915_gem_context_invalidated(ctx))
> > > +		args->flags |= I915_CONTEXT_INVALIDATED;
> > > +
> > >   	i915_gem_context_put(ctx);
> > >   	return 0;
> > >   }
> > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.h b/drivers/gpu/drm/i915/gem/i915_gem_context.h
> > > index 18060536b0c2..d932a70122fa 100644
> > > --- a/drivers/gpu/drm/i915/gem/i915_gem_context.h
> > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.h
> > > @@ -108,6 +108,24 @@ i915_gem_context_clear_user_engines(struct i915_gem_context *ctx)
> > >   	clear_bit(CONTEXT_USER_ENGINES, &ctx->flags);
> > >   }
> > > +static inline bool
> > > +i915_gem_context_invalidated(const struct i915_gem_context *ctx)
> > > +{
> > > +	return test_bit(CONTEXT_INVALID, &ctx->flags);
> > > +}
> > > +
> > > +static inline void
> > > +i915_gem_context_set_invalid(struct i915_gem_context *ctx)
> > > +{
> > > +	set_bit(CONTEXT_INVALID, &ctx->flags);
> > > +}
> > > +
> > > +static inline bool
> > > +i915_gem_context_uses_protected_content(const struct i915_gem_context *ctx)
> > > +{
> > > +	return test_bit(UCONTEXT_PROTECTED, &ctx->user_flags);
> > > +}
> > > +
> > >   /* i915_gem_context.c */
> > >   void i915_gem_init__contexts(struct drm_i915_private *i915);
> > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
> > > index 94c03a97cb77..1aa2290aa3c7 100644
> > > --- a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
> > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
> > > @@ -301,6 +301,7 @@ struct i915_gem_context {
> > >   #define UCONTEXT_BANNABLE		2
> > >   #define UCONTEXT_RECOVERABLE		3
> > >   #define UCONTEXT_PERSISTENCE		4
> > > +#define UCONTEXT_PROTECTED		5
> > >   	/**
> > >   	 * @flags: small set of booleans
> > > @@ -308,6 +309,7 @@ struct i915_gem_context {
> > >   	unsigned long flags;
> > >   #define CONTEXT_CLOSED			0
> > >   #define CONTEXT_USER_ENGINES		1
> > > +#define CONTEXT_INVALID			2
> > >   	/** @mutex: guards everything that isn't engines or handles_vma */
> > >   	struct mutex mutex;
> > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c b/drivers/gpu/drm/i915/gem/i915_gem_create.c
> > > index 23fee13a3384..0e48629316bb 100644
> > > --- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
> > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
> > > @@ -6,6 +6,7 @@
> > >   #include "gem/i915_gem_ioctls.h"
> > >   #include "gem/i915_gem_lmem.h"
> > >   #include "gem/i915_gem_region.h"
> > > +#include "pxp/intel_pxp.h"
> > >   #include "i915_drv.h"
> > >   #include "i915_trace.h"
> > > @@ -82,21 +83,11 @@ static int i915_gem_publish(struct drm_i915_gem_object *obj,
> > >   	return 0;
> > >   }
> > > -/**
> > > - * Creates a new object using the same path as DRM_I915_GEM_CREATE_EXT
> > > - * @i915: i915 private
> > > - * @size: size of the buffer, in bytes
> > > - * @placements: possible placement regions, in priority order
> > > - * @n_placements: number of possible placement regions
> > > - *
> > > - * This function is exposed primarily for selftests and does very little
> > > - * error checking.  It is assumed that the set of placement regions has
> > > - * already been verified to be valid.
> > > - */
> > > -struct drm_i915_gem_object *
> > > -__i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
> > > -			      struct intel_memory_region **placements,
> > > -			      unsigned int n_placements)
> > > +static struct drm_i915_gem_object *
> > > +__i915_gem_object_create_user_ext(struct drm_i915_private *i915, u64 size,
> > > +				  struct intel_memory_region **placements,
> > > +				  unsigned int n_placements,
> > > +				  unsigned int ext_flags)
> > >   {
> > >   	struct intel_memory_region *mr = placements[0];
> > >   	struct drm_i915_gem_object *obj;
> > > @@ -135,6 +126,12 @@ __i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
> > >   	GEM_BUG_ON(size != obj->base.size);
> > > +	/* Add any flag set by create_ext options */
> > > +	flags |= ext_flags;
> > > +
> > > +	if (i915_gem_object_is_protected(obj))
> > > +		intel_pxp_object_add(obj);
> > > +
> > >   	trace_i915_gem_object_create(obj);
> > >   	return obj;
> > > @@ -145,6 +142,26 @@ __i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
> > >   	return ERR_PTR(ret);
> > >   }
> > > +/**
> > > + * Creates a new object using the same path as DRM_I915_GEM_CREATE_EXT
> > > + * @i915: i915 private
> > > + * @size: size of the buffer, in bytes
> > > + * @placements: possible placement regions, in priority order
> > > + * @n_placements: number of possible placement regions
> > > + *
> > > + * This function is exposed primarily for selftests and does very little
> > > + * error checking.  It is assumed that the set of placement regions has
> > > + * already been verified to be valid.
> > > + */
> > > +struct drm_i915_gem_object *
> > > +__i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
> > > +			      struct intel_memory_region **placements,
> > > +			      unsigned int n_placements)
> > > +{
> > > +	return __i915_gem_object_create_user_ext(i915, size, placements,
> > > +						 n_placements, 0);
> > > +}
> > > +
> > >   int
> > >   i915_gem_dumb_create(struct drm_file *file,
> > >   		     struct drm_device *dev,
> > > @@ -224,6 +241,7 @@ struct create_ext {
> > >   	struct drm_i915_private *i915;
> > >   	struct intel_memory_region *placements[INTEL_REGION_UNKNOWN];
> > >   	unsigned int n_placements;
> > > +	unsigned long flags;
> > >   };
> > >   static void repr_placements(char *buf, size_t size,
> > > @@ -356,8 +374,28 @@ static int ext_set_placements(struct i915_user_extension __user *base,
> > >   	return set_placements(&ext, data);
> > >   }
> > > +static int ext_set_protected(struct i915_user_extension __user *base, void *data)
> > > +{
> > > +	struct drm_i915_gem_create_ext_protected_content ext;
> > > +	struct create_ext *ext_data = data;
> > > +
> > > +	if (copy_from_user(&ext, base, sizeof(ext)))
> > > +		return -EFAULT;
> > > +
> > > +	if (ext.flags)
> > > +		return -EINVAL;
> > > +
> > > +	if (!intel_pxp_is_enabled(&ext_data->i915->gt.pxp))
> > > +		return -ENODEV;
> > > +
> > > +	ext_data->flags |= I915_BO_PROTECTED;
> > > +
> > > +	return 0;
> > > +}
> > > +
> > >   static const i915_user_extension_fn create_extensions[] = {
> > >   	[I915_GEM_CREATE_EXT_MEMORY_REGIONS] = ext_set_placements,
> > > +	[I915_GEM_CREATE_EXT_PROTECTED_CONTENT] = ext_set_protected,
> > >   };
> > >   /**
> > > @@ -392,9 +430,10 @@ i915_gem_create_ext_ioctl(struct drm_device *dev, void *data,
> > >   		ext_data.n_placements = 1;
> > >   	}
> > > -	obj = __i915_gem_object_create_user(i915, args->size,
> > > -					    ext_data.placements,
> > > -					    ext_data.n_placements);
> > > +	obj = __i915_gem_object_create_user_ext(i915, args->size,
> > > +						ext_data.placements,
> > > +						ext_data.n_placements,
> > > +						ext_data.flags);
> > >   	if (IS_ERR(obj))
> > >   		return PTR_ERR(obj);
> > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> > > index 1ed7475de454..04f33d163340 100644
> > > --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> > > @@ -21,6 +21,8 @@
> > >   #include "gt/intel_gt_pm.h"
> > >   #include "gt/intel_ring.h"
> > > +#include "pxp/intel_pxp.h"
> > > +
> > >   #include "i915_drv.h"
> > >   #include "i915_gem_clflush.h"
> > >   #include "i915_gem_context.h"
> > > @@ -751,6 +753,11 @@ static int eb_select_context(struct i915_execbuffer *eb)
> > >   	if (unlikely(IS_ERR(ctx)))
> > >   		return PTR_ERR(ctx);
> > > +	if (i915_gem_context_invalidated(ctx)) {
> > > +		i915_gem_context_put(ctx);
> > > +		return -EACCES;
> > > +	}
> > > +
> > >   	eb->gem_context = ctx;
> > >   	if (rcu_access_pointer(ctx->vm))
> > >   		eb->invalid_flags |= EXEC_OBJECT_NEEDS_GTT;
> > > @@ -819,7 +826,7 @@ static struct i915_vma *eb_lookup_vma(struct i915_execbuffer *eb, u32 handle)
> > >   	do {
> > >   		struct drm_i915_gem_object *obj;
> > >   		struct i915_vma *vma;
> > > -		int err;
> > > +		int err = 0;
> > >   		rcu_read_lock();
> > >   		vma = radix_tree_lookup(&eb->gem_context->handles_vma, handle);
> > > @@ -833,6 +840,26 @@ static struct i915_vma *eb_lookup_vma(struct i915_execbuffer *eb, u32 handle)
> > >   		if (unlikely(!obj))
> > >   			return ERR_PTR(-ENOENT);
> > > +		/*
> > > +		 * If the user has opted-in for protected-object tracking, make
> > > +		 * sure the object encryption can be used.
> > > +		 * We only need to do this when the object is first used with
> > > +		 * this context, because the context itself will be banned when
> > > +		 * the protected objects become invalid.
> > > +		 */
> > > +		if (i915_gem_context_uses_protected_content(eb->gem_context) &&
> > > +		    i915_gem_object_is_protected(obj)) {
> > > +			if (!intel_pxp_is_active(&vm->gt->pxp))
> > > +				err = -ENODEV;
> > > +			else if (!i915_gem_object_has_valid_protection(obj))
> > > +				err = -ENOEXEC;
> > > +
> > > +			if (err) {
> > > +				i915_gem_object_put(obj);
> > > +				return ERR_PTR(err);
> > > +			}
> > > +		}
> > > +
> > >   		vma = i915_vma_instance(obj, vm, NULL);
> > >   		if (IS_ERR(vma)) {
> > >   			i915_gem_object_put(obj);
> > > @@ -2752,6 +2779,17 @@ eb_select_engine(struct i915_execbuffer *eb)
> > >   	intel_gt_pm_get(ce->engine->gt);
> > > +	if (i915_gem_context_uses_protected_content(eb->gem_context)) {
> > > +		err = intel_pxp_wait_for_arb_start(&ce->engine->gt->pxp);
> > > +		if (err)
> > > +			goto err;
> > > +
> > > +		if (i915_gem_context_invalidated(eb->gem_context)) {
> > > +			err = -EACCES;
> > > +			goto err;
> > > +		}
> > > +	}
> > > +
> > >   	if (!test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
> > >   		err = intel_context_alloc_state(ce);
> > >   		if (err)
> > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c
> > > index 6fb9afb65034..658a42a7fa07 100644
> > > --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
> > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
> > > @@ -25,6 +25,7 @@
> > >   #include <linux/sched/mm.h>
> > >   #include "display/intel_frontbuffer.h"
> > > +#include "pxp/intel_pxp.h"
> > >   #include "i915_drv.h"
> > >   #include "i915_gem_clflush.h"
> > >   #include "i915_gem_context.h"
> > > @@ -73,6 +74,8 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj,
> > >   	INIT_LIST_HEAD(&obj->lut_list);
> > >   	spin_lock_init(&obj->lut_lock);
> > > +	INIT_LIST_HEAD(&obj->pxp_link);
> > > +
> > >   	spin_lock_init(&obj->mmo.lock);
> > >   	obj->mmo.offsets = RB_ROOT;
> > > @@ -231,6 +234,9 @@ void __i915_gem_free_object(struct drm_i915_gem_object *obj)
> > >   		spin_unlock(&obj->vma.lock);
> > >   	}
> > > +	if (i915_gem_object_has_valid_protection(obj))
> > > +		intel_pxp_object_remove(obj);
> > > +
> > >   	__i915_gem_object_free_mmaps(obj);
> > >   	GEM_BUG_ON(!list_empty(&obj->lut_list));
> > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h
> > > index 48112b9d76df..137ae2723514 100644
> > > --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
> > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
> > > @@ -269,6 +269,18 @@ i915_gem_object_clear_tiling_quirk(struct drm_i915_gem_object *obj)
> > >   	clear_bit(I915_TILING_QUIRK_BIT, &obj->flags);
> > >   }
> > > +static inline bool
> > > +i915_gem_object_is_protected(const struct drm_i915_gem_object *obj)
> > > +{
> > > +	return obj->flags & I915_BO_PROTECTED;
> > > +}
> > > +
> > > +static inline bool
> > > +i915_gem_object_has_valid_protection(const struct drm_i915_gem_object *obj)
> > > +{
> > > +	return i915_gem_object_is_protected(obj) && !list_empty(&obj->pxp_link);
> > > +}
> > > +
> > >   static inline bool
> > >   i915_gem_object_type_has(const struct drm_i915_gem_object *obj,
> > >   			 unsigned long flags)
> > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> > > index 2471f36aaff3..38e4a190607a 100644
> > > --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> > > @@ -298,6 +298,7 @@ struct drm_i915_gem_object {
> > >   			     I915_BO_ALLOC_USER)
> > >   #define I915_BO_READONLY         BIT(4)
> > >   #define I915_TILING_QUIRK_BIT    5 /* unknown swizzling; do not release! */
> > > +#define I915_BO_PROTECTED        BIT(6)
> > >   	/**
> > >   	 * @mem_flags - Mutable placement-related flags
> > > @@ -537,6 +538,14 @@ struct drm_i915_gem_object {
> > >   		bool created:1;
> > >   	} ttm;
> > > +	/*
> > > +	 * When the PXP session is invalidated, we need to mark all protected
> > > +	 * objects as invalid. To easily do so we add them all to a list. The
> > > +	 * presence on the list is used to check if the encryption is valid or
> > > +	 * not.
> > > +	 */
> > > +	struct list_head pxp_link;
> > > +
> > >   	/** Record of address bit 17 of each page at last unbind. */
> > >   	unsigned long *bit_17;
> > > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
> > > index b0c7edc10cc3..f418281e8c10 100644
> > > --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
> > > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
> > > @@ -7,6 +7,7 @@
> > >   #include "intel_pxp_irq.h"
> > >   #include "intel_pxp_session.h"
> > >   #include "intel_pxp_tee.h"
> > > +#include "gem/i915_gem_context.h"
> > >   #include "gt/intel_context.h"
> > >   #include "i915_drv.h"
> > > @@ -70,6 +71,9 @@ void intel_pxp_init(struct intel_pxp *pxp)
> > >   	mutex_init(&pxp->tee_mutex);
> > > +	spin_lock_init(&pxp->lock);
> > > +	INIT_LIST_HEAD(&pxp->protected_objects);
> > > +
> > >   	/*
> > >   	 * we'll use the completion to check if there is a termination pending,
> > >   	 * so we start it as completed and we reinit it when a termination
> > > @@ -166,3 +170,88 @@ void intel_pxp_fini_hw(struct intel_pxp *pxp)
> > >   	intel_pxp_irq_disable(pxp);
> > >   }
> > > +
> > > +int intel_pxp_object_add(struct drm_i915_gem_object *obj)
> > > +{
> > > +	struct intel_pxp *pxp = &to_i915(obj->base.dev)->gt.pxp;
> > > +
> > > +	if (!intel_pxp_is_enabled(pxp))
> > > +		return -ENODEV;
> > > +
> > > +	if (!list_empty(&obj->pxp_link))
> > > +		return -EEXIST;
> > > +
> > > +	spin_lock_irq(&pxp->lock);
> > > +	list_add(&obj->pxp_link, &pxp->protected_objects);
> > > +	spin_unlock_irq(&pxp->lock);
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +void intel_pxp_object_remove(struct drm_i915_gem_object *obj)
> > > +{
> > > +	struct intel_pxp *pxp = &to_i915(obj->base.dev)->gt.pxp;
> > > +
> > > +	if (!intel_pxp_is_enabled(pxp))
> > > +		return;
> > > +
> > > +	spin_lock_irq(&pxp->lock);
> > > +	list_del_init(&obj->pxp_link);
> > > +	spin_unlock_irq(&pxp->lock);
> > > +}
> > > +
> > > +void intel_pxp_invalidate(struct intel_pxp *pxp)
> > > +{
> > > +	struct drm_i915_private *i915 = pxp_to_gt(pxp)->i915;
> > > +	struct drm_i915_gem_object *obj, *tmp;
> > > +	struct i915_gem_context *ctx, *cn;
> > > +
> > > +	/* delete objects that have been used with the invalidated session */
> > > +	spin_lock_irq(&pxp->lock);
> > > +	list_for_each_entry_safe(obj, tmp, &pxp->protected_objects, pxp_link) {
> > > +		if (i915_gem_object_has_pages(obj))
> > > +			list_del_init(&obj->pxp_link);
> > > +	}
> > > +	spin_unlock_irq(&pxp->lock);
> > > +
> > > +	/* 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) {
> > > +		struct i915_gem_engines_iter it;
> > > +		struct intel_context *ce;
> > > +
> > > +		if (!kref_get_unless_zero(&ctx->ref))
> > > +			continue;
> > > +
> > > +		if (likely(!i915_gem_context_uses_protected_content(ctx)) ||
> > > +		    i915_gem_context_invalidated(ctx)) {
> > > +			i915_gem_context_put(ctx);
> > > +			continue;
> > > +		}
> > > +
> > > +		spin_unlock_irq(&i915->gem.contexts.lock);
> > > +
> > > +		/*
> > > +		 * Note that by the time we get here the HW keys are already
> > > +		 * long gone, so any batch using them that's already on the
> > > +		 * engines is very likely a lost cause (and it has probably
> > > +		 * already hung the engine). Therefore, we skip attempting to
> > > +		 * pull the running context out of the HW and we prioritize
> > > +		 * bringing the session back as soon as possible.
> > > +		 */
> > > +		for_each_gem_engine(ce, i915_gem_context_lock_engines(ctx), it) {
> > > +			/* only invalidate if at least one ce was allocated */
> > > +			if (test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
> > > +				intel_context_set_banned(ce);
> > > +				i915_gem_context_set_invalid(ctx);
> > > +			}
> > > +		}
> > > +		i915_gem_context_unlock_engines(ctx);
> > > +
> > > +		spin_lock_irq(&i915->gem.contexts.lock);
> > > +		list_safe_reset_next(ctx, cn, link);
> > > +		i915_gem_context_put(ctx);
> > > +	}
> > > +	spin_unlock_irq(&i915->gem.contexts.lock);
> > > +}
> > > +
> > > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
> > > index 074b3b980957..4f7647f34153 100644
> > > --- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
> > > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
> > > @@ -9,6 +9,8 @@
> > >   #include "gt/intel_gt_types.h"
> > >   #include "intel_pxp_types.h"
> > > +struct drm_i915_gem_object;
> > > +
> > >   static inline struct intel_gt *pxp_to_gt(const struct intel_pxp *pxp)
> > >   {
> > >   	return container_of(pxp, struct intel_gt, pxp);
> > > @@ -33,6 +35,11 @@ void intel_pxp_fini_hw(struct intel_pxp *pxp);
> > >   void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp);
> > >   int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp);
> > > +
> > > +int intel_pxp_object_add(struct drm_i915_gem_object *obj);
> > > +void intel_pxp_object_remove(struct drm_i915_gem_object *obj);
> > > +
> > > +void intel_pxp_invalidate(struct intel_pxp *pxp);
> > >   #else
> > >   static inline void intel_pxp_init(struct intel_pxp *pxp)
> > >   {
> > > @@ -46,6 +53,14 @@ static inline int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp)
> > >   {
> > >   	return 0;
> > >   }
> > > +
> > > +static inline int intel_pxp_object_add(struct drm_i915_gem_object *obj)
> > > +{
> > > +	return 0;
> > > +}
> > > +static inline void intel_pxp_object_remove(struct drm_i915_gem_object *obj)
> > > +{
> > > +}
> > >   #endif
> > >   #endif /* __INTEL_PXP_H__ */
> > > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> > > index 67c30e534d50..0edd563a653d 100644
> > > --- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> > > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> > > @@ -85,6 +85,9 @@ static int pxp_terminate_arb_session_and_global(struct intel_pxp *pxp)
> > >   	/* must mark termination in progress calling this function */
> > >   	GEM_WARN_ON(pxp->arb_is_valid);
> > > +	/* invalidate protected objects */
> > > +	intel_pxp_invalidate(pxp);
> > > +
> > >   	/* terminate the hw sessions */
> > >   	ret = intel_pxp_terminate_session(pxp, ARB_SESSION);
> > >   	if (ret) {
> > > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
> > > index 475e3312c287..be2bed3a2e4e 100644
> > > --- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
> > > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
> > > @@ -7,7 +7,9 @@
> > >   #define __INTEL_PXP_TYPES_H__
> > >   #include <linux/completion.h>
> > > +#include <linux/list.h>
> > >   #include <linux/mutex.h>
> > > +#include <linux/spinlock.h>
> > >   #include <linux/types.h>
> > >   #include <linux/workqueue.h>
> > > @@ -43,6 +45,9 @@ struct intel_pxp {
> > >   	u32 session_events; /* protected with gt->irq_lock */
> > >   #define PXP_TERMINATION_REQUEST  BIT(0)
> > >   #define PXP_TERMINATION_COMPLETE BIT(1)
> > > +
> > > +	spinlock_t lock; /* protects the objects list */
> > > +	struct list_head protected_objects;
> > >   };
> > >   #endif /* __INTEL_PXP_TYPES_H__ */
> > > diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
> > > index 4393eef59d9b..2c9febdae6a5 100644
> > > --- a/include/uapi/drm/i915_drm.h
> > > +++ b/include/uapi/drm/i915_drm.h
> > > @@ -1843,12 +1843,32 @@ struct drm_i915_gem_context_param {
> > >    * attempted to use it, never re-use this context param number.
> > >    */
> > >   #define I915_CONTEXT_PARAM_RINGSIZE	0xc
> > > +
> > > +/*
> > > + * I915_CONTEXT_PARAM_PROTECTED_CONTENT:
> > > + *
> > > + * Mark that the context makes use of protected content, which will result
> > > + * in the context being invalidated when the protected content session is. The
> > > + * invalidation is reported back to userspace via the RESET_STATS ioctl (see
> > > + * relevant doc for details).
> > > + * This flag can only be set at context creation time and, when set to true,
> > > + * must be preceded by an explicit setting of I915_CONTEXT_PARAM_RECOVERABLE
> > > + * to false. This flag can't be set to true in conjunction with setting the
> > > + * I915_CONTEXT_PARAM_BANNABLE flag to false.
> > > + *
> > > + * In addition to the normal failure cases, setting this flag during context
> > > + * creation can result in the following errors:
> > > + *
> > > + * -ENODEV: feature not available
> > > + * -EPERM: trying to mark a recoverable or not bannable context as protected
> > > + */
> > > +#define I915_CONTEXT_PARAM_PROTECTED_CONTENT    0xd
> > >   /* Must be kept compact -- no holes and well documented */
> > >   	__u64 value;
> > >   };
> > > -/*
> > > +/**
> > >    * Context SSEU programming
> > >    *
> > >    * It may be necessary for either functional or performance reason to configure
> > > @@ -2181,6 +2201,12 @@ struct drm_i915_reg_read {
> > >   struct drm_i915_reset_stats {
> > >   	__u32 ctx_id;
> > >   	__u32 flags;
> > > +	/*
> > > +	 * contexts marked as using protected content are invalidated when the
> > > +	 * protected content session dies. Submission of invalidated contexts
> > > +	 * is rejected with -EACCES.
> > > +	 */
> > > +#define I915_CONTEXT_INVALIDATED 0x1
> > >   	/* All resets since boot/module reload, for all contexts */
> > >   	__u32 reset_count;
> > > @@ -2959,8 +2985,12 @@ struct drm_i915_gem_create_ext {
> > >   	 *
> > >   	 * For I915_GEM_CREATE_EXT_MEMORY_REGIONS usage see
> > >   	 * struct drm_i915_gem_create_ext_memory_regions.
> > > +	 *
> > > +	 * For I915_GEM_CREATE_EXT_PROTECTED_CONTENT usage see
> > > +	 * struct drm_i915_gem_create_ext_protected_content.
> > >   	 */
> > >   #define I915_GEM_CREATE_EXT_MEMORY_REGIONS 0
> > > +#define I915_GEM_CREATE_EXT_PROTECTED_CONTENT 1
> > >   	__u64 extensions;
> > >   };
> > > @@ -3018,6 +3048,29 @@ struct drm_i915_gem_create_ext_memory_regions {
> > >   	__u64 regions;
> > >   };
> > > +/**
> > > + * struct drm_i915_gem_create_ext_protected_content - The
> > > + * I915_OBJECT_PARAM_PROTECTED_CONTENT extension.
> > > + *
> > > + * If this extension is provided, buffer contents are expected to be protected
> > > + * by PXP encryption and require decryption for scan out and processing. This
> > > + * is only possible on platforms that have PXP enabled, on all other scenarios
> > > + * using this extension will cause the ioctl to fail and return -ENODEV. The
> > > + * flags parameter is reserved for future expansion and must currently be set
> > > + * to zero.
> > > + *
> > > + * The buffer contents are considered invalid after a PXP session teardown.
> > > + *
> > > + * The encryption is guaranteed to be processed correctly only if the object
> > > + * is submitted with a context created using the
> > > + * I915_CONTEXT_PARAM_PROTECTED_CONTENT flag. This will also enable extra checks
> > > + * at submission time on the validity of the objects involved.
> > > + */
> > > +struct drm_i915_gem_create_ext_protected_content {
> > > +	struct i915_user_extension base;
> > > +	__u32 flags;
> > > +};
> > > +
> > >   /* ID of the protected content session managed by i915 when PXP is active */
> > >   #define I915_PROTECTED_CONTENT_DEFAULT_SESSION 0xf
> > > -- 
> > > 2.32.0
> > > 
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [PATCH v6 02/15] mei: pxp: export pavp client to me client bus
  2021-07-29  2:00   ` [Intel-gfx] " Daniele Ceraolo Spurio
@ 2021-07-29 20:45     ` Rodrigo Vivi
  -1 siblings, 0 replies; 64+ messages in thread
From: Rodrigo Vivi @ 2021-07-29 20:45 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio; +Cc: intel-gfx, Tomas Winkler, dri-devel, Vitaly Lubart

On Wed, Jul 28, 2021 at 07:00:53PM -0700, Daniele Ceraolo Spurio wrote:
> From: Vitaly Lubart <vitaly.lubart@intel.com>
> 
> Export PAVP client to work with i915 driver,
> for binding it uses kernel component framework.
> 
> v2:drop debug prints, refactor match code to match mei_hdcp (Tomas)
> 
> Signed-off-by: Vitaly Lubart <vitaly.lubart@intel.com>
> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> #v1

shouldn't we use the 2020-2021 in the other headers as well?

anyway, rv-b remains

> ---
>  drivers/misc/mei/Kconfig       |   2 +
>  drivers/misc/mei/Makefile      |   1 +
>  drivers/misc/mei/pxp/Kconfig   |  13 ++
>  drivers/misc/mei/pxp/Makefile  |   7 +
>  drivers/misc/mei/pxp/mei_pxp.c | 229 +++++++++++++++++++++++++++++++++
>  drivers/misc/mei/pxp/mei_pxp.h |  18 +++
>  6 files changed, 270 insertions(+)
>  create mode 100644 drivers/misc/mei/pxp/Kconfig
>  create mode 100644 drivers/misc/mei/pxp/Makefile
>  create mode 100644 drivers/misc/mei/pxp/mei_pxp.c
>  create mode 100644 drivers/misc/mei/pxp/mei_pxp.h
> 
> diff --git a/drivers/misc/mei/Kconfig b/drivers/misc/mei/Kconfig
> index f5fd5b786607..0e0bcd0da852 100644
> --- a/drivers/misc/mei/Kconfig
> +++ b/drivers/misc/mei/Kconfig
> @@ -47,3 +47,5 @@ config INTEL_MEI_TXE
>  	  Intel Bay Trail
>  
>  source "drivers/misc/mei/hdcp/Kconfig"
> +source "drivers/misc/mei/pxp/Kconfig"
> +
> diff --git a/drivers/misc/mei/Makefile b/drivers/misc/mei/Makefile
> index f1c76f7ee804..d8e5165917f2 100644
> --- a/drivers/misc/mei/Makefile
> +++ b/drivers/misc/mei/Makefile
> @@ -26,3 +26,4 @@ mei-$(CONFIG_EVENT_TRACING) += mei-trace.o
>  CFLAGS_mei-trace.o = -I$(src)
>  
>  obj-$(CONFIG_INTEL_MEI_HDCP) += hdcp/
> +obj-$(CONFIG_INTEL_MEI_PXP) += pxp/
> diff --git a/drivers/misc/mei/pxp/Kconfig b/drivers/misc/mei/pxp/Kconfig
> new file mode 100644
> index 000000000000..4029b96afc04
> --- /dev/null
> +++ b/drivers/misc/mei/pxp/Kconfig
> @@ -0,0 +1,13 @@
> +
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (c) 2020, Intel Corporation. All rights reserved.
> +#
> +config INTEL_MEI_PXP
> +	tristate "Intel PXP services of ME Interface"
> +	select INTEL_MEI_ME
> +	depends on DRM_I915
> +	help
> +	  MEI Support for PXP Services on Intel platforms.
> +
> +	  Enables the ME FW services required for PXP support through
> +	  I915 display driver of Intel.
> diff --git a/drivers/misc/mei/pxp/Makefile b/drivers/misc/mei/pxp/Makefile
> new file mode 100644
> index 000000000000..0329950d5794
> --- /dev/null
> +++ b/drivers/misc/mei/pxp/Makefile
> @@ -0,0 +1,7 @@
> +# SPDX-License-Identifier: GPL-2.0
> +#
> +# Copyright (c) 2020, Intel Corporation. All rights reserved.
> +#
> +# Makefile - PXP client driver for Intel MEI Bus Driver.
> +
> +obj-$(CONFIG_INTEL_MEI_PXP) += mei_pxp.o
> diff --git a/drivers/misc/mei/pxp/mei_pxp.c b/drivers/misc/mei/pxp/mei_pxp.c
> new file mode 100644
> index 000000000000..f7380d387bab
> --- /dev/null
> +++ b/drivers/misc/mei/pxp/mei_pxp.c
> @@ -0,0 +1,229 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright © 2020 - 2021 Intel Corporation
> + */
> +
> +/**
> + * DOC: MEI_PXP Client Driver
> + *
> + * The mei_pxp driver acts as a translation layer between PXP
> + * protocol  implementer (I915) and ME FW by translating PXP
> + * negotiation messages to ME FW command payloads and vice versa.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/slab.h>
> +#include <linux/uuid.h>
> +#include <linux/mei_cl_bus.h>
> +#include <linux/component.h>
> +#include <drm/drm_connector.h>
> +#include <drm/i915_component.h>
> +#include <drm/i915_pxp_tee_interface.h>
> +
> +#include "mei_pxp.h"
> +
> +/**
> + * mei_pxp_send_message() - Sends a PXP message to ME FW.
> + * @dev: device corresponding to the mei_cl_device
> + * @message: a message buffer to send
> + * @size: size of the message
> + * Return: 0 on Success, <0 on Failure
> + */
> +static int
> +mei_pxp_send_message(struct device *dev, const void *message, size_t size)
> +{
> +	struct mei_cl_device *cldev;
> +	ssize_t byte;
> +
> +	if (!dev || !message)
> +		return -EINVAL;
> +
> +	cldev = to_mei_cl_device(dev);
> +
> +	/* temporary drop const qualifier till the API is fixed */
> +	byte = mei_cldev_send(cldev, (u8 *)message, size);
> +	if (byte < 0) {
> +		dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte);
> +		return byte;
> +	}
> +
> +	return 0;
> +}
> +
> +/**
> + * mei_pxp_receive_message() - Receives a PXP message from ME FW.
> + * @dev: device corresponding to the mei_cl_device
> + * @buffer: a message buffer to contain the received message
> + * @size: size of the buffer
> + * Return: bytes sent on Success, <0 on Failure
> + */
> +static int
> +mei_pxp_receive_message(struct device *dev, void *buffer, size_t size)
> +{
> +	struct mei_cl_device *cldev;
> +	ssize_t byte;
> +
> +	if (!dev || !buffer)
> +		return -EINVAL;
> +
> +	cldev = to_mei_cl_device(dev);
> +
> +	byte = mei_cldev_recv(cldev, buffer, size);
> +	if (byte < 0) {
> +		dev_dbg(dev, "mei_cldev_recv failed. %zd\n", byte);
> +		return byte;
> +	}
> +
> +	return byte;
> +}
> +
> +static const struct i915_pxp_component_ops mei_pxp_ops = {
> +	.owner = THIS_MODULE,
> +	.send = mei_pxp_send_message,
> +	.recv = mei_pxp_receive_message,
> +};
> +
> +static int mei_component_master_bind(struct device *dev)
> +{
> +	struct mei_cl_device *cldev = to_mei_cl_device(dev);
> +	struct i915_pxp_component *comp_master = mei_cldev_get_drvdata(cldev);
> +	int ret;
> +
> +	comp_master->ops = &mei_pxp_ops;
> +	comp_master->tee_dev = dev;
> +	ret = component_bind_all(dev, comp_master);
> +	if (ret < 0)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +static void mei_component_master_unbind(struct device *dev)
> +{
> +	struct mei_cl_device *cldev = to_mei_cl_device(dev);
> +	struct i915_pxp_component *comp_master = mei_cldev_get_drvdata(cldev);
> +
> +	component_unbind_all(dev, comp_master);
> +}
> +
> +static const struct component_master_ops mei_component_master_ops = {
> +	.bind = mei_component_master_bind,
> +	.unbind = mei_component_master_unbind,
> +};
> +
> +/**
> + * mei_pxp_component_match - compare function for matching mei pxp.
> + *
> + *    The function checks if the driver is i915, the subcomponent is PXP
> + *    and the grand parent of pxp and the parent of i915 are the same
> + *    PCH device.
> + *
> + * @dev: master device
> + * @subcomponent: subcomponent to match (I915_COMPONENT_PXP)
> + * @data: compare data (mei pxp device)
> + *
> + * Return:
> + * * 1 - if components match
> + * * 0 - otherwise
> + */
> +static int mei_pxp_component_match(struct device *dev, int subcomponent,
> +				   void *data)
> +{
> +	struct device *base = data;
> +
> +	if (strcmp(dev->driver->name, "i915") ||
> +	    subcomponent != I915_COMPONENT_PXP)
> +		return 0;
> +
> +	base = base->parent;
> +	if (!base)
> +		return 0;
> +
> +	base = base->parent;
> +	dev = dev->parent;
> +
> +	return (base && dev && dev == base);
> +}
> +
> +static int mei_pxp_probe(struct mei_cl_device *cldev,
> +			 const struct mei_cl_device_id *id)
> +{
> +	struct i915_pxp_component *comp_master;
> +	struct component_match *master_match;
> +	int ret;
> +
> +	ret = mei_cldev_enable(cldev);
> +	if (ret < 0) {
> +		dev_err(&cldev->dev, "mei_cldev_enable Failed. %d\n", ret);
> +		goto enable_err_exit;
> +	}
> +
> +	comp_master = kzalloc(sizeof(*comp_master), GFP_KERNEL);
> +	if (!comp_master) {
> +		ret = -ENOMEM;
> +		goto err_exit;
> +	}
> +
> +	master_match = NULL;
> +	component_match_add_typed(&cldev->dev, &master_match,
> +				  mei_pxp_component_match, &cldev->dev);
> +	if (IS_ERR_OR_NULL(master_match)) {
> +		ret = -ENOMEM;
> +		goto err_exit;
> +	}
> +
> +	mei_cldev_set_drvdata(cldev, comp_master);
> +	ret = component_master_add_with_match(&cldev->dev,
> +					      &mei_component_master_ops,
> +					      master_match);
> +	if (ret < 0) {
> +		dev_err(&cldev->dev, "Master comp add failed %d\n", ret);
> +		goto err_exit;
> +	}
> +
> +	return 0;
> +
> +err_exit:
> +	mei_cldev_set_drvdata(cldev, NULL);
> +	kfree(comp_master);
> +	mei_cldev_disable(cldev);
> +enable_err_exit:
> +	return ret;
> +}
> +
> +static void mei_pxp_remove(struct mei_cl_device *cldev)
> +{
> +	struct i915_pxp_component *comp_master = mei_cldev_get_drvdata(cldev);
> +	int ret;
> +
> +	component_master_del(&cldev->dev, &mei_component_master_ops);
> +	kfree(comp_master);
> +	mei_cldev_set_drvdata(cldev, NULL);
> +
> +	ret = mei_cldev_disable(cldev);
> +	if (ret)
> +		dev_warn(&cldev->dev, "mei_cldev_disable() failed\n");
> +}
> +
> +/* fbf6fcf1-96cf-4e2e-a6a6-1bab8cbe36b1 : PAVP GUID*/
> +#define MEI_GUID_PXP GUID_INIT(0xfbf6fcf1, 0x96cf, 0x4e2e, 0xA6, \
> +			       0xa6, 0x1b, 0xab, 0x8c, 0xbe, 0x36, 0xb1)
> +
> +static struct mei_cl_device_id mei_pxp_tbl[] = {
> +	{ .uuid = MEI_GUID_PXP, .version = MEI_CL_VERSION_ANY },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(mei, mei_pxp_tbl);
> +
> +static struct mei_cl_driver mei_pxp_driver = {
> +	.id_table = mei_pxp_tbl,
> +	.name = KBUILD_MODNAME,
> +	.probe = mei_pxp_probe,
> +	.remove	= mei_pxp_remove,
> +};
> +
> +module_mei_cl_driver(mei_pxp_driver);
> +
> +MODULE_AUTHOR("Intel Corporation");
> +MODULE_LICENSE("GPL");
> +MODULE_DESCRIPTION("MEI PXP");
> diff --git a/drivers/misc/mei/pxp/mei_pxp.h b/drivers/misc/mei/pxp/mei_pxp.h
> new file mode 100644
> index 000000000000..e7b15373fefd
> --- /dev/null
> +++ b/drivers/misc/mei/pxp/mei_pxp.h
> @@ -0,0 +1,18 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright © 2020 Intel Corporation
> + *
> + * Authors:
> + * Vitaly Lubart <vitaly.lubart@intel.com>
> + */
> +
> +#ifndef __MEI_PXP_H__
> +#define __MEI_PXP_H__
> +
> +/* me_pxp_status: Enumeration of all PXP Status Codes */
> +enum me_pxp_status {
> +	ME_PXP_STATUS_SUCCESS			= 0x0000,
> +
> +};
> +
> +#endif /* __MEI_PXP_H__ */
> -- 
> 2.32.0
> 

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Intel-gfx] [PATCH v6 02/15] mei: pxp: export pavp client to me client bus
@ 2021-07-29 20:45     ` Rodrigo Vivi
  0 siblings, 0 replies; 64+ messages in thread
From: Rodrigo Vivi @ 2021-07-29 20:45 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio; +Cc: intel-gfx, Tomas Winkler, dri-devel, Vitaly Lubart

On Wed, Jul 28, 2021 at 07:00:53PM -0700, Daniele Ceraolo Spurio wrote:
> From: Vitaly Lubart <vitaly.lubart@intel.com>
> 
> Export PAVP client to work with i915 driver,
> for binding it uses kernel component framework.
> 
> v2:drop debug prints, refactor match code to match mei_hdcp (Tomas)
> 
> Signed-off-by: Vitaly Lubart <vitaly.lubart@intel.com>
> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> #v1

shouldn't we use the 2020-2021 in the other headers as well?

anyway, rv-b remains

> ---
>  drivers/misc/mei/Kconfig       |   2 +
>  drivers/misc/mei/Makefile      |   1 +
>  drivers/misc/mei/pxp/Kconfig   |  13 ++
>  drivers/misc/mei/pxp/Makefile  |   7 +
>  drivers/misc/mei/pxp/mei_pxp.c | 229 +++++++++++++++++++++++++++++++++
>  drivers/misc/mei/pxp/mei_pxp.h |  18 +++
>  6 files changed, 270 insertions(+)
>  create mode 100644 drivers/misc/mei/pxp/Kconfig
>  create mode 100644 drivers/misc/mei/pxp/Makefile
>  create mode 100644 drivers/misc/mei/pxp/mei_pxp.c
>  create mode 100644 drivers/misc/mei/pxp/mei_pxp.h
> 
> diff --git a/drivers/misc/mei/Kconfig b/drivers/misc/mei/Kconfig
> index f5fd5b786607..0e0bcd0da852 100644
> --- a/drivers/misc/mei/Kconfig
> +++ b/drivers/misc/mei/Kconfig
> @@ -47,3 +47,5 @@ config INTEL_MEI_TXE
>  	  Intel Bay Trail
>  
>  source "drivers/misc/mei/hdcp/Kconfig"
> +source "drivers/misc/mei/pxp/Kconfig"
> +
> diff --git a/drivers/misc/mei/Makefile b/drivers/misc/mei/Makefile
> index f1c76f7ee804..d8e5165917f2 100644
> --- a/drivers/misc/mei/Makefile
> +++ b/drivers/misc/mei/Makefile
> @@ -26,3 +26,4 @@ mei-$(CONFIG_EVENT_TRACING) += mei-trace.o
>  CFLAGS_mei-trace.o = -I$(src)
>  
>  obj-$(CONFIG_INTEL_MEI_HDCP) += hdcp/
> +obj-$(CONFIG_INTEL_MEI_PXP) += pxp/
> diff --git a/drivers/misc/mei/pxp/Kconfig b/drivers/misc/mei/pxp/Kconfig
> new file mode 100644
> index 000000000000..4029b96afc04
> --- /dev/null
> +++ b/drivers/misc/mei/pxp/Kconfig
> @@ -0,0 +1,13 @@
> +
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (c) 2020, Intel Corporation. All rights reserved.
> +#
> +config INTEL_MEI_PXP
> +	tristate "Intel PXP services of ME Interface"
> +	select INTEL_MEI_ME
> +	depends on DRM_I915
> +	help
> +	  MEI Support for PXP Services on Intel platforms.
> +
> +	  Enables the ME FW services required for PXP support through
> +	  I915 display driver of Intel.
> diff --git a/drivers/misc/mei/pxp/Makefile b/drivers/misc/mei/pxp/Makefile
> new file mode 100644
> index 000000000000..0329950d5794
> --- /dev/null
> +++ b/drivers/misc/mei/pxp/Makefile
> @@ -0,0 +1,7 @@
> +# SPDX-License-Identifier: GPL-2.0
> +#
> +# Copyright (c) 2020, Intel Corporation. All rights reserved.
> +#
> +# Makefile - PXP client driver for Intel MEI Bus Driver.
> +
> +obj-$(CONFIG_INTEL_MEI_PXP) += mei_pxp.o
> diff --git a/drivers/misc/mei/pxp/mei_pxp.c b/drivers/misc/mei/pxp/mei_pxp.c
> new file mode 100644
> index 000000000000..f7380d387bab
> --- /dev/null
> +++ b/drivers/misc/mei/pxp/mei_pxp.c
> @@ -0,0 +1,229 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright © 2020 - 2021 Intel Corporation
> + */
> +
> +/**
> + * DOC: MEI_PXP Client Driver
> + *
> + * The mei_pxp driver acts as a translation layer between PXP
> + * protocol  implementer (I915) and ME FW by translating PXP
> + * negotiation messages to ME FW command payloads and vice versa.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/slab.h>
> +#include <linux/uuid.h>
> +#include <linux/mei_cl_bus.h>
> +#include <linux/component.h>
> +#include <drm/drm_connector.h>
> +#include <drm/i915_component.h>
> +#include <drm/i915_pxp_tee_interface.h>
> +
> +#include "mei_pxp.h"
> +
> +/**
> + * mei_pxp_send_message() - Sends a PXP message to ME FW.
> + * @dev: device corresponding to the mei_cl_device
> + * @message: a message buffer to send
> + * @size: size of the message
> + * Return: 0 on Success, <0 on Failure
> + */
> +static int
> +mei_pxp_send_message(struct device *dev, const void *message, size_t size)
> +{
> +	struct mei_cl_device *cldev;
> +	ssize_t byte;
> +
> +	if (!dev || !message)
> +		return -EINVAL;
> +
> +	cldev = to_mei_cl_device(dev);
> +
> +	/* temporary drop const qualifier till the API is fixed */
> +	byte = mei_cldev_send(cldev, (u8 *)message, size);
> +	if (byte < 0) {
> +		dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte);
> +		return byte;
> +	}
> +
> +	return 0;
> +}
> +
> +/**
> + * mei_pxp_receive_message() - Receives a PXP message from ME FW.
> + * @dev: device corresponding to the mei_cl_device
> + * @buffer: a message buffer to contain the received message
> + * @size: size of the buffer
> + * Return: bytes sent on Success, <0 on Failure
> + */
> +static int
> +mei_pxp_receive_message(struct device *dev, void *buffer, size_t size)
> +{
> +	struct mei_cl_device *cldev;
> +	ssize_t byte;
> +
> +	if (!dev || !buffer)
> +		return -EINVAL;
> +
> +	cldev = to_mei_cl_device(dev);
> +
> +	byte = mei_cldev_recv(cldev, buffer, size);
> +	if (byte < 0) {
> +		dev_dbg(dev, "mei_cldev_recv failed. %zd\n", byte);
> +		return byte;
> +	}
> +
> +	return byte;
> +}
> +
> +static const struct i915_pxp_component_ops mei_pxp_ops = {
> +	.owner = THIS_MODULE,
> +	.send = mei_pxp_send_message,
> +	.recv = mei_pxp_receive_message,
> +};
> +
> +static int mei_component_master_bind(struct device *dev)
> +{
> +	struct mei_cl_device *cldev = to_mei_cl_device(dev);
> +	struct i915_pxp_component *comp_master = mei_cldev_get_drvdata(cldev);
> +	int ret;
> +
> +	comp_master->ops = &mei_pxp_ops;
> +	comp_master->tee_dev = dev;
> +	ret = component_bind_all(dev, comp_master);
> +	if (ret < 0)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +static void mei_component_master_unbind(struct device *dev)
> +{
> +	struct mei_cl_device *cldev = to_mei_cl_device(dev);
> +	struct i915_pxp_component *comp_master = mei_cldev_get_drvdata(cldev);
> +
> +	component_unbind_all(dev, comp_master);
> +}
> +
> +static const struct component_master_ops mei_component_master_ops = {
> +	.bind = mei_component_master_bind,
> +	.unbind = mei_component_master_unbind,
> +};
> +
> +/**
> + * mei_pxp_component_match - compare function for matching mei pxp.
> + *
> + *    The function checks if the driver is i915, the subcomponent is PXP
> + *    and the grand parent of pxp and the parent of i915 are the same
> + *    PCH device.
> + *
> + * @dev: master device
> + * @subcomponent: subcomponent to match (I915_COMPONENT_PXP)
> + * @data: compare data (mei pxp device)
> + *
> + * Return:
> + * * 1 - if components match
> + * * 0 - otherwise
> + */
> +static int mei_pxp_component_match(struct device *dev, int subcomponent,
> +				   void *data)
> +{
> +	struct device *base = data;
> +
> +	if (strcmp(dev->driver->name, "i915") ||
> +	    subcomponent != I915_COMPONENT_PXP)
> +		return 0;
> +
> +	base = base->parent;
> +	if (!base)
> +		return 0;
> +
> +	base = base->parent;
> +	dev = dev->parent;
> +
> +	return (base && dev && dev == base);
> +}
> +
> +static int mei_pxp_probe(struct mei_cl_device *cldev,
> +			 const struct mei_cl_device_id *id)
> +{
> +	struct i915_pxp_component *comp_master;
> +	struct component_match *master_match;
> +	int ret;
> +
> +	ret = mei_cldev_enable(cldev);
> +	if (ret < 0) {
> +		dev_err(&cldev->dev, "mei_cldev_enable Failed. %d\n", ret);
> +		goto enable_err_exit;
> +	}
> +
> +	comp_master = kzalloc(sizeof(*comp_master), GFP_KERNEL);
> +	if (!comp_master) {
> +		ret = -ENOMEM;
> +		goto err_exit;
> +	}
> +
> +	master_match = NULL;
> +	component_match_add_typed(&cldev->dev, &master_match,
> +				  mei_pxp_component_match, &cldev->dev);
> +	if (IS_ERR_OR_NULL(master_match)) {
> +		ret = -ENOMEM;
> +		goto err_exit;
> +	}
> +
> +	mei_cldev_set_drvdata(cldev, comp_master);
> +	ret = component_master_add_with_match(&cldev->dev,
> +					      &mei_component_master_ops,
> +					      master_match);
> +	if (ret < 0) {
> +		dev_err(&cldev->dev, "Master comp add failed %d\n", ret);
> +		goto err_exit;
> +	}
> +
> +	return 0;
> +
> +err_exit:
> +	mei_cldev_set_drvdata(cldev, NULL);
> +	kfree(comp_master);
> +	mei_cldev_disable(cldev);
> +enable_err_exit:
> +	return ret;
> +}
> +
> +static void mei_pxp_remove(struct mei_cl_device *cldev)
> +{
> +	struct i915_pxp_component *comp_master = mei_cldev_get_drvdata(cldev);
> +	int ret;
> +
> +	component_master_del(&cldev->dev, &mei_component_master_ops);
> +	kfree(comp_master);
> +	mei_cldev_set_drvdata(cldev, NULL);
> +
> +	ret = mei_cldev_disable(cldev);
> +	if (ret)
> +		dev_warn(&cldev->dev, "mei_cldev_disable() failed\n");
> +}
> +
> +/* fbf6fcf1-96cf-4e2e-a6a6-1bab8cbe36b1 : PAVP GUID*/
> +#define MEI_GUID_PXP GUID_INIT(0xfbf6fcf1, 0x96cf, 0x4e2e, 0xA6, \
> +			       0xa6, 0x1b, 0xab, 0x8c, 0xbe, 0x36, 0xb1)
> +
> +static struct mei_cl_device_id mei_pxp_tbl[] = {
> +	{ .uuid = MEI_GUID_PXP, .version = MEI_CL_VERSION_ANY },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(mei, mei_pxp_tbl);
> +
> +static struct mei_cl_driver mei_pxp_driver = {
> +	.id_table = mei_pxp_tbl,
> +	.name = KBUILD_MODNAME,
> +	.probe = mei_pxp_probe,
> +	.remove	= mei_pxp_remove,
> +};
> +
> +module_mei_cl_driver(mei_pxp_driver);
> +
> +MODULE_AUTHOR("Intel Corporation");
> +MODULE_LICENSE("GPL");
> +MODULE_DESCRIPTION("MEI PXP");
> diff --git a/drivers/misc/mei/pxp/mei_pxp.h b/drivers/misc/mei/pxp/mei_pxp.h
> new file mode 100644
> index 000000000000..e7b15373fefd
> --- /dev/null
> +++ b/drivers/misc/mei/pxp/mei_pxp.h
> @@ -0,0 +1,18 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright © 2020 Intel Corporation
> + *
> + * Authors:
> + * Vitaly Lubart <vitaly.lubart@intel.com>
> + */
> +
> +#ifndef __MEI_PXP_H__
> +#define __MEI_PXP_H__
> +
> +/* me_pxp_status: Enumeration of all PXP Status Codes */
> +enum me_pxp_status {
> +	ME_PXP_STATUS_SUCCESS			= 0x0000,
> +
> +};
> +
> +#endif /* __MEI_PXP_H__ */
> -- 
> 2.32.0
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 64+ messages in thread

* [Intel-gfx] [PATCH v6 13/15] drm/i915/pxp: Add plane decryption support
  2021-07-29  2:01   ` [Intel-gfx] " Daniele Ceraolo Spurio
  (?)
@ 2021-08-12  8:17   ` Anshuman Gupta
  2021-08-23  7:50     ` Shankar, Uma
  -1 siblings, 1 reply; 64+ messages in thread
From: Anshuman Gupta @ 2021-08-12  8:17 UTC (permalink / raw)
  To: intel-gfx
  Cc: uma.shankar, Anshuman Gupta, Bommu Krishnaiah, Huang Sean Z,
	Gaurav Kumar, Ville Syrjälä,
	Daniele Ceraolo Spurio, Juston Li, Rodrigo Vivi

Add support to enable/disable PLANE_SURF Decryption Request bit.
It requires only to enable plane decryption support when following
condition met.
1. PXP session is enabled.
2. Buffer object is protected.

v2:
- Used gen fb obj user_flags instead gem_object_metadata. [Krishna]

v3:
- intel_pxp_gem_object_status() API changes.

v4: use intel_pxp_is_active (Daniele)

v5: rebase and use the new protected object status checker (Daniele)

v6: used plane state for plane_decryption to handle async flip
    as suggested by Ville.

v7: check pxp session while plane decrypt state computation. [Ville]
    removed pointless code. [Ville]

v8 (Daniele): update PXP check

v9: move decrypt check after icl_check_nv12_planes() when overlays
    have fb set (Juston)

Cc: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
Cc: Huang Sean Z <sean.z.huang@intel.com>
Cc: Gaurav Kumar <kumar.gaurav@intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Anshuman Gupta <anshuman.gupta@intel.com>
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: Juston Li <juston.li@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c  | 27 +++++++++++++++++++
 .../drm/i915/display/intel_display_types.h    |  3 +++
 .../drm/i915/display/skl_universal_plane.c    | 15 ++++++++---
 drivers/gpu/drm/i915/i915_reg.h               |  1 +
 4 files changed, 43 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index b25c596f6f7e..accdd6614681 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -70,6 +70,8 @@
 #include "gt/intel_rps.h"
 #include "gt/gen8_ppgtt.h"
 
+#include "pxp/intel_pxp.h"
+
 #include "g4x_dp.h"
 #include "g4x_hdmi.h"
 #include "i915_drv.h"
@@ -9610,13 +9612,24 @@ static int intel_bigjoiner_add_affected_planes(struct intel_atomic_state *state)
 	return 0;
 }
 
+static int bo_has_valid_encryption(const struct drm_i915_gem_object *obj)
+{
+        struct drm_i915_private *i915 = to_i915(obj->base.dev);
+
+        return i915_gem_object_has_valid_protection(obj) &&
+               intel_pxp_is_active(&i915->gt.pxp);
+}
+
 static int intel_atomic_check_planes(struct intel_atomic_state *state)
 {
 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
 	struct intel_crtc_state *old_crtc_state, *new_crtc_state;
 	struct intel_plane_state *plane_state;
 	struct intel_plane *plane;
+	struct intel_plane_state *new_plane_state;
+	struct intel_plane_state *old_plane_state;
 	struct intel_crtc *crtc;
+	const struct drm_framebuffer *fb;
 	int i, ret;
 
 	ret = icl_add_linked_planes(state);
@@ -9664,6 +9677,16 @@ static int intel_atomic_check_planes(struct intel_atomic_state *state)
 			return ret;
 	}
 
+	for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
+		new_plane_state = intel_atomic_get_new_plane_state(state, plane);
+		old_plane_state = intel_atomic_get_old_plane_state(state, plane);
+		fb = new_plane_state->hw.fb;
+		if (fb)
+			new_plane_state->decrypt = bo_has_valid_encryption(intel_fb_obj(fb));
+		else
+			new_plane_state->decrypt = old_plane_state->decrypt;
+        }
+
 	return 0;
 }
 
@@ -9950,6 +9973,10 @@ static int intel_atomic_check_async(struct intel_atomic_state *state)
 			drm_dbg_kms(&i915->drm, "Color range cannot be changed in async flip\n");
 			return -EINVAL;
 		}
+
+		/* plane decryption is allow to change only in synchronous flips */
+		if (old_plane_state->decrypt != new_plane_state->decrypt)
+			return -EINVAL;
 	}
 
 	return 0;
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 6beeeeba1bed..53b5db3c6228 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -629,6 +629,9 @@ struct intel_plane_state {
 
 	struct intel_fb_view view;
 
+	/* Plane pxp decryption state */
+	bool decrypt;
+
 	/* plane control register */
 	u32 ctl;
 
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index 724e7b04f3b6..55e3f093b951 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -18,6 +18,7 @@
 #include "intel_sprite.h"
 #include "skl_scaler.h"
 #include "skl_universal_plane.h"
+#include "pxp/intel_pxp.h"
 
 static const u32 skl_plane_formats[] = {
 	DRM_FORMAT_C8,
@@ -1024,7 +1025,7 @@ skl_program_plane(struct intel_plane *plane,
 	u8 alpha = plane_state->hw.alpha >> 8;
 	u32 plane_color_ctl = 0, aux_dist = 0;
 	unsigned long irqflags;
-	u32 keymsk, keymax;
+	u32 keymsk, keymax, plane_surf;
 	u32 plane_ctl = plane_state->ctl;
 
 	plane_ctl |= skl_plane_ctl_crtc(crtc_state);
@@ -1113,8 +1114,16 @@ skl_program_plane(struct intel_plane *plane,
 	 * the control register just before the surface register.
 	 */
 	intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), plane_ctl);
-	intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id),
-			  intel_plane_ggtt_offset(plane_state) + surf_addr);
+	plane_surf = intel_plane_ggtt_offset(plane_state) + surf_addr;
+
+	/*
+	 * FIXME: pxp session invalidation can hit any time even at time of commit
+	 * or after the commit, display content will be garbage.
+	 */
+	if (plane_state->decrypt)
+		plane_surf |= PLANE_SURF_DECRYPT;
+
+	intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), plane_surf);
 
 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index f76eaed8e855..57f22f54d9f7 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -7347,6 +7347,7 @@ enum {
 #define _PLANE_SURF_3(pipe)	_PIPE(pipe, _PLANE_SURF_3_A, _PLANE_SURF_3_B)
 #define PLANE_SURF(pipe, plane)	\
 	_MMIO_PLANE(plane, _PLANE_SURF_1(pipe), _PLANE_SURF_2(pipe))
+#define   PLANE_SURF_DECRYPT			REG_BIT(2)
 
 #define _PLANE_OFFSET_1_B			0x711a4
 #define _PLANE_OFFSET_2_B			0x712a4
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [Intel-gfx] [PATCH v6 14/15] drm/i915/pxp: black pixels on pxp disabled
  2021-07-29  2:01   ` [Intel-gfx] " Daniele Ceraolo Spurio
  (?)
@ 2021-08-12  8:20   ` Anshuman Gupta
  2021-08-23  7:56     ` Shankar, Uma
  -1 siblings, 1 reply; 64+ messages in thread
From: Anshuman Gupta @ 2021-08-12  8:20 UTC (permalink / raw)
  To: intel-gfx
  Cc: uma.shankar, Anshuman Gupta, Ville Syrjälä,
	Gaurav Kumar, Daniele Ceraolo Spurio, Juston Li, Rodrigo Vivi

When protected sufaces has flipped and pxp session is disabled,
display black pixels by using plane color CTM correction.

v2:
- Display black pixels in async flip too.

v3:
- Removed the black pixels logic for async flip. [Ville]
- Used plane state to force black pixels. [Ville]

v4 (Daniele): update pxp_is_borked check.

v5: rebase on top of v9 plane decryption moving the decrypt check
    (Juston)

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Gaurav Kumar <kumar.gaurav@intel.com>
Cc: Shankar Uma <uma.shankar@intel.com>
Signed-off-by: Anshuman Gupta <anshuman.gupta@intel.com>
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Signed-off-by: Juston Li <juston.li@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c  | 12 ++++-
 .../drm/i915/display/intel_display_types.h    |  3 ++
 .../drm/i915/display/skl_universal_plane.c    | 36 ++++++++++++++-
 drivers/gpu/drm/i915/i915_reg.h               | 46 +++++++++++++++++++
 4 files changed, 94 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index accdd6614681..c6babb47471e 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -9620,6 +9620,11 @@ static int bo_has_valid_encryption(const struct drm_i915_gem_object *obj)
                intel_pxp_is_active(&i915->gt.pxp);
 }
 
+static bool pxp_is_borked(const struct drm_i915_gem_object *obj)
+{
+	return i915_gem_object_is_protected(obj) && !bo_has_valid_encryption(obj);
+}
+
 static int intel_atomic_check_planes(struct intel_atomic_state *state)
 {
 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
@@ -9681,10 +9686,13 @@ static int intel_atomic_check_planes(struct intel_atomic_state *state)
 		new_plane_state = intel_atomic_get_new_plane_state(state, plane);
 		old_plane_state = intel_atomic_get_old_plane_state(state, plane);
 		fb = new_plane_state->hw.fb;
-		if (fb)
+		if (fb) {
 			new_plane_state->decrypt = bo_has_valid_encryption(intel_fb_obj(fb));
-		else
+			new_plane_state->force_black = pxp_is_borked(intel_fb_obj(fb));
+		} else {
 			new_plane_state->decrypt = old_plane_state->decrypt;
+			new_plane_state->force_black = old_plane_state->force_black;
+		}
         }
 
 	return 0;
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 53b5db3c6228..0fe03ef57023 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -632,6 +632,9 @@ struct intel_plane_state {
 	/* Plane pxp decryption state */
 	bool decrypt;
 
+	/* Plane state to display black pixels when pxp is borked */
+	bool force_black;
+
 	/* plane control register */
 	u32 ctl;
 
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index 55e3f093b951..c4adcb3e12b3 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -1002,6 +1002,33 @@ static u32 skl_surf_address(const struct intel_plane_state *plane_state,
 	}
 }
 
+static void intel_load_plane_csc_black(struct intel_plane *intel_plane)
+{
+	struct drm_i915_private *dev_priv = to_i915(intel_plane->base.dev);
+	enum pipe pipe = intel_plane->pipe;
+	enum plane_id plane = intel_plane->id;
+	u16 postoff = 0;
+
+	drm_dbg_kms(&dev_priv->drm, "plane color CTM to black  %s:%d\n",
+		    intel_plane->base.name, plane);
+	intel_de_write_fw(dev_priv, PLANE_CSC_COEFF(pipe, plane, 0), 0);
+	intel_de_write_fw(dev_priv, PLANE_CSC_COEFF(pipe, plane, 1), 0);
+
+	intel_de_write_fw(dev_priv, PLANE_CSC_COEFF(pipe, plane, 2), 0);
+	intel_de_write_fw(dev_priv, PLANE_CSC_COEFF(pipe, plane, 3), 0);
+
+	intel_de_write_fw(dev_priv, PLANE_CSC_COEFF(pipe, plane, 4), 0);
+	intel_de_write_fw(dev_priv, PLANE_CSC_COEFF(pipe, plane, 5), 0);
+
+	intel_de_write_fw(dev_priv, PLANE_CSC_PREOFF(pipe, plane, 0), 0);
+	intel_de_write_fw(dev_priv, PLANE_CSC_PREOFF(pipe, plane, 1), 0);
+	intel_de_write_fw(dev_priv, PLANE_CSC_PREOFF(pipe, plane, 2), 0);
+
+	intel_de_write_fw(dev_priv, PLANE_CSC_POSTOFF(pipe, plane, 0), postoff);
+	intel_de_write_fw(dev_priv, PLANE_CSC_POSTOFF(pipe, plane, 1), postoff);
+	intel_de_write_fw(dev_priv, PLANE_CSC_POSTOFF(pipe, plane, 2), postoff);
+}
+
 static void
 skl_program_plane(struct intel_plane *plane,
 		  const struct intel_crtc_state *crtc_state,
@@ -1115,14 +1142,21 @@ skl_program_plane(struct intel_plane *plane,
 	 */
 	intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), plane_ctl);
 	plane_surf = intel_plane_ggtt_offset(plane_state) + surf_addr;
+	plane_color_ctl = intel_de_read_fw(dev_priv, PLANE_COLOR_CTL(pipe, plane_id));
 
 	/*
 	 * FIXME: pxp session invalidation can hit any time even at time of commit
 	 * or after the commit, display content will be garbage.
 	 */
-	if (plane_state->decrypt)
+	if (plane_state->decrypt) {
 		plane_surf |= PLANE_SURF_DECRYPT;
+	} else if (plane_state->force_black) {
+		intel_load_plane_csc_black(plane);
+		plane_color_ctl |= PLANE_COLOR_PLANE_CSC_ENABLE;
+	}
 
+	intel_de_write_fw(dev_priv, PLANE_COLOR_CTL(pipe, plane_id),
+			  plane_color_ctl);
 	intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), plane_surf);
 
 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 57f22f54d9f7..db714ea91997 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -7224,6 +7224,7 @@ enum {
 #define _PLANE_COLOR_CTL_3_A			0x703CC /* GLK+ */
 #define   PLANE_COLOR_PIPE_GAMMA_ENABLE		(1 << 30) /* Pre-ICL */
 #define   PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE	(1 << 28)
+#define   PLANE_COLOR_PLANE_CSC_ENABLE			REG_BIT(21) /* ICL+ */
 #define   PLANE_COLOR_INPUT_CSC_ENABLE		(1 << 20) /* ICL+ */
 #define   PLANE_COLOR_PIPE_CSC_ENABLE		(1 << 23) /* Pre-ICL */
 #define   PLANE_COLOR_CSC_MODE_BYPASS			(0 << 17)
@@ -11341,6 +11342,51 @@ enum skl_power_gate {
 					_PAL_PREC_MULTI_SEG_DATA_A, \
 					_PAL_PREC_MULTI_SEG_DATA_B)
 
+#define _MMIO_PLANE_GAMC(plane, i, a, b)  _MMIO(_PIPE(plane, a, b) + (i) * 4)
+
+/* Plane CSC Registers */
+#define _PLANE_CSC_RY_GY_1_A	0x70210
+#define _PLANE_CSC_RY_GY_2_A	0x70310
+
+#define _PLANE_CSC_RY_GY_1_B	0x71210
+#define _PLANE_CSC_RY_GY_2_B	0x71310
+
+#define _PLANE_CSC_RY_GY_1(pipe)	_PIPE(pipe, _PLANE_CSC_RY_GY_1_A, \
+					      _PLANE_CSC_RY_GY_1_B)
+#define _PLANE_CSC_RY_GY_2(pipe)	_PIPE(pipe, _PLANE_INPUT_CSC_RY_GY_2_A, \
+					      _PLANE_INPUT_CSC_RY_GY_2_B)
+#define PLANE_CSC_COEFF(pipe, plane, index)	_MMIO_PLANE(plane, \
+							    _PLANE_CSC_RY_GY_1(pipe) +  (index) * 4, \
+							    _PLANE_CSC_RY_GY_2(pipe) + (index) * 4)
+
+#define _PLANE_CSC_PREOFF_HI_1_A		0x70228
+#define _PLANE_CSC_PREOFF_HI_2_A		0x70328
+
+#define _PLANE_CSC_PREOFF_HI_1_B		0x71228
+#define _PLANE_CSC_PREOFF_HI_2_B		0x71328
+
+#define _PLANE_CSC_PREOFF_HI_1(pipe)	_PIPE(pipe, _PLANE_CSC_PREOFF_HI_1_A, \
+					      _PLANE_CSC_PREOFF_HI_1_B)
+#define _PLANE_CSC_PREOFF_HI_2(pipe)	_PIPE(pipe, _PLANE_CSC_PREOFF_HI_2_A, \
+					      _PLANE_CSC_PREOFF_HI_2_B)
+#define PLANE_CSC_PREOFF(pipe, plane, index)	_MMIO_PLANE(plane, _PLANE_CSC_PREOFF_HI_1(pipe) + \
+							    (index) * 4, _PLANE_CSC_PREOFF_HI_2(pipe) + \
+							    (index) * 4)
+
+#define _PLANE_CSC_POSTOFF_HI_1_A		0x70234
+#define _PLANE_CSC_POSTOFF_HI_2_A		0x70334
+
+#define _PLANE_CSC_POSTOFF_HI_1_B		0x71234
+#define _PLANE_CSC_POSTOFF_HI_2_B		0x71334
+
+#define _PLANE_CSC_POSTOFF_HI_1(pipe)	_PIPE(pipe, _PLANE_CSC_POSTOFF_HI_1_A, \
+					      _PLANE_CSC_POSTOFF_HI_1_B)
+#define _PLANE_CSC_POSTOFF_HI_2(pipe)	_PIPE(pipe, _PLANE_CSC_POSTOFF_HI_2_A, \
+					      _PLANE_CSC_POSTOFF_HI_2_B)
+#define PLANE_CSC_POSTOFF(pipe, plane, index)	_MMIO_PLANE(plane, _PLANE_CSC_POSTOFF_HI_1(pipe) + \
+							    (index) * 4, _PLANE_CSC_POSTOFF_HI_2(pipe) + \
+							    (index) * 4)
+
 /* pipe CSC & degamma/gamma LUTs on CHV */
 #define _CGM_PIPE_A_CSC_COEFF01	(VLV_DISPLAY_BASE + 0x67900)
 #define _CGM_PIPE_A_CSC_COEFF23	(VLV_DISPLAY_BASE + 0x67904)
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Introduce Intel PXP (rev4)
  2021-07-29  2:00 ` [Intel-gfx] " Daniele Ceraolo Spurio
                   ` (20 preceding siblings ...)
  (?)
@ 2021-08-12 12:07 ` Patchwork
  -1 siblings, 0 replies; 64+ messages in thread
From: Patchwork @ 2021-08-12 12:07 UTC (permalink / raw)
  To: Anshuman Gupta; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: Introduce Intel PXP (rev4)
URL   : https://patchwork.freedesktop.org/series/90503/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
65c355279252 drm/i915/pxp: Define PXP component interface
-:31: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#31: 
new file mode 100644

total: 0 errors, 1 warnings, 0 checks, 52 lines checked
2d8e564a00c6 mei: pxp: export pavp client to me client bus
-:36: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#36: 
new file mode 100644

total: 0 errors, 1 warnings, 0 checks, 276 lines checked
bfb4bf081281 drm/i915/pxp: define PXP device flag and kconfig
-:46: ERROR:COMPLEX_MACRO: Macros with complex values should be enclosed in parentheses
#46: FILE: drivers/gpu/drm/i915/i915_drv.h:1724:
+#define HAS_PXP(dev_priv) (IS_ENABLED(CONFIG_DRM_I915_PXP) && \
+			   INTEL_INFO(dev_priv)->has_pxp) && \
+			   VDBOX_MASK(&dev_priv->gt)

-:46: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'dev_priv' - possible side-effects?
#46: FILE: drivers/gpu/drm/i915/i915_drv.h:1724:
+#define HAS_PXP(dev_priv) (IS_ENABLED(CONFIG_DRM_I915_PXP) && \
+			   INTEL_INFO(dev_priv)->has_pxp) && \
+			   VDBOX_MASK(&dev_priv->gt)

total: 1 errors, 0 warnings, 1 checks, 34 lines checked
9ad093624bbe drm/i915/pxp: allocate a vcs context for pxp usage
-:98: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#98: 
new file mode 100644

-:122: ERROR:TRAILING_STATEMENTS: trailing statements should be on next line
#122: FILE: drivers/gpu/drm/i915/pxp/intel_pxp.c:20:
+	for (engine = gt->engine_class[VIDEO_DECODE_CLASS][0]; !engine; engine++);

total: 1 errors, 1 warnings, 0 checks, 168 lines checked
9d3aaae13dbd drm/i915/pxp: Implement funcs to create the TEE channel
-:75: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#75: 
new file mode 100644

total: 0 errors, 1 warnings, 0 checks, 142 lines checked
231491eefcc7 drm/i915/pxp: set KCR reg init
6ee365ff48d6 drm/i915/pxp: Create the arbitrary session after boot
-:98: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#98: 
new file mode 100644

-:383: CHECK:LINE_SPACING: Please don't use multiple blank lines
#383: FILE: drivers/gpu/drm/i915/pxp/intel_pxp_tee_interface.h:36:
+
+

total: 0 errors, 1 warnings, 1 checks, 339 lines checked
389286854a1d drm/i915/pxp: Implement arb session teardown
-:63: CHECK:SPACING: spaces preferred around that '<<' (ctx:VxV)
#63: FILE: drivers/gpu/drm/i915/gt/intel_gpu_commands.h:153:
+#define   MI_FLUSH_DW_PROTECTED_MEM_EN	(1<<22)
                                       	  ^

-:117: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#117: 
new file mode 100644

total: 0 errors, 1 warnings, 1 checks, 283 lines checked
8bb9f3f77bad drm/i915/pxp: Implement PXP irq handler
-:211: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#211: 
new file mode 100644

total: 0 errors, 1 warnings, 0 checks, 423 lines checked
c5a878193242 drm/i915/pxp: interfaces for using protected objects
-:674: CHECK:LINE_SPACING: Please use a blank line after function/struct/union/enum declarations
#674: FILE: drivers/gpu/drm/i915/pxp/intel_pxp.h:61:
+}
+static inline void intel_pxp_object_remove(struct drm_i915_gem_object *obj)

total: 0 errors, 0 warnings, 1 checks, 676 lines checked
5d5cf83b00a6 drm/i915/pxp: start the arb session on demand
6c338ff4035f drm/i915/pxp: Enable PXP power management
-:120: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#120: 
new file mode 100644

-:188: CHECK:LINE_SPACING: Please use a blank line after function/struct/union/enum declarations
#188: FILE: drivers/gpu/drm/i915/pxp/intel_pxp_pm.h:18:
+}
+static inline void intel_pxp_resume(struct intel_pxp *pxp)

total: 0 errors, 1 warnings, 1 checks, 232 lines checked
acfc177b569e drm/i915/pxp: Add plane decryption support
-:64: ERROR:CODE_INDENT: code indent should use tabs where possible
#64: FILE: drivers/gpu/drm/i915/display/intel_display.c:9631:
+        struct drm_i915_private *i915 = to_i915(obj->base.dev);$

-:64: WARNING:LEADING_SPACE: please, no spaces at the start of a line
#64: FILE: drivers/gpu/drm/i915/display/intel_display.c:9631:
+        struct drm_i915_private *i915 = to_i915(obj->base.dev);$

-:66: ERROR:CODE_INDENT: code indent should use tabs where possible
#66: FILE: drivers/gpu/drm/i915/display/intel_display.c:9633:
+        return i915_gem_object_has_valid_protection(obj) &&$

-:66: WARNING:LEADING_SPACE: please, no spaces at the start of a line
#66: FILE: drivers/gpu/drm/i915/display/intel_display.c:9633:
+        return i915_gem_object_has_valid_protection(obj) &&$

-:67: ERROR:CODE_INDENT: code indent should use tabs where possible
#67: FILE: drivers/gpu/drm/i915/display/intel_display.c:9634:
+               intel_pxp_is_active(&i915->gt.pxp);$

-:67: WARNING:LEADING_SPACE: please, no spaces at the start of a line
#67: FILE: drivers/gpu/drm/i915/display/intel_display.c:9634:
+               intel_pxp_is_active(&i915->gt.pxp);$

-:95: ERROR:CODE_INDENT: code indent should use tabs where possible
#95: FILE: drivers/gpu/drm/i915/display/intel_display.c:9702:
+        }$

-:95: WARNING:LEADING_SPACE: please, no spaces at the start of a line
#95: FILE: drivers/gpu/drm/i915/display/intel_display.c:9702:
+        }$

total: 4 errors, 4 warnings, 0 checks, 107 lines checked
44da0d1d6f69 drm/i915/pxp: black pixels on pxp disabled
-:168: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'pipe' - possible side-effects?
#168: FILE: drivers/gpu/drm/i915/i915_reg.h:11366:
+#define PLANE_CSC_COEFF(pipe, plane, index)	_MMIO_PLANE(plane, \
+							    _PLANE_CSC_RY_GY_1(pipe) +  (index) * 4, \
+							    _PLANE_CSC_RY_GY_2(pipe) + (index) * 4)

-:168: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'index' - possible side-effects?
#168: FILE: drivers/gpu/drm/i915/i915_reg.h:11366:
+#define PLANE_CSC_COEFF(pipe, plane, index)	_MMIO_PLANE(plane, \
+							    _PLANE_CSC_RY_GY_1(pipe) +  (index) * 4, \
+							    _PLANE_CSC_RY_GY_2(pipe) + (index) * 4)

-:169: WARNING:LONG_LINE: line length of 102 exceeds 100 columns
#169: FILE: drivers/gpu/drm/i915/i915_reg.h:11367:
+							    _PLANE_CSC_RY_GY_1(pipe) +  (index) * 4, \

-:182: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'pipe' - possible side-effects?
#182: FILE: drivers/gpu/drm/i915/i915_reg.h:11380:
+#define PLANE_CSC_PREOFF(pipe, plane, index)	_MMIO_PLANE(plane, _PLANE_CSC_PREOFF_HI_1(pipe) + \
+							    (index) * 4, _PLANE_CSC_PREOFF_HI_2(pipe) + \
+							    (index) * 4)

-:182: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'index' - possible side-effects?
#182: FILE: drivers/gpu/drm/i915/i915_reg.h:11380:
+#define PLANE_CSC_PREOFF(pipe, plane, index)	_MMIO_PLANE(plane, _PLANE_CSC_PREOFF_HI_1(pipe) + \
+							    (index) * 4, _PLANE_CSC_PREOFF_HI_2(pipe) + \
+							    (index) * 4)

-:183: WARNING:LONG_LINE: line length of 105 exceeds 100 columns
#183: FILE: drivers/gpu/drm/i915/i915_reg.h:11381:
+							    (index) * 4, _PLANE_CSC_PREOFF_HI_2(pipe) + \

-:196: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'pipe' - possible side-effects?
#196: FILE: drivers/gpu/drm/i915/i915_reg.h:11394:
+#define PLANE_CSC_POSTOFF(pipe, plane, index)	_MMIO_PLANE(plane, _PLANE_CSC_POSTOFF_HI_1(pipe) + \
+							    (index) * 4, _PLANE_CSC_POSTOFF_HI_2(pipe) + \
+							    (index) * 4)

-:196: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'index' - possible side-effects?
#196: FILE: drivers/gpu/drm/i915/i915_reg.h:11394:
+#define PLANE_CSC_POSTOFF(pipe, plane, index)	_MMIO_PLANE(plane, _PLANE_CSC_POSTOFF_HI_1(pipe) + \
+							    (index) * 4, _PLANE_CSC_POSTOFF_HI_2(pipe) + \
+							    (index) * 4)

-:197: WARNING:LONG_LINE: line length of 106 exceeds 100 columns
#197: FILE: drivers/gpu/drm/i915/i915_reg.h:11395:
+							    (index) * 4, _PLANE_CSC_POSTOFF_HI_2(pipe) + \

total: 0 errors, 3 warnings, 6 checks, 148 lines checked
3fffe5731ae9 drm/i915/pxp: enable PXP for integrated Gen12



^ permalink raw reply	[flat|nested] 64+ messages in thread

* [Intel-gfx] ✗ Fi.CI.SPARSE: warning for drm/i915: Introduce Intel PXP (rev4)
  2021-07-29  2:00 ` [Intel-gfx] " Daniele Ceraolo Spurio
                   ` (21 preceding siblings ...)
  (?)
@ 2021-08-12 12:09 ` Patchwork
  -1 siblings, 0 replies; 64+ messages in thread
From: Patchwork @ 2021-08-12 12:09 UTC (permalink / raw)
  To: Anshuman Gupta; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: Introduce Intel PXP (rev4)
URL   : https://patchwork.freedesktop.org/series/90503/
State : warning

== Summary ==

$ dim sparse --fast origin/drm-tip
Sparse version: v0.6.2
Fast mode used, each commit won't be checked separately.
-
+drivers/gpu/drm/i915/display/intel_display.c:1903:21:    expected struct i915_vma *[assigned] vma
+drivers/gpu/drm/i915/display/intel_display.c:1903:21:    got void [noderef] __iomem *[assigned] iomem
+drivers/gpu/drm/i915/display/intel_display.c:1903:21: warning: incorrect type in assignment (different address spaces)
+drivers/gpu/drm/i915/gem/i915_gem_context.c:1447:34:    expected struct i915_address_space *vm
+drivers/gpu/drm/i915/gem/i915_gem_context.c:1447:34:    got struct i915_address_space [noderef] __rcu *vm
+drivers/gpu/drm/i915/gem/i915_gem_context.c:1447:34: warning: incorrect type in argument 1 (different address spaces)
+drivers/gpu/drm/i915/gem/selftests/mock_context.c:43:25:    expected struct i915_address_space [noderef] __rcu *vm
+drivers/gpu/drm/i915/gem/selftests/mock_context.c:43:25:    got struct i915_address_space *
+drivers/gpu/drm/i915/gem/selftests/mock_context.c:43:25: warning: incorrect type in assignment (different address spaces)
+drivers/gpu/drm/i915/gem/selftests/mock_context.c:60:34:    expected struct i915_address_space *vm
+drivers/gpu/drm/i915/gem/selftests/mock_context.c:60:34:    got struct i915_address_space [noderef] __rcu *vm
+drivers/gpu/drm/i915/gem/selftests/mock_context.c:60:34: warning: incorrect type in argument 1 (different address spaces)
+drivers/gpu/drm/i915/gt/intel_engine_stats.h:27:9: warning: trying to copy expression type 31
+drivers/gpu/drm/i915/gt/intel_engine_stats.h:27:9: warning: trying to copy expression type 31
+drivers/gpu/drm/i915/gt/intel_engine_stats.h:27:9: warning: trying to copy expression type 31
+drivers/gpu/drm/i915/gt/intel_engine_stats.h:32:9: warning: trying to copy expression type 31
+drivers/gpu/drm/i915/gt/intel_engine_stats.h:32:9: warning: trying to copy expression type 31
+drivers/gpu/drm/i915/gt/intel_engine_stats.h:49:9: warning: trying to copy expression type 31
+drivers/gpu/drm/i915/gt/intel_engine_stats.h:49:9: warning: trying to copy expression type 31
+drivers/gpu/drm/i915/gt/intel_engine_stats.h:49:9: warning: trying to copy expression type 31
+drivers/gpu/drm/i915/gt/intel_engine_stats.h:56:9: warning: trying to copy expression type 31
+drivers/gpu/drm/i915/gt/intel_engine_stats.h:56:9: warning: trying to copy expression type 31
+drivers/gpu/drm/i915/gt/intel_reset.c:1392:5: warning: context imbalance in 'intel_gt_reset_trylock' - different lock contexts for basic block
+drivers/gpu/drm/i915/gt/intel_ring_submission.c:1268:24: warning: Using plain integer as NULL pointer
+drivers/gpu/drm/i915/i915_perf.c:1442:15: warning: memset with byte count of 16777216
+drivers/gpu/drm/i915/i915_perf.c:1496:15: warning: memset with byte count of 16777216
+./include/asm-generic/bitops/find.h:112:45: warning: shift count is negative (-262080)
+./include/asm-generic/bitops/find.h:32:31: warning: shift count is negative (-262080)
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'fwtable_read16' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'fwtable_read32' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'fwtable_read64' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'fwtable_read8' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'fwtable_write16' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'fwtable_write32' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'fwtable_write8' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen11_fwtable_read16' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen11_fwtable_read32' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen11_fwtable_read64' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen11_fwtable_read8' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen11_fwtable_write16' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen11_fwtable_write32' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen11_fwtable_write8' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen12_fwtable_write16' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen12_fwtable_write32' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen12_fwtable_write8' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen6_read16' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen6_read32' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen6_read64' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen6_read8' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen6_write16' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen6_write32' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen6_write8' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen8_write16' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen8_write32' - different lock contexts for basic block
+./include/linux/spinlock.h:409:9: warning: context imbalance in 'gen8_write8' - different lock contexts for basic block
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+./include/linux/stddef.h:17:9: this was the original definition
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h:417:9: warning: preprocessor token offsetof redefined



^ permalink raw reply	[flat|nested] 64+ messages in thread

* [Intel-gfx] ✗ Fi.CI.DOCS: warning for drm/i915: Introduce Intel PXP (rev4)
  2021-07-29  2:00 ` [Intel-gfx] " Daniele Ceraolo Spurio
                   ` (22 preceding siblings ...)
  (?)
@ 2021-08-12 12:13 ` Patchwork
  -1 siblings, 0 replies; 64+ messages in thread
From: Patchwork @ 2021-08-12 12:13 UTC (permalink / raw)
  To: Anshuman Gupta; +Cc: intel-gfx

== Series Details ==

Series: drm/i915: Introduce Intel PXP (rev4)
URL   : https://patchwork.freedesktop.org/series/90503/
State : warning

== Summary ==

$ make htmldocs 2>&1 > /dev/null | grep i915
./include/uapi/drm/i915_drm.h:1875: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
./include/uapi/drm/i915_drm.h:3092: warning: Function parameter or member 'base' not described in 'drm_i915_gem_create_ext_protected_content'
./include/uapi/drm/i915_drm.h:3092: warning: Function parameter or member 'flags' not described in 'drm_i915_gem_create_ext_protected_content'



^ permalink raw reply	[flat|nested] 64+ messages in thread

* [Intel-gfx] ✓ Fi.CI.BAT: success for drm/i915: Introduce Intel PXP (rev4)
  2021-07-29  2:00 ` [Intel-gfx] " Daniele Ceraolo Spurio
                   ` (23 preceding siblings ...)
  (?)
@ 2021-08-12 12:37 ` Patchwork
  -1 siblings, 0 replies; 64+ messages in thread
From: Patchwork @ 2021-08-12 12:37 UTC (permalink / raw)
  To: Anshuman Gupta; +Cc: intel-gfx

[-- Attachment #1: Type: text/plain, Size: 3030 bytes --]

== Series Details ==

Series: drm/i915: Introduce Intel PXP (rev4)
URL   : https://patchwork.freedesktop.org/series/90503/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_10474 -> Patchwork_20802
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/index.html

Known issues
------------

  Here are the changes found in Patchwork_20802 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@i915_selftest@live@gt_heartbeat:
    - fi-icl-u2:          [PASS][1] -> [DMESG-FAIL][2] ([i915#2291] / [i915#541])
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/fi-icl-u2/igt@i915_selftest@live@gt_heartbeat.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/fi-icl-u2/igt@i915_selftest@live@gt_heartbeat.html

  
#### Possible fixes ####

  * igt@i915_selftest@live@execlists:
    - fi-icl-y:           [DMESG-FAIL][3] ([i915#1993]) -> [PASS][4]
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/fi-icl-y/igt@i915_selftest@live@execlists.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/fi-icl-y/igt@i915_selftest@live@execlists.html

  
  [i915#1993]: https://gitlab.freedesktop.org/drm/intel/issues/1993
  [i915#2291]: https://gitlab.freedesktop.org/drm/intel/issues/2291
  [i915#541]: https://gitlab.freedesktop.org/drm/intel/issues/541


Participating hosts (39 -> 35)
------------------------------

  Missing    (4): fi-bdw-samus fi-bsw-cyan bat-jsl-1 fi-hsw-4200u 


Build changes
-------------

  * Linux: CI_DRM_10474 -> Patchwork_20802

  CI-20190529: 20190529
  CI_DRM_10474: 046552fb86ff8adbcff75775fa5f407139cc8507 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_6172: ffda3a23ee9c108f17147a05c321f32ae1f25132 @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
  Patchwork_20802: 3fffe5731ae99181964d2eb3d58c35797e15c753 @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

3fffe5731ae9 drm/i915/pxp: enable PXP for integrated Gen12
44da0d1d6f69 drm/i915/pxp: black pixels on pxp disabled
acfc177b569e drm/i915/pxp: Add plane decryption support
6c338ff4035f drm/i915/pxp: Enable PXP power management
5d5cf83b00a6 drm/i915/pxp: start the arb session on demand
c5a878193242 drm/i915/pxp: interfaces for using protected objects
8bb9f3f77bad drm/i915/pxp: Implement PXP irq handler
389286854a1d drm/i915/pxp: Implement arb session teardown
6ee365ff48d6 drm/i915/pxp: Create the arbitrary session after boot
231491eefcc7 drm/i915/pxp: set KCR reg init
9d3aaae13dbd drm/i915/pxp: Implement funcs to create the TEE channel
9ad093624bbe drm/i915/pxp: allocate a vcs context for pxp usage
bfb4bf081281 drm/i915/pxp: define PXP device flag and kconfig
2d8e564a00c6 mei: pxp: export pavp client to me client bus
65c355279252 drm/i915/pxp: Define PXP component interface

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/index.html

[-- Attachment #2: Type: text/html, Size: 3730 bytes --]

^ permalink raw reply	[flat|nested] 64+ messages in thread

* [Intel-gfx] ✗ Fi.CI.IGT: failure for drm/i915: Introduce Intel PXP (rev4)
  2021-07-29  2:00 ` [Intel-gfx] " Daniele Ceraolo Spurio
                   ` (24 preceding siblings ...)
  (?)
@ 2021-08-12 14:59 ` Patchwork
  -1 siblings, 0 replies; 64+ messages in thread
From: Patchwork @ 2021-08-12 14:59 UTC (permalink / raw)
  To: Anshuman Gupta; +Cc: intel-gfx

[-- Attachment #1: Type: text/plain, Size: 30259 bytes --]

== Series Details ==

Series: drm/i915: Introduce Intel PXP (rev4)
URL   : https://patchwork.freedesktop.org/series/90503/
State : failure

== Summary ==

CI Bug Log - changes from CI_DRM_10474_full -> Patchwork_20802_full
====================================================

Summary
-------

  **FAILURE**

  Serious unknown changes coming with Patchwork_20802_full absolutely need to be
  verified manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in Patchwork_20802_full, please notify your bug team to allow them
  to document this new failure mode, which will reduce false positives in CI.

  

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in Patchwork_20802_full:

### IGT changes ###

#### Possible regressions ####

  * igt@i915_selftest@live@memory_region:
    - shard-skl:          NOTRUN -> [INCOMPLETE][1] +1 similar issue
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-skl9/igt@i915_selftest@live@memory_region.html

  
#### Suppressed ####

  The following results come from untrusted machines, tests, or statuses.
  They do not affect the overall result.

  * igt@gem_userptr_blits@huge-split:
    - {shard-rkl}:        [PASS][2] -> [FAIL][3]
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-rkl-1/igt@gem_userptr_blits@huge-split.html
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-rkl-5/igt@gem_userptr_blits@huge-split.html

  * igt@kms_busy@extended-pageflip-modeset-hang-oldfb:
    - {shard-rkl}:        NOTRUN -> [SKIP][4]
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-rkl-1/igt@kms_busy@extended-pageflip-modeset-hang-oldfb.html

  
Known issues
------------

  Here are the changes found in Patchwork_20802_full that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_create@create-massive:
    - shard-apl:          NOTRUN -> [DMESG-WARN][5] ([i915#3002])
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-apl8/igt@gem_create@create-massive.html

  * igt@gem_ctx_isolation@preservation-s3@rcs0:
    - shard-glk:          [PASS][6] -> [INCOMPLETE][7] ([i915#2199])
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-glk1/igt@gem_ctx_isolation@preservation-s3@rcs0.html
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-glk3/igt@gem_ctx_isolation@preservation-s3@rcs0.html

  * igt@gem_ctx_persistence@engines-queued:
    - shard-snb:          NOTRUN -> [SKIP][8] ([fdo#109271] / [i915#1099]) +6 similar issues
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-snb2/igt@gem_ctx_persistence@engines-queued.html

  * igt@gem_eio@unwedge-stress:
    - shard-iclb:         [PASS][9] -> [TIMEOUT][10] ([i915#2369] / [i915#2481] / [i915#3070])
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-iclb6/igt@gem_eio@unwedge-stress.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-iclb3/igt@gem_eio@unwedge-stress.html

  * igt@gem_exec_fair@basic-deadline:
    - shard-apl:          NOTRUN -> [FAIL][11] ([i915#2846])
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-apl6/igt@gem_exec_fair@basic-deadline.html

  * igt@gem_exec_fair@basic-none@vcs1:
    - shard-iclb:         NOTRUN -> [FAIL][12] ([i915#2842]) +1 similar issue
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-iclb4/igt@gem_exec_fair@basic-none@vcs1.html

  * igt@gem_exec_fair@basic-pace-share@rcs0:
    - shard-glk:          [PASS][13] -> [FAIL][14] ([i915#2842])
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-glk9/igt@gem_exec_fair@basic-pace-share@rcs0.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-glk8/igt@gem_exec_fair@basic-pace-share@rcs0.html

  * igt@gem_exec_fair@basic-pace-solo@rcs0:
    - shard-skl:          NOTRUN -> [SKIP][15] ([fdo#109271]) +1 similar issue
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-skl1/igt@gem_exec_fair@basic-pace-solo@rcs0.html

  * igt@gem_exec_fair@basic-pace@vcs0:
    - shard-kbl:          [PASS][16] -> [SKIP][17] ([fdo#109271])
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-kbl6/igt@gem_exec_fair@basic-pace@vcs0.html
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-kbl4/igt@gem_exec_fair@basic-pace@vcs0.html

  * igt@gem_exec_fair@basic-pace@vecs0:
    - shard-kbl:          [PASS][18] -> [FAIL][19] ([i915#2842]) +2 similar issues
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-kbl6/igt@gem_exec_fair@basic-pace@vecs0.html
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-kbl4/igt@gem_exec_fair@basic-pace@vecs0.html
    - shard-iclb:         [PASS][20] -> [FAIL][21] ([i915#2842]) +1 similar issue
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-iclb7/igt@gem_exec_fair@basic-pace@vecs0.html
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-iclb5/igt@gem_exec_fair@basic-pace@vecs0.html

  * igt@gem_exec_fair@basic-throttle@rcs0:
    - shard-iclb:         [PASS][22] -> [FAIL][23] ([i915#2849])
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-iclb5/igt@gem_exec_fair@basic-throttle@rcs0.html
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-iclb1/igt@gem_exec_fair@basic-throttle@rcs0.html

  * igt@gem_mmap_gtt@cpuset-big-copy:
    - shard-iclb:         [PASS][24] -> [FAIL][25] ([i915#307])
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-iclb3/igt@gem_mmap_gtt@cpuset-big-copy.html
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-iclb6/igt@gem_mmap_gtt@cpuset-big-copy.html

  * igt@gem_pread@exhaustion:
    - shard-apl:          NOTRUN -> [WARN][26] ([i915#2658])
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-apl8/igt@gem_pread@exhaustion.html

  * igt@gem_userptr_blits@unsync-unmap-cycles:
    - shard-iclb:         NOTRUN -> [SKIP][27] ([i915#3297])
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-iclb2/igt@gem_userptr_blits@unsync-unmap-cycles.html

  * igt@gem_userptr_blits@vma-merge:
    - shard-snb:          NOTRUN -> [FAIL][28] ([i915#2724])
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-snb2/igt@gem_userptr_blits@vma-merge.html

  * igt@gem_workarounds@suspend-resume-fd:
    - shard-apl:          NOTRUN -> [DMESG-WARN][29] ([i915#180])
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-apl1/igt@gem_workarounds@suspend-resume-fd.html

  * igt@gen9_exec_parse@allowed-single:
    - shard-skl:          [PASS][30] -> [DMESG-WARN][31] ([i915#1436] / [i915#716])
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-skl9/igt@gen9_exec_parse@allowed-single.html
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-skl2/igt@gen9_exec_parse@allowed-single.html

  * igt@gen9_exec_parse@bb-start-cmd:
    - shard-iclb:         NOTRUN -> [SKIP][32] ([i915#2856])
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-iclb2/igt@gen9_exec_parse@bb-start-cmd.html

  * igt@i915_pm_lpsp@kms-lpsp@kms-lpsp-dp:
    - shard-apl:          NOTRUN -> [SKIP][33] ([fdo#109271] / [i915#1937])
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-apl7/igt@i915_pm_lpsp@kms-lpsp@kms-lpsp-dp.html

  * igt@i915_pm_rpm@basic-rte:
    - shard-apl:          NOTRUN -> [FAIL][34] ([i915#579])
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-apl8/igt@i915_pm_rpm@basic-rte.html

  * igt@i915_pm_rpm@drm-resources-equal:
    - shard-iclb:         NOTRUN -> [SKIP][35] ([i915#579])
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-iclb2/igt@i915_pm_rpm@drm-resources-equal.html

  * igt@kms_addfb_basic@invalid-smem-bo-on-discrete:
    - shard-iclb:         NOTRUN -> [SKIP][36] ([i915#3826])
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-iclb2/igt@kms_addfb_basic@invalid-smem-bo-on-discrete.html

  * igt@kms_big_fb@linear-16bpp-rotate-270:
    - shard-iclb:         NOTRUN -> [SKIP][37] ([fdo#110725] / [fdo#111614])
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-iclb2/igt@kms_big_fb@linear-16bpp-rotate-270.html

  * igt@kms_big_fb@x-tiled-32bpp-rotate-90:
    - shard-tglb:         NOTRUN -> [SKIP][38] ([fdo#111614])
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-tglb3/igt@kms_big_fb@x-tiled-32bpp-rotate-90.html

  * igt@kms_big_fb@x-tiled-max-hw-stride-32bpp-rotate-180-hflip:
    - shard-kbl:          NOTRUN -> [SKIP][39] ([fdo#109271] / [i915#3777])
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-kbl1/igt@kms_big_fb@x-tiled-max-hw-stride-32bpp-rotate-180-hflip.html

  * igt@kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-180-hflip:
    - shard-apl:          NOTRUN -> [SKIP][40] ([fdo#109271] / [i915#3777]) +3 similar issues
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-apl6/igt@kms_big_fb@y-tiled-max-hw-stride-64bpp-rotate-180-hflip.html

  * igt@kms_big_fb@yf-tiled-max-hw-stride-32bpp-rotate-0-hflip-async-flip:
    - shard-kbl:          NOTRUN -> [SKIP][41] ([fdo#109271]) +42 similar issues
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-kbl3/igt@kms_big_fb@yf-tiled-max-hw-stride-32bpp-rotate-0-hflip-async-flip.html

  * igt@kms_big_fb@yf-tiled-max-hw-stride-64bpp-rotate-0:
    - shard-apl:          NOTRUN -> [SKIP][42] ([fdo#109271]) +369 similar issues
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-apl8/igt@kms_big_fb@yf-tiled-max-hw-stride-64bpp-rotate-0.html

  * igt@kms_ccs@pipe-a-bad-rotation-90-y_tiled_gen12_rc_ccs_cc:
    - shard-kbl:          NOTRUN -> [SKIP][43] ([fdo#109271] / [i915#3886]) +1 similar issue
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-kbl1/igt@kms_ccs@pipe-a-bad-rotation-90-y_tiled_gen12_rc_ccs_cc.html

  * igt@kms_ccs@pipe-a-ccs-on-another-bo-y_tiled_gen12_mc_ccs:
    - shard-apl:          NOTRUN -> [SKIP][44] ([fdo#109271] / [i915#3886]) +14 similar issues
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-apl6/igt@kms_ccs@pipe-a-ccs-on-another-bo-y_tiled_gen12_mc_ccs.html

  * igt@kms_ccs@pipe-b-bad-pixel-format-y_tiled_ccs:
    - shard-snb:          NOTRUN -> [SKIP][45] ([fdo#109271]) +446 similar issues
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-snb5/igt@kms_ccs@pipe-b-bad-pixel-format-y_tiled_ccs.html

  * igt@kms_ccs@pipe-c-bad-rotation-90-y_tiled_gen12_mc_ccs:
    - shard-iclb:         NOTRUN -> [SKIP][46] ([fdo#109278] / [i915#3886])
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-iclb2/igt@kms_ccs@pipe-c-bad-rotation-90-y_tiled_gen12_mc_ccs.html

  * igt@kms_chamelium@dp-hpd-for-each-pipe:
    - shard-iclb:         NOTRUN -> [SKIP][47] ([fdo#109284] / [fdo#111827]) +2 similar issues
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-iclb2/igt@kms_chamelium@dp-hpd-for-each-pipe.html

  * igt@kms_chamelium@vga-hpd-after-suspend:
    - shard-tglb:         NOTRUN -> [SKIP][48] ([fdo#109284] / [fdo#111827])
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-tglb3/igt@kms_chamelium@vga-hpd-after-suspend.html

  * igt@kms_color_chamelium@pipe-a-ctm-limited-range:
    - shard-apl:          NOTRUN -> [SKIP][49] ([fdo#109271] / [fdo#111827]) +30 similar issues
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-apl1/igt@kms_color_chamelium@pipe-a-ctm-limited-range.html

  * igt@kms_color_chamelium@pipe-d-ctm-0-5:
    - shard-kbl:          NOTRUN -> [SKIP][50] ([fdo#109271] / [fdo#111827]) +3 similar issues
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-kbl7/igt@kms_color_chamelium@pipe-d-ctm-0-5.html

  * igt@kms_color_chamelium@pipe-invalid-ctm-matrix-sizes:
    - shard-snb:          NOTRUN -> [SKIP][51] ([fdo#109271] / [fdo#111827]) +23 similar issues
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-snb7/igt@kms_color_chamelium@pipe-invalid-ctm-matrix-sizes.html

  * igt@kms_content_protection@atomic-dpms:
    - shard-kbl:          NOTRUN -> [TIMEOUT][52] ([i915#1319])
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-kbl1/igt@kms_content_protection@atomic-dpms.html

  * igt@kms_content_protection@srm:
    - shard-apl:          NOTRUN -> [TIMEOUT][53] ([i915#1319])
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-apl2/igt@kms_content_protection@srm.html

  * igt@kms_cursor_edge_walk@pipe-d-256x256-right-edge:
    - shard-iclb:         NOTRUN -> [SKIP][54] ([fdo#109278]) +9 similar issues
   [54]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-iclb2/igt@kms_cursor_edge_walk@pipe-d-256x256-right-edge.html

  * igt@kms_cursor_legacy@cursora-vs-flipb-toggle:
    - shard-iclb:         NOTRUN -> [SKIP][55] ([fdo#109274] / [fdo#109278])
   [55]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-iclb2/igt@kms_cursor_legacy@cursora-vs-flipb-toggle.html

  * igt@kms_dither@fb-8bpc-vs-panel-8bpc@edp-1-pipe-a:
    - shard-iclb:         [PASS][56] -> [SKIP][57] ([i915#3788])
   [56]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-iclb3/igt@kms_dither@fb-8bpc-vs-panel-8bpc@edp-1-pipe-a.html
   [57]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-iclb2/igt@kms_dither@fb-8bpc-vs-panel-8bpc@edp-1-pipe-a.html

  * igt@kms_flip@2x-flip-vs-absolute-wf_vblank-interruptible:
    - shard-iclb:         NOTRUN -> [SKIP][58] ([fdo#109274])
   [58]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-iclb2/igt@kms_flip@2x-flip-vs-absolute-wf_vblank-interruptible.html

  * igt@kms_flip@flip-vs-expired-vblank-interruptible@c-edp1:
    - shard-skl:          [PASS][59] -> [FAIL][60] ([i915#2122]) +1 similar issue
   [59]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-skl3/igt@kms_flip@flip-vs-expired-vblank-interruptible@c-edp1.html
   [60]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-skl7/igt@kms_flip@flip-vs-expired-vblank-interruptible@c-edp1.html

  * igt@kms_flip@flip-vs-suspend-interruptible@a-dp1:
    - shard-kbl:          [PASS][61] -> [DMESG-WARN][62] ([i915#180]) +6 similar issues
   [61]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-kbl2/igt@kms_flip@flip-vs-suspend-interruptible@a-dp1.html
   [62]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-kbl7/igt@kms_flip@flip-vs-suspend-interruptible@a-dp1.html

  * igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytilegen12rcccs:
    - shard-kbl:          NOTRUN -> [SKIP][63] ([fdo#109271] / [i915#2672])
   [63]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-kbl3/igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytilegen12rcccs.html

  * igt@kms_frontbuffer_tracking@fbc-2p-scndscrn-spr-indfb-draw-blt:
    - shard-iclb:         NOTRUN -> [SKIP][64] ([fdo#109280]) +7 similar issues
   [64]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-iclb2/igt@kms_frontbuffer_tracking@fbc-2p-scndscrn-spr-indfb-draw-blt.html

  * igt@kms_hdr@static-toggle-suspend:
    - shard-iclb:         NOTRUN -> [SKIP][65] ([i915#1187])
   [65]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-iclb2/igt@kms_hdr@static-toggle-suspend.html

  * igt@kms_pipe_b_c_ivb@pipe-b-dpms-off-modeset-pipe-c:
    - shard-iclb:         NOTRUN -> [SKIP][66] ([fdo#109289])
   [66]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-iclb2/igt@kms_pipe_b_c_ivb@pipe-b-dpms-off-modeset-pipe-c.html

  * igt@kms_pipe_crc_basic@hang-read-crc-pipe-d:
    - shard-kbl:          NOTRUN -> [SKIP][67] ([fdo#109271] / [i915#533])
   [67]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-kbl7/igt@kms_pipe_crc_basic@hang-read-crc-pipe-d.html

  * igt@kms_plane_alpha_blend@pipe-b-alpha-basic:
    - shard-apl:          NOTRUN -> [FAIL][68] ([fdo#108145] / [i915#265]) +5 similar issues
   [68]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-apl1/igt@kms_plane_alpha_blend@pipe-b-alpha-basic.html

  * igt@kms_psr2_sf@overlay-plane-update-sf-dmg-area-1:
    - shard-iclb:         NOTRUN -> [SKIP][69] ([i915#2920])
   [69]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-iclb2/igt@kms_psr2_sf@overlay-plane-update-sf-dmg-area-1.html

  * igt@kms_psr2_sf@overlay-plane-update-sf-dmg-area-2:
    - shard-apl:          NOTRUN -> [SKIP][70] ([fdo#109271] / [i915#658]) +7 similar issues
   [70]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-apl6/igt@kms_psr2_sf@overlay-plane-update-sf-dmg-area-2.html

  * igt@kms_psr@psr2_no_drrs:
    - shard-iclb:         [PASS][71] -> [SKIP][72] ([fdo#109441]) +1 similar issue
   [71]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-iclb2/igt@kms_psr@psr2_no_drrs.html
   [72]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-iclb8/igt@kms_psr@psr2_no_drrs.html

  * igt@kms_setmode@basic:
    - shard-snb:          NOTRUN -> [FAIL][73] ([i915#31])
   [73]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-snb6/igt@kms_setmode@basic.html

  * igt@kms_vblank@pipe-d-wait-idle:
    - shard-apl:          NOTRUN -> [SKIP][74] ([fdo#109271] / [i915#533]) +5 similar issues
   [74]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-apl7/igt@kms_vblank@pipe-d-wait-idle.html

  * igt@kms_vrr@flip-basic:
    - shard-iclb:         NOTRUN -> [SKIP][75] ([fdo#109502])
   [75]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-iclb2/igt@kms_vrr@flip-basic.html

  * igt@nouveau_crc@pipe-d-ctx-flip-skip-current-frame:
    - shard-iclb:         NOTRUN -> [SKIP][76] ([fdo#109278] / [i915#2530])
   [76]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-iclb2/igt@nouveau_crc@pipe-d-ctx-flip-skip-current-frame.html

  * igt@prime_nv_test@nv_i915_sharing:
    - shard-iclb:         NOTRUN -> [SKIP][77] ([fdo#109291])
   [77]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-iclb2/igt@prime_nv_test@nv_i915_sharing.html

  * igt@sysfs_clients@fair-3:
    - shard-kbl:          NOTRUN -> [SKIP][78] ([fdo#109271] / [i915#2994]) +2 similar issues
   [78]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-kbl3/igt@sysfs_clients@fair-3.html

  * igt@sysfs_clients@sema-10:
    - shard-apl:          NOTRUN -> [SKIP][79] ([fdo#109271] / [i915#2994]) +3 similar issues
   [79]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-apl7/igt@sysfs_clients@sema-10.html

  
#### Possible fixes ####

  * igt@gem_ctx_persistence@many-contexts:
    - {shard-rkl}:        [FAIL][80] ([i915#2410]) -> [PASS][81]
   [80]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-rkl-2/igt@gem_ctx_persistence@many-contexts.html
   [81]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-rkl-1/igt@gem_ctx_persistence@many-contexts.html

  * igt@gem_eio@in-flight-suspend:
    - shard-kbl:          [INCOMPLETE][82] ([i915#155]) -> [PASS][83]
   [82]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-kbl4/igt@gem_eio@in-flight-suspend.html
   [83]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-kbl7/igt@gem_eio@in-flight-suspend.html

  * igt@gem_eio@unwedge-stress:
    - {shard-rkl}:        [TIMEOUT][84] ([i915#3063]) -> [PASS][85]
   [84]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-rkl-6/igt@gem_eio@unwedge-stress.html
   [85]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-rkl-5/igt@gem_eio@unwedge-stress.html

  * igt@gem_exec_fair@basic-none@vcs0:
    - shard-kbl:          [FAIL][86] ([i915#2842]) -> [PASS][87] +1 similar issue
   [86]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-kbl2/igt@gem_exec_fair@basic-none@vcs0.html
   [87]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-kbl7/igt@gem_exec_fair@basic-none@vcs0.html

  * igt@gem_exec_fair@basic-pace@rcs0:
    - {shard-rkl}:        [FAIL][88] ([i915#2842]) -> [PASS][89] +2 similar issues
   [88]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-rkl-5/igt@gem_exec_fair@basic-pace@rcs0.html
   [89]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-rkl-2/igt@gem_exec_fair@basic-pace@rcs0.html

  * igt@gem_exec_fair@basic-throttle@rcs0:
    - shard-glk:          [FAIL][90] ([i915#2842]) -> [PASS][91] +1 similar issue
   [90]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-glk1/igt@gem_exec_fair@basic-throttle@rcs0.html
   [91]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-glk3/igt@gem_exec_fair@basic-throttle@rcs0.html

  * igt@gem_mmap_gtt@cpuset-basic-small-copy-odd:
    - {shard-rkl}:        [FAIL][92] ([i915#307]) -> [PASS][93]
   [92]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-rkl-2/igt@gem_mmap_gtt@cpuset-basic-small-copy-odd.html
   [93]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-rkl-1/igt@gem_mmap_gtt@cpuset-basic-small-copy-odd.html

  * igt@i915_selftest@live@gt_pm:
    - {shard-rkl}:        [DMESG-FAIL][94] ([i915#1021]) -> [PASS][95]
   [94]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-rkl-5/igt@i915_selftest@live@gt_pm.html
   [95]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-rkl-1/igt@i915_selftest@live@gt_pm.html

  * igt@i915_selftest@live@reset:
    - shard-skl:          [INCOMPLETE][96] -> [PASS][97]
   [96]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-skl6/igt@i915_selftest@live@reset.html
   [97]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-skl9/igt@i915_selftest@live@reset.html

  * igt@kms_big_fb@x-tiled-max-hw-stride-64bpp-rotate-180-async-flip:
    - shard-iclb:         [DMESG-WARN][98] ([i915#3621]) -> [PASS][99]
   [98]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-iclb1/igt@kms_big_fb@x-tiled-max-hw-stride-64bpp-rotate-180-async-flip.html
   [99]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-iclb2/igt@kms_big_fb@x-tiled-max-hw-stride-64bpp-rotate-180-async-flip.html

  * igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a:
    - shard-kbl:          [DMESG-WARN][100] ([i915#180]) -> [PASS][101] +1 similar issue
   [100]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-kbl7/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a.html
   [101]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-kbl1/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a.html

  * igt@kms_plane_alpha_blend@pipe-c-coverage-7efc:
    - shard-skl:          [FAIL][102] ([fdo#108145] / [i915#265]) -> [PASS][103]
   [102]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-skl2/igt@kms_plane_alpha_blend@pipe-c-coverage-7efc.html
   [103]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-skl5/igt@kms_plane_alpha_blend@pipe-c-coverage-7efc.html

  * igt@kms_psr@psr2_sprite_plane_move:
    - shard-iclb:         [SKIP][104] ([fdo#109441]) -> [PASS][105] +2 similar issues
   [104]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-iclb4/igt@kms_psr@psr2_sprite_plane_move.html
   [105]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-iclb2/igt@kms_psr@psr2_sprite_plane_move.html

  * igt@kms_vblank@pipe-b-ts-continuation-dpms-suspend:
    - shard-skl:          [INCOMPLETE][106] ([i915#198] / [i915#2828]) -> [PASS][107]
   [106]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-skl7/igt@kms_vblank@pipe-b-ts-continuation-dpms-suspend.html
   [107]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-skl8/igt@kms_vblank@pipe-b-ts-continuation-dpms-suspend.html

  * igt@perf@polling:
    - {shard-rkl}:        [FAIL][108] ([i915#1542]) -> [PASS][109]
   [108]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-rkl-2/igt@perf@polling.html
   [109]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-rkl-1/igt@perf@polling.html

  * igt@sysfs_timeslice_duration@timeout@rcs0:
    - {shard-rkl}:        [FAIL][110] ([i915#3259]) -> [PASS][111] +3 similar issues
   [110]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-rkl-2/igt@sysfs_timeslice_duration@timeout@rcs0.html
   [111]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-rkl-1/igt@sysfs_timeslice_duration@timeout@rcs0.html

  
#### Warnings ####

  * igt@kms_psr2_sf@overlay-primary-update-sf-dmg-area-3:
    - shard-iclb:         [SKIP][112] ([i915#658]) -> [SKIP][113] ([i915#2920]) +2 similar issues
   [112]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-iclb3/igt@kms_psr2_sf@overlay-primary-update-sf-dmg-area-3.html
   [113]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-iclb2/igt@kms_psr2_sf@overlay-primary-update-sf-dmg-area-3.html

  * igt@kms_psr2_sf@primary-plane-update-sf-dmg-area-1:
    - shard-iclb:         [SKIP][114] ([i915#2920]) -> [SKIP][115] ([i915#658]) +2 similar issues
   [114]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-iclb2/igt@kms_psr2_sf@primary-plane-update-sf-dmg-area-1.html
   [115]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-iclb8/igt@kms_psr2_sf@primary-plane-update-sf-dmg-area-1.html

  * igt@runner@aborted:
    - shard-kbl:          ([FAIL][116], [FAIL][117], [FAIL][118], [FAIL][119]) ([i915#1436] / [i915#1814] / [i915#2505] / [i915#3002] / [i915#3363]) -> ([FAIL][120], [FAIL][121], [FAIL][122], [FAIL][123], [FAIL][124]) ([fdo#109271] / [i915#180] / [i915#1814] / [i915#2505] / [i915#3002] / [i915#3363])
   [116]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-kbl7/igt@runner@aborted.html
   [117]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-kbl6/igt@runner@aborted.html
   [118]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-kbl7/igt@runner@aborted.html
   [119]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-kbl2/igt@runner@aborted.html
   [120]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-kbl4/igt@runner@aborted.html
   [121]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-kbl1/igt@runner@aborted.html
   [122]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-kbl6/igt@runner@aborted.html
   [123]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-kbl4/igt@runner@aborted.html
   [124]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-kbl7/igt@runner@aborted.html
    - shard-iclb:         ([FAIL][125], [FAIL][126], [FAIL][127]) ([i915#1814] / [i915#3002]) -> ([FAIL][128], [FAIL][129]) ([i915#3002])
   [125]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-iclb2/igt@runner@aborted.html
   [126]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-iclb1/igt@runner@aborted.html
   [127]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-iclb6/igt@runner@aborted.html
   [128]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-iclb4/igt@runner@aborted.html
   [129]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-iclb8/igt@runner@aborted.html
    - shard-apl:          ([FAIL][130], [FAIL][131], [FAIL][132]) ([i915#180] / [i915#3002] / [i915#3363]) -> ([FAIL][133], [FAIL][134], [FAIL][135], [FAIL][136]) ([fdo#109271] / [i915#180] / [i915#3002] / [i915#3363])
   [130]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-apl3/igt@runner@aborted.html
   [131]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-apl8/igt@runner@aborted.html
   [132]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-apl2/igt@runner@aborted.html
   [133]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-apl2/igt@runner@aborted.html
   [134]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-apl3/igt@runner@aborted.html
   [135]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-apl1/igt@runner@aborted.html
   [136]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-apl8/igt@runner@aborted.html
    - shard-skl:          ([FAIL][137], [FAIL][138]) ([i915#3002] / [i915#3363]) -> ([FAIL][139], [FAIL][140], [FAIL][141]) ([i915#1436] / [i915#2029] / [i915#3002] / [i915#3363])
   [137]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-skl8/igt@runner@aborted.html
   [138]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10474/shard-skl5/igt@runner@aborted.html
   [139]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-skl5/igt@runner@aborted.html
   [140]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-skl10/igt@runner@aborted.html
   [141]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/shard-skl2/igt@runner@aborted.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [fdo#108145]: https://bugs.freedesktop.org/show_bug.cgi?id=108145
  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#109274]: https://bugs.freedesktop.org/show_bug.cgi?id=109274
  [fdo#109278]: https://bugs.freedesktop.org/show_bug.cgi?id=109278
  [fdo#109279]: https://bugs.freedesktop.org/show_bug.cgi?id=109279
  [fdo#109280]: https://bugs.freedesktop.org/show_bug.cgi?id=109280
  [fdo#109283]: https://bugs.freedesktop.org/show_bug.cgi?id=109283
  [fdo#109284]: https://bugs.freedesktop.org/show_bug.cgi?id=109284
  [fdo#109289]: https://bugs.freedesktop.org/show_bug.cgi?id=109289
  [fdo#109291]: https://bugs.freedesktop.org/show_bug.cgi?id=109291
  [fdo#109300]: https://bugs.freedesktop.org/show_bug.cgi?id=109300
  [fdo#109307]: https://bugs.freedesktop.org/show_bug.cgi?id=109307
  [fdo#109308]: https://bugs.freedesktop.org/show_bug.cgi?id=109308
  [fdo#109441]: https://bugs.freedesktop.org/show_bug.cgi?id=109441
  [fdo#109502]: https://bugs.freedesktop.org/show_bug.cgi?id=109502
  [fdo#110542]: https://bugs.freedesktop.org/show_bug.cgi?id=110542
  [fdo#110725]:

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_20802/index.html

[-- Attachment #2: Type: text/html, Size: 35117 bytes --]

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Intel-gfx] [PATCH v6 01/15] drm/i915/pxp: Define PXP component interface
  2021-07-29  2:00   ` [Intel-gfx] " Daniele Ceraolo Spurio
  (?)
@ 2021-08-13  7:51   ` Jani Nikula
  -1 siblings, 0 replies; 64+ messages in thread
From: Jani Nikula @ 2021-08-13  7:51 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio, intel-gfx; +Cc: dri-devel

On Wed, 28 Jul 2021, Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com> wrote:
> This will be used for communication between the i915 driver and the mei
> one. Defining it in a stand-alone patch to avoid circualr dependedencies
> between the patches modifying the 2 drivers.
>
> Split out from an original patch from  Huang, Sean Z
>
> v2: rename the component struct (Rodrigo)
>
> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> ---
>  include/drm/i915_component.h         |  1 +
>  include/drm/i915_pxp_tee_interface.h | 45 ++++++++++++++++++++++++++++
>  2 files changed, 46 insertions(+)
>  create mode 100644 include/drm/i915_pxp_tee_interface.h
>
> diff --git a/include/drm/i915_component.h b/include/drm/i915_component.h
> index 55c3b123581b..c1e2a43d2d1e 100644
> --- a/include/drm/i915_component.h
> +++ b/include/drm/i915_component.h
> @@ -29,6 +29,7 @@
>  enum i915_component_type {
>  	I915_COMPONENT_AUDIO = 1,
>  	I915_COMPONENT_HDCP,
> +	I915_COMPONENT_PXP
>  };
>  
>  /* MAX_PORT is the number of port
> diff --git a/include/drm/i915_pxp_tee_interface.h b/include/drm/i915_pxp_tee_interface.h
> new file mode 100644
> index 000000000000..09b8389152af
> --- /dev/null
> +++ b/include/drm/i915_pxp_tee_interface.h
> @@ -0,0 +1,45 @@
> +/* SPDX-License-Identifier: MIT */
> +/*
> + * Copyright © 2020 Intel Corporation
> + *
> + * Authors:
> + * Vitaly Lubart <vitaly.lubart@intel.com>

IMO we should avoid adding new authors lists in code comments. Git log
provides accurate and up-to-date information, and I don't want patches
where people add their names to authors lists.

BR,
Jani.


> + */
> +
> +#ifndef _I915_PXP_TEE_INTERFACE_H_
> +#define _I915_PXP_TEE_INTERFACE_H_
> +
> +#include <linux/mutex.h>
> +#include <linux/device.h>
> +
> +/**
> + * struct i915_pxp_component_ops - ops for PXP services.
> + * @owner: Module providing the ops
> + * @send: sends data to PXP
> + * @receive: receives data from PXP
> + */
> +struct i915_pxp_component_ops {
> +	/**
> +	 * @owner: owner of the module provding the ops
> +	 */
> +	struct module *owner;
> +
> +	int (*send)(struct device *dev, const void *message, size_t size);
> +	int (*recv)(struct device *dev, void *buffer, size_t size);
> +};
> +
> +/**
> + * struct i915_pxp_component - Used for communication between i915 and TEE
> + * drivers for the PXP services
> + * @tee_dev: device that provide the PXP service from TEE Bus.
> + * @pxp_ops: Ops implemented by TEE driver, used by i915 driver.
> + */
> +struct i915_pxp_component {
> +	struct device *tee_dev;
> +	const struct i915_pxp_component_ops *ops;
> +
> +	/* To protect the above members. */
> +	struct mutex mutex;
> +};
> +
> +#endif /* _I915_TEE_PXP_INTERFACE_H_ */

-- 
Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Intel-gfx] [PATCH v6 09/15] drm/i915/pxp: Implement PXP irq handler
  2021-07-29  2:01   ` [Intel-gfx] " Daniele Ceraolo Spurio
  (?)
@ 2021-08-13 14:28   ` Daniel Vetter
  -1 siblings, 0 replies; 64+ messages in thread
From: Daniel Vetter @ 2021-08-13 14:28 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio
  Cc: intel-gfx, Huang, Sean Z, dri-devel, Chris Wilson, Huang

On Wed, Jul 28, 2021 at 07:01:00PM -0700, Daniele Ceraolo Spurio wrote:
> From: "Huang, Sean Z" <sean.z.huang@intel.com>
> 
> The HW will generate a teardown interrupt when session termination is
> required, which requires i915 to submit a terminating batch. Once the HW
> is done with the termination it will generate another interrupt, at
> which point it is safe to re-create the session.
> 
> Since the termination and re-creation flow is something we want to
> trigger from the driver as well, use a common work function that can be
> called both from the irq handler and from the driver set-up flows, which
> has the addded benefit of allowing us to skip any extra locks because
> the work itself serializes the operations.
> 
> v2: use struct completion instead of bool (Chris)
> v3: drop locks, clean up functions and improve comments (Chris),
>     move to common work function.
> v4: improve comments, simplify wait logic (Rodrigo)
> v5: unconditionally set interrupts, rename state_attacked var (Rodrigo)
> 
> Signed-off-by: Huang, Sean Z <sean.z.huang@intel.com>
> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> ---
>  drivers/gpu/drm/i915/Makefile                |  1 +
>  drivers/gpu/drm/i915/gt/intel_gt_irq.c       |  7 ++
>  drivers/gpu/drm/i915/i915_reg.h              |  1 +
>  drivers/gpu/drm/i915/pxp/intel_pxp.c         | 66 +++++++++++--
>  drivers/gpu/drm/i915/pxp/intel_pxp.h         |  8 ++
>  drivers/gpu/drm/i915/pxp/intel_pxp_irq.c     | 99 ++++++++++++++++++++
>  drivers/gpu/drm/i915/pxp/intel_pxp_irq.h     | 32 +++++++
>  drivers/gpu/drm/i915/pxp/intel_pxp_session.c | 54 ++++++++++-
>  drivers/gpu/drm/i915/pxp/intel_pxp_session.h |  5 +-
>  drivers/gpu/drm/i915/pxp/intel_pxp_tee.c     |  8 +-
>  drivers/gpu/drm/i915/pxp/intel_pxp_types.h   | 18 ++++
>  11 files changed, 283 insertions(+), 16 deletions(-)
>  create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
>  create mode 100644 drivers/gpu/drm/i915/pxp/intel_pxp_irq.h
> 
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index e13bc803e5ce..5dcdf5942d32 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -279,6 +279,7 @@ i915-y += i915_perf.o
>  i915-$(CONFIG_DRM_I915_PXP) += \
>  	pxp/intel_pxp.o \
>  	pxp/intel_pxp_cmd.o \
> +	pxp/intel_pxp_irq.o \
>  	pxp/intel_pxp_session.o \
>  	pxp/intel_pxp_tee.o
>  
> diff --git a/drivers/gpu/drm/i915/gt/intel_gt_irq.c b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
> index b2de83be4d97..699a74582d32 100644
> --- a/drivers/gpu/drm/i915/gt/intel_gt_irq.c
> +++ b/drivers/gpu/drm/i915/gt/intel_gt_irq.c
> @@ -13,6 +13,7 @@
>  #include "intel_lrc_reg.h"
>  #include "intel_uncore.h"
>  #include "intel_rps.h"
> +#include "pxp/intel_pxp_irq.h"
>  
>  static void guc_irq_handler(struct intel_guc *guc, u16 iir)
>  {
> @@ -64,6 +65,9 @@ gen11_other_irq_handler(struct intel_gt *gt, const u8 instance,
>  	if (instance == OTHER_GTPM_INSTANCE)
>  		return gen11_rps_irq_handler(&gt->rps, iir);
>  
> +	if (instance == OTHER_KCR_INSTANCE)
> +		return intel_pxp_irq_handler(&gt->pxp, iir);
> +
>  	WARN_ONCE(1, "unhandled other interrupt instance=0x%x, iir=0x%x\n",
>  		  instance, iir);
>  }
> @@ -196,6 +200,9 @@ void gen11_gt_irq_reset(struct intel_gt *gt)
>  	intel_uncore_write(uncore, GEN11_GPM_WGBOXPERF_INTR_MASK,  ~0);
>  	intel_uncore_write(uncore, GEN11_GUC_SG_INTR_ENABLE, 0);
>  	intel_uncore_write(uncore, GEN11_GUC_SG_INTR_MASK,  ~0);
> +
> +	intel_uncore_write(uncore, GEN11_CRYPTO_RSVD_INTR_ENABLE, 0);
> +	intel_uncore_write(uncore, GEN11_CRYPTO_RSVD_INTR_MASK,  ~0);
>  }
>  
>  void gen11_gt_irq_postinstall(struct intel_gt *gt)
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 70eed4fe3fe3..1a2a71916dfc 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -8086,6 +8086,7 @@ enum {
>  /* irq instances for OTHER_CLASS */
>  #define OTHER_GUC_INSTANCE	0
>  #define OTHER_GTPM_INSTANCE	1
> +#define OTHER_KCR_INSTANCE	4
>  
>  #define GEN11_INTR_IDENTITY_REG(x)	_MMIO(0x190060 + ((x) * 4))
>  
> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
> index 26176d43a02d..b0c7edc10cc3 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
> @@ -2,7 +2,9 @@
>  /*
>   * Copyright(c) 2020 Intel Corporation.
>   */
> +#include <linux/workqueue.h>
>  #include "intel_pxp.h"
> +#include "intel_pxp_irq.h"
>  #include "intel_pxp_session.h"
>  #include "intel_pxp_tee.h"
>  #include "gt/intel_context.h"
> @@ -68,6 +70,16 @@ void intel_pxp_init(struct intel_pxp *pxp)
>  
>  	mutex_init(&pxp->tee_mutex);
>  
> +	/*
> +	 * we'll use the completion to check if there is a termination pending,
> +	 * so we start it as completed and we reinit it when a termination
> +	 * is triggered.
> +	 */
> +	init_completion(&pxp->termination);
> +	complete_all(&pxp->termination);
> +
> +	INIT_WORK(&pxp->session_work, intel_pxp_session_work);
> +
>  	ret = create_vcs_context(pxp);
>  	if (ret)
>  		return;
> @@ -96,19 +108,61 @@ void intel_pxp_fini(struct intel_pxp *pxp)
>  	destroy_vcs_context(pxp);
>  }
>  
> -void intel_pxp_init_hw(struct intel_pxp *pxp)
> +void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp)
>  {
> -	int ret;
> +	pxp->arb_is_valid = false;
> +	reinit_completion(&pxp->termination);
> +}
> +
> +static void intel_pxp_queue_termination(struct intel_pxp *pxp)
> +{
> +	struct intel_gt *gt = pxp_to_gt(pxp);
> +
> +	/*
> +	 * We want to get the same effect as if we received a termination
> +	 * interrupt, so just pretend that we did.
> +	 */
> +	spin_lock_irq(&gt->irq_lock);
> +	intel_pxp_mark_termination_in_progress(pxp);
> +	pxp->session_events |= PXP_TERMINATION_REQUEST;
> +	queue_work(system_unbound_wq, &pxp->session_work);
> +	spin_unlock_irq(&gt->irq_lock);
> +}
>  
> +/*
> + * the arb session is restarted from the irq work when we receive the
> + * termination completion interrupt
> + */
> +int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp)
> +{
> +	if (!intel_pxp_is_enabled(pxp))
> +		return 0;
> +
> +	if (!wait_for_completion_timeout(&pxp->termination,
> +					 msecs_to_jiffies(100)))
> +		return -ETIMEDOUT;
> +
> +	if (!pxp->arb_is_valid)
> +		return -EIO;
> +
> +	return 0;
> +}
> +
> +void intel_pxp_init_hw(struct intel_pxp *pxp)
> +{
>  	kcr_pxp_enable(pxp_to_gt(pxp));
> +	intel_pxp_irq_enable(pxp);
>  
> -	/* always emit a full termination to clean the state */
> -	ret = intel_pxp_terminate_arb_session_and_global(pxp);
> -	if (!ret)
> -		intel_pxp_create_arb_session(pxp);
> +	/*
> +	 * the session could've been attacked while we weren't loaded, so
> +	 * handle it as if it was and re-create it.
> +	 */
> +	intel_pxp_queue_termination(pxp);
>  }
>  
>  void intel_pxp_fini_hw(struct intel_pxp *pxp)
>  {
>  	kcr_pxp_disable(pxp_to_gt(pxp));
> +
> +	intel_pxp_irq_disable(pxp);
>  }
> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
> index 8eeb65af78b1..074b3b980957 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
> @@ -30,6 +30,9 @@ void intel_pxp_fini(struct intel_pxp *pxp);
>  
>  void intel_pxp_init_hw(struct intel_pxp *pxp);
>  void intel_pxp_fini_hw(struct intel_pxp *pxp);
> +
> +void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp);
> +int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp);
>  #else
>  static inline void intel_pxp_init(struct intel_pxp *pxp)
>  {
> @@ -38,6 +41,11 @@ static inline void intel_pxp_init(struct intel_pxp *pxp)
>  static inline void intel_pxp_fini(struct intel_pxp *pxp)
>  {
>  }
> +
> +static inline int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp)
> +{
> +	return 0;
> +}
>  #endif
>  
>  #endif /* __INTEL_PXP_H__ */
> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
> new file mode 100644
> index 000000000000..46eca1e81b9b
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
> @@ -0,0 +1,99 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright(c) 2020 Intel Corporation.
> + */
> +#include <linux/workqueue.h>
> +#include "intel_pxp.h"
> +#include "intel_pxp_irq.h"
> +#include "intel_pxp_session.h"
> +#include "gt/intel_gt_irq.h"
> +#include "i915_irq.h"
> +#include "i915_reg.h"
> +
> +/**
> + * intel_pxp_irq_handler - Handles PXP interrupts.
> + * @pxp: pointer to pxp struct
> + * @iir: interrupt vector
> + */
> +void intel_pxp_irq_handler(struct intel_pxp *pxp, u16 iir)
> +{
> +	struct intel_gt *gt = pxp_to_gt(pxp);
> +
> +	if (GEM_WARN_ON(!intel_pxp_is_enabled(pxp)))
> +		return;
> +
> +	lockdep_assert_held(&gt->irq_lock);
> +
> +	if (unlikely(!iir))
> +		return;
> +
> +	if (iir & (GEN12_DISPLAY_PXP_STATE_TERMINATED_INTERRUPT |
> +		   GEN12_DISPLAY_APP_TERMINATED_PER_FW_REQ_INTERRUPT)) {
> +		/* immediately mark PXP as inactive on termination */
> +		intel_pxp_mark_termination_in_progress(pxp);
> +		pxp->session_events |= PXP_TERMINATION_REQUEST;
> +	}
> +
> +	if (iir & GEN12_DISPLAY_STATE_RESET_COMPLETE_INTERRUPT)
> +		pxp->session_events |= PXP_TERMINATION_COMPLETE;
> +
> +	if (pxp->session_events)
> +		queue_work(system_unbound_wq, &pxp->session_work);
> +}
> +
> +static inline void __pxp_set_interrupts(struct intel_gt *gt, u32 interrupts)
> +{
> +	struct intel_uncore *uncore = gt->uncore;
> +	const u32 mask = interrupts << 16;
> +
> +	intel_uncore_write(uncore, GEN11_CRYPTO_RSVD_INTR_ENABLE, mask);
> +	intel_uncore_write(uncore, GEN11_CRYPTO_RSVD_INTR_MASK,  ~mask);
> +}
> +
> +static inline void pxp_irq_reset(struct intel_gt *gt)
> +{
> +	spin_lock_irq(&gt->irq_lock);
> +	gen11_gt_reset_one_iir(gt, 0, GEN11_KCR);
> +	spin_unlock_irq(&gt->irq_lock);
> +}
> +
> +void intel_pxp_irq_enable(struct intel_pxp *pxp)
> +{
> +	struct intel_gt *gt = pxp_to_gt(pxp);
> +
> +	spin_lock_irq(&gt->irq_lock);
> +
> +	if (!pxp->irq_enabled)
> +		WARN_ON_ONCE(gen11_gt_reset_one_iir(gt, 0, GEN11_KCR));
> +
> +	__pxp_set_interrupts(gt, GEN12_PXP_INTERRUPTS);
> +	pxp->irq_enabled = true;
> +
> +	spin_unlock_irq(&gt->irq_lock);
> +}
> +
> +void intel_pxp_irq_disable(struct intel_pxp *pxp)
> +{
> +	struct intel_gt *gt = pxp_to_gt(pxp);
> +
> +	/*
> +	 * We always need to submit a global termination when we re-enable the
> +	 * interrupts, so there is no need to make sure that the session state
> +	 * makes sense at the end of this function. Just make sure this is not
> +	 * called in a path were the driver consider the session as valid and
> +	 * doesn't call a termination on restart.
> +	 */
> +	GEM_WARN_ON(intel_pxp_is_active(pxp));
> +
> +	spin_lock_irq(&gt->irq_lock);
> +
> +	pxp->irq_enabled = false;
> +	__pxp_set_interrupts(gt, 0);
> +
> +	spin_unlock_irq(&gt->irq_lock);
> +	intel_synchronize_irq(gt->i915);
> +
> +	pxp_irq_reset(gt);
> +
> +	flush_work(&pxp->session_work);
> +}
> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_irq.h b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.h
> new file mode 100644
> index 000000000000..8b5793654844
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.h
> @@ -0,0 +1,32 @@
> +/* SPDX-License-Identifier: MIT */
> +/*
> + * Copyright(c) 2020, Intel Corporation. All rights reserved.
> + */
> +
> +#ifndef __INTEL_PXP_IRQ_H__
> +#define __INTEL_PXP_IRQ_H__
> +
> +#include <linux/types.h>
> +
> +struct intel_pxp;
> +
> +#define GEN12_DISPLAY_PXP_STATE_TERMINATED_INTERRUPT BIT(1)
> +#define GEN12_DISPLAY_APP_TERMINATED_PER_FW_REQ_INTERRUPT BIT(2)
> +#define GEN12_DISPLAY_STATE_RESET_COMPLETE_INTERRUPT BIT(3)
> +
> +#define GEN12_PXP_INTERRUPTS \
> +	(GEN12_DISPLAY_PXP_STATE_TERMINATED_INTERRUPT | \
> +	 GEN12_DISPLAY_APP_TERMINATED_PER_FW_REQ_INTERRUPT | \
> +	 GEN12_DISPLAY_STATE_RESET_COMPLETE_INTERRUPT)
> +
> +#ifdef CONFIG_DRM_I915_PXP
> +void intel_pxp_irq_enable(struct intel_pxp *pxp);
> +void intel_pxp_irq_disable(struct intel_pxp *pxp);
> +void intel_pxp_irq_handler(struct intel_pxp *pxp, u16 iir);
> +#else
> +static inline void intel_pxp_irq_handler(struct intel_pxp *pxp, u16 iir)
> +{
> +}
> +#endif
> +
> +#endif /* __INTEL_PXP_IRQ_H__ */
> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> index b8e24adeb1f3..67c30e534d50 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> @@ -48,7 +48,7 @@ static int pxp_wait_for_session_state(struct intel_pxp *pxp, u32 id, bool in_pla
>  	return ret;
>  }
>  
> -int intel_pxp_create_arb_session(struct intel_pxp *pxp)
> +static int pxp_create_arb_session(struct intel_pxp *pxp)
>  {
>  	struct intel_gt *gt = pxp_to_gt(pxp);
>  	int ret;
> @@ -77,12 +77,13 @@ int intel_pxp_create_arb_session(struct intel_pxp *pxp)
>  	return 0;
>  }
>  
> -int intel_pxp_terminate_arb_session_and_global(struct intel_pxp *pxp)
> +static int pxp_terminate_arb_session_and_global(struct intel_pxp *pxp)
>  {
>  	int ret;
>  	struct intel_gt *gt = pxp_to_gt(pxp);
>  
> -	pxp->arb_is_valid = false;
> +	/* must mark termination in progress calling this function */
> +	GEM_WARN_ON(pxp->arb_is_valid);
>  
>  	/* terminate the hw sessions */
>  	ret = intel_pxp_terminate_session(pxp, ARB_SESSION);
> @@ -101,3 +102,50 @@ int intel_pxp_terminate_arb_session_and_global(struct intel_pxp *pxp)
>  
>  	return ret;
>  }
> +
> +static void pxp_terminate(struct intel_pxp *pxp)
> +{
> +	int ret;
> +
> +	pxp->hw_state_invalidated = true;
> +
> +	/*
> +	 * if we fail to submit the termination there is no point in waiting for
> +	 * it to complete. PXP will be marked as non-active until the next
> +	 * termination is issued.
> +	 */
> +	ret = pxp_terminate_arb_session_and_global(pxp);
> +	if (ret)
> +		complete_all(&pxp->termination);
> +}
> +
> +static void pxp_terminate_complete(struct intel_pxp *pxp)
> +{
> +	/* Re-create the arb session after teardown handle complete */
> +	if (fetch_and_zero(&pxp->hw_state_invalidated))
> +		pxp_create_arb_session(pxp);
> +
> +	complete_all(&pxp->termination);
> +}
> +
> +void intel_pxp_session_work(struct work_struct *work)
> +{
> +	struct intel_pxp *pxp = container_of(work, typeof(*pxp), session_work);
> +	struct intel_gt *gt = pxp_to_gt(pxp);
> +	u32 events = 0;
> +
> +	spin_lock_irq(&gt->irq_lock);
> +	events = fetch_and_zero(&pxp->session_events);
> +	spin_unlock_irq(&gt->irq_lock);
> +
> +	if (!events)
> +		return;
> +
> +	if (events & PXP_TERMINATION_REQUEST) {
> +		events &= ~PXP_TERMINATION_COMPLETE;
> +		pxp_terminate(pxp);
> +	}
> +
> +	if (events & PXP_TERMINATION_COMPLETE)
> +		pxp_terminate_complete(pxp);
> +}
> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.h b/drivers/gpu/drm/i915/pxp/intel_pxp_session.h
> index 7354314b1cc4..ba4c9d2b94b7 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.h
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.h
> @@ -8,9 +8,8 @@
>  
>  #include <linux/types.h>
>  
> -struct intel_pxp;
> +struct work_struct;
>  
> -int intel_pxp_create_arb_session(struct intel_pxp *pxp);
> -int intel_pxp_terminate_arb_session_and_global(struct intel_pxp *pxp);
> +void intel_pxp_session_work(struct work_struct *work);
>  
>  #endif /* __INTEL_PXP_SESSION_H__ */
> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
> index 3662bf67407a..7693540dc1f9 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
> @@ -80,6 +80,7 @@ static int i915_pxp_tee_component_bind(struct device *i915_kdev,
>  {
>  	struct drm_i915_private *i915 = kdev_to_i915(i915_kdev);
>  	struct intel_pxp *pxp = i915_dev_to_pxp(i915_kdev);
> +	int ret;
>  
>  	mutex_lock(&pxp->tee_mutex);
>  	pxp->pxp_component = data;
> @@ -88,15 +89,14 @@ static int i915_pxp_tee_component_bind(struct device *i915_kdev,
>  
>  	/* the component is required to fully start the PXP HW */
>  	intel_pxp_init_hw(pxp);
> -
> -	if (!pxp->arb_is_valid) {
> +	ret = intel_pxp_wait_for_arb_start(pxp);
> +	if (ret) {
>  		drm_err(&i915->drm, "Failed to create arb session during bind\n");
>  		intel_pxp_fini_hw(pxp);
>  		pxp->pxp_component = NULL;
> -		return -EIO;
>  	}
>  
> -	return 0;
> +	return ret;
>  }
>  
>  static void i915_pxp_tee_component_unbind(struct device *i915_kdev,
> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
> index a4797a98c1f9..475e3312c287 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
> @@ -6,8 +6,10 @@
>  #ifndef __INTEL_PXP_TYPES_H__
>  #define __INTEL_PXP_TYPES_H__
>  
> +#include <linux/completion.h>
>  #include <linux/mutex.h>
>  #include <linux/types.h>
> +#include <linux/workqueue.h>
>  
>  struct intel_context;
>  struct i915_pxp_component;
> @@ -25,6 +27,22 @@ struct intel_pxp {
>  	bool arb_is_valid;
>  
>  	struct mutex tee_mutex; /* protects the tee channel binding */
> +
> +	/*
> +	 * If the HW perceives an attack on the integrity of the encryption it
> +	 * will invalidate the keys and expect SW to re-initialize the session.
> +	 * We keep track of this state to make sure we only re-start the arb
> +	 * session when required.
> +	 */

Please convert these into kerneldoc, pull them somewhere into driver docs,
and then document the locking rules for all the members here. At least
where relevant. Even if the locking rules are "only &session_work mutates
this completion" or whatever the rules are.

Yeah I know this is very late, but I've read too much i915-gem/gt/core
locking code, and it's way too much incomprehensible overall. And probably
worse, not documented at all. So we need to step up here.
-Daniel

> +	bool hw_state_invalidated;
> +
> +	bool irq_enabled;
> +	struct completion termination;
> +
> +	struct work_struct session_work;
> +	u32 session_events; /* protected with gt->irq_lock */
> +#define PXP_TERMINATION_REQUEST  BIT(0)
> +#define PXP_TERMINATION_COMPLETE BIT(1)
>  };
>  
>  #endif /* __INTEL_PXP_TYPES_H__ */
> -- 
> 2.32.0
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Intel-gfx] [PATCH v6 10/15] drm/i915/pxp: interfaces for using protected objects
  2021-07-29  2:01   ` [Intel-gfx] " Daniele Ceraolo Spurio
  (?)
  (?)
@ 2021-08-13 14:37   ` Daniel Vetter
  2021-08-13 14:42     ` Daniel Vetter
  2021-08-13 15:18     ` Daniele Ceraolo Spurio
  -1 siblings, 2 replies; 64+ messages in thread
From: Daniel Vetter @ 2021-08-13 14:37 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio
  Cc: intel-gfx, Daniel Vetter, Chris Wilson, dri-devel, Bommu Krishnaiah

On Wed, Jul 28, 2021 at 07:01:01PM -0700, Daniele Ceraolo Spurio wrote:
> This api allow user mode to create protected buffers and to mark
> contexts as making use of such objects. Only when using contexts
> marked in such a way is the execution guaranteed to work as expected.
> 
> Contexts can only be marked as using protected content at creation time
> (i.e. the parameter is immutable) and they must be both bannable and not
> recoverable.
> 
> All protected objects and contexts that have backing storage will be
> considered invalid when the PXP session is destroyed and all new
> submissions using them will be rejected. All intel contexts within the
> invalidated gem contexts will be marked banned. A new flag has been
> added to the RESET_STATS ioctl to report the context invalidation to
> userspace.
> 
> This patch was previously sent as 2 separate patches, which have been
> squashed following a request to have all the uapi in a single patch.
> I've retained the s-o-b from both.
> 
> v5: squash patches, rebase on proto_ctx, update kerneldoc
> 
> v6: rebase on obj create_ext changes
> 
> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
> Signed-off-by: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
> Cc: Jason Ekstrand <jason@jlekstrand.net>
> Cc: Daniel Vetter <daniel.vetter@intel.com>
> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> #v5
> ---
>  drivers/gpu/drm/i915/gem/i915_gem_context.c   | 68 ++++++++++++--
>  drivers/gpu/drm/i915/gem/i915_gem_context.h   | 18 ++++
>  .../gpu/drm/i915/gem/i915_gem_context_types.h |  2 +
>  drivers/gpu/drm/i915/gem/i915_gem_create.c    | 75 ++++++++++++----
>  .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 40 ++++++++-
>  drivers/gpu/drm/i915/gem/i915_gem_object.c    |  6 ++
>  drivers/gpu/drm/i915/gem/i915_gem_object.h    | 12 +++
>  .../gpu/drm/i915/gem/i915_gem_object_types.h  |  9 ++
>  drivers/gpu/drm/i915/pxp/intel_pxp.c          | 89 +++++++++++++++++++
>  drivers/gpu/drm/i915/pxp/intel_pxp.h          | 15 ++++
>  drivers/gpu/drm/i915/pxp/intel_pxp_session.c  |  3 +
>  drivers/gpu/drm/i915/pxp/intel_pxp_types.h    |  5 ++
>  include/uapi/drm/i915_drm.h                   | 55 +++++++++++-
>  13 files changed, 371 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> index cff72679ad7c..0cd3e2d06188 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> @@ -77,6 +77,8 @@
>  #include "gt/intel_gpu_commands.h"
>  #include "gt/intel_ring.h"
>  
> +#include "pxp/intel_pxp.h"
> +
>  #include "i915_gem_context.h"
>  #include "i915_trace.h"
>  #include "i915_user_extensions.h"
> @@ -241,6 +243,25 @@ static int proto_context_set_persistence(struct drm_i915_private *i915,
>  	return 0;
>  }
>  
> +static int proto_context_set_protected(struct drm_i915_private *i915,
> +				       struct i915_gem_proto_context *pc,
> +				       bool protected)
> +{
> +	int ret = 0;
> +
> +	if (!intel_pxp_is_enabled(&i915->gt.pxp))
> +		ret = -ENODEV;
> +	else if (!protected)
> +		pc->user_flags &= ~BIT(UCONTEXT_PROTECTED);
> +	else if ((pc->user_flags & BIT(UCONTEXT_RECOVERABLE)) ||
> +		 !(pc->user_flags & BIT(UCONTEXT_BANNABLE)))
> +		ret = -EPERM;
> +	else
> +		pc->user_flags |= BIT(UCONTEXT_PROTECTED);
> +
> +	return ret;
> +}
> +
>  static struct i915_gem_proto_context *
>  proto_context_create(struct drm_i915_private *i915, unsigned int flags)
>  {
> @@ -686,6 +707,8 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
>  			ret = -EPERM;
>  		else if (args->value)
>  			pc->user_flags |= BIT(UCONTEXT_BANNABLE);
> +		else if (pc->user_flags & BIT(UCONTEXT_PROTECTED))
> +			ret = -EPERM;
>  		else
>  			pc->user_flags &= ~BIT(UCONTEXT_BANNABLE);
>  		break;
> @@ -693,10 +716,12 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
>  	case I915_CONTEXT_PARAM_RECOVERABLE:
>  		if (args->size)
>  			ret = -EINVAL;
> -		else if (args->value)
> -			pc->user_flags |= BIT(UCONTEXT_RECOVERABLE);
> -		else
> +		else if (!args->value)
>  			pc->user_flags &= ~BIT(UCONTEXT_RECOVERABLE);
> +		else if (pc->user_flags & BIT(UCONTEXT_PROTECTED))
> +			ret = -EPERM;
> +		else
> +			pc->user_flags |= BIT(UCONTEXT_RECOVERABLE);
>  		break;
>  
>  	case I915_CONTEXT_PARAM_PRIORITY:
> @@ -724,6 +749,11 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
>  						    args->value);
>  		break;
>  
> +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
> +		ret = proto_context_set_protected(fpriv->dev_priv, pc,
> +						  args->value);
> +		break;
> +
>  	case I915_CONTEXT_PARAM_NO_ZEROMAP:
>  	case I915_CONTEXT_PARAM_BAN_PERIOD:
>  	case I915_CONTEXT_PARAM_RINGSIZE:
> @@ -1798,6 +1828,18 @@ static int set_priority(struct i915_gem_context *ctx,
>  	return 0;
>  }
>  
> +static int get_protected(struct i915_gem_context *ctx,
> +			 struct drm_i915_gem_context_param *args)
> +{
> +	if (!intel_pxp_is_enabled(&ctx->i915->gt.pxp))
> +		return -ENODEV;
> +
> +	args->size = 0;
> +	args->value = i915_gem_context_uses_protected_content(ctx);
> +
> +	return 0;
> +}
> +
>  static int ctx_setparam(struct drm_i915_file_private *fpriv,
>  			struct i915_gem_context *ctx,
>  			struct drm_i915_gem_context_param *args)
> @@ -1821,6 +1863,8 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
>  			ret = -EPERM;
>  		else if (args->value)
>  			i915_gem_context_set_bannable(ctx);
> +		else if (i915_gem_context_uses_protected_content(ctx))
> +			ret = -EPERM; /* can't clear this for protected contexts */
>  		else
>  			i915_gem_context_clear_bannable(ctx);
>  		break;
> @@ -1828,10 +1872,12 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
>  	case I915_CONTEXT_PARAM_RECOVERABLE:
>  		if (args->size)
>  			ret = -EINVAL;
> -		else if (args->value)
> -			i915_gem_context_set_recoverable(ctx);
> -		else
> +		else if (!args->value)
>  			i915_gem_context_clear_recoverable(ctx);
> +		else if (i915_gem_context_uses_protected_content(ctx))
> +			ret = -EPERM; /* can't set this for protected contexts */
> +		else
> +			i915_gem_context_set_recoverable(ctx);
>  		break;
>  
>  	case I915_CONTEXT_PARAM_PRIORITY:
> @@ -1846,6 +1892,7 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
>  		ret = set_persistence(ctx, args);
>  		break;
>  
> +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
>  	case I915_CONTEXT_PARAM_NO_ZEROMAP:
>  	case I915_CONTEXT_PARAM_BAN_PERIOD:
>  	case I915_CONTEXT_PARAM_RINGSIZE:
> @@ -2174,6 +2221,10 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
>  		args->value = i915_gem_context_is_persistent(ctx);
>  		break;
>  
> +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
> +		ret = get_protected(ctx, args);
> +		break;
> +
>  	case I915_CONTEXT_PARAM_NO_ZEROMAP:
>  	case I915_CONTEXT_PARAM_BAN_PERIOD:
>  	case I915_CONTEXT_PARAM_ENGINES:
> @@ -2250,6 +2301,11 @@ int i915_gem_context_reset_stats_ioctl(struct drm_device *dev,
>  	args->batch_active = atomic_read(&ctx->guilty_count);
>  	args->batch_pending = atomic_read(&ctx->active_count);
>  
> +	/* re-use args->flags for output flags */
> +	args->flags = 0;
> +	if (i915_gem_context_invalidated(ctx))
> +		args->flags |= I915_CONTEXT_INVALIDATED;
> +
>  	i915_gem_context_put(ctx);
>  	return 0;
>  }
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.h b/drivers/gpu/drm/i915/gem/i915_gem_context.h
> index 18060536b0c2..d932a70122fa 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_context.h
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.h
> @@ -108,6 +108,24 @@ i915_gem_context_clear_user_engines(struct i915_gem_context *ctx)
>  	clear_bit(CONTEXT_USER_ENGINES, &ctx->flags);
>  }
>  
> +static inline bool
> +i915_gem_context_invalidated(const struct i915_gem_context *ctx)
> +{
> +	return test_bit(CONTEXT_INVALID, &ctx->flags);
> +}
> +
> +static inline void
> +i915_gem_context_set_invalid(struct i915_gem_context *ctx)
> +{
> +	set_bit(CONTEXT_INVALID, &ctx->flags);

Do we _really_ need a new bit in this already very complex state
machinery, and can't we reuse the BANNED flag instead?

This ctx->flags is atomic, unorderd, and that means you need barriers and
everything.

If you don't actually need the atomic state bit machinery because you're
using simple locking, then pls use your own boolean, and document by which
lock it's protected.

> +}
> +
> +static inline bool
> +i915_gem_context_uses_protected_content(const struct i915_gem_context *ctx)
> +{
> +	return test_bit(UCONTEXT_PROTECTED, &ctx->user_flags);

For immutable state (I really hope this is immutable) pls don't reuse the
atomic bitfield of mutable state, but create a flag of your own.

Also please document all the rules around how this is set/changed in the
kerneldoc header comments for the data structure. Finally if you never set
it except at creation.

> +}
> +
>  /* i915_gem_context.c */
>  void i915_gem_init__contexts(struct drm_i915_private *i915);
>  
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
> index 94c03a97cb77..1aa2290aa3c7 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
> @@ -301,6 +301,7 @@ struct i915_gem_context {
>  #define UCONTEXT_BANNABLE		2
>  #define UCONTEXT_RECOVERABLE		3
>  #define UCONTEXT_PERSISTENCE		4
> +#define UCONTEXT_PROTECTED		5
>  
>  	/**
>  	 * @flags: small set of booleans
> @@ -308,6 +309,7 @@ struct i915_gem_context {
>  	unsigned long flags;
>  #define CONTEXT_CLOSED			0
>  #define CONTEXT_USER_ENGINES		1
> +#define CONTEXT_INVALID			2
>  
>  	/** @mutex: guards everything that isn't engines or handles_vma */
>  	struct mutex mutex;
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c b/drivers/gpu/drm/i915/gem/i915_gem_create.c
> index 23fee13a3384..0e48629316bb 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
> @@ -6,6 +6,7 @@
>  #include "gem/i915_gem_ioctls.h"
>  #include "gem/i915_gem_lmem.h"
>  #include "gem/i915_gem_region.h"
> +#include "pxp/intel_pxp.h"
>  
>  #include "i915_drv.h"
>  #include "i915_trace.h"
> @@ -82,21 +83,11 @@ static int i915_gem_publish(struct drm_i915_gem_object *obj,
>  	return 0;
>  }
>  
> -/**
> - * Creates a new object using the same path as DRM_I915_GEM_CREATE_EXT
> - * @i915: i915 private
> - * @size: size of the buffer, in bytes
> - * @placements: possible placement regions, in priority order
> - * @n_placements: number of possible placement regions
> - *
> - * This function is exposed primarily for selftests and does very little
> - * error checking.  It is assumed that the set of placement regions has
> - * already been verified to be valid.
> - */
> -struct drm_i915_gem_object *
> -__i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
> -			      struct intel_memory_region **placements,
> -			      unsigned int n_placements)
> +static struct drm_i915_gem_object *
> +__i915_gem_object_create_user_ext(struct drm_i915_private *i915, u64 size,
> +				  struct intel_memory_region **placements,
> +				  unsigned int n_placements,
> +				  unsigned int ext_flags)
>  {
>  	struct intel_memory_region *mr = placements[0];
>  	struct drm_i915_gem_object *obj;
> @@ -135,6 +126,12 @@ __i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
>  
>  	GEM_BUG_ON(size != obj->base.size);
>  
> +	/* Add any flag set by create_ext options */
> +	flags |= ext_flags;
> +
> +	if (i915_gem_object_is_protected(obj))
> +		intel_pxp_object_add(obj);
> +
>  	trace_i915_gem_object_create(obj);
>  	return obj;
>  
> @@ -145,6 +142,26 @@ __i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
>  	return ERR_PTR(ret);
>  }
>  
> +/**
> + * Creates a new object using the same path as DRM_I915_GEM_CREATE_EXT
> + * @i915: i915 private
> + * @size: size of the buffer, in bytes
> + * @placements: possible placement regions, in priority order
> + * @n_placements: number of possible placement regions
> + *
> + * This function is exposed primarily for selftests and does very little
> + * error checking.  It is assumed that the set of placement regions has
> + * already been verified to be valid.
> + */
> +struct drm_i915_gem_object *
> +__i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
> +			      struct intel_memory_region **placements,
> +			      unsigned int n_placements)
> +{
> +	return __i915_gem_object_create_user_ext(i915, size, placements,
> +						 n_placements, 0);
> +}
> +
>  int
>  i915_gem_dumb_create(struct drm_file *file,
>  		     struct drm_device *dev,
> @@ -224,6 +241,7 @@ struct create_ext {
>  	struct drm_i915_private *i915;
>  	struct intel_memory_region *placements[INTEL_REGION_UNKNOWN];
>  	unsigned int n_placements;
> +	unsigned long flags;
>  };
>  
>  static void repr_placements(char *buf, size_t size,
> @@ -356,8 +374,28 @@ static int ext_set_placements(struct i915_user_extension __user *base,
>  	return set_placements(&ext, data);
>  }
>  
> +static int ext_set_protected(struct i915_user_extension __user *base, void *data)
> +{
> +	struct drm_i915_gem_create_ext_protected_content ext;
> +	struct create_ext *ext_data = data;
> +
> +	if (copy_from_user(&ext, base, sizeof(ext)))
> +		return -EFAULT;
> +
> +	if (ext.flags)
> +		return -EINVAL;
> +
> +	if (!intel_pxp_is_enabled(&ext_data->i915->gt.pxp))
> +		return -ENODEV;
> +
> +	ext_data->flags |= I915_BO_PROTECTED;
> +
> +	return 0;
> +}
> +
>  static const i915_user_extension_fn create_extensions[] = {
>  	[I915_GEM_CREATE_EXT_MEMORY_REGIONS] = ext_set_placements,
> +	[I915_GEM_CREATE_EXT_PROTECTED_CONTENT] = ext_set_protected,
>  };
>  
>  /**
> @@ -392,9 +430,10 @@ i915_gem_create_ext_ioctl(struct drm_device *dev, void *data,
>  		ext_data.n_placements = 1;
>  	}
>  
> -	obj = __i915_gem_object_create_user(i915, args->size,
> -					    ext_data.placements,
> -					    ext_data.n_placements);
> +	obj = __i915_gem_object_create_user_ext(i915, args->size,
> +						ext_data.placements,
> +						ext_data.n_placements,
> +						ext_data.flags);
>  	if (IS_ERR(obj))
>  		return PTR_ERR(obj);
>  
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> index 1ed7475de454..04f33d163340 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> @@ -21,6 +21,8 @@
>  #include "gt/intel_gt_pm.h"
>  #include "gt/intel_ring.h"
>  
> +#include "pxp/intel_pxp.h"
> +
>  #include "i915_drv.h"
>  #include "i915_gem_clflush.h"
>  #include "i915_gem_context.h"
> @@ -751,6 +753,11 @@ static int eb_select_context(struct i915_execbuffer *eb)
>  	if (unlikely(IS_ERR(ctx)))
>  		return PTR_ERR(ctx);
>  
> +	if (i915_gem_context_invalidated(ctx)) {
> +		i915_gem_context_put(ctx);
> +		return -EACCES;
> +	}
> +
>  	eb->gem_context = ctx;
>  	if (rcu_access_pointer(ctx->vm))
>  		eb->invalid_flags |= EXEC_OBJECT_NEEDS_GTT;
> @@ -819,7 +826,7 @@ static struct i915_vma *eb_lookup_vma(struct i915_execbuffer *eb, u32 handle)
>  	do {
>  		struct drm_i915_gem_object *obj;
>  		struct i915_vma *vma;
> -		int err;
> +		int err = 0;
>  
>  		rcu_read_lock();
>  		vma = radix_tree_lookup(&eb->gem_context->handles_vma, handle);
> @@ -833,6 +840,26 @@ static struct i915_vma *eb_lookup_vma(struct i915_execbuffer *eb, u32 handle)
>  		if (unlikely(!obj))
>  			return ERR_PTR(-ENOENT);
>  
> +		/*
> +		 * If the user has opted-in for protected-object tracking, make
> +		 * sure the object encryption can be used.
> +		 * We only need to do this when the object is first used with
> +		 * this context, because the context itself will be banned when
> +		 * the protected objects become invalid.
> +		 */
> +		if (i915_gem_context_uses_protected_content(eb->gem_context) &&
> +		    i915_gem_object_is_protected(obj)) {
> +			if (!intel_pxp_is_active(&vm->gt->pxp))
> +				err = -ENODEV;
> +			else if (!i915_gem_object_has_valid_protection(obj))
> +				err = -ENOEXEC;
> +
> +			if (err) {
> +				i915_gem_object_put(obj);
> +				return ERR_PTR(err);
> +			}
> +		}
> +
>  		vma = i915_vma_instance(obj, vm, NULL);
>  		if (IS_ERR(vma)) {
>  			i915_gem_object_put(obj);
> @@ -2752,6 +2779,17 @@ eb_select_engine(struct i915_execbuffer *eb)
>  
>  	intel_gt_pm_get(ce->engine->gt);
>  
> +	if (i915_gem_context_uses_protected_content(eb->gem_context)) {
> +		err = intel_pxp_wait_for_arb_start(&ce->engine->gt->pxp);
> +		if (err)
> +			goto err;
> +
> +		if (i915_gem_context_invalidated(eb->gem_context)) {
> +			err = -EACCES;

Shouldn't the normal banned context handling takee care of anything that
slips through? Rolling your own racy invalidation checks doesn't look like
a good idea.

> +			goto err;
> +		}
> +	}
> +
>  	if (!test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
>  		err = intel_context_alloc_state(ce);
>  		if (err)
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c
> index 6fb9afb65034..658a42a7fa07 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
> @@ -25,6 +25,7 @@
>  #include <linux/sched/mm.h>
>  
>  #include "display/intel_frontbuffer.h"
> +#include "pxp/intel_pxp.h"
>  #include "i915_drv.h"
>  #include "i915_gem_clflush.h"
>  #include "i915_gem_context.h"
> @@ -73,6 +74,8 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj,
>  	INIT_LIST_HEAD(&obj->lut_list);
>  	spin_lock_init(&obj->lut_lock);
>  
> +	INIT_LIST_HEAD(&obj->pxp_link);
> +
>  	spin_lock_init(&obj->mmo.lock);
>  	obj->mmo.offsets = RB_ROOT;
>  
> @@ -231,6 +234,9 @@ void __i915_gem_free_object(struct drm_i915_gem_object *obj)
>  		spin_unlock(&obj->vma.lock);
>  	}
>  
> +	if (i915_gem_object_has_valid_protection(obj))
> +		intel_pxp_object_remove(obj);
> +
>  	__i915_gem_object_free_mmaps(obj);
>  
>  	GEM_BUG_ON(!list_empty(&obj->lut_list));
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h
> index 48112b9d76df..137ae2723514 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
> @@ -269,6 +269,18 @@ i915_gem_object_clear_tiling_quirk(struct drm_i915_gem_object *obj)
>  	clear_bit(I915_TILING_QUIRK_BIT, &obj->flags);
>  }
>  
> +static inline bool
> +i915_gem_object_is_protected(const struct drm_i915_gem_object *obj)
> +{
> +	return obj->flags & I915_BO_PROTECTED;
> +}
> +
> +static inline bool
> +i915_gem_object_has_valid_protection(const struct drm_i915_gem_object *obj)
> +{
> +	return i915_gem_object_is_protected(obj) && !list_empty(&obj->pxp_link);
> +}
> +
>  static inline bool
>  i915_gem_object_type_has(const struct drm_i915_gem_object *obj,
>  			 unsigned long flags)
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> index 2471f36aaff3..38e4a190607a 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> @@ -298,6 +298,7 @@ struct drm_i915_gem_object {
>  			     I915_BO_ALLOC_USER)
>  #define I915_BO_READONLY         BIT(4)
>  #define I915_TILING_QUIRK_BIT    5 /* unknown swizzling; do not release! */
> +#define I915_BO_PROTECTED        BIT(6)
>  
>  	/**
>  	 * @mem_flags - Mutable placement-related flags
> @@ -537,6 +538,14 @@ struct drm_i915_gem_object {
>  		bool created:1;
>  	} ttm;
>  
> +	/*
> +	 * When the PXP session is invalidated, we need to mark all protected
> +	 * objects as invalid. To easily do so we add them all to a list. The
> +	 * presence on the list is used to check if the encryption is valid or
> +	 * not.
> +	 */
> +	struct list_head pxp_link;
> +
>  	/** Record of address bit 17 of each page at last unbind. */
>  	unsigned long *bit_17;
>  
> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
> index b0c7edc10cc3..f418281e8c10 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
> @@ -7,6 +7,7 @@
>  #include "intel_pxp_irq.h"
>  #include "intel_pxp_session.h"
>  #include "intel_pxp_tee.h"
> +#include "gem/i915_gem_context.h"
>  #include "gt/intel_context.h"
>  #include "i915_drv.h"
>  
> @@ -70,6 +71,9 @@ void intel_pxp_init(struct intel_pxp *pxp)
>  
>  	mutex_init(&pxp->tee_mutex);
>  
> +	spin_lock_init(&pxp->lock);
> +	INIT_LIST_HEAD(&pxp->protected_objects);
> +
>  	/*
>  	 * we'll use the completion to check if there is a termination pending,
>  	 * so we start it as completed and we reinit it when a termination
> @@ -166,3 +170,88 @@ void intel_pxp_fini_hw(struct intel_pxp *pxp)
>  
>  	intel_pxp_irq_disable(pxp);
>  }
> +
> +int intel_pxp_object_add(struct drm_i915_gem_object *obj)
> +{
> +	struct intel_pxp *pxp = &to_i915(obj->base.dev)->gt.pxp;
> +
> +	if (!intel_pxp_is_enabled(pxp))
> +		return -ENODEV;
> +
> +	if (!list_empty(&obj->pxp_link))
> +		return -EEXIST;
> +
> +	spin_lock_irq(&pxp->lock);
> +	list_add(&obj->pxp_link, &pxp->protected_objects);
> +	spin_unlock_irq(&pxp->lock);
> +
> +	return 0;
> +}
> +
> +void intel_pxp_object_remove(struct drm_i915_gem_object *obj)
> +{
> +	struct intel_pxp *pxp = &to_i915(obj->base.dev)->gt.pxp;
> +
> +	if (!intel_pxp_is_enabled(pxp))
> +		return;
> +
> +	spin_lock_irq(&pxp->lock);
> +	list_del_init(&obj->pxp_link);
> +	spin_unlock_irq(&pxp->lock);
> +}
> +
> +void intel_pxp_invalidate(struct intel_pxp *pxp)

There is a lot of locking going on here. Please make sure it's all
properly documented what the rules are in kerneldoc, even for existing
stuff.

Especially anytime there's anything tricky going on, like:
- kref_get_unless_zero
- test_bit (that's an unorderd atomic, so either you don't actually need
  the atomic, or you need a pile of barriers and comments about them)
- hiddent atomic ops like intel_context_set_banned or
  i915_gem_context_set_invalid also need great care, least because the
  current rules aren't documented really. So step one here before using
  them is documenting the rules of how banning works.

> +{
> +	struct drm_i915_private *i915 = pxp_to_gt(pxp)->i915;
> +	struct drm_i915_gem_object *obj, *tmp;
> +	struct i915_gem_context *ctx, *cn;
> +
> +	/* delete objects that have been used with the invalidated session */
> +	spin_lock_irq(&pxp->lock);
> +	list_for_each_entry_safe(obj, tmp, &pxp->protected_objects, pxp_link) {
> +		if (i915_gem_object_has_pages(obj))
> +			list_del_init(&obj->pxp_link);
> +	}
> +	spin_unlock_irq(&pxp->lock);
> +
> +	/* 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) {
> +		struct i915_gem_engines_iter it;
> +		struct intel_context *ce;
> +
> +		if (!kref_get_unless_zero(&ctx->ref))
> +			continue;
> +
> +		if (likely(!i915_gem_context_uses_protected_content(ctx)) ||
> +		    i915_gem_context_invalidated(ctx)) {
> +			i915_gem_context_put(ctx);
> +			continue;
> +		}
> +
> +		spin_unlock_irq(&i915->gem.contexts.lock);
> +
> +		/*
> +		 * Note that by the time we get here the HW keys are already
> +		 * long gone, so any batch using them that's already on the
> +		 * engines is very likely a lost cause (and it has probably
> +		 * already hung the engine). Therefore, we skip attempting to
> +		 * pull the running context out of the HW and we prioritize
> +		 * bringing the session back as soon as possible.
> +		 */
> +		for_each_gem_engine(ce, i915_gem_context_lock_engines(ctx), it) {
> +			/* only invalidate if at least one ce was allocated */
> +			if (test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
> +				intel_context_set_banned(ce);
> +				i915_gem_context_set_invalid(ctx);
> +			}
> +		}
> +		i915_gem_context_unlock_engines(ctx);
> +
> +		spin_lock_irq(&i915->gem.contexts.lock);
> +		list_safe_reset_next(ctx, cn, link);
> +		i915_gem_context_put(ctx);
> +	}
> +	spin_unlock_irq(&i915->gem.contexts.lock);
> +}
> +
> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
> index 074b3b980957..4f7647f34153 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
> @@ -9,6 +9,8 @@
>  #include "gt/intel_gt_types.h"
>  #include "intel_pxp_types.h"
>  
> +struct drm_i915_gem_object;
> +
>  static inline struct intel_gt *pxp_to_gt(const struct intel_pxp *pxp)
>  {
>  	return container_of(pxp, struct intel_gt, pxp);
> @@ -33,6 +35,11 @@ void intel_pxp_fini_hw(struct intel_pxp *pxp);
>  
>  void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp);
>  int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp);
> +
> +int intel_pxp_object_add(struct drm_i915_gem_object *obj);
> +void intel_pxp_object_remove(struct drm_i915_gem_object *obj);
> +
> +void intel_pxp_invalidate(struct intel_pxp *pxp);
>  #else
>  static inline void intel_pxp_init(struct intel_pxp *pxp)
>  {
> @@ -46,6 +53,14 @@ static inline int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp)
>  {
>  	return 0;
>  }
> +
> +static inline int intel_pxp_object_add(struct drm_i915_gem_object *obj)
> +{
> +	return 0;
> +}
> +static inline void intel_pxp_object_remove(struct drm_i915_gem_object *obj)
> +{
> +}
>  #endif
>  
>  #endif /* __INTEL_PXP_H__ */
> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> index 67c30e534d50..0edd563a653d 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> @@ -85,6 +85,9 @@ static int pxp_terminate_arb_session_and_global(struct intel_pxp *pxp)
>  	/* must mark termination in progress calling this function */
>  	GEM_WARN_ON(pxp->arb_is_valid);
>  
> +	/* invalidate protected objects */
> +	intel_pxp_invalidate(pxp);
> +
>  	/* terminate the hw sessions */
>  	ret = intel_pxp_terminate_session(pxp, ARB_SESSION);
>  	if (ret) {
> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
> index 475e3312c287..be2bed3a2e4e 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
> @@ -7,7 +7,9 @@
>  #define __INTEL_PXP_TYPES_H__
>  
>  #include <linux/completion.h>
> +#include <linux/list.h>
>  #include <linux/mutex.h>
> +#include <linux/spinlock.h>
>  #include <linux/types.h>
>  #include <linux/workqueue.h>
>  
> @@ -43,6 +45,9 @@ struct intel_pxp {
>  	u32 session_events; /* protected with gt->irq_lock */
>  #define PXP_TERMINATION_REQUEST  BIT(0)
>  #define PXP_TERMINATION_COMPLETE BIT(1)
> +
> +	spinlock_t lock; /* protects the objects list */
> +	struct list_head protected_objects;
>  };
>  
>  #endif /* __INTEL_PXP_TYPES_H__ */
> diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
> index 4393eef59d9b..2c9febdae6a5 100644
> --- a/include/uapi/drm/i915_drm.h
> +++ b/include/uapi/drm/i915_drm.h
> @@ -1843,12 +1843,32 @@ struct drm_i915_gem_context_param {
>   * attempted to use it, never re-use this context param number.
>   */
>  #define I915_CONTEXT_PARAM_RINGSIZE	0xc
> +
> +/*
> + * I915_CONTEXT_PARAM_PROTECTED_CONTENT:
> + *
> + * Mark that the context makes use of protected content, which will result
> + * in the context being invalidated when the protected content session is. The
> + * invalidation is reported back to userspace via the RESET_STATS ioctl (see
> + * relevant doc for details).
> + * This flag can only be set at context creation time and, when set to true,
> + * must be preceded by an explicit setting of I915_CONTEXT_PARAM_RECOVERABLE
> + * to false. This flag can't be set to true in conjunction with setting the
> + * I915_CONTEXT_PARAM_BANNABLE flag to false.
> + *
> + * In addition to the normal failure cases, setting this flag during context
> + * creation can result in the following errors:
> + *
> + * -ENODEV: feature not available
> + * -EPERM: trying to mark a recoverable or not bannable context as protected
> + */
> +#define I915_CONTEXT_PARAM_PROTECTED_CONTENT    0xd
>  /* Must be kept compact -- no holes and well documented */
>  
>  	__u64 value;
>  };
>  
> -/*
> +/**
>   * Context SSEU programming
>   *
>   * It may be necessary for either functional or performance reason to configure
> @@ -2181,6 +2201,12 @@ struct drm_i915_reg_read {
>  struct drm_i915_reset_stats {
>  	__u32 ctx_id;
>  	__u32 flags;
> +	/*
> +	 * contexts marked as using protected content are invalidated when the
> +	 * protected content session dies. Submission of invalidated contexts
> +	 * is rejected with -EACCES.
> +	 */
> +#define I915_CONTEXT_INVALIDATED 0x1
>  
>  	/* All resets since boot/module reload, for all contexts */
>  	__u32 reset_count;
> @@ -2959,8 +2985,12 @@ struct drm_i915_gem_create_ext {
>  	 *
>  	 * For I915_GEM_CREATE_EXT_MEMORY_REGIONS usage see
>  	 * struct drm_i915_gem_create_ext_memory_regions.
> +	 *
> +	 * For I915_GEM_CREATE_EXT_PROTECTED_CONTENT usage see
> +	 * struct drm_i915_gem_create_ext_protected_content.
>  	 */
>  #define I915_GEM_CREATE_EXT_MEMORY_REGIONS 0
> +#define I915_GEM_CREATE_EXT_PROTECTED_CONTENT 1
>  	__u64 extensions;
>  };
>  
> @@ -3018,6 +3048,29 @@ struct drm_i915_gem_create_ext_memory_regions {
>  	__u64 regions;
>  };
>  
> +/**
> + * struct drm_i915_gem_create_ext_protected_content - The
> + * I915_OBJECT_PARAM_PROTECTED_CONTENT extension.
> + *
> + * If this extension is provided, buffer contents are expected to be protected
> + * by PXP encryption and require decryption for scan out and processing. This
> + * is only possible on platforms that have PXP enabled, on all other scenarios
> + * using this extension will cause the ioctl to fail and return -ENODEV. The
> + * flags parameter is reserved for future expansion and must currently be set
> + * to zero.
> + *
> + * The buffer contents are considered invalid after a PXP session teardown.
> + *
> + * The encryption is guaranteed to be processed correctly only if the object
> + * is submitted with a context created using the
> + * I915_CONTEXT_PARAM_PROTECTED_CONTENT flag. This will also enable extra checks
> + * at submission time on the validity of the objects involved.
> + */
> +struct drm_i915_gem_create_ext_protected_content {
> +	struct i915_user_extension base;
> +	__u32 flags;
> +};
> +
>  /* ID of the protected content session managed by i915 when PXP is active */
>  #define I915_PROTECTED_CONTENT_DEFAULT_SESSION 0xf
>  
> -- 
> 2.32.0
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Intel-gfx] [PATCH v6 10/15] drm/i915/pxp: interfaces for using protected objects
  2021-08-13 14:37   ` Daniel Vetter
@ 2021-08-13 14:42     ` Daniel Vetter
  2021-08-13 15:24       ` Daniele Ceraolo Spurio
  2021-08-13 15:18     ` Daniele Ceraolo Spurio
  1 sibling, 1 reply; 64+ messages in thread
From: Daniel Vetter @ 2021-08-13 14:42 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio
  Cc: intel-gfx, Daniel Vetter, Chris Wilson, dri-devel, Bommu Krishnaiah

On Fri, Aug 13, 2021 at 04:37:53PM +0200, Daniel Vetter wrote:
> On Wed, Jul 28, 2021 at 07:01:01PM -0700, Daniele Ceraolo Spurio wrote:
> > This api allow user mode to create protected buffers and to mark
> > contexts as making use of such objects. Only when using contexts
> > marked in such a way is the execution guaranteed to work as expected.
> > 
> > Contexts can only be marked as using protected content at creation time
> > (i.e. the parameter is immutable) and they must be both bannable and not
> > recoverable.
> > 
> > All protected objects and contexts that have backing storage will be
> > considered invalid when the PXP session is destroyed and all new
> > submissions using them will be rejected. All intel contexts within the
> > invalidated gem contexts will be marked banned. A new flag has been
> > added to the RESET_STATS ioctl to report the context invalidation to
> > userspace.
> > 
> > This patch was previously sent as 2 separate patches, which have been
> > squashed following a request to have all the uapi in a single patch.
> > I've retained the s-o-b from both.
> > 
> > v5: squash patches, rebase on proto_ctx, update kerneldoc
> > 
> > v6: rebase on obj create_ext changes
> > 
> > Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
> > Signed-off-by: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
> > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > Cc: Chris Wilson <chris@chris-wilson.co.uk>
> > Cc: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
> > Cc: Jason Ekstrand <jason@jlekstrand.net>
> > Cc: Daniel Vetter <daniel.vetter@intel.com>
> > Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> #v5
> > ---
> >  drivers/gpu/drm/i915/gem/i915_gem_context.c   | 68 ++++++++++++--
> >  drivers/gpu/drm/i915/gem/i915_gem_context.h   | 18 ++++
> >  .../gpu/drm/i915/gem/i915_gem_context_types.h |  2 +
> >  drivers/gpu/drm/i915/gem/i915_gem_create.c    | 75 ++++++++++++----
> >  .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 40 ++++++++-
> >  drivers/gpu/drm/i915/gem/i915_gem_object.c    |  6 ++
> >  drivers/gpu/drm/i915/gem/i915_gem_object.h    | 12 +++
> >  .../gpu/drm/i915/gem/i915_gem_object_types.h  |  9 ++
> >  drivers/gpu/drm/i915/pxp/intel_pxp.c          | 89 +++++++++++++++++++
> >  drivers/gpu/drm/i915/pxp/intel_pxp.h          | 15 ++++
> >  drivers/gpu/drm/i915/pxp/intel_pxp_session.c  |  3 +
> >  drivers/gpu/drm/i915/pxp/intel_pxp_types.h    |  5 ++
> >  include/uapi/drm/i915_drm.h                   | 55 +++++++++++-
> >  13 files changed, 371 insertions(+), 26 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> > index cff72679ad7c..0cd3e2d06188 100644
> > --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
> > +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> > @@ -77,6 +77,8 @@
> >  #include "gt/intel_gpu_commands.h"
> >  #include "gt/intel_ring.h"
> >  
> > +#include "pxp/intel_pxp.h"
> > +
> >  #include "i915_gem_context.h"
> >  #include "i915_trace.h"
> >  #include "i915_user_extensions.h"
> > @@ -241,6 +243,25 @@ static int proto_context_set_persistence(struct drm_i915_private *i915,
> >  	return 0;
> >  }
> >  
> > +static int proto_context_set_protected(struct drm_i915_private *i915,
> > +				       struct i915_gem_proto_context *pc,
> > +				       bool protected)
> > +{
> > +	int ret = 0;
> > +
> > +	if (!intel_pxp_is_enabled(&i915->gt.pxp))
> > +		ret = -ENODEV;
> > +	else if (!protected)
> > +		pc->user_flags &= ~BIT(UCONTEXT_PROTECTED);
> > +	else if ((pc->user_flags & BIT(UCONTEXT_RECOVERABLE)) ||
> > +		 !(pc->user_flags & BIT(UCONTEXT_BANNABLE)))
> > +		ret = -EPERM;
> > +	else
> > +		pc->user_flags |= BIT(UCONTEXT_PROTECTED);
> > +
> > +	return ret;
> > +}
> > +
> >  static struct i915_gem_proto_context *
> >  proto_context_create(struct drm_i915_private *i915, unsigned int flags)
> >  {
> > @@ -686,6 +707,8 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
> >  			ret = -EPERM;
> >  		else if (args->value)
> >  			pc->user_flags |= BIT(UCONTEXT_BANNABLE);
> > +		else if (pc->user_flags & BIT(UCONTEXT_PROTECTED))
> > +			ret = -EPERM;
> >  		else
> >  			pc->user_flags &= ~BIT(UCONTEXT_BANNABLE);
> >  		break;
> > @@ -693,10 +716,12 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
> >  	case I915_CONTEXT_PARAM_RECOVERABLE:
> >  		if (args->size)
> >  			ret = -EINVAL;
> > -		else if (args->value)
> > -			pc->user_flags |= BIT(UCONTEXT_RECOVERABLE);
> > -		else
> > +		else if (!args->value)
> >  			pc->user_flags &= ~BIT(UCONTEXT_RECOVERABLE);
> > +		else if (pc->user_flags & BIT(UCONTEXT_PROTECTED))
> > +			ret = -EPERM;
> > +		else
> > +			pc->user_flags |= BIT(UCONTEXT_RECOVERABLE);
> >  		break;
> >  
> >  	case I915_CONTEXT_PARAM_PRIORITY:
> > @@ -724,6 +749,11 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
> >  						    args->value);
> >  		break;
> >  
> > +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
> > +		ret = proto_context_set_protected(fpriv->dev_priv, pc,
> > +						  args->value);
> > +		break;
> > +
> >  	case I915_CONTEXT_PARAM_NO_ZEROMAP:
> >  	case I915_CONTEXT_PARAM_BAN_PERIOD:
> >  	case I915_CONTEXT_PARAM_RINGSIZE:
> > @@ -1798,6 +1828,18 @@ static int set_priority(struct i915_gem_context *ctx,
> >  	return 0;
> >  }
> >  
> > +static int get_protected(struct i915_gem_context *ctx,
> > +			 struct drm_i915_gem_context_param *args)
> > +{
> > +	if (!intel_pxp_is_enabled(&ctx->i915->gt.pxp))
> > +		return -ENODEV;
> > +
> > +	args->size = 0;
> > +	args->value = i915_gem_context_uses_protected_content(ctx);
> > +
> > +	return 0;
> > +}
> > +
> >  static int ctx_setparam(struct drm_i915_file_private *fpriv,
> >  			struct i915_gem_context *ctx,
> >  			struct drm_i915_gem_context_param *args)
> > @@ -1821,6 +1863,8 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
> >  			ret = -EPERM;
> >  		else if (args->value)
> >  			i915_gem_context_set_bannable(ctx);
> > +		else if (i915_gem_context_uses_protected_content(ctx))
> > +			ret = -EPERM; /* can't clear this for protected contexts */
> >  		else
> >  			i915_gem_context_clear_bannable(ctx);
> >  		break;
> > @@ -1828,10 +1872,12 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
> >  	case I915_CONTEXT_PARAM_RECOVERABLE:
> >  		if (args->size)
> >  			ret = -EINVAL;
> > -		else if (args->value)
> > -			i915_gem_context_set_recoverable(ctx);
> > -		else
> > +		else if (!args->value)
> >  			i915_gem_context_clear_recoverable(ctx);
> > +		else if (i915_gem_context_uses_protected_content(ctx))
> > +			ret = -EPERM; /* can't set this for protected contexts */
> > +		else
> > +			i915_gem_context_set_recoverable(ctx);
> >  		break;
> >  
> >  	case I915_CONTEXT_PARAM_PRIORITY:
> > @@ -1846,6 +1892,7 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
> >  		ret = set_persistence(ctx, args);
> >  		break;
> >  
> > +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
> >  	case I915_CONTEXT_PARAM_NO_ZEROMAP:
> >  	case I915_CONTEXT_PARAM_BAN_PERIOD:
> >  	case I915_CONTEXT_PARAM_RINGSIZE:
> > @@ -2174,6 +2221,10 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
> >  		args->value = i915_gem_context_is_persistent(ctx);
> >  		break;
> >  
> > +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
> > +		ret = get_protected(ctx, args);
> > +		break;
> > +
> >  	case I915_CONTEXT_PARAM_NO_ZEROMAP:
> >  	case I915_CONTEXT_PARAM_BAN_PERIOD:
> >  	case I915_CONTEXT_PARAM_ENGINES:
> > @@ -2250,6 +2301,11 @@ int i915_gem_context_reset_stats_ioctl(struct drm_device *dev,
> >  	args->batch_active = atomic_read(&ctx->guilty_count);
> >  	args->batch_pending = atomic_read(&ctx->active_count);
> >  
> > +	/* re-use args->flags for output flags */
> > +	args->flags = 0;
> > +	if (i915_gem_context_invalidated(ctx))
> > +		args->flags |= I915_CONTEXT_INVALIDATED;
> > +
> >  	i915_gem_context_put(ctx);
> >  	return 0;
> >  }
> > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.h b/drivers/gpu/drm/i915/gem/i915_gem_context.h
> > index 18060536b0c2..d932a70122fa 100644
> > --- a/drivers/gpu/drm/i915/gem/i915_gem_context.h
> > +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.h
> > @@ -108,6 +108,24 @@ i915_gem_context_clear_user_engines(struct i915_gem_context *ctx)
> >  	clear_bit(CONTEXT_USER_ENGINES, &ctx->flags);
> >  }
> >  
> > +static inline bool
> > +i915_gem_context_invalidated(const struct i915_gem_context *ctx)
> > +{
> > +	return test_bit(CONTEXT_INVALID, &ctx->flags);
> > +}
> > +
> > +static inline void
> > +i915_gem_context_set_invalid(struct i915_gem_context *ctx)
> > +{
> > +	set_bit(CONTEXT_INVALID, &ctx->flags);
> 
> Do we _really_ need a new bit in this already very complex state
> machinery, and can't we reuse the BANNED flag instead?
> 
> This ctx->flags is atomic, unorderd, and that means you need barriers and
> everything.
> 
> If you don't actually need the atomic state bit machinery because you're
> using simple locking, then pls use your own boolean, and document by which
> lock it's protected.
> 
> > +}
> > +
> > +static inline bool
> > +i915_gem_context_uses_protected_content(const struct i915_gem_context *ctx)
> > +{
> > +	return test_bit(UCONTEXT_PROTECTED, &ctx->user_flags);
> 
> For immutable state (I really hope this is immutable) pls don't reuse the
> atomic bitfield of mutable state, but create a flag of your own.
> 
> Also please document all the rules around how this is set/changed in the
> kerneldoc header comments for the data structure. Finally if you never set
> it except at creation.
> 
> > +}
> > +
> >  /* i915_gem_context.c */
> >  void i915_gem_init__contexts(struct drm_i915_private *i915);
> >  
> > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
> > index 94c03a97cb77..1aa2290aa3c7 100644
> > --- a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
> > +++ b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
> > @@ -301,6 +301,7 @@ struct i915_gem_context {
> >  #define UCONTEXT_BANNABLE		2
> >  #define UCONTEXT_RECOVERABLE		3
> >  #define UCONTEXT_PERSISTENCE		4
> > +#define UCONTEXT_PROTECTED		5
> >  
> >  	/**
> >  	 * @flags: small set of booleans
> > @@ -308,6 +309,7 @@ struct i915_gem_context {
> >  	unsigned long flags;
> >  #define CONTEXT_CLOSED			0
> >  #define CONTEXT_USER_ENGINES		1
> > +#define CONTEXT_INVALID			2
> >  
> >  	/** @mutex: guards everything that isn't engines or handles_vma */
> >  	struct mutex mutex;
> > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c b/drivers/gpu/drm/i915/gem/i915_gem_create.c
> > index 23fee13a3384..0e48629316bb 100644
> > --- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
> > +++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
> > @@ -6,6 +6,7 @@
> >  #include "gem/i915_gem_ioctls.h"
> >  #include "gem/i915_gem_lmem.h"
> >  #include "gem/i915_gem_region.h"
> > +#include "pxp/intel_pxp.h"
> >  
> >  #include "i915_drv.h"
> >  #include "i915_trace.h"
> > @@ -82,21 +83,11 @@ static int i915_gem_publish(struct drm_i915_gem_object *obj,
> >  	return 0;
> >  }
> >  
> > -/**
> > - * Creates a new object using the same path as DRM_I915_GEM_CREATE_EXT
> > - * @i915: i915 private
> > - * @size: size of the buffer, in bytes
> > - * @placements: possible placement regions, in priority order
> > - * @n_placements: number of possible placement regions
> > - *
> > - * This function is exposed primarily for selftests and does very little
> > - * error checking.  It is assumed that the set of placement regions has
> > - * already been verified to be valid.
> > - */
> > -struct drm_i915_gem_object *
> > -__i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
> > -			      struct intel_memory_region **placements,
> > -			      unsigned int n_placements)
> > +static struct drm_i915_gem_object *
> > +__i915_gem_object_create_user_ext(struct drm_i915_private *i915, u64 size,
> > +				  struct intel_memory_region **placements,
> > +				  unsigned int n_placements,
> > +				  unsigned int ext_flags)
> >  {
> >  	struct intel_memory_region *mr = placements[0];
> >  	struct drm_i915_gem_object *obj;
> > @@ -135,6 +126,12 @@ __i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
> >  
> >  	GEM_BUG_ON(size != obj->base.size);
> >  
> > +	/* Add any flag set by create_ext options */
> > +	flags |= ext_flags;
> > +
> > +	if (i915_gem_object_is_protected(obj))
> > +		intel_pxp_object_add(obj);
> > +
> >  	trace_i915_gem_object_create(obj);
> >  	return obj;
> >  
> > @@ -145,6 +142,26 @@ __i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
> >  	return ERR_PTR(ret);
> >  }
> >  
> > +/**
> > + * Creates a new object using the same path as DRM_I915_GEM_CREATE_EXT
> > + * @i915: i915 private
> > + * @size: size of the buffer, in bytes
> > + * @placements: possible placement regions, in priority order
> > + * @n_placements: number of possible placement regions
> > + *
> > + * This function is exposed primarily for selftests and does very little
> > + * error checking.  It is assumed that the set of placement regions has
> > + * already been verified to be valid.
> > + */
> > +struct drm_i915_gem_object *
> > +__i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
> > +			      struct intel_memory_region **placements,
> > +			      unsigned int n_placements)
> > +{
> > +	return __i915_gem_object_create_user_ext(i915, size, placements,
> > +						 n_placements, 0);
> > +}
> > +
> >  int
> >  i915_gem_dumb_create(struct drm_file *file,
> >  		     struct drm_device *dev,
> > @@ -224,6 +241,7 @@ struct create_ext {
> >  	struct drm_i915_private *i915;
> >  	struct intel_memory_region *placements[INTEL_REGION_UNKNOWN];
> >  	unsigned int n_placements;
> > +	unsigned long flags;
> >  };
> >  
> >  static void repr_placements(char *buf, size_t size,
> > @@ -356,8 +374,28 @@ static int ext_set_placements(struct i915_user_extension __user *base,
> >  	return set_placements(&ext, data);
> >  }
> >  
> > +static int ext_set_protected(struct i915_user_extension __user *base, void *data)
> > +{
> > +	struct drm_i915_gem_create_ext_protected_content ext;
> > +	struct create_ext *ext_data = data;
> > +
> > +	if (copy_from_user(&ext, base, sizeof(ext)))
> > +		return -EFAULT;
> > +
> > +	if (ext.flags)
> > +		return -EINVAL;
> > +
> > +	if (!intel_pxp_is_enabled(&ext_data->i915->gt.pxp))
> > +		return -ENODEV;
> > +
> > +	ext_data->flags |= I915_BO_PROTECTED;
> > +
> > +	return 0;
> > +}
> > +
> >  static const i915_user_extension_fn create_extensions[] = {
> >  	[I915_GEM_CREATE_EXT_MEMORY_REGIONS] = ext_set_placements,
> > +	[I915_GEM_CREATE_EXT_PROTECTED_CONTENT] = ext_set_protected,
> >  };
> >  
> >  /**
> > @@ -392,9 +430,10 @@ i915_gem_create_ext_ioctl(struct drm_device *dev, void *data,
> >  		ext_data.n_placements = 1;
> >  	}
> >  
> > -	obj = __i915_gem_object_create_user(i915, args->size,
> > -					    ext_data.placements,
> > -					    ext_data.n_placements);
> > +	obj = __i915_gem_object_create_user_ext(i915, args->size,
> > +						ext_data.placements,
> > +						ext_data.n_placements,
> > +						ext_data.flags);
> >  	if (IS_ERR(obj))
> >  		return PTR_ERR(obj);
> >  
> > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> > index 1ed7475de454..04f33d163340 100644
> > --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> > +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> > @@ -21,6 +21,8 @@
> >  #include "gt/intel_gt_pm.h"
> >  #include "gt/intel_ring.h"
> >  
> > +#include "pxp/intel_pxp.h"
> > +
> >  #include "i915_drv.h"
> >  #include "i915_gem_clflush.h"
> >  #include "i915_gem_context.h"
> > @@ -751,6 +753,11 @@ static int eb_select_context(struct i915_execbuffer *eb)
> >  	if (unlikely(IS_ERR(ctx)))
> >  		return PTR_ERR(ctx);
> >  
> > +	if (i915_gem_context_invalidated(ctx)) {
> > +		i915_gem_context_put(ctx);
> > +		return -EACCES;
> > +	}
> > +
> >  	eb->gem_context = ctx;
> >  	if (rcu_access_pointer(ctx->vm))
> >  		eb->invalid_flags |= EXEC_OBJECT_NEEDS_GTT;
> > @@ -819,7 +826,7 @@ static struct i915_vma *eb_lookup_vma(struct i915_execbuffer *eb, u32 handle)
> >  	do {
> >  		struct drm_i915_gem_object *obj;
> >  		struct i915_vma *vma;
> > -		int err;
> > +		int err = 0;
> >  
> >  		rcu_read_lock();
> >  		vma = radix_tree_lookup(&eb->gem_context->handles_vma, handle);
> > @@ -833,6 +840,26 @@ static struct i915_vma *eb_lookup_vma(struct i915_execbuffer *eb, u32 handle)
> >  		if (unlikely(!obj))
> >  			return ERR_PTR(-ENOENT);
> >  
> > +		/*
> > +		 * If the user has opted-in for protected-object tracking, make
> > +		 * sure the object encryption can be used.
> > +		 * We only need to do this when the object is first used with
> > +		 * this context, because the context itself will be banned when
> > +		 * the protected objects become invalid.
> > +		 */
> > +		if (i915_gem_context_uses_protected_content(eb->gem_context) &&
> > +		    i915_gem_object_is_protected(obj)) {
> > +			if (!intel_pxp_is_active(&vm->gt->pxp))
> > +				err = -ENODEV;
> > +			else if (!i915_gem_object_has_valid_protection(obj))
> > +				err = -ENOEXEC;
> > +
> > +			if (err) {
> > +				i915_gem_object_put(obj);
> > +				return ERR_PTR(err);
> > +			}
> > +		}
> > +
> >  		vma = i915_vma_instance(obj, vm, NULL);
> >  		if (IS_ERR(vma)) {
> >  			i915_gem_object_put(obj);
> > @@ -2752,6 +2779,17 @@ eb_select_engine(struct i915_execbuffer *eb)
> >  
> >  	intel_gt_pm_get(ce->engine->gt);
> >  
> > +	if (i915_gem_context_uses_protected_content(eb->gem_context)) {
> > +		err = intel_pxp_wait_for_arb_start(&ce->engine->gt->pxp);
> > +		if (err)
> > +			goto err;
> > +
> > +		if (i915_gem_context_invalidated(eb->gem_context)) {
> > +			err = -EACCES;
> 
> Shouldn't the normal banned context handling takee care of anything that
> slips through? Rolling your own racy invalidation checks doesn't look like
> a good idea.
> 
> > +			goto err;
> > +		}
> > +	}
> > +
> >  	if (!test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
> >  		err = intel_context_alloc_state(ce);
> >  		if (err)
> > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c
> > index 6fb9afb65034..658a42a7fa07 100644
> > --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
> > +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
> > @@ -25,6 +25,7 @@
> >  #include <linux/sched/mm.h>
> >  
> >  #include "display/intel_frontbuffer.h"
> > +#include "pxp/intel_pxp.h"
> >  #include "i915_drv.h"
> >  #include "i915_gem_clflush.h"
> >  #include "i915_gem_context.h"
> > @@ -73,6 +74,8 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj,
> >  	INIT_LIST_HEAD(&obj->lut_list);
> >  	spin_lock_init(&obj->lut_lock);
> >  
> > +	INIT_LIST_HEAD(&obj->pxp_link);
> > +
> >  	spin_lock_init(&obj->mmo.lock);
> >  	obj->mmo.offsets = RB_ROOT;
> >  
> > @@ -231,6 +234,9 @@ void __i915_gem_free_object(struct drm_i915_gem_object *obj)
> >  		spin_unlock(&obj->vma.lock);
> >  	}
> >  
> > +	if (i915_gem_object_has_valid_protection(obj))
> > +		intel_pxp_object_remove(obj);
> > +
> >  	__i915_gem_object_free_mmaps(obj);
> >  
> >  	GEM_BUG_ON(!list_empty(&obj->lut_list));
> > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h
> > index 48112b9d76df..137ae2723514 100644
> > --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
> > +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
> > @@ -269,6 +269,18 @@ i915_gem_object_clear_tiling_quirk(struct drm_i915_gem_object *obj)
> >  	clear_bit(I915_TILING_QUIRK_BIT, &obj->flags);
> >  }
> >  
> > +static inline bool
> > +i915_gem_object_is_protected(const struct drm_i915_gem_object *obj)
> > +{
> > +	return obj->flags & I915_BO_PROTECTED;
> > +}
> > +
> > +static inline bool
> > +i915_gem_object_has_valid_protection(const struct drm_i915_gem_object *obj)
> > +{
> > +	return i915_gem_object_is_protected(obj) && !list_empty(&obj->pxp_link);
> > +}
> > +
> >  static inline bool
> >  i915_gem_object_type_has(const struct drm_i915_gem_object *obj,
> >  			 unsigned long flags)
> > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> > index 2471f36aaff3..38e4a190607a 100644
> > --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> > +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> > @@ -298,6 +298,7 @@ struct drm_i915_gem_object {
> >  			     I915_BO_ALLOC_USER)
> >  #define I915_BO_READONLY         BIT(4)
> >  #define I915_TILING_QUIRK_BIT    5 /* unknown swizzling; do not release! */
> > +#define I915_BO_PROTECTED        BIT(6)
> >  
> >  	/**
> >  	 * @mem_flags - Mutable placement-related flags
> > @@ -537,6 +538,14 @@ struct drm_i915_gem_object {
> >  		bool created:1;
> >  	} ttm;
> >  
> > +	/*
> > +	 * When the PXP session is invalidated, we need to mark all protected
> > +	 * objects as invalid. To easily do so we add them all to a list. The
> > +	 * presence on the list is used to check if the encryption is valid or
> > +	 * not.
> > +	 */
> > +	struct list_head pxp_link;

This
- seems to be accessed locklessly, which needs giant amounts of comments
  and justifications to prove a) it's needed and b) it's correct against
  all races
- we already have a per-object lock in the form of dma_resv_lock. Why
  can't we use that to protect pxp object state?

Looking needs to be done with extreme care, or we're just burrying
ourselves into something that cannot be understood and maintained anymore.
-Daniel

> > +
> >  	/** Record of address bit 17 of each page at last unbind. */
> >  	unsigned long *bit_17;
> >  
> > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
> > index b0c7edc10cc3..f418281e8c10 100644
> > --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
> > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
> > @@ -7,6 +7,7 @@
> >  #include "intel_pxp_irq.h"
> >  #include "intel_pxp_session.h"
> >  #include "intel_pxp_tee.h"
> > +#include "gem/i915_gem_context.h"
> >  #include "gt/intel_context.h"
> >  #include "i915_drv.h"
> >  
> > @@ -70,6 +71,9 @@ void intel_pxp_init(struct intel_pxp *pxp)
> >  
> >  	mutex_init(&pxp->tee_mutex);
> >  
> > +	spin_lock_init(&pxp->lock);
> > +	INIT_LIST_HEAD(&pxp->protected_objects);
> > +
> >  	/*
> >  	 * we'll use the completion to check if there is a termination pending,
> >  	 * so we start it as completed and we reinit it when a termination
> > @@ -166,3 +170,88 @@ void intel_pxp_fini_hw(struct intel_pxp *pxp)
> >  
> >  	intel_pxp_irq_disable(pxp);
> >  }
> > +
> > +int intel_pxp_object_add(struct drm_i915_gem_object *obj)
> > +{
> > +	struct intel_pxp *pxp = &to_i915(obj->base.dev)->gt.pxp;
> > +
> > +	if (!intel_pxp_is_enabled(pxp))
> > +		return -ENODEV;
> > +
> > +	if (!list_empty(&obj->pxp_link))
> > +		return -EEXIST;
> > +
> > +	spin_lock_irq(&pxp->lock);
> > +	list_add(&obj->pxp_link, &pxp->protected_objects);
> > +	spin_unlock_irq(&pxp->lock);
> > +
> > +	return 0;
> > +}
> > +
> > +void intel_pxp_object_remove(struct drm_i915_gem_object *obj)
> > +{
> > +	struct intel_pxp *pxp = &to_i915(obj->base.dev)->gt.pxp;
> > +
> > +	if (!intel_pxp_is_enabled(pxp))
> > +		return;
> > +
> > +	spin_lock_irq(&pxp->lock);
> > +	list_del_init(&obj->pxp_link);
> > +	spin_unlock_irq(&pxp->lock);
> > +}
> > +
> > +void intel_pxp_invalidate(struct intel_pxp *pxp)
> 
> There is a lot of locking going on here. Please make sure it's all
> properly documented what the rules are in kerneldoc, even for existing
> stuff.
> 
> Especially anytime there's anything tricky going on, like:
> - kref_get_unless_zero
> - test_bit (that's an unorderd atomic, so either you don't actually need
>   the atomic, or you need a pile of barriers and comments about them)
> - hiddent atomic ops like intel_context_set_banned or
>   i915_gem_context_set_invalid also need great care, least because the
>   current rules aren't documented really. So step one here before using
>   them is documenting the rules of how banning works.
> 
> > +{
> > +	struct drm_i915_private *i915 = pxp_to_gt(pxp)->i915;
> > +	struct drm_i915_gem_object *obj, *tmp;
> > +	struct i915_gem_context *ctx, *cn;
> > +
> > +	/* delete objects that have been used with the invalidated session */
> > +	spin_lock_irq(&pxp->lock);
> > +	list_for_each_entry_safe(obj, tmp, &pxp->protected_objects, pxp_link) {
> > +		if (i915_gem_object_has_pages(obj))
> > +			list_del_init(&obj->pxp_link);

We have a per
> > +	}
> > +	spin_unlock_irq(&pxp->lock);
> > +
> > +	/* 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) {
> > +		struct i915_gem_engines_iter it;
> > +		struct intel_context *ce;
> > +
> > +		if (!kref_get_unless_zero(&ctx->ref))
> > +			continue;
> > +
> > +		if (likely(!i915_gem_context_uses_protected_content(ctx)) ||
> > +		    i915_gem_context_invalidated(ctx)) {
> > +			i915_gem_context_put(ctx);
> > +			continue;
> > +		}
> > +
> > +		spin_unlock_irq(&i915->gem.contexts.lock);
> > +
> > +		/*
> > +		 * Note that by the time we get here the HW keys are already
> > +		 * long gone, so any batch using them that's already on the
> > +		 * engines is very likely a lost cause (and it has probably
> > +		 * already hung the engine). Therefore, we skip attempting to
> > +		 * pull the running context out of the HW and we prioritize
> > +		 * bringing the session back as soon as possible.
> > +		 */
> > +		for_each_gem_engine(ce, i915_gem_context_lock_engines(ctx), it) {
> > +			/* only invalidate if at least one ce was allocated */
> > +			if (test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
> > +				intel_context_set_banned(ce);
> > +				i915_gem_context_set_invalid(ctx);
> > +			}
> > +		}
> > +		i915_gem_context_unlock_engines(ctx);
> > +
> > +		spin_lock_irq(&i915->gem.contexts.lock);
> > +		list_safe_reset_next(ctx, cn, link);
> > +		i915_gem_context_put(ctx);
> > +	}
> > +	spin_unlock_irq(&i915->gem.contexts.lock);
> > +}
> > +
> > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
> > index 074b3b980957..4f7647f34153 100644
> > --- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
> > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
> > @@ -9,6 +9,8 @@
> >  #include "gt/intel_gt_types.h"
> >  #include "intel_pxp_types.h"
> >  
> > +struct drm_i915_gem_object;
> > +
> >  static inline struct intel_gt *pxp_to_gt(const struct intel_pxp *pxp)
> >  {
> >  	return container_of(pxp, struct intel_gt, pxp);
> > @@ -33,6 +35,11 @@ void intel_pxp_fini_hw(struct intel_pxp *pxp);
> >  
> >  void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp);
> >  int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp);
> > +
> > +int intel_pxp_object_add(struct drm_i915_gem_object *obj);
> > +void intel_pxp_object_remove(struct drm_i915_gem_object *obj);
> > +
> > +void intel_pxp_invalidate(struct intel_pxp *pxp);
> >  #else
> >  static inline void intel_pxp_init(struct intel_pxp *pxp)
> >  {
> > @@ -46,6 +53,14 @@ static inline int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp)
> >  {
> >  	return 0;
> >  }
> > +
> > +static inline int intel_pxp_object_add(struct drm_i915_gem_object *obj)
> > +{
> > +	return 0;
> > +}
> > +static inline void intel_pxp_object_remove(struct drm_i915_gem_object *obj)
> > +{
> > +}
> >  #endif
> >  
> >  #endif /* __INTEL_PXP_H__ */
> > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> > index 67c30e534d50..0edd563a653d 100644
> > --- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> > @@ -85,6 +85,9 @@ static int pxp_terminate_arb_session_and_global(struct intel_pxp *pxp)
> >  	/* must mark termination in progress calling this function */
> >  	GEM_WARN_ON(pxp->arb_is_valid);
> >  
> > +	/* invalidate protected objects */
> > +	intel_pxp_invalidate(pxp);
> > +
> >  	/* terminate the hw sessions */
> >  	ret = intel_pxp_terminate_session(pxp, ARB_SESSION);
> >  	if (ret) {
> > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
> > index 475e3312c287..be2bed3a2e4e 100644
> > --- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
> > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
> > @@ -7,7 +7,9 @@
> >  #define __INTEL_PXP_TYPES_H__
> >  
> >  #include <linux/completion.h>
> > +#include <linux/list.h>
> >  #include <linux/mutex.h>
> > +#include <linux/spinlock.h>
> >  #include <linux/types.h>
> >  #include <linux/workqueue.h>
> >  
> > @@ -43,6 +45,9 @@ struct intel_pxp {
> >  	u32 session_events; /* protected with gt->irq_lock */
> >  #define PXP_TERMINATION_REQUEST  BIT(0)
> >  #define PXP_TERMINATION_COMPLETE BIT(1)
> > +
> > +	spinlock_t lock; /* protects the objects list */
> > +	struct list_head protected_objects;
> >  };
> >  
> >  #endif /* __INTEL_PXP_TYPES_H__ */
> > diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
> > index 4393eef59d9b..2c9febdae6a5 100644
> > --- a/include/uapi/drm/i915_drm.h
> > +++ b/include/uapi/drm/i915_drm.h
> > @@ -1843,12 +1843,32 @@ struct drm_i915_gem_context_param {
> >   * attempted to use it, never re-use this context param number.
> >   */
> >  #define I915_CONTEXT_PARAM_RINGSIZE	0xc
> > +
> > +/*
> > + * I915_CONTEXT_PARAM_PROTECTED_CONTENT:
> > + *
> > + * Mark that the context makes use of protected content, which will result
> > + * in the context being invalidated when the protected content session is. The
> > + * invalidation is reported back to userspace via the RESET_STATS ioctl (see
> > + * relevant doc for details).
> > + * This flag can only be set at context creation time and, when set to true,
> > + * must be preceded by an explicit setting of I915_CONTEXT_PARAM_RECOVERABLE
> > + * to false. This flag can't be set to true in conjunction with setting the
> > + * I915_CONTEXT_PARAM_BANNABLE flag to false.
> > + *
> > + * In addition to the normal failure cases, setting this flag during context
> > + * creation can result in the following errors:
> > + *
> > + * -ENODEV: feature not available
> > + * -EPERM: trying to mark a recoverable or not bannable context as protected
> > + */
> > +#define I915_CONTEXT_PARAM_PROTECTED_CONTENT    0xd
> >  /* Must be kept compact -- no holes and well documented */
> >  
> >  	__u64 value;
> >  };
> >  
> > -/*
> > +/**
> >   * Context SSEU programming
> >   *
> >   * It may be necessary for either functional or performance reason to configure
> > @@ -2181,6 +2201,12 @@ struct drm_i915_reg_read {
> >  struct drm_i915_reset_stats {
> >  	__u32 ctx_id;
> >  	__u32 flags;
> > +	/*
> > +	 * contexts marked as using protected content are invalidated when the
> > +	 * protected content session dies. Submission of invalidated contexts
> > +	 * is rejected with -EACCES.
> > +	 */
> > +#define I915_CONTEXT_INVALIDATED 0x1
> >  
> >  	/* All resets since boot/module reload, for all contexts */
> >  	__u32 reset_count;
> > @@ -2959,8 +2985,12 @@ struct drm_i915_gem_create_ext {
> >  	 *
> >  	 * For I915_GEM_CREATE_EXT_MEMORY_REGIONS usage see
> >  	 * struct drm_i915_gem_create_ext_memory_regions.
> > +	 *
> > +	 * For I915_GEM_CREATE_EXT_PROTECTED_CONTENT usage see
> > +	 * struct drm_i915_gem_create_ext_protected_content.
> >  	 */
> >  #define I915_GEM_CREATE_EXT_MEMORY_REGIONS 0
> > +#define I915_GEM_CREATE_EXT_PROTECTED_CONTENT 1
> >  	__u64 extensions;
> >  };
> >  
> > @@ -3018,6 +3048,29 @@ struct drm_i915_gem_create_ext_memory_regions {
> >  	__u64 regions;
> >  };
> >  
> > +/**
> > + * struct drm_i915_gem_create_ext_protected_content - The
> > + * I915_OBJECT_PARAM_PROTECTED_CONTENT extension.
> > + *
> > + * If this extension is provided, buffer contents are expected to be protected
> > + * by PXP encryption and require decryption for scan out and processing. This
> > + * is only possible on platforms that have PXP enabled, on all other scenarios
> > + * using this extension will cause the ioctl to fail and return -ENODEV. The
> > + * flags parameter is reserved for future expansion and must currently be set
> > + * to zero.
> > + *
> > + * The buffer contents are considered invalid after a PXP session teardown.
> > + *
> > + * The encryption is guaranteed to be processed correctly only if the object
> > + * is submitted with a context created using the
> > + * I915_CONTEXT_PARAM_PROTECTED_CONTENT flag. This will also enable extra checks
> > + * at submission time on the validity of the objects involved.
> > + */
> > +struct drm_i915_gem_create_ext_protected_content {
> > +	struct i915_user_extension base;
> > +	__u32 flags;
> > +};
> > +
> >  /* ID of the protected content session managed by i915 when PXP is active */
> >  #define I915_PROTECTED_CONTENT_DEFAULT_SESSION 0xf
> >  
> > -- 
> > 2.32.0
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Intel-gfx] [PATCH v6 10/15] drm/i915/pxp: interfaces for using protected objects
  2021-08-13 14:37   ` Daniel Vetter
  2021-08-13 14:42     ` Daniel Vetter
@ 2021-08-13 15:18     ` Daniele Ceraolo Spurio
  2021-08-16 15:15       ` Daniel Vetter
  1 sibling, 1 reply; 64+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-08-13 15:18 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: intel-gfx, Daniel Vetter, Chris Wilson, dri-devel, Bommu Krishnaiah



On 8/13/2021 7:37 AM, Daniel Vetter wrote:
> On Wed, Jul 28, 2021 at 07:01:01PM -0700, Daniele Ceraolo Spurio wrote:
>> This api allow user mode to create protected buffers and to mark
>> contexts as making use of such objects. Only when using contexts
>> marked in such a way is the execution guaranteed to work as expected.
>>
>> Contexts can only be marked as using protected content at creation time
>> (i.e. the parameter is immutable) and they must be both bannable and not
>> recoverable.
>>
>> All protected objects and contexts that have backing storage will be
>> considered invalid when the PXP session is destroyed and all new
>> submissions using them will be rejected. All intel contexts within the
>> invalidated gem contexts will be marked banned. A new flag has been
>> added to the RESET_STATS ioctl to report the context invalidation to
>> userspace.
>>
>> This patch was previously sent as 2 separate patches, which have been
>> squashed following a request to have all the uapi in a single patch.
>> I've retained the s-o-b from both.
>>
>> v5: squash patches, rebase on proto_ctx, update kerneldoc
>>
>> v6: rebase on obj create_ext changes
>>
>> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
>> Signed-off-by: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
>> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
>> Cc: Chris Wilson <chris@chris-wilson.co.uk>
>> Cc: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
>> Cc: Jason Ekstrand <jason@jlekstrand.net>
>> Cc: Daniel Vetter <daniel.vetter@intel.com>
>> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> #v5
>> ---
>>   drivers/gpu/drm/i915/gem/i915_gem_context.c   | 68 ++++++++++++--
>>   drivers/gpu/drm/i915/gem/i915_gem_context.h   | 18 ++++
>>   .../gpu/drm/i915/gem/i915_gem_context_types.h |  2 +
>>   drivers/gpu/drm/i915/gem/i915_gem_create.c    | 75 ++++++++++++----
>>   .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 40 ++++++++-
>>   drivers/gpu/drm/i915/gem/i915_gem_object.c    |  6 ++
>>   drivers/gpu/drm/i915/gem/i915_gem_object.h    | 12 +++
>>   .../gpu/drm/i915/gem/i915_gem_object_types.h  |  9 ++
>>   drivers/gpu/drm/i915/pxp/intel_pxp.c          | 89 +++++++++++++++++++
>>   drivers/gpu/drm/i915/pxp/intel_pxp.h          | 15 ++++
>>   drivers/gpu/drm/i915/pxp/intel_pxp_session.c  |  3 +
>>   drivers/gpu/drm/i915/pxp/intel_pxp_types.h    |  5 ++
>>   include/uapi/drm/i915_drm.h                   | 55 +++++++++++-
>>   13 files changed, 371 insertions(+), 26 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c
>> index cff72679ad7c..0cd3e2d06188 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
>> @@ -77,6 +77,8 @@
>>   #include "gt/intel_gpu_commands.h"
>>   #include "gt/intel_ring.h"
>>   
>> +#include "pxp/intel_pxp.h"
>> +
>>   #include "i915_gem_context.h"
>>   #include "i915_trace.h"
>>   #include "i915_user_extensions.h"
>> @@ -241,6 +243,25 @@ static int proto_context_set_persistence(struct drm_i915_private *i915,
>>   	return 0;
>>   }
>>   
>> +static int proto_context_set_protected(struct drm_i915_private *i915,
>> +				       struct i915_gem_proto_context *pc,
>> +				       bool protected)
>> +{
>> +	int ret = 0;
>> +
>> +	if (!intel_pxp_is_enabled(&i915->gt.pxp))
>> +		ret = -ENODEV;
>> +	else if (!protected)
>> +		pc->user_flags &= ~BIT(UCONTEXT_PROTECTED);
>> +	else if ((pc->user_flags & BIT(UCONTEXT_RECOVERABLE)) ||
>> +		 !(pc->user_flags & BIT(UCONTEXT_BANNABLE)))
>> +		ret = -EPERM;
>> +	else
>> +		pc->user_flags |= BIT(UCONTEXT_PROTECTED);
>> +
>> +	return ret;
>> +}
>> +
>>   static struct i915_gem_proto_context *
>>   proto_context_create(struct drm_i915_private *i915, unsigned int flags)
>>   {
>> @@ -686,6 +707,8 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
>>   			ret = -EPERM;
>>   		else if (args->value)
>>   			pc->user_flags |= BIT(UCONTEXT_BANNABLE);
>> +		else if (pc->user_flags & BIT(UCONTEXT_PROTECTED))
>> +			ret = -EPERM;
>>   		else
>>   			pc->user_flags &= ~BIT(UCONTEXT_BANNABLE);
>>   		break;
>> @@ -693,10 +716,12 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
>>   	case I915_CONTEXT_PARAM_RECOVERABLE:
>>   		if (args->size)
>>   			ret = -EINVAL;
>> -		else if (args->value)
>> -			pc->user_flags |= BIT(UCONTEXT_RECOVERABLE);
>> -		else
>> +		else if (!args->value)
>>   			pc->user_flags &= ~BIT(UCONTEXT_RECOVERABLE);
>> +		else if (pc->user_flags & BIT(UCONTEXT_PROTECTED))
>> +			ret = -EPERM;
>> +		else
>> +			pc->user_flags |= BIT(UCONTEXT_RECOVERABLE);
>>   		break;
>>   
>>   	case I915_CONTEXT_PARAM_PRIORITY:
>> @@ -724,6 +749,11 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
>>   						    args->value);
>>   		break;
>>   
>> +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
>> +		ret = proto_context_set_protected(fpriv->dev_priv, pc,
>> +						  args->value);
>> +		break;
>> +
>>   	case I915_CONTEXT_PARAM_NO_ZEROMAP:
>>   	case I915_CONTEXT_PARAM_BAN_PERIOD:
>>   	case I915_CONTEXT_PARAM_RINGSIZE:
>> @@ -1798,6 +1828,18 @@ static int set_priority(struct i915_gem_context *ctx,
>>   	return 0;
>>   }
>>   
>> +static int get_protected(struct i915_gem_context *ctx,
>> +			 struct drm_i915_gem_context_param *args)
>> +{
>> +	if (!intel_pxp_is_enabled(&ctx->i915->gt.pxp))
>> +		return -ENODEV;
>> +
>> +	args->size = 0;
>> +	args->value = i915_gem_context_uses_protected_content(ctx);
>> +
>> +	return 0;
>> +}
>> +
>>   static int ctx_setparam(struct drm_i915_file_private *fpriv,
>>   			struct i915_gem_context *ctx,
>>   			struct drm_i915_gem_context_param *args)
>> @@ -1821,6 +1863,8 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
>>   			ret = -EPERM;
>>   		else if (args->value)
>>   			i915_gem_context_set_bannable(ctx);
>> +		else if (i915_gem_context_uses_protected_content(ctx))
>> +			ret = -EPERM; /* can't clear this for protected contexts */
>>   		else
>>   			i915_gem_context_clear_bannable(ctx);
>>   		break;
>> @@ -1828,10 +1872,12 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
>>   	case I915_CONTEXT_PARAM_RECOVERABLE:
>>   		if (args->size)
>>   			ret = -EINVAL;
>> -		else if (args->value)
>> -			i915_gem_context_set_recoverable(ctx);
>> -		else
>> +		else if (!args->value)
>>   			i915_gem_context_clear_recoverable(ctx);
>> +		else if (i915_gem_context_uses_protected_content(ctx))
>> +			ret = -EPERM; /* can't set this for protected contexts */
>> +		else
>> +			i915_gem_context_set_recoverable(ctx);
>>   		break;
>>   
>>   	case I915_CONTEXT_PARAM_PRIORITY:
>> @@ -1846,6 +1892,7 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
>>   		ret = set_persistence(ctx, args);
>>   		break;
>>   
>> +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
>>   	case I915_CONTEXT_PARAM_NO_ZEROMAP:
>>   	case I915_CONTEXT_PARAM_BAN_PERIOD:
>>   	case I915_CONTEXT_PARAM_RINGSIZE:
>> @@ -2174,6 +2221,10 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
>>   		args->value = i915_gem_context_is_persistent(ctx);
>>   		break;
>>   
>> +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
>> +		ret = get_protected(ctx, args);
>> +		break;
>> +
>>   	case I915_CONTEXT_PARAM_NO_ZEROMAP:
>>   	case I915_CONTEXT_PARAM_BAN_PERIOD:
>>   	case I915_CONTEXT_PARAM_ENGINES:
>> @@ -2250,6 +2301,11 @@ int i915_gem_context_reset_stats_ioctl(struct drm_device *dev,
>>   	args->batch_active = atomic_read(&ctx->guilty_count);
>>   	args->batch_pending = atomic_read(&ctx->active_count);
>>   
>> +	/* re-use args->flags for output flags */
>> +	args->flags = 0;
>> +	if (i915_gem_context_invalidated(ctx))
>> +		args->flags |= I915_CONTEXT_INVALIDATED;
>> +
>>   	i915_gem_context_put(ctx);
>>   	return 0;
>>   }
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.h b/drivers/gpu/drm/i915/gem/i915_gem_context.h
>> index 18060536b0c2..d932a70122fa 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_context.h
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.h
>> @@ -108,6 +108,24 @@ i915_gem_context_clear_user_engines(struct i915_gem_context *ctx)
>>   	clear_bit(CONTEXT_USER_ENGINES, &ctx->flags);
>>   }
>>   
>> +static inline bool
>> +i915_gem_context_invalidated(const struct i915_gem_context *ctx)
>> +{
>> +	return test_bit(CONTEXT_INVALID, &ctx->flags);
>> +}
>> +
>> +static inline void
>> +i915_gem_context_set_invalid(struct i915_gem_context *ctx)
>> +{
>> +	set_bit(CONTEXT_INVALID, &ctx->flags);
> Do we _really_ need a new bit in this already very complex state
> machinery, and can't we reuse the BANNED flag instead?
>
> This ctx->flags is atomic, unorderd, and that means you need barriers and
> everything.
>
> If you don't actually need the atomic state bit machinery because you're
> using simple locking, then pls use your own boolean, and document by which
> lock it's protected.

The BANNED flag is at the intel_context level, while I needed something 
at the gem_context level to report out. Can make it a bool if you prefer.
The invalidation process is inherently racy (the teardown can always 
occur after we've checked the flag) so no amount of locking can help 
there. The flag itself is only set once and never cleared, so no risk of 
a set and clear racing.

>
>> +}
>> +
>> +static inline bool
>> +i915_gem_context_uses_protected_content(const struct i915_gem_context *ctx)
>> +{
>> +	return test_bit(UCONTEXT_PROTECTED, &ctx->user_flags);
> For immutable state (I really hope this is immutable) pls don't reuse the
> atomic bitfield of mutable state, but create a flag of your own.

It is immutable. Should we have a ctx->immutable_flags, or better a bool?

>
> Also please document all the rules around how this is set/changed in the
> kerneldoc header comments for the data structure. Finally if you never set
> it except at creation.
>
>> +}
>> +
>>   /* i915_gem_context.c */
>>   void i915_gem_init__contexts(struct drm_i915_private *i915);
>>   
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
>> index 94c03a97cb77..1aa2290aa3c7 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
>> @@ -301,6 +301,7 @@ struct i915_gem_context {
>>   #define UCONTEXT_BANNABLE		2
>>   #define UCONTEXT_RECOVERABLE		3
>>   #define UCONTEXT_PERSISTENCE		4
>> +#define UCONTEXT_PROTECTED		5
>>   
>>   	/**
>>   	 * @flags: small set of booleans
>> @@ -308,6 +309,7 @@ struct i915_gem_context {
>>   	unsigned long flags;
>>   #define CONTEXT_CLOSED			0
>>   #define CONTEXT_USER_ENGINES		1
>> +#define CONTEXT_INVALID			2
>>   
>>   	/** @mutex: guards everything that isn't engines or handles_vma */
>>   	struct mutex mutex;
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c b/drivers/gpu/drm/i915/gem/i915_gem_create.c
>> index 23fee13a3384..0e48629316bb 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
>> @@ -6,6 +6,7 @@
>>   #include "gem/i915_gem_ioctls.h"
>>   #include "gem/i915_gem_lmem.h"
>>   #include "gem/i915_gem_region.h"
>> +#include "pxp/intel_pxp.h"
>>   
>>   #include "i915_drv.h"
>>   #include "i915_trace.h"
>> @@ -82,21 +83,11 @@ static int i915_gem_publish(struct drm_i915_gem_object *obj,
>>   	return 0;
>>   }
>>   
>> -/**
>> - * Creates a new object using the same path as DRM_I915_GEM_CREATE_EXT
>> - * @i915: i915 private
>> - * @size: size of the buffer, in bytes
>> - * @placements: possible placement regions, in priority order
>> - * @n_placements: number of possible placement regions
>> - *
>> - * This function is exposed primarily for selftests and does very little
>> - * error checking.  It is assumed that the set of placement regions has
>> - * already been verified to be valid.
>> - */
>> -struct drm_i915_gem_object *
>> -__i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
>> -			      struct intel_memory_region **placements,
>> -			      unsigned int n_placements)
>> +static struct drm_i915_gem_object *
>> +__i915_gem_object_create_user_ext(struct drm_i915_private *i915, u64 size,
>> +				  struct intel_memory_region **placements,
>> +				  unsigned int n_placements,
>> +				  unsigned int ext_flags)
>>   {
>>   	struct intel_memory_region *mr = placements[0];
>>   	struct drm_i915_gem_object *obj;
>> @@ -135,6 +126,12 @@ __i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
>>   
>>   	GEM_BUG_ON(size != obj->base.size);
>>   
>> +	/* Add any flag set by create_ext options */
>> +	flags |= ext_flags;
>> +
>> +	if (i915_gem_object_is_protected(obj))
>> +		intel_pxp_object_add(obj);
>> +
>>   	trace_i915_gem_object_create(obj);
>>   	return obj;
>>   
>> @@ -145,6 +142,26 @@ __i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
>>   	return ERR_PTR(ret);
>>   }
>>   
>> +/**
>> + * Creates a new object using the same path as DRM_I915_GEM_CREATE_EXT
>> + * @i915: i915 private
>> + * @size: size of the buffer, in bytes
>> + * @placements: possible placement regions, in priority order
>> + * @n_placements: number of possible placement regions
>> + *
>> + * This function is exposed primarily for selftests and does very little
>> + * error checking.  It is assumed that the set of placement regions has
>> + * already been verified to be valid.
>> + */
>> +struct drm_i915_gem_object *
>> +__i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
>> +			      struct intel_memory_region **placements,
>> +			      unsigned int n_placements)
>> +{
>> +	return __i915_gem_object_create_user_ext(i915, size, placements,
>> +						 n_placements, 0);
>> +}
>> +
>>   int
>>   i915_gem_dumb_create(struct drm_file *file,
>>   		     struct drm_device *dev,
>> @@ -224,6 +241,7 @@ struct create_ext {
>>   	struct drm_i915_private *i915;
>>   	struct intel_memory_region *placements[INTEL_REGION_UNKNOWN];
>>   	unsigned int n_placements;
>> +	unsigned long flags;
>>   };
>>   
>>   static void repr_placements(char *buf, size_t size,
>> @@ -356,8 +374,28 @@ static int ext_set_placements(struct i915_user_extension __user *base,
>>   	return set_placements(&ext, data);
>>   }
>>   
>> +static int ext_set_protected(struct i915_user_extension __user *base, void *data)
>> +{
>> +	struct drm_i915_gem_create_ext_protected_content ext;
>> +	struct create_ext *ext_data = data;
>> +
>> +	if (copy_from_user(&ext, base, sizeof(ext)))
>> +		return -EFAULT;
>> +
>> +	if (ext.flags)
>> +		return -EINVAL;
>> +
>> +	if (!intel_pxp_is_enabled(&ext_data->i915->gt.pxp))
>> +		return -ENODEV;
>> +
>> +	ext_data->flags |= I915_BO_PROTECTED;
>> +
>> +	return 0;
>> +}
>> +
>>   static const i915_user_extension_fn create_extensions[] = {
>>   	[I915_GEM_CREATE_EXT_MEMORY_REGIONS] = ext_set_placements,
>> +	[I915_GEM_CREATE_EXT_PROTECTED_CONTENT] = ext_set_protected,
>>   };
>>   
>>   /**
>> @@ -392,9 +430,10 @@ i915_gem_create_ext_ioctl(struct drm_device *dev, void *data,
>>   		ext_data.n_placements = 1;
>>   	}
>>   
>> -	obj = __i915_gem_object_create_user(i915, args->size,
>> -					    ext_data.placements,
>> -					    ext_data.n_placements);
>> +	obj = __i915_gem_object_create_user_ext(i915, args->size,
>> +						ext_data.placements,
>> +						ext_data.n_placements,
>> +						ext_data.flags);
>>   	if (IS_ERR(obj))
>>   		return PTR_ERR(obj);
>>   
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>> index 1ed7475de454..04f33d163340 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>> @@ -21,6 +21,8 @@
>>   #include "gt/intel_gt_pm.h"
>>   #include "gt/intel_ring.h"
>>   
>> +#include "pxp/intel_pxp.h"
>> +
>>   #include "i915_drv.h"
>>   #include "i915_gem_clflush.h"
>>   #include "i915_gem_context.h"
>> @@ -751,6 +753,11 @@ static int eb_select_context(struct i915_execbuffer *eb)
>>   	if (unlikely(IS_ERR(ctx)))
>>   		return PTR_ERR(ctx);
>>   
>> +	if (i915_gem_context_invalidated(ctx)) {
>> +		i915_gem_context_put(ctx);
>> +		return -EACCES;
>> +	}
>> +
>>   	eb->gem_context = ctx;
>>   	if (rcu_access_pointer(ctx->vm))
>>   		eb->invalid_flags |= EXEC_OBJECT_NEEDS_GTT;
>> @@ -819,7 +826,7 @@ static struct i915_vma *eb_lookup_vma(struct i915_execbuffer *eb, u32 handle)
>>   	do {
>>   		struct drm_i915_gem_object *obj;
>>   		struct i915_vma *vma;
>> -		int err;
>> +		int err = 0;
>>   
>>   		rcu_read_lock();
>>   		vma = radix_tree_lookup(&eb->gem_context->handles_vma, handle);
>> @@ -833,6 +840,26 @@ static struct i915_vma *eb_lookup_vma(struct i915_execbuffer *eb, u32 handle)
>>   		if (unlikely(!obj))
>>   			return ERR_PTR(-ENOENT);
>>   
>> +		/*
>> +		 * If the user has opted-in for protected-object tracking, make
>> +		 * sure the object encryption can be used.
>> +		 * We only need to do this when the object is first used with
>> +		 * this context, because the context itself will be banned when
>> +		 * the protected objects become invalid.
>> +		 */
>> +		if (i915_gem_context_uses_protected_content(eb->gem_context) &&
>> +		    i915_gem_object_is_protected(obj)) {
>> +			if (!intel_pxp_is_active(&vm->gt->pxp))
>> +				err = -ENODEV;
>> +			else if (!i915_gem_object_has_valid_protection(obj))
>> +				err = -ENOEXEC;
>> +
>> +			if (err) {
>> +				i915_gem_object_put(obj);
>> +				return ERR_PTR(err);
>> +			}
>> +		}
>> +
>>   		vma = i915_vma_instance(obj, vm, NULL);
>>   		if (IS_ERR(vma)) {
>>   			i915_gem_object_put(obj);
>> @@ -2752,6 +2779,17 @@ eb_select_engine(struct i915_execbuffer *eb)
>>   
>>   	intel_gt_pm_get(ce->engine->gt);
>>   
>> +	if (i915_gem_context_uses_protected_content(eb->gem_context)) {
>> +		err = intel_pxp_wait_for_arb_start(&ce->engine->gt->pxp);
>> +		if (err)
>> +			goto err;
>> +
>> +		if (i915_gem_context_invalidated(eb->gem_context)) {
>> +			err = -EACCES;
> Shouldn't the normal banned context handling takee care of anything that
> slips through? Rolling your own racy invalidation checks doesn't look like
> a good idea.

This is to bail out early and report the error to userspace. If the 
invalidation flag gets set after this check then we'll still catch it 
later as you said, but IMO there is value in bailing out early when 
possible, especially since it is a low-effort check. The invalidation 
flag can't be cleared, so no risk of rejecting something that shouldn't be.

Daniele

>
>> +			goto err;
>> +		}
>> +	}
>> +
>>   	if (!test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
>>   		err = intel_context_alloc_state(ce);
>>   		if (err)
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c
>> index 6fb9afb65034..658a42a7fa07 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
>> @@ -25,6 +25,7 @@
>>   #include <linux/sched/mm.h>
>>   
>>   #include "display/intel_frontbuffer.h"
>> +#include "pxp/intel_pxp.h"
>>   #include "i915_drv.h"
>>   #include "i915_gem_clflush.h"
>>   #include "i915_gem_context.h"
>> @@ -73,6 +74,8 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj,
>>   	INIT_LIST_HEAD(&obj->lut_list);
>>   	spin_lock_init(&obj->lut_lock);
>>   
>> +	INIT_LIST_HEAD(&obj->pxp_link);
>> +
>>   	spin_lock_init(&obj->mmo.lock);
>>   	obj->mmo.offsets = RB_ROOT;
>>   
>> @@ -231,6 +234,9 @@ void __i915_gem_free_object(struct drm_i915_gem_object *obj)
>>   		spin_unlock(&obj->vma.lock);
>>   	}
>>   
>> +	if (i915_gem_object_has_valid_protection(obj))
>> +		intel_pxp_object_remove(obj);
>> +
>>   	__i915_gem_object_free_mmaps(obj);
>>   
>>   	GEM_BUG_ON(!list_empty(&obj->lut_list));
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h
>> index 48112b9d76df..137ae2723514 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
>> @@ -269,6 +269,18 @@ i915_gem_object_clear_tiling_quirk(struct drm_i915_gem_object *obj)
>>   	clear_bit(I915_TILING_QUIRK_BIT, &obj->flags);
>>   }
>>   
>> +static inline bool
>> +i915_gem_object_is_protected(const struct drm_i915_gem_object *obj)
>> +{
>> +	return obj->flags & I915_BO_PROTECTED;
>> +}
>> +
>> +static inline bool
>> +i915_gem_object_has_valid_protection(const struct drm_i915_gem_object *obj)
>> +{
>> +	return i915_gem_object_is_protected(obj) && !list_empty(&obj->pxp_link);
>> +}
>> +
>>   static inline bool
>>   i915_gem_object_type_has(const struct drm_i915_gem_object *obj,
>>   			 unsigned long flags)
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
>> index 2471f36aaff3..38e4a190607a 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
>> @@ -298,6 +298,7 @@ struct drm_i915_gem_object {
>>   			     I915_BO_ALLOC_USER)
>>   #define I915_BO_READONLY         BIT(4)
>>   #define I915_TILING_QUIRK_BIT    5 /* unknown swizzling; do not release! */
>> +#define I915_BO_PROTECTED        BIT(6)
>>   
>>   	/**
>>   	 * @mem_flags - Mutable placement-related flags
>> @@ -537,6 +538,14 @@ struct drm_i915_gem_object {
>>   		bool created:1;
>>   	} ttm;
>>   
>> +	/*
>> +	 * When the PXP session is invalidated, we need to mark all protected
>> +	 * objects as invalid. To easily do so we add them all to a list. The
>> +	 * presence on the list is used to check if the encryption is valid or
>> +	 * not.
>> +	 */
>> +	struct list_head pxp_link;
>> +
>>   	/** Record of address bit 17 of each page at last unbind. */
>>   	unsigned long *bit_17;
>>   
>> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
>> index b0c7edc10cc3..f418281e8c10 100644
>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
>> @@ -7,6 +7,7 @@
>>   #include "intel_pxp_irq.h"
>>   #include "intel_pxp_session.h"
>>   #include "intel_pxp_tee.h"
>> +#include "gem/i915_gem_context.h"
>>   #include "gt/intel_context.h"
>>   #include "i915_drv.h"
>>   
>> @@ -70,6 +71,9 @@ void intel_pxp_init(struct intel_pxp *pxp)
>>   
>>   	mutex_init(&pxp->tee_mutex);
>>   
>> +	spin_lock_init(&pxp->lock);
>> +	INIT_LIST_HEAD(&pxp->protected_objects);
>> +
>>   	/*
>>   	 * we'll use the completion to check if there is a termination pending,
>>   	 * so we start it as completed and we reinit it when a termination
>> @@ -166,3 +170,88 @@ void intel_pxp_fini_hw(struct intel_pxp *pxp)
>>   
>>   	intel_pxp_irq_disable(pxp);
>>   }
>> +
>> +int intel_pxp_object_add(struct drm_i915_gem_object *obj)
>> +{
>> +	struct intel_pxp *pxp = &to_i915(obj->base.dev)->gt.pxp;
>> +
>> +	if (!intel_pxp_is_enabled(pxp))
>> +		return -ENODEV;
>> +
>> +	if (!list_empty(&obj->pxp_link))
>> +		return -EEXIST;
>> +
>> +	spin_lock_irq(&pxp->lock);
>> +	list_add(&obj->pxp_link, &pxp->protected_objects);
>> +	spin_unlock_irq(&pxp->lock);
>> +
>> +	return 0;
>> +}
>> +
>> +void intel_pxp_object_remove(struct drm_i915_gem_object *obj)
>> +{
>> +	struct intel_pxp *pxp = &to_i915(obj->base.dev)->gt.pxp;
>> +
>> +	if (!intel_pxp_is_enabled(pxp))
>> +		return;
>> +
>> +	spin_lock_irq(&pxp->lock);
>> +	list_del_init(&obj->pxp_link);
>> +	spin_unlock_irq(&pxp->lock);
>> +}
>> +
>> +void intel_pxp_invalidate(struct intel_pxp *pxp)
> There is a lot of locking going on here. Please make sure it's all
> properly documented what the rules are in kerneldoc, even for existing
> stuff.
>
> Especially anytime there's anything tricky going on, like:
> - kref_get_unless_zero
> - test_bit (that's an unorderd atomic, so either you don't actually need
>    the atomic, or you need a pile of barriers and comments about them)
> - hiddent atomic ops like intel_context_set_banned or
>    i915_gem_context_set_invalid also need great care, least because the
>    current rules aren't documented really. So step one here before using
>    them is documenting the rules of how banning works.
>
>> +{
>> +	struct drm_i915_private *i915 = pxp_to_gt(pxp)->i915;
>> +	struct drm_i915_gem_object *obj, *tmp;
>> +	struct i915_gem_context *ctx, *cn;
>> +
>> +	/* delete objects that have been used with the invalidated session */
>> +	spin_lock_irq(&pxp->lock);
>> +	list_for_each_entry_safe(obj, tmp, &pxp->protected_objects, pxp_link) {
>> +		if (i915_gem_object_has_pages(obj))
>> +			list_del_init(&obj->pxp_link);
>> +	}
>> +	spin_unlock_irq(&pxp->lock);
>> +
>> +	/* 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) {
>> +		struct i915_gem_engines_iter it;
>> +		struct intel_context *ce;
>> +
>> +		if (!kref_get_unless_zero(&ctx->ref))
>> +			continue;
>> +
>> +		if (likely(!i915_gem_context_uses_protected_content(ctx)) ||
>> +		    i915_gem_context_invalidated(ctx)) {
>> +			i915_gem_context_put(ctx);
>> +			continue;
>> +		}
>> +
>> +		spin_unlock_irq(&i915->gem.contexts.lock);
>> +
>> +		/*
>> +		 * Note that by the time we get here the HW keys are already
>> +		 * long gone, so any batch using them that's already on the
>> +		 * engines is very likely a lost cause (and it has probably
>> +		 * already hung the engine). Therefore, we skip attempting to
>> +		 * pull the running context out of the HW and we prioritize
>> +		 * bringing the session back as soon as possible.
>> +		 */
>> +		for_each_gem_engine(ce, i915_gem_context_lock_engines(ctx), it) {
>> +			/* only invalidate if at least one ce was allocated */
>> +			if (test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
>> +				intel_context_set_banned(ce);
>> +				i915_gem_context_set_invalid(ctx);
>> +			}
>> +		}
>> +		i915_gem_context_unlock_engines(ctx);
>> +
>> +		spin_lock_irq(&i915->gem.contexts.lock);
>> +		list_safe_reset_next(ctx, cn, link);
>> +		i915_gem_context_put(ctx);
>> +	}
>> +	spin_unlock_irq(&i915->gem.contexts.lock);
>> +}
>> +
>> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
>> index 074b3b980957..4f7647f34153 100644
>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
>> @@ -9,6 +9,8 @@
>>   #include "gt/intel_gt_types.h"
>>   #include "intel_pxp_types.h"
>>   
>> +struct drm_i915_gem_object;
>> +
>>   static inline struct intel_gt *pxp_to_gt(const struct intel_pxp *pxp)
>>   {
>>   	return container_of(pxp, struct intel_gt, pxp);
>> @@ -33,6 +35,11 @@ void intel_pxp_fini_hw(struct intel_pxp *pxp);
>>   
>>   void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp);
>>   int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp);
>> +
>> +int intel_pxp_object_add(struct drm_i915_gem_object *obj);
>> +void intel_pxp_object_remove(struct drm_i915_gem_object *obj);
>> +
>> +void intel_pxp_invalidate(struct intel_pxp *pxp);
>>   #else
>>   static inline void intel_pxp_init(struct intel_pxp *pxp)
>>   {
>> @@ -46,6 +53,14 @@ static inline int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp)
>>   {
>>   	return 0;
>>   }
>> +
>> +static inline int intel_pxp_object_add(struct drm_i915_gem_object *obj)
>> +{
>> +	return 0;
>> +}
>> +static inline void intel_pxp_object_remove(struct drm_i915_gem_object *obj)
>> +{
>> +}
>>   #endif
>>   
>>   #endif /* __INTEL_PXP_H__ */
>> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
>> index 67c30e534d50..0edd563a653d 100644
>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
>> @@ -85,6 +85,9 @@ static int pxp_terminate_arb_session_and_global(struct intel_pxp *pxp)
>>   	/* must mark termination in progress calling this function */
>>   	GEM_WARN_ON(pxp->arb_is_valid);
>>   
>> +	/* invalidate protected objects */
>> +	intel_pxp_invalidate(pxp);
>> +
>>   	/* terminate the hw sessions */
>>   	ret = intel_pxp_terminate_session(pxp, ARB_SESSION);
>>   	if (ret) {
>> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
>> index 475e3312c287..be2bed3a2e4e 100644
>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
>> @@ -7,7 +7,9 @@
>>   #define __INTEL_PXP_TYPES_H__
>>   
>>   #include <linux/completion.h>
>> +#include <linux/list.h>
>>   #include <linux/mutex.h>
>> +#include <linux/spinlock.h>
>>   #include <linux/types.h>
>>   #include <linux/workqueue.h>
>>   
>> @@ -43,6 +45,9 @@ struct intel_pxp {
>>   	u32 session_events; /* protected with gt->irq_lock */
>>   #define PXP_TERMINATION_REQUEST  BIT(0)
>>   #define PXP_TERMINATION_COMPLETE BIT(1)
>> +
>> +	spinlock_t lock; /* protects the objects list */
>> +	struct list_head protected_objects;
>>   };
>>   
>>   #endif /* __INTEL_PXP_TYPES_H__ */
>> diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
>> index 4393eef59d9b..2c9febdae6a5 100644
>> --- a/include/uapi/drm/i915_drm.h
>> +++ b/include/uapi/drm/i915_drm.h
>> @@ -1843,12 +1843,32 @@ struct drm_i915_gem_context_param {
>>    * attempted to use it, never re-use this context param number.
>>    */
>>   #define I915_CONTEXT_PARAM_RINGSIZE	0xc
>> +
>> +/*
>> + * I915_CONTEXT_PARAM_PROTECTED_CONTENT:
>> + *
>> + * Mark that the context makes use of protected content, which will result
>> + * in the context being invalidated when the protected content session is. The
>> + * invalidation is reported back to userspace via the RESET_STATS ioctl (see
>> + * relevant doc for details).
>> + * This flag can only be set at context creation time and, when set to true,
>> + * must be preceded by an explicit setting of I915_CONTEXT_PARAM_RECOVERABLE
>> + * to false. This flag can't be set to true in conjunction with setting the
>> + * I915_CONTEXT_PARAM_BANNABLE flag to false.
>> + *
>> + * In addition to the normal failure cases, setting this flag during context
>> + * creation can result in the following errors:
>> + *
>> + * -ENODEV: feature not available
>> + * -EPERM: trying to mark a recoverable or not bannable context as protected
>> + */
>> +#define I915_CONTEXT_PARAM_PROTECTED_CONTENT    0xd
>>   /* Must be kept compact -- no holes and well documented */
>>   
>>   	__u64 value;
>>   };
>>   
>> -/*
>> +/**
>>    * Context SSEU programming
>>    *
>>    * It may be necessary for either functional or performance reason to configure
>> @@ -2181,6 +2201,12 @@ struct drm_i915_reg_read {
>>   struct drm_i915_reset_stats {
>>   	__u32 ctx_id;
>>   	__u32 flags;
>> +	/*
>> +	 * contexts marked as using protected content are invalidated when the
>> +	 * protected content session dies. Submission of invalidated contexts
>> +	 * is rejected with -EACCES.
>> +	 */
>> +#define I915_CONTEXT_INVALIDATED 0x1
>>   
>>   	/* All resets since boot/module reload, for all contexts */
>>   	__u32 reset_count;
>> @@ -2959,8 +2985,12 @@ struct drm_i915_gem_create_ext {
>>   	 *
>>   	 * For I915_GEM_CREATE_EXT_MEMORY_REGIONS usage see
>>   	 * struct drm_i915_gem_create_ext_memory_regions.
>> +	 *
>> +	 * For I915_GEM_CREATE_EXT_PROTECTED_CONTENT usage see
>> +	 * struct drm_i915_gem_create_ext_protected_content.
>>   	 */
>>   #define I915_GEM_CREATE_EXT_MEMORY_REGIONS 0
>> +#define I915_GEM_CREATE_EXT_PROTECTED_CONTENT 1
>>   	__u64 extensions;
>>   };
>>   
>> @@ -3018,6 +3048,29 @@ struct drm_i915_gem_create_ext_memory_regions {
>>   	__u64 regions;
>>   };
>>   
>> +/**
>> + * struct drm_i915_gem_create_ext_protected_content - The
>> + * I915_OBJECT_PARAM_PROTECTED_CONTENT extension.
>> + *
>> + * If this extension is provided, buffer contents are expected to be protected
>> + * by PXP encryption and require decryption for scan out and processing. This
>> + * is only possible on platforms that have PXP enabled, on all other scenarios
>> + * using this extension will cause the ioctl to fail and return -ENODEV. The
>> + * flags parameter is reserved for future expansion and must currently be set
>> + * to zero.
>> + *
>> + * The buffer contents are considered invalid after a PXP session teardown.
>> + *
>> + * The encryption is guaranteed to be processed correctly only if the object
>> + * is submitted with a context created using the
>> + * I915_CONTEXT_PARAM_PROTECTED_CONTENT flag. This will also enable extra checks
>> + * at submission time on the validity of the objects involved.
>> + */
>> +struct drm_i915_gem_create_ext_protected_content {
>> +	struct i915_user_extension base;
>> +	__u32 flags;
>> +};
>> +
>>   /* ID of the protected content session managed by i915 when PXP is active */
>>   #define I915_PROTECTED_CONTENT_DEFAULT_SESSION 0xf
>>   
>> -- 
>> 2.32.0
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/intel-gfx


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Intel-gfx] [PATCH v6 10/15] drm/i915/pxp: interfaces for using protected objects
  2021-08-13 14:42     ` Daniel Vetter
@ 2021-08-13 15:24       ` Daniele Ceraolo Spurio
  2021-08-16 15:29         ` Daniel Vetter
  0 siblings, 1 reply; 64+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-08-13 15:24 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: intel-gfx, Daniel Vetter, Chris Wilson, dri-devel, Bommu Krishnaiah



On 8/13/2021 7:42 AM, Daniel Vetter wrote:
> On Fri, Aug 13, 2021 at 04:37:53PM +0200, Daniel Vetter wrote:
>> On Wed, Jul 28, 2021 at 07:01:01PM -0700, Daniele Ceraolo Spurio wrote:
>>> This api allow user mode to create protected buffers and to mark
>>> contexts as making use of such objects. Only when using contexts
>>> marked in such a way is the execution guaranteed to work as expected.
>>>
>>> Contexts can only be marked as using protected content at creation time
>>> (i.e. the parameter is immutable) and they must be both bannable and not
>>> recoverable.
>>>
>>> All protected objects and contexts that have backing storage will be
>>> considered invalid when the PXP session is destroyed and all new
>>> submissions using them will be rejected. All intel contexts within the
>>> invalidated gem contexts will be marked banned. A new flag has been
>>> added to the RESET_STATS ioctl to report the context invalidation to
>>> userspace.
>>>
>>> This patch was previously sent as 2 separate patches, which have been
>>> squashed following a request to have all the uapi in a single patch.
>>> I've retained the s-o-b from both.
>>>
>>> v5: squash patches, rebase on proto_ctx, update kerneldoc
>>>
>>> v6: rebase on obj create_ext changes
>>>
>>> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
>>> Signed-off-by: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
>>> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
>>> Cc: Chris Wilson <chris@chris-wilson.co.uk>
>>> Cc: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
>>> Cc: Jason Ekstrand <jason@jlekstrand.net>
>>> Cc: Daniel Vetter <daniel.vetter@intel.com>
>>> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> #v5
>>> ---
>>>   drivers/gpu/drm/i915/gem/i915_gem_context.c   | 68 ++++++++++++--
>>>   drivers/gpu/drm/i915/gem/i915_gem_context.h   | 18 ++++
>>>   .../gpu/drm/i915/gem/i915_gem_context_types.h |  2 +
>>>   drivers/gpu/drm/i915/gem/i915_gem_create.c    | 75 ++++++++++++----
>>>   .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 40 ++++++++-
>>>   drivers/gpu/drm/i915/gem/i915_gem_object.c    |  6 ++
>>>   drivers/gpu/drm/i915/gem/i915_gem_object.h    | 12 +++
>>>   .../gpu/drm/i915/gem/i915_gem_object_types.h  |  9 ++
>>>   drivers/gpu/drm/i915/pxp/intel_pxp.c          | 89 +++++++++++++++++++
>>>   drivers/gpu/drm/i915/pxp/intel_pxp.h          | 15 ++++
>>>   drivers/gpu/drm/i915/pxp/intel_pxp_session.c  |  3 +
>>>   drivers/gpu/drm/i915/pxp/intel_pxp_types.h    |  5 ++
>>>   include/uapi/drm/i915_drm.h                   | 55 +++++++++++-
>>>   13 files changed, 371 insertions(+), 26 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c
>>> index cff72679ad7c..0cd3e2d06188 100644
>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
>>> @@ -77,6 +77,8 @@
>>>   #include "gt/intel_gpu_commands.h"
>>>   #include "gt/intel_ring.h"
>>>   
>>> +#include "pxp/intel_pxp.h"
>>> +
>>>   #include "i915_gem_context.h"
>>>   #include "i915_trace.h"
>>>   #include "i915_user_extensions.h"
>>> @@ -241,6 +243,25 @@ static int proto_context_set_persistence(struct drm_i915_private *i915,
>>>   	return 0;
>>>   }
>>>   
>>> +static int proto_context_set_protected(struct drm_i915_private *i915,
>>> +				       struct i915_gem_proto_context *pc,
>>> +				       bool protected)
>>> +{
>>> +	int ret = 0;
>>> +
>>> +	if (!intel_pxp_is_enabled(&i915->gt.pxp))
>>> +		ret = -ENODEV;
>>> +	else if (!protected)
>>> +		pc->user_flags &= ~BIT(UCONTEXT_PROTECTED);
>>> +	else if ((pc->user_flags & BIT(UCONTEXT_RECOVERABLE)) ||
>>> +		 !(pc->user_flags & BIT(UCONTEXT_BANNABLE)))
>>> +		ret = -EPERM;
>>> +	else
>>> +		pc->user_flags |= BIT(UCONTEXT_PROTECTED);
>>> +
>>> +	return ret;
>>> +}
>>> +
>>>   static struct i915_gem_proto_context *
>>>   proto_context_create(struct drm_i915_private *i915, unsigned int flags)
>>>   {
>>> @@ -686,6 +707,8 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
>>>   			ret = -EPERM;
>>>   		else if (args->value)
>>>   			pc->user_flags |= BIT(UCONTEXT_BANNABLE);
>>> +		else if (pc->user_flags & BIT(UCONTEXT_PROTECTED))
>>> +			ret = -EPERM;
>>>   		else
>>>   			pc->user_flags &= ~BIT(UCONTEXT_BANNABLE);
>>>   		break;
>>> @@ -693,10 +716,12 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
>>>   	case I915_CONTEXT_PARAM_RECOVERABLE:
>>>   		if (args->size)
>>>   			ret = -EINVAL;
>>> -		else if (args->value)
>>> -			pc->user_flags |= BIT(UCONTEXT_RECOVERABLE);
>>> -		else
>>> +		else if (!args->value)
>>>   			pc->user_flags &= ~BIT(UCONTEXT_RECOVERABLE);
>>> +		else if (pc->user_flags & BIT(UCONTEXT_PROTECTED))
>>> +			ret = -EPERM;
>>> +		else
>>> +			pc->user_flags |= BIT(UCONTEXT_RECOVERABLE);
>>>   		break;
>>>   
>>>   	case I915_CONTEXT_PARAM_PRIORITY:
>>> @@ -724,6 +749,11 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
>>>   						    args->value);
>>>   		break;
>>>   
>>> +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
>>> +		ret = proto_context_set_protected(fpriv->dev_priv, pc,
>>> +						  args->value);
>>> +		break;
>>> +
>>>   	case I915_CONTEXT_PARAM_NO_ZEROMAP:
>>>   	case I915_CONTEXT_PARAM_BAN_PERIOD:
>>>   	case I915_CONTEXT_PARAM_RINGSIZE:
>>> @@ -1798,6 +1828,18 @@ static int set_priority(struct i915_gem_context *ctx,
>>>   	return 0;
>>>   }
>>>   
>>> +static int get_protected(struct i915_gem_context *ctx,
>>> +			 struct drm_i915_gem_context_param *args)
>>> +{
>>> +	if (!intel_pxp_is_enabled(&ctx->i915->gt.pxp))
>>> +		return -ENODEV;
>>> +
>>> +	args->size = 0;
>>> +	args->value = i915_gem_context_uses_protected_content(ctx);
>>> +
>>> +	return 0;
>>> +}
>>> +
>>>   static int ctx_setparam(struct drm_i915_file_private *fpriv,
>>>   			struct i915_gem_context *ctx,
>>>   			struct drm_i915_gem_context_param *args)
>>> @@ -1821,6 +1863,8 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
>>>   			ret = -EPERM;
>>>   		else if (args->value)
>>>   			i915_gem_context_set_bannable(ctx);
>>> +		else if (i915_gem_context_uses_protected_content(ctx))
>>> +			ret = -EPERM; /* can't clear this for protected contexts */
>>>   		else
>>>   			i915_gem_context_clear_bannable(ctx);
>>>   		break;
>>> @@ -1828,10 +1872,12 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
>>>   	case I915_CONTEXT_PARAM_RECOVERABLE:
>>>   		if (args->size)
>>>   			ret = -EINVAL;
>>> -		else if (args->value)
>>> -			i915_gem_context_set_recoverable(ctx);
>>> -		else
>>> +		else if (!args->value)
>>>   			i915_gem_context_clear_recoverable(ctx);
>>> +		else if (i915_gem_context_uses_protected_content(ctx))
>>> +			ret = -EPERM; /* can't set this for protected contexts */
>>> +		else
>>> +			i915_gem_context_set_recoverable(ctx);
>>>   		break;
>>>   
>>>   	case I915_CONTEXT_PARAM_PRIORITY:
>>> @@ -1846,6 +1892,7 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
>>>   		ret = set_persistence(ctx, args);
>>>   		break;
>>>   
>>> +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
>>>   	case I915_CONTEXT_PARAM_NO_ZEROMAP:
>>>   	case I915_CONTEXT_PARAM_BAN_PERIOD:
>>>   	case I915_CONTEXT_PARAM_RINGSIZE:
>>> @@ -2174,6 +2221,10 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
>>>   		args->value = i915_gem_context_is_persistent(ctx);
>>>   		break;
>>>   
>>> +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
>>> +		ret = get_protected(ctx, args);
>>> +		break;
>>> +
>>>   	case I915_CONTEXT_PARAM_NO_ZEROMAP:
>>>   	case I915_CONTEXT_PARAM_BAN_PERIOD:
>>>   	case I915_CONTEXT_PARAM_ENGINES:
>>> @@ -2250,6 +2301,11 @@ int i915_gem_context_reset_stats_ioctl(struct drm_device *dev,
>>>   	args->batch_active = atomic_read(&ctx->guilty_count);
>>>   	args->batch_pending = atomic_read(&ctx->active_count);
>>>   
>>> +	/* re-use args->flags for output flags */
>>> +	args->flags = 0;
>>> +	if (i915_gem_context_invalidated(ctx))
>>> +		args->flags |= I915_CONTEXT_INVALIDATED;
>>> +
>>>   	i915_gem_context_put(ctx);
>>>   	return 0;
>>>   }
>>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.h b/drivers/gpu/drm/i915/gem/i915_gem_context.h
>>> index 18060536b0c2..d932a70122fa 100644
>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_context.h
>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.h
>>> @@ -108,6 +108,24 @@ i915_gem_context_clear_user_engines(struct i915_gem_context *ctx)
>>>   	clear_bit(CONTEXT_USER_ENGINES, &ctx->flags);
>>>   }
>>>   
>>> +static inline bool
>>> +i915_gem_context_invalidated(const struct i915_gem_context *ctx)
>>> +{
>>> +	return test_bit(CONTEXT_INVALID, &ctx->flags);
>>> +}
>>> +
>>> +static inline void
>>> +i915_gem_context_set_invalid(struct i915_gem_context *ctx)
>>> +{
>>> +	set_bit(CONTEXT_INVALID, &ctx->flags);
>> Do we _really_ need a new bit in this already very complex state
>> machinery, and can't we reuse the BANNED flag instead?
>>
>> This ctx->flags is atomic, unorderd, and that means you need barriers and
>> everything.
>>
>> If you don't actually need the atomic state bit machinery because you're
>> using simple locking, then pls use your own boolean, and document by which
>> lock it's protected.
>>
>>> +}
>>> +
>>> +static inline bool
>>> +i915_gem_context_uses_protected_content(const struct i915_gem_context *ctx)
>>> +{
>>> +	return test_bit(UCONTEXT_PROTECTED, &ctx->user_flags);
>> For immutable state (I really hope this is immutable) pls don't reuse the
>> atomic bitfield of mutable state, but create a flag of your own.
>>
>> Also please document all the rules around how this is set/changed in the
>> kerneldoc header comments for the data structure. Finally if you never set
>> it except at creation.
>>
>>> +}
>>> +
>>>   /* i915_gem_context.c */
>>>   void i915_gem_init__contexts(struct drm_i915_private *i915);
>>>   
>>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
>>> index 94c03a97cb77..1aa2290aa3c7 100644
>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
>>> @@ -301,6 +301,7 @@ struct i915_gem_context {
>>>   #define UCONTEXT_BANNABLE		2
>>>   #define UCONTEXT_RECOVERABLE		3
>>>   #define UCONTEXT_PERSISTENCE		4
>>> +#define UCONTEXT_PROTECTED		5
>>>   
>>>   	/**
>>>   	 * @flags: small set of booleans
>>> @@ -308,6 +309,7 @@ struct i915_gem_context {
>>>   	unsigned long flags;
>>>   #define CONTEXT_CLOSED			0
>>>   #define CONTEXT_USER_ENGINES		1
>>> +#define CONTEXT_INVALID			2
>>>   
>>>   	/** @mutex: guards everything that isn't engines or handles_vma */
>>>   	struct mutex mutex;
>>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c b/drivers/gpu/drm/i915/gem/i915_gem_create.c
>>> index 23fee13a3384..0e48629316bb 100644
>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
>>> @@ -6,6 +6,7 @@
>>>   #include "gem/i915_gem_ioctls.h"
>>>   #include "gem/i915_gem_lmem.h"
>>>   #include "gem/i915_gem_region.h"
>>> +#include "pxp/intel_pxp.h"
>>>   
>>>   #include "i915_drv.h"
>>>   #include "i915_trace.h"
>>> @@ -82,21 +83,11 @@ static int i915_gem_publish(struct drm_i915_gem_object *obj,
>>>   	return 0;
>>>   }
>>>   
>>> -/**
>>> - * Creates a new object using the same path as DRM_I915_GEM_CREATE_EXT
>>> - * @i915: i915 private
>>> - * @size: size of the buffer, in bytes
>>> - * @placements: possible placement regions, in priority order
>>> - * @n_placements: number of possible placement regions
>>> - *
>>> - * This function is exposed primarily for selftests and does very little
>>> - * error checking.  It is assumed that the set of placement regions has
>>> - * already been verified to be valid.
>>> - */
>>> -struct drm_i915_gem_object *
>>> -__i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
>>> -			      struct intel_memory_region **placements,
>>> -			      unsigned int n_placements)
>>> +static struct drm_i915_gem_object *
>>> +__i915_gem_object_create_user_ext(struct drm_i915_private *i915, u64 size,
>>> +				  struct intel_memory_region **placements,
>>> +				  unsigned int n_placements,
>>> +				  unsigned int ext_flags)
>>>   {
>>>   	struct intel_memory_region *mr = placements[0];
>>>   	struct drm_i915_gem_object *obj;
>>> @@ -135,6 +126,12 @@ __i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
>>>   
>>>   	GEM_BUG_ON(size != obj->base.size);
>>>   
>>> +	/* Add any flag set by create_ext options */
>>> +	flags |= ext_flags;
>>> +
>>> +	if (i915_gem_object_is_protected(obj))
>>> +		intel_pxp_object_add(obj);
>>> +
>>>   	trace_i915_gem_object_create(obj);
>>>   	return obj;
>>>   
>>> @@ -145,6 +142,26 @@ __i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
>>>   	return ERR_PTR(ret);
>>>   }
>>>   
>>> +/**
>>> + * Creates a new object using the same path as DRM_I915_GEM_CREATE_EXT
>>> + * @i915: i915 private
>>> + * @size: size of the buffer, in bytes
>>> + * @placements: possible placement regions, in priority order
>>> + * @n_placements: number of possible placement regions
>>> + *
>>> + * This function is exposed primarily for selftests and does very little
>>> + * error checking.  It is assumed that the set of placement regions has
>>> + * already been verified to be valid.
>>> + */
>>> +struct drm_i915_gem_object *
>>> +__i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
>>> +			      struct intel_memory_region **placements,
>>> +			      unsigned int n_placements)
>>> +{
>>> +	return __i915_gem_object_create_user_ext(i915, size, placements,
>>> +						 n_placements, 0);
>>> +}
>>> +
>>>   int
>>>   i915_gem_dumb_create(struct drm_file *file,
>>>   		     struct drm_device *dev,
>>> @@ -224,6 +241,7 @@ struct create_ext {
>>>   	struct drm_i915_private *i915;
>>>   	struct intel_memory_region *placements[INTEL_REGION_UNKNOWN];
>>>   	unsigned int n_placements;
>>> +	unsigned long flags;
>>>   };
>>>   
>>>   static void repr_placements(char *buf, size_t size,
>>> @@ -356,8 +374,28 @@ static int ext_set_placements(struct i915_user_extension __user *base,
>>>   	return set_placements(&ext, data);
>>>   }
>>>   
>>> +static int ext_set_protected(struct i915_user_extension __user *base, void *data)
>>> +{
>>> +	struct drm_i915_gem_create_ext_protected_content ext;
>>> +	struct create_ext *ext_data = data;
>>> +
>>> +	if (copy_from_user(&ext, base, sizeof(ext)))
>>> +		return -EFAULT;
>>> +
>>> +	if (ext.flags)
>>> +		return -EINVAL;
>>> +
>>> +	if (!intel_pxp_is_enabled(&ext_data->i915->gt.pxp))
>>> +		return -ENODEV;
>>> +
>>> +	ext_data->flags |= I915_BO_PROTECTED;
>>> +
>>> +	return 0;
>>> +}
>>> +
>>>   static const i915_user_extension_fn create_extensions[] = {
>>>   	[I915_GEM_CREATE_EXT_MEMORY_REGIONS] = ext_set_placements,
>>> +	[I915_GEM_CREATE_EXT_PROTECTED_CONTENT] = ext_set_protected,
>>>   };
>>>   
>>>   /**
>>> @@ -392,9 +430,10 @@ i915_gem_create_ext_ioctl(struct drm_device *dev, void *data,
>>>   		ext_data.n_placements = 1;
>>>   	}
>>>   
>>> -	obj = __i915_gem_object_create_user(i915, args->size,
>>> -					    ext_data.placements,
>>> -					    ext_data.n_placements);
>>> +	obj = __i915_gem_object_create_user_ext(i915, args->size,
>>> +						ext_data.placements,
>>> +						ext_data.n_placements,
>>> +						ext_data.flags);
>>>   	if (IS_ERR(obj))
>>>   		return PTR_ERR(obj);
>>>   
>>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>>> index 1ed7475de454..04f33d163340 100644
>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>>> @@ -21,6 +21,8 @@
>>>   #include "gt/intel_gt_pm.h"
>>>   #include "gt/intel_ring.h"
>>>   
>>> +#include "pxp/intel_pxp.h"
>>> +
>>>   #include "i915_drv.h"
>>>   #include "i915_gem_clflush.h"
>>>   #include "i915_gem_context.h"
>>> @@ -751,6 +753,11 @@ static int eb_select_context(struct i915_execbuffer *eb)
>>>   	if (unlikely(IS_ERR(ctx)))
>>>   		return PTR_ERR(ctx);
>>>   
>>> +	if (i915_gem_context_invalidated(ctx)) {
>>> +		i915_gem_context_put(ctx);
>>> +		return -EACCES;
>>> +	}
>>> +
>>>   	eb->gem_context = ctx;
>>>   	if (rcu_access_pointer(ctx->vm))
>>>   		eb->invalid_flags |= EXEC_OBJECT_NEEDS_GTT;
>>> @@ -819,7 +826,7 @@ static struct i915_vma *eb_lookup_vma(struct i915_execbuffer *eb, u32 handle)
>>>   	do {
>>>   		struct drm_i915_gem_object *obj;
>>>   		struct i915_vma *vma;
>>> -		int err;
>>> +		int err = 0;
>>>   
>>>   		rcu_read_lock();
>>>   		vma = radix_tree_lookup(&eb->gem_context->handles_vma, handle);
>>> @@ -833,6 +840,26 @@ static struct i915_vma *eb_lookup_vma(struct i915_execbuffer *eb, u32 handle)
>>>   		if (unlikely(!obj))
>>>   			return ERR_PTR(-ENOENT);
>>>   
>>> +		/*
>>> +		 * If the user has opted-in for protected-object tracking, make
>>> +		 * sure the object encryption can be used.
>>> +		 * We only need to do this when the object is first used with
>>> +		 * this context, because the context itself will be banned when
>>> +		 * the protected objects become invalid.
>>> +		 */
>>> +		if (i915_gem_context_uses_protected_content(eb->gem_context) &&
>>> +		    i915_gem_object_is_protected(obj)) {
>>> +			if (!intel_pxp_is_active(&vm->gt->pxp))
>>> +				err = -ENODEV;
>>> +			else if (!i915_gem_object_has_valid_protection(obj))
>>> +				err = -ENOEXEC;
>>> +
>>> +			if (err) {
>>> +				i915_gem_object_put(obj);
>>> +				return ERR_PTR(err);
>>> +			}
>>> +		}
>>> +
>>>   		vma = i915_vma_instance(obj, vm, NULL);
>>>   		if (IS_ERR(vma)) {
>>>   			i915_gem_object_put(obj);
>>> @@ -2752,6 +2779,17 @@ eb_select_engine(struct i915_execbuffer *eb)
>>>   
>>>   	intel_gt_pm_get(ce->engine->gt);
>>>   
>>> +	if (i915_gem_context_uses_protected_content(eb->gem_context)) {
>>> +		err = intel_pxp_wait_for_arb_start(&ce->engine->gt->pxp);
>>> +		if (err)
>>> +			goto err;
>>> +
>>> +		if (i915_gem_context_invalidated(eb->gem_context)) {
>>> +			err = -EACCES;
>> Shouldn't the normal banned context handling takee care of anything that
>> slips through? Rolling your own racy invalidation checks doesn't look like
>> a good idea.
>>
>>> +			goto err;
>>> +		}
>>> +	}
>>> +
>>>   	if (!test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
>>>   		err = intel_context_alloc_state(ce);
>>>   		if (err)
>>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c
>>> index 6fb9afb65034..658a42a7fa07 100644
>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
>>> @@ -25,6 +25,7 @@
>>>   #include <linux/sched/mm.h>
>>>   
>>>   #include "display/intel_frontbuffer.h"
>>> +#include "pxp/intel_pxp.h"
>>>   #include "i915_drv.h"
>>>   #include "i915_gem_clflush.h"
>>>   #include "i915_gem_context.h"
>>> @@ -73,6 +74,8 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj,
>>>   	INIT_LIST_HEAD(&obj->lut_list);
>>>   	spin_lock_init(&obj->lut_lock);
>>>   
>>> +	INIT_LIST_HEAD(&obj->pxp_link);
>>> +
>>>   	spin_lock_init(&obj->mmo.lock);
>>>   	obj->mmo.offsets = RB_ROOT;
>>>   
>>> @@ -231,6 +234,9 @@ void __i915_gem_free_object(struct drm_i915_gem_object *obj)
>>>   		spin_unlock(&obj->vma.lock);
>>>   	}
>>>   
>>> +	if (i915_gem_object_has_valid_protection(obj))
>>> +		intel_pxp_object_remove(obj);
>>> +
>>>   	__i915_gem_object_free_mmaps(obj);
>>>   
>>>   	GEM_BUG_ON(!list_empty(&obj->lut_list));
>>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h
>>> index 48112b9d76df..137ae2723514 100644
>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
>>> @@ -269,6 +269,18 @@ i915_gem_object_clear_tiling_quirk(struct drm_i915_gem_object *obj)
>>>   	clear_bit(I915_TILING_QUIRK_BIT, &obj->flags);
>>>   }
>>>   
>>> +static inline bool
>>> +i915_gem_object_is_protected(const struct drm_i915_gem_object *obj)
>>> +{
>>> +	return obj->flags & I915_BO_PROTECTED;
>>> +}
>>> +
>>> +static inline bool
>>> +i915_gem_object_has_valid_protection(const struct drm_i915_gem_object *obj)
>>> +{
>>> +	return i915_gem_object_is_protected(obj) && !list_empty(&obj->pxp_link);
>>> +}
>>> +
>>>   static inline bool
>>>   i915_gem_object_type_has(const struct drm_i915_gem_object *obj,
>>>   			 unsigned long flags)
>>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
>>> index 2471f36aaff3..38e4a190607a 100644
>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
>>> @@ -298,6 +298,7 @@ struct drm_i915_gem_object {
>>>   			     I915_BO_ALLOC_USER)
>>>   #define I915_BO_READONLY         BIT(4)
>>>   #define I915_TILING_QUIRK_BIT    5 /* unknown swizzling; do not release! */
>>> +#define I915_BO_PROTECTED        BIT(6)
>>>   
>>>   	/**
>>>   	 * @mem_flags - Mutable placement-related flags
>>> @@ -537,6 +538,14 @@ struct drm_i915_gem_object {
>>>   		bool created:1;
>>>   	} ttm;
>>>   
>>> +	/*
>>> +	 * When the PXP session is invalidated, we need to mark all protected
>>> +	 * objects as invalid. To easily do so we add them all to a list. The
>>> +	 * presence on the list is used to check if the encryption is valid or
>>> +	 * not.
>>> +	 */
>>> +	struct list_head pxp_link;
> This
> - seems to be accessed locklessly, which needs giant amounts of comments
>    and justifications to prove a) it's needed and b) it's correct against
>    all races
> - we already have a per-object lock in the form of dma_resv_lock. Why
>    can't we use that to protect pxp object state?

This is always modified under pxp->lock. The only lockless access we do 
is a list_empty() check to see if the protection is valid, and that's 
because the check is inherently racy anyway (state can change at any 
point before or after we've checked) so adding a lock wouldn't really 
help. Note that the list can only be set at object creation time and it 
is only cleared either during the first invalidation or during object 
destruction.

Daniele

> Looking needs to be done with extreme care, or we're just burrying
> ourselves into something that cannot be understood and maintained anymore.
> -Daniel
>
>>> +
>>>   	/** Record of address bit 17 of each page at last unbind. */
>>>   	unsigned long *bit_17;
>>>   
>>> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
>>> index b0c7edc10cc3..f418281e8c10 100644
>>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
>>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
>>> @@ -7,6 +7,7 @@
>>>   #include "intel_pxp_irq.h"
>>>   #include "intel_pxp_session.h"
>>>   #include "intel_pxp_tee.h"
>>> +#include "gem/i915_gem_context.h"
>>>   #include "gt/intel_context.h"
>>>   #include "i915_drv.h"
>>>   
>>> @@ -70,6 +71,9 @@ void intel_pxp_init(struct intel_pxp *pxp)
>>>   
>>>   	mutex_init(&pxp->tee_mutex);
>>>   
>>> +	spin_lock_init(&pxp->lock);
>>> +	INIT_LIST_HEAD(&pxp->protected_objects);
>>> +
>>>   	/*
>>>   	 * we'll use the completion to check if there is a termination pending,
>>>   	 * so we start it as completed and we reinit it when a termination
>>> @@ -166,3 +170,88 @@ void intel_pxp_fini_hw(struct intel_pxp *pxp)
>>>   
>>>   	intel_pxp_irq_disable(pxp);
>>>   }
>>> +
>>> +int intel_pxp_object_add(struct drm_i915_gem_object *obj)
>>> +{
>>> +	struct intel_pxp *pxp = &to_i915(obj->base.dev)->gt.pxp;
>>> +
>>> +	if (!intel_pxp_is_enabled(pxp))
>>> +		return -ENODEV;
>>> +
>>> +	if (!list_empty(&obj->pxp_link))
>>> +		return -EEXIST;
>>> +
>>> +	spin_lock_irq(&pxp->lock);
>>> +	list_add(&obj->pxp_link, &pxp->protected_objects);
>>> +	spin_unlock_irq(&pxp->lock);
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +void intel_pxp_object_remove(struct drm_i915_gem_object *obj)
>>> +{
>>> +	struct intel_pxp *pxp = &to_i915(obj->base.dev)->gt.pxp;
>>> +
>>> +	if (!intel_pxp_is_enabled(pxp))
>>> +		return;
>>> +
>>> +	spin_lock_irq(&pxp->lock);
>>> +	list_del_init(&obj->pxp_link);
>>> +	spin_unlock_irq(&pxp->lock);
>>> +}
>>> +
>>> +void intel_pxp_invalidate(struct intel_pxp *pxp)
>> There is a lot of locking going on here. Please make sure it's all
>> properly documented what the rules are in kerneldoc, even for existing
>> stuff.
>>
>> Especially anytime there's anything tricky going on, like:
>> - kref_get_unless_zero
>> - test_bit (that's an unorderd atomic, so either you don't actually need
>>    the atomic, or you need a pile of barriers and comments about them)
>> - hiddent atomic ops like intel_context_set_banned or
>>    i915_gem_context_set_invalid also need great care, least because the
>>    current rules aren't documented really. So step one here before using
>>    them is documenting the rules of how banning works.
>>
>>> +{
>>> +	struct drm_i915_private *i915 = pxp_to_gt(pxp)->i915;
>>> +	struct drm_i915_gem_object *obj, *tmp;
>>> +	struct i915_gem_context *ctx, *cn;
>>> +
>>> +	/* delete objects that have been used with the invalidated session */
>>> +	spin_lock_irq(&pxp->lock);
>>> +	list_for_each_entry_safe(obj, tmp, &pxp->protected_objects, pxp_link) {
>>> +		if (i915_gem_object_has_pages(obj))
>>> +			list_del_init(&obj->pxp_link);
> We have a per
>>> +	}
>>> +	spin_unlock_irq(&pxp->lock);
>>> +
>>> +	/* 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) {
>>> +		struct i915_gem_engines_iter it;
>>> +		struct intel_context *ce;
>>> +
>>> +		if (!kref_get_unless_zero(&ctx->ref))
>>> +			continue;
>>> +
>>> +		if (likely(!i915_gem_context_uses_protected_content(ctx)) ||
>>> +		    i915_gem_context_invalidated(ctx)) {
>>> +			i915_gem_context_put(ctx);
>>> +			continue;
>>> +		}
>>> +
>>> +		spin_unlock_irq(&i915->gem.contexts.lock);
>>> +
>>> +		/*
>>> +		 * Note that by the time we get here the HW keys are already
>>> +		 * long gone, so any batch using them that's already on the
>>> +		 * engines is very likely a lost cause (and it has probably
>>> +		 * already hung the engine). Therefore, we skip attempting to
>>> +		 * pull the running context out of the HW and we prioritize
>>> +		 * bringing the session back as soon as possible.
>>> +		 */
>>> +		for_each_gem_engine(ce, i915_gem_context_lock_engines(ctx), it) {
>>> +			/* only invalidate if at least one ce was allocated */
>>> +			if (test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
>>> +				intel_context_set_banned(ce);
>>> +				i915_gem_context_set_invalid(ctx);
>>> +			}
>>> +		}
>>> +		i915_gem_context_unlock_engines(ctx);
>>> +
>>> +		spin_lock_irq(&i915->gem.contexts.lock);
>>> +		list_safe_reset_next(ctx, cn, link);
>>> +		i915_gem_context_put(ctx);
>>> +	}
>>> +	spin_unlock_irq(&i915->gem.contexts.lock);
>>> +}
>>> +
>>> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
>>> index 074b3b980957..4f7647f34153 100644
>>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
>>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
>>> @@ -9,6 +9,8 @@
>>>   #include "gt/intel_gt_types.h"
>>>   #include "intel_pxp_types.h"
>>>   
>>> +struct drm_i915_gem_object;
>>> +
>>>   static inline struct intel_gt *pxp_to_gt(const struct intel_pxp *pxp)
>>>   {
>>>   	return container_of(pxp, struct intel_gt, pxp);
>>> @@ -33,6 +35,11 @@ void intel_pxp_fini_hw(struct intel_pxp *pxp);
>>>   
>>>   void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp);
>>>   int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp);
>>> +
>>> +int intel_pxp_object_add(struct drm_i915_gem_object *obj);
>>> +void intel_pxp_object_remove(struct drm_i915_gem_object *obj);
>>> +
>>> +void intel_pxp_invalidate(struct intel_pxp *pxp);
>>>   #else
>>>   static inline void intel_pxp_init(struct intel_pxp *pxp)
>>>   {
>>> @@ -46,6 +53,14 @@ static inline int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp)
>>>   {
>>>   	return 0;
>>>   }
>>> +
>>> +static inline int intel_pxp_object_add(struct drm_i915_gem_object *obj)
>>> +{
>>> +	return 0;
>>> +}
>>> +static inline void intel_pxp_object_remove(struct drm_i915_gem_object *obj)
>>> +{
>>> +}
>>>   #endif
>>>   
>>>   #endif /* __INTEL_PXP_H__ */
>>> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
>>> index 67c30e534d50..0edd563a653d 100644
>>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
>>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
>>> @@ -85,6 +85,9 @@ static int pxp_terminate_arb_session_and_global(struct intel_pxp *pxp)
>>>   	/* must mark termination in progress calling this function */
>>>   	GEM_WARN_ON(pxp->arb_is_valid);
>>>   
>>> +	/* invalidate protected objects */
>>> +	intel_pxp_invalidate(pxp);
>>> +
>>>   	/* terminate the hw sessions */
>>>   	ret = intel_pxp_terminate_session(pxp, ARB_SESSION);
>>>   	if (ret) {
>>> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
>>> index 475e3312c287..be2bed3a2e4e 100644
>>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
>>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
>>> @@ -7,7 +7,9 @@
>>>   #define __INTEL_PXP_TYPES_H__
>>>   
>>>   #include <linux/completion.h>
>>> +#include <linux/list.h>
>>>   #include <linux/mutex.h>
>>> +#include <linux/spinlock.h>
>>>   #include <linux/types.h>
>>>   #include <linux/workqueue.h>
>>>   
>>> @@ -43,6 +45,9 @@ struct intel_pxp {
>>>   	u32 session_events; /* protected with gt->irq_lock */
>>>   #define PXP_TERMINATION_REQUEST  BIT(0)
>>>   #define PXP_TERMINATION_COMPLETE BIT(1)
>>> +
>>> +	spinlock_t lock; /* protects the objects list */
>>> +	struct list_head protected_objects;
>>>   };
>>>   
>>>   #endif /* __INTEL_PXP_TYPES_H__ */
>>> diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
>>> index 4393eef59d9b..2c9febdae6a5 100644
>>> --- a/include/uapi/drm/i915_drm.h
>>> +++ b/include/uapi/drm/i915_drm.h
>>> @@ -1843,12 +1843,32 @@ struct drm_i915_gem_context_param {
>>>    * attempted to use it, never re-use this context param number.
>>>    */
>>>   #define I915_CONTEXT_PARAM_RINGSIZE	0xc
>>> +
>>> +/*
>>> + * I915_CONTEXT_PARAM_PROTECTED_CONTENT:
>>> + *
>>> + * Mark that the context makes use of protected content, which will result
>>> + * in the context being invalidated when the protected content session is. The
>>> + * invalidation is reported back to userspace via the RESET_STATS ioctl (see
>>> + * relevant doc for details).
>>> + * This flag can only be set at context creation time and, when set to true,
>>> + * must be preceded by an explicit setting of I915_CONTEXT_PARAM_RECOVERABLE
>>> + * to false. This flag can't be set to true in conjunction with setting the
>>> + * I915_CONTEXT_PARAM_BANNABLE flag to false.
>>> + *
>>> + * In addition to the normal failure cases, setting this flag during context
>>> + * creation can result in the following errors:
>>> + *
>>> + * -ENODEV: feature not available
>>> + * -EPERM: trying to mark a recoverable or not bannable context as protected
>>> + */
>>> +#define I915_CONTEXT_PARAM_PROTECTED_CONTENT    0xd
>>>   /* Must be kept compact -- no holes and well documented */
>>>   
>>>   	__u64 value;
>>>   };
>>>   
>>> -/*
>>> +/**
>>>    * Context SSEU programming
>>>    *
>>>    * It may be necessary for either functional or performance reason to configure
>>> @@ -2181,6 +2201,12 @@ struct drm_i915_reg_read {
>>>   struct drm_i915_reset_stats {
>>>   	__u32 ctx_id;
>>>   	__u32 flags;
>>> +	/*
>>> +	 * contexts marked as using protected content are invalidated when the
>>> +	 * protected content session dies. Submission of invalidated contexts
>>> +	 * is rejected with -EACCES.
>>> +	 */
>>> +#define I915_CONTEXT_INVALIDATED 0x1
>>>   
>>>   	/* All resets since boot/module reload, for all contexts */
>>>   	__u32 reset_count;
>>> @@ -2959,8 +2985,12 @@ struct drm_i915_gem_create_ext {
>>>   	 *
>>>   	 * For I915_GEM_CREATE_EXT_MEMORY_REGIONS usage see
>>>   	 * struct drm_i915_gem_create_ext_memory_regions.
>>> +	 *
>>> +	 * For I915_GEM_CREATE_EXT_PROTECTED_CONTENT usage see
>>> +	 * struct drm_i915_gem_create_ext_protected_content.
>>>   	 */
>>>   #define I915_GEM_CREATE_EXT_MEMORY_REGIONS 0
>>> +#define I915_GEM_CREATE_EXT_PROTECTED_CONTENT 1
>>>   	__u64 extensions;
>>>   };
>>>   
>>> @@ -3018,6 +3048,29 @@ struct drm_i915_gem_create_ext_memory_regions {
>>>   	__u64 regions;
>>>   };
>>>   
>>> +/**
>>> + * struct drm_i915_gem_create_ext_protected_content - The
>>> + * I915_OBJECT_PARAM_PROTECTED_CONTENT extension.
>>> + *
>>> + * If this extension is provided, buffer contents are expected to be protected
>>> + * by PXP encryption and require decryption for scan out and processing. This
>>> + * is only possible on platforms that have PXP enabled, on all other scenarios
>>> + * using this extension will cause the ioctl to fail and return -ENODEV. The
>>> + * flags parameter is reserved for future expansion and must currently be set
>>> + * to zero.
>>> + *
>>> + * The buffer contents are considered invalid after a PXP session teardown.
>>> + *
>>> + * The encryption is guaranteed to be processed correctly only if the object
>>> + * is submitted with a context created using the
>>> + * I915_CONTEXT_PARAM_PROTECTED_CONTENT flag. This will also enable extra checks
>>> + * at submission time on the validity of the objects involved.
>>> + */
>>> +struct drm_i915_gem_create_ext_protected_content {
>>> +	struct i915_user_extension base;
>>> +	__u32 flags;
>>> +};
>>> +
>>>   /* ID of the protected content session managed by i915 when PXP is active */
>>>   #define I915_PROTECTED_CONTENT_DEFAULT_SESSION 0xf
>>>   
>>> -- 
>>> 2.32.0
>>>
>>> _______________________________________________
>>> Intel-gfx mailing list
>>> Intel-gfx@lists.freedesktop.org
>>> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
>> -- 
>> Daniel Vetter
>> Software Engineer, Intel Corporation
>> http://blog.ffwll.ch


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Intel-gfx] [PATCH v6 10/15] drm/i915/pxp: interfaces for using protected objects
  2021-08-13 15:18     ` Daniele Ceraolo Spurio
@ 2021-08-16 15:15       ` Daniel Vetter
  2021-08-16 15:58         ` Daniele Ceraolo Spurio
  0 siblings, 1 reply; 64+ messages in thread
From: Daniel Vetter @ 2021-08-16 15:15 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio
  Cc: Daniel Vetter, intel-gfx, Daniel Vetter, Chris Wilson, dri-devel,
	Bommu Krishnaiah

On Fri, Aug 13, 2021 at 08:18:02AM -0700, Daniele Ceraolo Spurio wrote:
> 
> 
> On 8/13/2021 7:37 AM, Daniel Vetter wrote:
> > On Wed, Jul 28, 2021 at 07:01:01PM -0700, Daniele Ceraolo Spurio wrote:
> > > This api allow user mode to create protected buffers and to mark
> > > contexts as making use of such objects. Only when using contexts
> > > marked in such a way is the execution guaranteed to work as expected.
> > > 
> > > Contexts can only be marked as using protected content at creation time
> > > (i.e. the parameter is immutable) and they must be both bannable and not
> > > recoverable.
> > > 
> > > All protected objects and contexts that have backing storage will be
> > > considered invalid when the PXP session is destroyed and all new
> > > submissions using them will be rejected. All intel contexts within the
> > > invalidated gem contexts will be marked banned. A new flag has been
> > > added to the RESET_STATS ioctl to report the context invalidation to
> > > userspace.
> > > 
> > > This patch was previously sent as 2 separate patches, which have been
> > > squashed following a request to have all the uapi in a single patch.
> > > I've retained the s-o-b from both.
> > > 
> > > v5: squash patches, rebase on proto_ctx, update kerneldoc
> > > 
> > > v6: rebase on obj create_ext changes
> > > 
> > > Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
> > > Signed-off-by: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
> > > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > > Cc: Chris Wilson <chris@chris-wilson.co.uk>
> > > Cc: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
> > > Cc: Jason Ekstrand <jason@jlekstrand.net>
> > > Cc: Daniel Vetter <daniel.vetter@intel.com>
> > > Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> #v5
> > > ---
> > >   drivers/gpu/drm/i915/gem/i915_gem_context.c   | 68 ++++++++++++--
> > >   drivers/gpu/drm/i915/gem/i915_gem_context.h   | 18 ++++
> > >   .../gpu/drm/i915/gem/i915_gem_context_types.h |  2 +
> > >   drivers/gpu/drm/i915/gem/i915_gem_create.c    | 75 ++++++++++++----
> > >   .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 40 ++++++++-
> > >   drivers/gpu/drm/i915/gem/i915_gem_object.c    |  6 ++
> > >   drivers/gpu/drm/i915/gem/i915_gem_object.h    | 12 +++
> > >   .../gpu/drm/i915/gem/i915_gem_object_types.h  |  9 ++
> > >   drivers/gpu/drm/i915/pxp/intel_pxp.c          | 89 +++++++++++++++++++
> > >   drivers/gpu/drm/i915/pxp/intel_pxp.h          | 15 ++++
> > >   drivers/gpu/drm/i915/pxp/intel_pxp_session.c  |  3 +
> > >   drivers/gpu/drm/i915/pxp/intel_pxp_types.h    |  5 ++
> > >   include/uapi/drm/i915_drm.h                   | 55 +++++++++++-
> > >   13 files changed, 371 insertions(+), 26 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> > > index cff72679ad7c..0cd3e2d06188 100644
> > > --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
> > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> > > @@ -77,6 +77,8 @@
> > >   #include "gt/intel_gpu_commands.h"
> > >   #include "gt/intel_ring.h"
> > > +#include "pxp/intel_pxp.h"
> > > +
> > >   #include "i915_gem_context.h"
> > >   #include "i915_trace.h"
> > >   #include "i915_user_extensions.h"
> > > @@ -241,6 +243,25 @@ static int proto_context_set_persistence(struct drm_i915_private *i915,
> > >   	return 0;
> > >   }
> > > +static int proto_context_set_protected(struct drm_i915_private *i915,
> > > +				       struct i915_gem_proto_context *pc,
> > > +				       bool protected)
> > > +{
> > > +	int ret = 0;
> > > +
> > > +	if (!intel_pxp_is_enabled(&i915->gt.pxp))
> > > +		ret = -ENODEV;
> > > +	else if (!protected)
> > > +		pc->user_flags &= ~BIT(UCONTEXT_PROTECTED);
> > > +	else if ((pc->user_flags & BIT(UCONTEXT_RECOVERABLE)) ||
> > > +		 !(pc->user_flags & BIT(UCONTEXT_BANNABLE)))
> > > +		ret = -EPERM;
> > > +	else
> > > +		pc->user_flags |= BIT(UCONTEXT_PROTECTED);
> > > +
> > > +	return ret;
> > > +}
> > > +
> > >   static struct i915_gem_proto_context *
> > >   proto_context_create(struct drm_i915_private *i915, unsigned int flags)
> > >   {
> > > @@ -686,6 +707,8 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
> > >   			ret = -EPERM;
> > >   		else if (args->value)
> > >   			pc->user_flags |= BIT(UCONTEXT_BANNABLE);
> > > +		else if (pc->user_flags & BIT(UCONTEXT_PROTECTED))
> > > +			ret = -EPERM;
> > >   		else
> > >   			pc->user_flags &= ~BIT(UCONTEXT_BANNABLE);
> > >   		break;
> > > @@ -693,10 +716,12 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
> > >   	case I915_CONTEXT_PARAM_RECOVERABLE:
> > >   		if (args->size)
> > >   			ret = -EINVAL;
> > > -		else if (args->value)
> > > -			pc->user_flags |= BIT(UCONTEXT_RECOVERABLE);
> > > -		else
> > > +		else if (!args->value)
> > >   			pc->user_flags &= ~BIT(UCONTEXT_RECOVERABLE);
> > > +		else if (pc->user_flags & BIT(UCONTEXT_PROTECTED))
> > > +			ret = -EPERM;
> > > +		else
> > > +			pc->user_flags |= BIT(UCONTEXT_RECOVERABLE);
> > >   		break;
> > >   	case I915_CONTEXT_PARAM_PRIORITY:
> > > @@ -724,6 +749,11 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
> > >   						    args->value);
> > >   		break;
> > > +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
> > > +		ret = proto_context_set_protected(fpriv->dev_priv, pc,
> > > +						  args->value);
> > > +		break;
> > > +
> > >   	case I915_CONTEXT_PARAM_NO_ZEROMAP:
> > >   	case I915_CONTEXT_PARAM_BAN_PERIOD:
> > >   	case I915_CONTEXT_PARAM_RINGSIZE:
> > > @@ -1798,6 +1828,18 @@ static int set_priority(struct i915_gem_context *ctx,
> > >   	return 0;
> > >   }
> > > +static int get_protected(struct i915_gem_context *ctx,
> > > +			 struct drm_i915_gem_context_param *args)
> > > +{
> > > +	if (!intel_pxp_is_enabled(&ctx->i915->gt.pxp))
> > > +		return -ENODEV;
> > > +
> > > +	args->size = 0;
> > > +	args->value = i915_gem_context_uses_protected_content(ctx);
> > > +
> > > +	return 0;
> > > +}
> > > +
> > >   static int ctx_setparam(struct drm_i915_file_private *fpriv,
> > >   			struct i915_gem_context *ctx,
> > >   			struct drm_i915_gem_context_param *args)
> > > @@ -1821,6 +1863,8 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
> > >   			ret = -EPERM;
> > >   		else if (args->value)
> > >   			i915_gem_context_set_bannable(ctx);
> > > +		else if (i915_gem_context_uses_protected_content(ctx))
> > > +			ret = -EPERM; /* can't clear this for protected contexts */
> > >   		else
> > >   			i915_gem_context_clear_bannable(ctx);
> > >   		break;
> > > @@ -1828,10 +1872,12 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
> > >   	case I915_CONTEXT_PARAM_RECOVERABLE:
> > >   		if (args->size)
> > >   			ret = -EINVAL;
> > > -		else if (args->value)
> > > -			i915_gem_context_set_recoverable(ctx);
> > > -		else
> > > +		else if (!args->value)
> > >   			i915_gem_context_clear_recoverable(ctx);
> > > +		else if (i915_gem_context_uses_protected_content(ctx))
> > > +			ret = -EPERM; /* can't set this for protected contexts */
> > > +		else
> > > +			i915_gem_context_set_recoverable(ctx);
> > >   		break;
> > >   	case I915_CONTEXT_PARAM_PRIORITY:
> > > @@ -1846,6 +1892,7 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
> > >   		ret = set_persistence(ctx, args);
> > >   		break;
> > > +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
> > >   	case I915_CONTEXT_PARAM_NO_ZEROMAP:
> > >   	case I915_CONTEXT_PARAM_BAN_PERIOD:
> > >   	case I915_CONTEXT_PARAM_RINGSIZE:
> > > @@ -2174,6 +2221,10 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
> > >   		args->value = i915_gem_context_is_persistent(ctx);
> > >   		break;
> > > +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
> > > +		ret = get_protected(ctx, args);
> > > +		break;
> > > +
> > >   	case I915_CONTEXT_PARAM_NO_ZEROMAP:
> > >   	case I915_CONTEXT_PARAM_BAN_PERIOD:
> > >   	case I915_CONTEXT_PARAM_ENGINES:
> > > @@ -2250,6 +2301,11 @@ int i915_gem_context_reset_stats_ioctl(struct drm_device *dev,
> > >   	args->batch_active = atomic_read(&ctx->guilty_count);
> > >   	args->batch_pending = atomic_read(&ctx->active_count);
> > > +	/* re-use args->flags for output flags */
> > > +	args->flags = 0;
> > > +	if (i915_gem_context_invalidated(ctx))
> > > +		args->flags |= I915_CONTEXT_INVALIDATED;
> > > +
> > >   	i915_gem_context_put(ctx);
> > >   	return 0;
> > >   }
> > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.h b/drivers/gpu/drm/i915/gem/i915_gem_context.h
> > > index 18060536b0c2..d932a70122fa 100644
> > > --- a/drivers/gpu/drm/i915/gem/i915_gem_context.h
> > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.h
> > > @@ -108,6 +108,24 @@ i915_gem_context_clear_user_engines(struct i915_gem_context *ctx)
> > >   	clear_bit(CONTEXT_USER_ENGINES, &ctx->flags);
> > >   }
> > > +static inline bool
> > > +i915_gem_context_invalidated(const struct i915_gem_context *ctx)
> > > +{
> > > +	return test_bit(CONTEXT_INVALID, &ctx->flags);
> > > +}
> > > +
> > > +static inline void
> > > +i915_gem_context_set_invalid(struct i915_gem_context *ctx)
> > > +{
> > > +	set_bit(CONTEXT_INVALID, &ctx->flags);
> > Do we _really_ need a new bit in this already very complex state
> > machinery, and can't we reuse the BANNED flag instead?
> > 
> > This ctx->flags is atomic, unorderd, and that means you need barriers and
> > everything.
> > 
> > If you don't actually need the atomic state bit machinery because you're
> > using simple locking, then pls use your own boolean, and document by which
> > lock it's protected.
> 
> The BANNED flag is at the intel_context level, while I needed something at
> the gem_context level to report out. Can make it a bool if you prefer.
> The invalidation process is inherently racy (the teardown can always occur
> after we've checked the flag) so no amount of locking can help there. The
> flag itself is only set once and never cleared, so no risk of a set and
> clear racing.

Yes the invalidate is racy, but we still need to make guarantees
internally in the kernel that nothing escapes and falls through cracks.

Wrt reporting out, this should be exactly the same flow as a gpu reset
that results in a banned gem context. We really shouldn't duplicate
infrastructure here.


> > > +}
> > > +
> > > +static inline bool
> > > +i915_gem_context_uses_protected_content(const struct i915_gem_context *ctx)
> > > +{
> > > +	return test_bit(UCONTEXT_PROTECTED, &ctx->user_flags);
> > For immutable state (I really hope this is immutable) pls don't reuse the
> > atomic bitfield of mutable state, but create a flag of your own.
> 
> It is immutable. Should we have a ctx->immutable_flags, or better a bool?

Yeah just make it a bool, and add a kerneldoc comment that it's immutable
and never changes.

> 
> > 
> > Also please document all the rules around how this is set/changed in the
> > kerneldoc header comments for the data structure. Finally if you never set
> > it except at creation.
> > 
> > > +}
> > > +
> > >   /* i915_gem_context.c */
> > >   void i915_gem_init__contexts(struct drm_i915_private *i915);
> > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
> > > index 94c03a97cb77..1aa2290aa3c7 100644
> > > --- a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
> > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
> > > @@ -301,6 +301,7 @@ struct i915_gem_context {
> > >   #define UCONTEXT_BANNABLE		2
> > >   #define UCONTEXT_RECOVERABLE		3
> > >   #define UCONTEXT_PERSISTENCE		4
> > > +#define UCONTEXT_PROTECTED		5
> > >   	/**
> > >   	 * @flags: small set of booleans
> > > @@ -308,6 +309,7 @@ struct i915_gem_context {
> > >   	unsigned long flags;
> > >   #define CONTEXT_CLOSED			0
> > >   #define CONTEXT_USER_ENGINES		1
> > > +#define CONTEXT_INVALID			2
> > >   	/** @mutex: guards everything that isn't engines or handles_vma */
> > >   	struct mutex mutex;
> > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c b/drivers/gpu/drm/i915/gem/i915_gem_create.c
> > > index 23fee13a3384..0e48629316bb 100644
> > > --- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
> > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
> > > @@ -6,6 +6,7 @@
> > >   #include "gem/i915_gem_ioctls.h"
> > >   #include "gem/i915_gem_lmem.h"
> > >   #include "gem/i915_gem_region.h"
> > > +#include "pxp/intel_pxp.h"
> > >   #include "i915_drv.h"
> > >   #include "i915_trace.h"
> > > @@ -82,21 +83,11 @@ static int i915_gem_publish(struct drm_i915_gem_object *obj,
> > >   	return 0;
> > >   }
> > > -/**
> > > - * Creates a new object using the same path as DRM_I915_GEM_CREATE_EXT
> > > - * @i915: i915 private
> > > - * @size: size of the buffer, in bytes
> > > - * @placements: possible placement regions, in priority order
> > > - * @n_placements: number of possible placement regions
> > > - *
> > > - * This function is exposed primarily for selftests and does very little
> > > - * error checking.  It is assumed that the set of placement regions has
> > > - * already been verified to be valid.
> > > - */
> > > -struct drm_i915_gem_object *
> > > -__i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
> > > -			      struct intel_memory_region **placements,
> > > -			      unsigned int n_placements)
> > > +static struct drm_i915_gem_object *
> > > +__i915_gem_object_create_user_ext(struct drm_i915_private *i915, u64 size,
> > > +				  struct intel_memory_region **placements,
> > > +				  unsigned int n_placements,
> > > +				  unsigned int ext_flags)
> > >   {
> > >   	struct intel_memory_region *mr = placements[0];
> > >   	struct drm_i915_gem_object *obj;
> > > @@ -135,6 +126,12 @@ __i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
> > >   	GEM_BUG_ON(size != obj->base.size);
> > > +	/* Add any flag set by create_ext options */
> > > +	flags |= ext_flags;
> > > +
> > > +	if (i915_gem_object_is_protected(obj))
> > > +		intel_pxp_object_add(obj);
> > > +
> > >   	trace_i915_gem_object_create(obj);
> > >   	return obj;
> > > @@ -145,6 +142,26 @@ __i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
> > >   	return ERR_PTR(ret);
> > >   }
> > > +/**
> > > + * Creates a new object using the same path as DRM_I915_GEM_CREATE_EXT
> > > + * @i915: i915 private
> > > + * @size: size of the buffer, in bytes
> > > + * @placements: possible placement regions, in priority order
> > > + * @n_placements: number of possible placement regions
> > > + *
> > > + * This function is exposed primarily for selftests and does very little
> > > + * error checking.  It is assumed that the set of placement regions has
> > > + * already been verified to be valid.
> > > + */
> > > +struct drm_i915_gem_object *
> > > +__i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
> > > +			      struct intel_memory_region **placements,
> > > +			      unsigned int n_placements)
> > > +{
> > > +	return __i915_gem_object_create_user_ext(i915, size, placements,
> > > +						 n_placements, 0);
> > > +}
> > > +
> > >   int
> > >   i915_gem_dumb_create(struct drm_file *file,
> > >   		     struct drm_device *dev,
> > > @@ -224,6 +241,7 @@ struct create_ext {
> > >   	struct drm_i915_private *i915;
> > >   	struct intel_memory_region *placements[INTEL_REGION_UNKNOWN];
> > >   	unsigned int n_placements;
> > > +	unsigned long flags;
> > >   };
> > >   static void repr_placements(char *buf, size_t size,
> > > @@ -356,8 +374,28 @@ static int ext_set_placements(struct i915_user_extension __user *base,
> > >   	return set_placements(&ext, data);
> > >   }
> > > +static int ext_set_protected(struct i915_user_extension __user *base, void *data)
> > > +{
> > > +	struct drm_i915_gem_create_ext_protected_content ext;
> > > +	struct create_ext *ext_data = data;
> > > +
> > > +	if (copy_from_user(&ext, base, sizeof(ext)))
> > > +		return -EFAULT;
> > > +
> > > +	if (ext.flags)
> > > +		return -EINVAL;
> > > +
> > > +	if (!intel_pxp_is_enabled(&ext_data->i915->gt.pxp))
> > > +		return -ENODEV;
> > > +
> > > +	ext_data->flags |= I915_BO_PROTECTED;
> > > +
> > > +	return 0;
> > > +}
> > > +
> > >   static const i915_user_extension_fn create_extensions[] = {
> > >   	[I915_GEM_CREATE_EXT_MEMORY_REGIONS] = ext_set_placements,
> > > +	[I915_GEM_CREATE_EXT_PROTECTED_CONTENT] = ext_set_protected,
> > >   };
> > >   /**
> > > @@ -392,9 +430,10 @@ i915_gem_create_ext_ioctl(struct drm_device *dev, void *data,
> > >   		ext_data.n_placements = 1;
> > >   	}
> > > -	obj = __i915_gem_object_create_user(i915, args->size,
> > > -					    ext_data.placements,
> > > -					    ext_data.n_placements);
> > > +	obj = __i915_gem_object_create_user_ext(i915, args->size,
> > > +						ext_data.placements,
> > > +						ext_data.n_placements,
> > > +						ext_data.flags);
> > >   	if (IS_ERR(obj))
> > >   		return PTR_ERR(obj);
> > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> > > index 1ed7475de454..04f33d163340 100644
> > > --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> > > @@ -21,6 +21,8 @@
> > >   #include "gt/intel_gt_pm.h"
> > >   #include "gt/intel_ring.h"
> > > +#include "pxp/intel_pxp.h"
> > > +
> > >   #include "i915_drv.h"
> > >   #include "i915_gem_clflush.h"
> > >   #include "i915_gem_context.h"
> > > @@ -751,6 +753,11 @@ static int eb_select_context(struct i915_execbuffer *eb)
> > >   	if (unlikely(IS_ERR(ctx)))
> > >   		return PTR_ERR(ctx);
> > > +	if (i915_gem_context_invalidated(ctx)) {
> > > +		i915_gem_context_put(ctx);
> > > +		return -EACCES;
> > > +	}
> > > +
> > >   	eb->gem_context = ctx;
> > >   	if (rcu_access_pointer(ctx->vm))
> > >   		eb->invalid_flags |= EXEC_OBJECT_NEEDS_GTT;
> > > @@ -819,7 +826,7 @@ static struct i915_vma *eb_lookup_vma(struct i915_execbuffer *eb, u32 handle)
> > >   	do {
> > >   		struct drm_i915_gem_object *obj;
> > >   		struct i915_vma *vma;
> > > -		int err;
> > > +		int err = 0;
> > >   		rcu_read_lock();
> > >   		vma = radix_tree_lookup(&eb->gem_context->handles_vma, handle);
> > > @@ -833,6 +840,26 @@ static struct i915_vma *eb_lookup_vma(struct i915_execbuffer *eb, u32 handle)
> > >   		if (unlikely(!obj))
> > >   			return ERR_PTR(-ENOENT);
> > > +		/*
> > > +		 * If the user has opted-in for protected-object tracking, make
> > > +		 * sure the object encryption can be used.
> > > +		 * We only need to do this when the object is first used with
> > > +		 * this context, because the context itself will be banned when
> > > +		 * the protected objects become invalid.
> > > +		 */
> > > +		if (i915_gem_context_uses_protected_content(eb->gem_context) &&
> > > +		    i915_gem_object_is_protected(obj)) {
> > > +			if (!intel_pxp_is_active(&vm->gt->pxp))
> > > +				err = -ENODEV;
> > > +			else if (!i915_gem_object_has_valid_protection(obj))
> > > +				err = -ENOEXEC;
> > > +
> > > +			if (err) {
> > > +				i915_gem_object_put(obj);
> > > +				return ERR_PTR(err);
> > > +			}
> > > +		}
> > > +
> > >   		vma = i915_vma_instance(obj, vm, NULL);
> > >   		if (IS_ERR(vma)) {
> > >   			i915_gem_object_put(obj);
> > > @@ -2752,6 +2779,17 @@ eb_select_engine(struct i915_execbuffer *eb)
> > >   	intel_gt_pm_get(ce->engine->gt);
> > > +	if (i915_gem_context_uses_protected_content(eb->gem_context)) {
> > > +		err = intel_pxp_wait_for_arb_start(&ce->engine->gt->pxp);
> > > +		if (err)
> > > +			goto err;
> > > +
> > > +		if (i915_gem_context_invalidated(eb->gem_context)) {
> > > +			err = -EACCES;
> > Shouldn't the normal banned context handling takee care of anything that
> > slips through? Rolling your own racy invalidation checks doesn't look like
> > a good idea.
> 
> This is to bail out early and report the error to userspace. If the
> invalidation flag gets set after this check then we'll still catch it later
> as you said, but IMO there is value in bailing out early when possible,
> especially since it is a low-effort check. The invalidation flag can't be
> cleared, so no risk of rejecting something that shouldn't be.

Nah, that just papers over races and means you now have to validate more
code for correctness - the later catching still must happen, but it's now
much harder to trigger.

Also, the context banning should do this for us already. Maybe a good idea
to audit and document that, to make sure it's working correctly and we're
using it correctly for pxp, but this wheel should exist and we don't need
a new one.

Except if the uapi promise is that we send back a different errno, but
that again should be integrated into the context banning stuff.
-Daniel

> 
> Daniele
> 
> > 
> > > +			goto err;
> > > +		}
> > > +	}
> > > +
> > >   	if (!test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
> > >   		err = intel_context_alloc_state(ce);
> > >   		if (err)
> > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c
> > > index 6fb9afb65034..658a42a7fa07 100644
> > > --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
> > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
> > > @@ -25,6 +25,7 @@
> > >   #include <linux/sched/mm.h>
> > >   #include "display/intel_frontbuffer.h"
> > > +#include "pxp/intel_pxp.h"
> > >   #include "i915_drv.h"
> > >   #include "i915_gem_clflush.h"
> > >   #include "i915_gem_context.h"
> > > @@ -73,6 +74,8 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj,
> > >   	INIT_LIST_HEAD(&obj->lut_list);
> > >   	spin_lock_init(&obj->lut_lock);
> > > +	INIT_LIST_HEAD(&obj->pxp_link);
> > > +
> > >   	spin_lock_init(&obj->mmo.lock);
> > >   	obj->mmo.offsets = RB_ROOT;
> > > @@ -231,6 +234,9 @@ void __i915_gem_free_object(struct drm_i915_gem_object *obj)
> > >   		spin_unlock(&obj->vma.lock);
> > >   	}
> > > +	if (i915_gem_object_has_valid_protection(obj))
> > > +		intel_pxp_object_remove(obj);
> > > +
> > >   	__i915_gem_object_free_mmaps(obj);
> > >   	GEM_BUG_ON(!list_empty(&obj->lut_list));
> > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h
> > > index 48112b9d76df..137ae2723514 100644
> > > --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
> > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
> > > @@ -269,6 +269,18 @@ i915_gem_object_clear_tiling_quirk(struct drm_i915_gem_object *obj)
> > >   	clear_bit(I915_TILING_QUIRK_BIT, &obj->flags);
> > >   }
> > > +static inline bool
> > > +i915_gem_object_is_protected(const struct drm_i915_gem_object *obj)
> > > +{
> > > +	return obj->flags & I915_BO_PROTECTED;
> > > +}
> > > +
> > > +static inline bool
> > > +i915_gem_object_has_valid_protection(const struct drm_i915_gem_object *obj)
> > > +{
> > > +	return i915_gem_object_is_protected(obj) && !list_empty(&obj->pxp_link);
> > > +}
> > > +
> > >   static inline bool
> > >   i915_gem_object_type_has(const struct drm_i915_gem_object *obj,
> > >   			 unsigned long flags)
> > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> > > index 2471f36aaff3..38e4a190607a 100644
> > > --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> > > @@ -298,6 +298,7 @@ struct drm_i915_gem_object {
> > >   			     I915_BO_ALLOC_USER)
> > >   #define I915_BO_READONLY         BIT(4)
> > >   #define I915_TILING_QUIRK_BIT    5 /* unknown swizzling; do not release! */
> > > +#define I915_BO_PROTECTED        BIT(6)
> > >   	/**
> > >   	 * @mem_flags - Mutable placement-related flags
> > > @@ -537,6 +538,14 @@ struct drm_i915_gem_object {
> > >   		bool created:1;
> > >   	} ttm;
> > > +	/*
> > > +	 * When the PXP session is invalidated, we need to mark all protected
> > > +	 * objects as invalid. To easily do so we add them all to a list. The
> > > +	 * presence on the list is used to check if the encryption is valid or
> > > +	 * not.
> > > +	 */
> > > +	struct list_head pxp_link;
> > > +
> > >   	/** Record of address bit 17 of each page at last unbind. */
> > >   	unsigned long *bit_17;
> > > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
> > > index b0c7edc10cc3..f418281e8c10 100644
> > > --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
> > > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
> > > @@ -7,6 +7,7 @@
> > >   #include "intel_pxp_irq.h"
> > >   #include "intel_pxp_session.h"
> > >   #include "intel_pxp_tee.h"
> > > +#include "gem/i915_gem_context.h"
> > >   #include "gt/intel_context.h"
> > >   #include "i915_drv.h"
> > > @@ -70,6 +71,9 @@ void intel_pxp_init(struct intel_pxp *pxp)
> > >   	mutex_init(&pxp->tee_mutex);
> > > +	spin_lock_init(&pxp->lock);
> > > +	INIT_LIST_HEAD(&pxp->protected_objects);
> > > +
> > >   	/*
> > >   	 * we'll use the completion to check if there is a termination pending,
> > >   	 * so we start it as completed and we reinit it when a termination
> > > @@ -166,3 +170,88 @@ void intel_pxp_fini_hw(struct intel_pxp *pxp)
> > >   	intel_pxp_irq_disable(pxp);
> > >   }
> > > +
> > > +int intel_pxp_object_add(struct drm_i915_gem_object *obj)
> > > +{
> > > +	struct intel_pxp *pxp = &to_i915(obj->base.dev)->gt.pxp;
> > > +
> > > +	if (!intel_pxp_is_enabled(pxp))
> > > +		return -ENODEV;
> > > +
> > > +	if (!list_empty(&obj->pxp_link))
> > > +		return -EEXIST;
> > > +
> > > +	spin_lock_irq(&pxp->lock);
> > > +	list_add(&obj->pxp_link, &pxp->protected_objects);
> > > +	spin_unlock_irq(&pxp->lock);
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +void intel_pxp_object_remove(struct drm_i915_gem_object *obj)
> > > +{
> > > +	struct intel_pxp *pxp = &to_i915(obj->base.dev)->gt.pxp;
> > > +
> > > +	if (!intel_pxp_is_enabled(pxp))
> > > +		return;
> > > +
> > > +	spin_lock_irq(&pxp->lock);
> > > +	list_del_init(&obj->pxp_link);
> > > +	spin_unlock_irq(&pxp->lock);
> > > +}
> > > +
> > > +void intel_pxp_invalidate(struct intel_pxp *pxp)
> > There is a lot of locking going on here. Please make sure it's all
> > properly documented what the rules are in kerneldoc, even for existing
> > stuff.
> > 
> > Especially anytime there's anything tricky going on, like:
> > - kref_get_unless_zero
> > - test_bit (that's an unorderd atomic, so either you don't actually need
> >    the atomic, or you need a pile of barriers and comments about them)
> > - hiddent atomic ops like intel_context_set_banned or
> >    i915_gem_context_set_invalid also need great care, least because the
> >    current rules aren't documented really. So step one here before using
> >    them is documenting the rules of how banning works.
> > 
> > > +{
> > > +	struct drm_i915_private *i915 = pxp_to_gt(pxp)->i915;
> > > +	struct drm_i915_gem_object *obj, *tmp;
> > > +	struct i915_gem_context *ctx, *cn;
> > > +
> > > +	/* delete objects that have been used with the invalidated session */
> > > +	spin_lock_irq(&pxp->lock);
> > > +	list_for_each_entry_safe(obj, tmp, &pxp->protected_objects, pxp_link) {
> > > +		if (i915_gem_object_has_pages(obj))
> > > +			list_del_init(&obj->pxp_link);
> > > +	}
> > > +	spin_unlock_irq(&pxp->lock);
> > > +
> > > +	/* 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) {
> > > +		struct i915_gem_engines_iter it;
> > > +		struct intel_context *ce;
> > > +
> > > +		if (!kref_get_unless_zero(&ctx->ref))
> > > +			continue;
> > > +
> > > +		if (likely(!i915_gem_context_uses_protected_content(ctx)) ||
> > > +		    i915_gem_context_invalidated(ctx)) {
> > > +			i915_gem_context_put(ctx);
> > > +			continue;
> > > +		}
> > > +
> > > +		spin_unlock_irq(&i915->gem.contexts.lock);
> > > +
> > > +		/*
> > > +		 * Note that by the time we get here the HW keys are already
> > > +		 * long gone, so any batch using them that's already on the
> > > +		 * engines is very likely a lost cause (and it has probably
> > > +		 * already hung the engine). Therefore, we skip attempting to
> > > +		 * pull the running context out of the HW and we prioritize
> > > +		 * bringing the session back as soon as possible.
> > > +		 */
> > > +		for_each_gem_engine(ce, i915_gem_context_lock_engines(ctx), it) {
> > > +			/* only invalidate if at least one ce was allocated */
> > > +			if (test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
> > > +				intel_context_set_banned(ce);
> > > +				i915_gem_context_set_invalid(ctx);
> > > +			}
> > > +		}
> > > +		i915_gem_context_unlock_engines(ctx);
> > > +
> > > +		spin_lock_irq(&i915->gem.contexts.lock);
> > > +		list_safe_reset_next(ctx, cn, link);
> > > +		i915_gem_context_put(ctx);
> > > +	}
> > > +	spin_unlock_irq(&i915->gem.contexts.lock);
> > > +}
> > > +
> > > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
> > > index 074b3b980957..4f7647f34153 100644
> > > --- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
> > > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
> > > @@ -9,6 +9,8 @@
> > >   #include "gt/intel_gt_types.h"
> > >   #include "intel_pxp_types.h"
> > > +struct drm_i915_gem_object;
> > > +
> > >   static inline struct intel_gt *pxp_to_gt(const struct intel_pxp *pxp)
> > >   {
> > >   	return container_of(pxp, struct intel_gt, pxp);
> > > @@ -33,6 +35,11 @@ void intel_pxp_fini_hw(struct intel_pxp *pxp);
> > >   void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp);
> > >   int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp);
> > > +
> > > +int intel_pxp_object_add(struct drm_i915_gem_object *obj);
> > > +void intel_pxp_object_remove(struct drm_i915_gem_object *obj);
> > > +
> > > +void intel_pxp_invalidate(struct intel_pxp *pxp);
> > >   #else
> > >   static inline void intel_pxp_init(struct intel_pxp *pxp)
> > >   {
> > > @@ -46,6 +53,14 @@ static inline int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp)
> > >   {
> > >   	return 0;
> > >   }
> > > +
> > > +static inline int intel_pxp_object_add(struct drm_i915_gem_object *obj)
> > > +{
> > > +	return 0;
> > > +}
> > > +static inline void intel_pxp_object_remove(struct drm_i915_gem_object *obj)
> > > +{
> > > +}
> > >   #endif
> > >   #endif /* __INTEL_PXP_H__ */
> > > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> > > index 67c30e534d50..0edd563a653d 100644
> > > --- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> > > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> > > @@ -85,6 +85,9 @@ static int pxp_terminate_arb_session_and_global(struct intel_pxp *pxp)
> > >   	/* must mark termination in progress calling this function */
> > >   	GEM_WARN_ON(pxp->arb_is_valid);
> > > +	/* invalidate protected objects */
> > > +	intel_pxp_invalidate(pxp);
> > > +
> > >   	/* terminate the hw sessions */
> > >   	ret = intel_pxp_terminate_session(pxp, ARB_SESSION);
> > >   	if (ret) {
> > > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
> > > index 475e3312c287..be2bed3a2e4e 100644
> > > --- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
> > > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
> > > @@ -7,7 +7,9 @@
> > >   #define __INTEL_PXP_TYPES_H__
> > >   #include <linux/completion.h>
> > > +#include <linux/list.h>
> > >   #include <linux/mutex.h>
> > > +#include <linux/spinlock.h>
> > >   #include <linux/types.h>
> > >   #include <linux/workqueue.h>
> > > @@ -43,6 +45,9 @@ struct intel_pxp {
> > >   	u32 session_events; /* protected with gt->irq_lock */
> > >   #define PXP_TERMINATION_REQUEST  BIT(0)
> > >   #define PXP_TERMINATION_COMPLETE BIT(1)
> > > +
> > > +	spinlock_t lock; /* protects the objects list */
> > > +	struct list_head protected_objects;
> > >   };
> > >   #endif /* __INTEL_PXP_TYPES_H__ */
> > > diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
> > > index 4393eef59d9b..2c9febdae6a5 100644
> > > --- a/include/uapi/drm/i915_drm.h
> > > +++ b/include/uapi/drm/i915_drm.h
> > > @@ -1843,12 +1843,32 @@ struct drm_i915_gem_context_param {
> > >    * attempted to use it, never re-use this context param number.
> > >    */
> > >   #define I915_CONTEXT_PARAM_RINGSIZE	0xc
> > > +
> > > +/*
> > > + * I915_CONTEXT_PARAM_PROTECTED_CONTENT:
> > > + *
> > > + * Mark that the context makes use of protected content, which will result
> > > + * in the context being invalidated when the protected content session is. The
> > > + * invalidation is reported back to userspace via the RESET_STATS ioctl (see
> > > + * relevant doc for details).
> > > + * This flag can only be set at context creation time and, when set to true,
> > > + * must be preceded by an explicit setting of I915_CONTEXT_PARAM_RECOVERABLE
> > > + * to false. This flag can't be set to true in conjunction with setting the
> > > + * I915_CONTEXT_PARAM_BANNABLE flag to false.
> > > + *
> > > + * In addition to the normal failure cases, setting this flag during context
> > > + * creation can result in the following errors:
> > > + *
> > > + * -ENODEV: feature not available
> > > + * -EPERM: trying to mark a recoverable or not bannable context as protected
> > > + */
> > > +#define I915_CONTEXT_PARAM_PROTECTED_CONTENT    0xd
> > >   /* Must be kept compact -- no holes and well documented */
> > >   	__u64 value;
> > >   };
> > > -/*
> > > +/**
> > >    * Context SSEU programming
> > >    *
> > >    * It may be necessary for either functional or performance reason to configure
> > > @@ -2181,6 +2201,12 @@ struct drm_i915_reg_read {
> > >   struct drm_i915_reset_stats {
> > >   	__u32 ctx_id;
> > >   	__u32 flags;
> > > +	/*
> > > +	 * contexts marked as using protected content are invalidated when the
> > > +	 * protected content session dies. Submission of invalidated contexts
> > > +	 * is rejected with -EACCES.
> > > +	 */
> > > +#define I915_CONTEXT_INVALIDATED 0x1
> > >   	/* All resets since boot/module reload, for all contexts */
> > >   	__u32 reset_count;
> > > @@ -2959,8 +2985,12 @@ struct drm_i915_gem_create_ext {
> > >   	 *
> > >   	 * For I915_GEM_CREATE_EXT_MEMORY_REGIONS usage see
> > >   	 * struct drm_i915_gem_create_ext_memory_regions.
> > > +	 *
> > > +	 * For I915_GEM_CREATE_EXT_PROTECTED_CONTENT usage see
> > > +	 * struct drm_i915_gem_create_ext_protected_content.
> > >   	 */
> > >   #define I915_GEM_CREATE_EXT_MEMORY_REGIONS 0
> > > +#define I915_GEM_CREATE_EXT_PROTECTED_CONTENT 1
> > >   	__u64 extensions;
> > >   };
> > > @@ -3018,6 +3048,29 @@ struct drm_i915_gem_create_ext_memory_regions {
> > >   	__u64 regions;
> > >   };
> > > +/**
> > > + * struct drm_i915_gem_create_ext_protected_content - The
> > > + * I915_OBJECT_PARAM_PROTECTED_CONTENT extension.
> > > + *
> > > + * If this extension is provided, buffer contents are expected to be protected
> > > + * by PXP encryption and require decryption for scan out and processing. This
> > > + * is only possible on platforms that have PXP enabled, on all other scenarios
> > > + * using this extension will cause the ioctl to fail and return -ENODEV. The
> > > + * flags parameter is reserved for future expansion and must currently be set
> > > + * to zero.
> > > + *
> > > + * The buffer contents are considered invalid after a PXP session teardown.
> > > + *
> > > + * The encryption is guaranteed to be processed correctly only if the object
> > > + * is submitted with a context created using the
> > > + * I915_CONTEXT_PARAM_PROTECTED_CONTENT flag. This will also enable extra checks
> > > + * at submission time on the validity of the objects involved.
> > > + */
> > > +struct drm_i915_gem_create_ext_protected_content {
> > > +	struct i915_user_extension base;
> > > +	__u32 flags;
> > > +};
> > > +
> > >   /* ID of the protected content session managed by i915 when PXP is active */
> > >   #define I915_PROTECTED_CONTENT_DEFAULT_SESSION 0xf
> > > -- 
> > > 2.32.0
> > > 
> > > _______________________________________________
> > > Intel-gfx mailing list
> > > Intel-gfx@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Intel-gfx] [PATCH v6 10/15] drm/i915/pxp: interfaces for using protected objects
  2021-08-13 15:24       ` Daniele Ceraolo Spurio
@ 2021-08-16 15:29         ` Daniel Vetter
  0 siblings, 0 replies; 64+ messages in thread
From: Daniel Vetter @ 2021-08-16 15:29 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio
  Cc: Daniel Vetter, intel-gfx, Daniel Vetter, Chris Wilson, dri-devel,
	Bommu Krishnaiah

On Fri, Aug 13, 2021 at 08:24:44AM -0700, Daniele Ceraolo Spurio wrote:
> 
> 
> On 8/13/2021 7:42 AM, Daniel Vetter wrote:
> > On Fri, Aug 13, 2021 at 04:37:53PM +0200, Daniel Vetter wrote:
> > > On Wed, Jul 28, 2021 at 07:01:01PM -0700, Daniele Ceraolo Spurio wrote:
> > > > This api allow user mode to create protected buffers and to mark
> > > > contexts as making use of such objects. Only when using contexts
> > > > marked in such a way is the execution guaranteed to work as expected.
> > > > 
> > > > Contexts can only be marked as using protected content at creation time
> > > > (i.e. the parameter is immutable) and they must be both bannable and not
> > > > recoverable.
> > > > 
> > > > All protected objects and contexts that have backing storage will be
> > > > considered invalid when the PXP session is destroyed and all new
> > > > submissions using them will be rejected. All intel contexts within the
> > > > invalidated gem contexts will be marked banned. A new flag has been
> > > > added to the RESET_STATS ioctl to report the context invalidation to
> > > > userspace.
> > > > 
> > > > This patch was previously sent as 2 separate patches, which have been
> > > > squashed following a request to have all the uapi in a single patch.
> > > > I've retained the s-o-b from both.
> > > > 
> > > > v5: squash patches, rebase on proto_ctx, update kerneldoc
> > > > 
> > > > v6: rebase on obj create_ext changes
> > > > 
> > > > Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
> > > > Signed-off-by: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
> > > > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > > > Cc: Chris Wilson <chris@chris-wilson.co.uk>
> > > > Cc: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
> > > > Cc: Jason Ekstrand <jason@jlekstrand.net>
> > > > Cc: Daniel Vetter <daniel.vetter@intel.com>
> > > > Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> #v5
> > > > ---
> > > >   drivers/gpu/drm/i915/gem/i915_gem_context.c   | 68 ++++++++++++--
> > > >   drivers/gpu/drm/i915/gem/i915_gem_context.h   | 18 ++++
> > > >   .../gpu/drm/i915/gem/i915_gem_context_types.h |  2 +
> > > >   drivers/gpu/drm/i915/gem/i915_gem_create.c    | 75 ++++++++++++----
> > > >   .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 40 ++++++++-
> > > >   drivers/gpu/drm/i915/gem/i915_gem_object.c    |  6 ++
> > > >   drivers/gpu/drm/i915/gem/i915_gem_object.h    | 12 +++
> > > >   .../gpu/drm/i915/gem/i915_gem_object_types.h  |  9 ++
> > > >   drivers/gpu/drm/i915/pxp/intel_pxp.c          | 89 +++++++++++++++++++
> > > >   drivers/gpu/drm/i915/pxp/intel_pxp.h          | 15 ++++
> > > >   drivers/gpu/drm/i915/pxp/intel_pxp_session.c  |  3 +
> > > >   drivers/gpu/drm/i915/pxp/intel_pxp_types.h    |  5 ++
> > > >   include/uapi/drm/i915_drm.h                   | 55 +++++++++++-
> > > >   13 files changed, 371 insertions(+), 26 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> > > > index cff72679ad7c..0cd3e2d06188 100644
> > > > --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
> > > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> > > > @@ -77,6 +77,8 @@
> > > >   #include "gt/intel_gpu_commands.h"
> > > >   #include "gt/intel_ring.h"
> > > > +#include "pxp/intel_pxp.h"
> > > > +
> > > >   #include "i915_gem_context.h"
> > > >   #include "i915_trace.h"
> > > >   #include "i915_user_extensions.h"
> > > > @@ -241,6 +243,25 @@ static int proto_context_set_persistence(struct drm_i915_private *i915,
> > > >   	return 0;
> > > >   }
> > > > +static int proto_context_set_protected(struct drm_i915_private *i915,
> > > > +				       struct i915_gem_proto_context *pc,
> > > > +				       bool protected)
> > > > +{
> > > > +	int ret = 0;
> > > > +
> > > > +	if (!intel_pxp_is_enabled(&i915->gt.pxp))
> > > > +		ret = -ENODEV;
> > > > +	else if (!protected)
> > > > +		pc->user_flags &= ~BIT(UCONTEXT_PROTECTED);
> > > > +	else if ((pc->user_flags & BIT(UCONTEXT_RECOVERABLE)) ||
> > > > +		 !(pc->user_flags & BIT(UCONTEXT_BANNABLE)))
> > > > +		ret = -EPERM;
> > > > +	else
> > > > +		pc->user_flags |= BIT(UCONTEXT_PROTECTED);
> > > > +
> > > > +	return ret;
> > > > +}
> > > > +
> > > >   static struct i915_gem_proto_context *
> > > >   proto_context_create(struct drm_i915_private *i915, unsigned int flags)
> > > >   {
> > > > @@ -686,6 +707,8 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
> > > >   			ret = -EPERM;
> > > >   		else if (args->value)
> > > >   			pc->user_flags |= BIT(UCONTEXT_BANNABLE);
> > > > +		else if (pc->user_flags & BIT(UCONTEXT_PROTECTED))
> > > > +			ret = -EPERM;
> > > >   		else
> > > >   			pc->user_flags &= ~BIT(UCONTEXT_BANNABLE);
> > > >   		break;
> > > > @@ -693,10 +716,12 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
> > > >   	case I915_CONTEXT_PARAM_RECOVERABLE:
> > > >   		if (args->size)
> > > >   			ret = -EINVAL;
> > > > -		else if (args->value)
> > > > -			pc->user_flags |= BIT(UCONTEXT_RECOVERABLE);
> > > > -		else
> > > > +		else if (!args->value)
> > > >   			pc->user_flags &= ~BIT(UCONTEXT_RECOVERABLE);
> > > > +		else if (pc->user_flags & BIT(UCONTEXT_PROTECTED))
> > > > +			ret = -EPERM;
> > > > +		else
> > > > +			pc->user_flags |= BIT(UCONTEXT_RECOVERABLE);
> > > >   		break;
> > > >   	case I915_CONTEXT_PARAM_PRIORITY:
> > > > @@ -724,6 +749,11 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
> > > >   						    args->value);
> > > >   		break;
> > > > +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
> > > > +		ret = proto_context_set_protected(fpriv->dev_priv, pc,
> > > > +						  args->value);
> > > > +		break;
> > > > +
> > > >   	case I915_CONTEXT_PARAM_NO_ZEROMAP:
> > > >   	case I915_CONTEXT_PARAM_BAN_PERIOD:
> > > >   	case I915_CONTEXT_PARAM_RINGSIZE:
> > > > @@ -1798,6 +1828,18 @@ static int set_priority(struct i915_gem_context *ctx,
> > > >   	return 0;
> > > >   }
> > > > +static int get_protected(struct i915_gem_context *ctx,
> > > > +			 struct drm_i915_gem_context_param *args)
> > > > +{
> > > > +	if (!intel_pxp_is_enabled(&ctx->i915->gt.pxp))
> > > > +		return -ENODEV;
> > > > +
> > > > +	args->size = 0;
> > > > +	args->value = i915_gem_context_uses_protected_content(ctx);
> > > > +
> > > > +	return 0;
> > > > +}
> > > > +
> > > >   static int ctx_setparam(struct drm_i915_file_private *fpriv,
> > > >   			struct i915_gem_context *ctx,
> > > >   			struct drm_i915_gem_context_param *args)
> > > > @@ -1821,6 +1863,8 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
> > > >   			ret = -EPERM;
> > > >   		else if (args->value)
> > > >   			i915_gem_context_set_bannable(ctx);
> > > > +		else if (i915_gem_context_uses_protected_content(ctx))
> > > > +			ret = -EPERM; /* can't clear this for protected contexts */
> > > >   		else
> > > >   			i915_gem_context_clear_bannable(ctx);
> > > >   		break;
> > > > @@ -1828,10 +1872,12 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
> > > >   	case I915_CONTEXT_PARAM_RECOVERABLE:
> > > >   		if (args->size)
> > > >   			ret = -EINVAL;
> > > > -		else if (args->value)
> > > > -			i915_gem_context_set_recoverable(ctx);
> > > > -		else
> > > > +		else if (!args->value)
> > > >   			i915_gem_context_clear_recoverable(ctx);
> > > > +		else if (i915_gem_context_uses_protected_content(ctx))
> > > > +			ret = -EPERM; /* can't set this for protected contexts */
> > > > +		else
> > > > +			i915_gem_context_set_recoverable(ctx);
> > > >   		break;
> > > >   	case I915_CONTEXT_PARAM_PRIORITY:
> > > > @@ -1846,6 +1892,7 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
> > > >   		ret = set_persistence(ctx, args);
> > > >   		break;
> > > > +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
> > > >   	case I915_CONTEXT_PARAM_NO_ZEROMAP:
> > > >   	case I915_CONTEXT_PARAM_BAN_PERIOD:
> > > >   	case I915_CONTEXT_PARAM_RINGSIZE:
> > > > @@ -2174,6 +2221,10 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
> > > >   		args->value = i915_gem_context_is_persistent(ctx);
> > > >   		break;
> > > > +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
> > > > +		ret = get_protected(ctx, args);
> > > > +		break;
> > > > +
> > > >   	case I915_CONTEXT_PARAM_NO_ZEROMAP:
> > > >   	case I915_CONTEXT_PARAM_BAN_PERIOD:
> > > >   	case I915_CONTEXT_PARAM_ENGINES:
> > > > @@ -2250,6 +2301,11 @@ int i915_gem_context_reset_stats_ioctl(struct drm_device *dev,
> > > >   	args->batch_active = atomic_read(&ctx->guilty_count);
> > > >   	args->batch_pending = atomic_read(&ctx->active_count);
> > > > +	/* re-use args->flags for output flags */
> > > > +	args->flags = 0;
> > > > +	if (i915_gem_context_invalidated(ctx))
> > > > +		args->flags |= I915_CONTEXT_INVALIDATED;
> > > > +
> > > >   	i915_gem_context_put(ctx);
> > > >   	return 0;
> > > >   }
> > > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.h b/drivers/gpu/drm/i915/gem/i915_gem_context.h
> > > > index 18060536b0c2..d932a70122fa 100644
> > > > --- a/drivers/gpu/drm/i915/gem/i915_gem_context.h
> > > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.h
> > > > @@ -108,6 +108,24 @@ i915_gem_context_clear_user_engines(struct i915_gem_context *ctx)
> > > >   	clear_bit(CONTEXT_USER_ENGINES, &ctx->flags);
> > > >   }
> > > > +static inline bool
> > > > +i915_gem_context_invalidated(const struct i915_gem_context *ctx)
> > > > +{
> > > > +	return test_bit(CONTEXT_INVALID, &ctx->flags);
> > > > +}
> > > > +
> > > > +static inline void
> > > > +i915_gem_context_set_invalid(struct i915_gem_context *ctx)
> > > > +{
> > > > +	set_bit(CONTEXT_INVALID, &ctx->flags);
> > > Do we _really_ need a new bit in this already very complex state
> > > machinery, and can't we reuse the BANNED flag instead?
> > > 
> > > This ctx->flags is atomic, unorderd, and that means you need barriers and
> > > everything.
> > > 
> > > If you don't actually need the atomic state bit machinery because you're
> > > using simple locking, then pls use your own boolean, and document by which
> > > lock it's protected.
> > > 
> > > > +}
> > > > +
> > > > +static inline bool
> > > > +i915_gem_context_uses_protected_content(const struct i915_gem_context *ctx)
> > > > +{
> > > > +	return test_bit(UCONTEXT_PROTECTED, &ctx->user_flags);
> > > For immutable state (I really hope this is immutable) pls don't reuse the
> > > atomic bitfield of mutable state, but create a flag of your own.
> > > 
> > > Also please document all the rules around how this is set/changed in the
> > > kerneldoc header comments for the data structure. Finally if you never set
> > > it except at creation.
> > > 
> > > > +}
> > > > +
> > > >   /* i915_gem_context.c */
> > > >   void i915_gem_init__contexts(struct drm_i915_private *i915);
> > > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
> > > > index 94c03a97cb77..1aa2290aa3c7 100644
> > > > --- a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
> > > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
> > > > @@ -301,6 +301,7 @@ struct i915_gem_context {
> > > >   #define UCONTEXT_BANNABLE		2
> > > >   #define UCONTEXT_RECOVERABLE		3
> > > >   #define UCONTEXT_PERSISTENCE		4
> > > > +#define UCONTEXT_PROTECTED		5
> > > >   	/**
> > > >   	 * @flags: small set of booleans
> > > > @@ -308,6 +309,7 @@ struct i915_gem_context {
> > > >   	unsigned long flags;
> > > >   #define CONTEXT_CLOSED			0
> > > >   #define CONTEXT_USER_ENGINES		1
> > > > +#define CONTEXT_INVALID			2
> > > >   	/** @mutex: guards everything that isn't engines or handles_vma */
> > > >   	struct mutex mutex;
> > > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c b/drivers/gpu/drm/i915/gem/i915_gem_create.c
> > > > index 23fee13a3384..0e48629316bb 100644
> > > > --- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
> > > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
> > > > @@ -6,6 +6,7 @@
> > > >   #include "gem/i915_gem_ioctls.h"
> > > >   #include "gem/i915_gem_lmem.h"
> > > >   #include "gem/i915_gem_region.h"
> > > > +#include "pxp/intel_pxp.h"
> > > >   #include "i915_drv.h"
> > > >   #include "i915_trace.h"
> > > > @@ -82,21 +83,11 @@ static int i915_gem_publish(struct drm_i915_gem_object *obj,
> > > >   	return 0;
> > > >   }
> > > > -/**
> > > > - * Creates a new object using the same path as DRM_I915_GEM_CREATE_EXT
> > > > - * @i915: i915 private
> > > > - * @size: size of the buffer, in bytes
> > > > - * @placements: possible placement regions, in priority order
> > > > - * @n_placements: number of possible placement regions
> > > > - *
> > > > - * This function is exposed primarily for selftests and does very little
> > > > - * error checking.  It is assumed that the set of placement regions has
> > > > - * already been verified to be valid.
> > > > - */
> > > > -struct drm_i915_gem_object *
> > > > -__i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
> > > > -			      struct intel_memory_region **placements,
> > > > -			      unsigned int n_placements)
> > > > +static struct drm_i915_gem_object *
> > > > +__i915_gem_object_create_user_ext(struct drm_i915_private *i915, u64 size,
> > > > +				  struct intel_memory_region **placements,
> > > > +				  unsigned int n_placements,
> > > > +				  unsigned int ext_flags)
> > > >   {
> > > >   	struct intel_memory_region *mr = placements[0];
> > > >   	struct drm_i915_gem_object *obj;
> > > > @@ -135,6 +126,12 @@ __i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
> > > >   	GEM_BUG_ON(size != obj->base.size);
> > > > +	/* Add any flag set by create_ext options */
> > > > +	flags |= ext_flags;
> > > > +
> > > > +	if (i915_gem_object_is_protected(obj))
> > > > +		intel_pxp_object_add(obj);
> > > > +
> > > >   	trace_i915_gem_object_create(obj);
> > > >   	return obj;
> > > > @@ -145,6 +142,26 @@ __i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
> > > >   	return ERR_PTR(ret);
> > > >   }
> > > > +/**
> > > > + * Creates a new object using the same path as DRM_I915_GEM_CREATE_EXT
> > > > + * @i915: i915 private
> > > > + * @size: size of the buffer, in bytes
> > > > + * @placements: possible placement regions, in priority order
> > > > + * @n_placements: number of possible placement regions
> > > > + *
> > > > + * This function is exposed primarily for selftests and does very little
> > > > + * error checking.  It is assumed that the set of placement regions has
> > > > + * already been verified to be valid.
> > > > + */
> > > > +struct drm_i915_gem_object *
> > > > +__i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
> > > > +			      struct intel_memory_region **placements,
> > > > +			      unsigned int n_placements)
> > > > +{
> > > > +	return __i915_gem_object_create_user_ext(i915, size, placements,
> > > > +						 n_placements, 0);
> > > > +}
> > > > +
> > > >   int
> > > >   i915_gem_dumb_create(struct drm_file *file,
> > > >   		     struct drm_device *dev,
> > > > @@ -224,6 +241,7 @@ struct create_ext {
> > > >   	struct drm_i915_private *i915;
> > > >   	struct intel_memory_region *placements[INTEL_REGION_UNKNOWN];
> > > >   	unsigned int n_placements;
> > > > +	unsigned long flags;
> > > >   };
> > > >   static void repr_placements(char *buf, size_t size,
> > > > @@ -356,8 +374,28 @@ static int ext_set_placements(struct i915_user_extension __user *base,
> > > >   	return set_placements(&ext, data);
> > > >   }
> > > > +static int ext_set_protected(struct i915_user_extension __user *base, void *data)
> > > > +{
> > > > +	struct drm_i915_gem_create_ext_protected_content ext;
> > > > +	struct create_ext *ext_data = data;
> > > > +
> > > > +	if (copy_from_user(&ext, base, sizeof(ext)))
> > > > +		return -EFAULT;
> > > > +
> > > > +	if (ext.flags)
> > > > +		return -EINVAL;
> > > > +
> > > > +	if (!intel_pxp_is_enabled(&ext_data->i915->gt.pxp))
> > > > +		return -ENODEV;
> > > > +
> > > > +	ext_data->flags |= I915_BO_PROTECTED;
> > > > +
> > > > +	return 0;
> > > > +}
> > > > +
> > > >   static const i915_user_extension_fn create_extensions[] = {
> > > >   	[I915_GEM_CREATE_EXT_MEMORY_REGIONS] = ext_set_placements,
> > > > +	[I915_GEM_CREATE_EXT_PROTECTED_CONTENT] = ext_set_protected,
> > > >   };
> > > >   /**
> > > > @@ -392,9 +430,10 @@ i915_gem_create_ext_ioctl(struct drm_device *dev, void *data,
> > > >   		ext_data.n_placements = 1;
> > > >   	}
> > > > -	obj = __i915_gem_object_create_user(i915, args->size,
> > > > -					    ext_data.placements,
> > > > -					    ext_data.n_placements);
> > > > +	obj = __i915_gem_object_create_user_ext(i915, args->size,
> > > > +						ext_data.placements,
> > > > +						ext_data.n_placements,
> > > > +						ext_data.flags);
> > > >   	if (IS_ERR(obj))
> > > >   		return PTR_ERR(obj);
> > > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> > > > index 1ed7475de454..04f33d163340 100644
> > > > --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> > > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> > > > @@ -21,6 +21,8 @@
> > > >   #include "gt/intel_gt_pm.h"
> > > >   #include "gt/intel_ring.h"
> > > > +#include "pxp/intel_pxp.h"
> > > > +
> > > >   #include "i915_drv.h"
> > > >   #include "i915_gem_clflush.h"
> > > >   #include "i915_gem_context.h"
> > > > @@ -751,6 +753,11 @@ static int eb_select_context(struct i915_execbuffer *eb)
> > > >   	if (unlikely(IS_ERR(ctx)))
> > > >   		return PTR_ERR(ctx);
> > > > +	if (i915_gem_context_invalidated(ctx)) {
> > > > +		i915_gem_context_put(ctx);
> > > > +		return -EACCES;
> > > > +	}
> > > > +
> > > >   	eb->gem_context = ctx;
> > > >   	if (rcu_access_pointer(ctx->vm))
> > > >   		eb->invalid_flags |= EXEC_OBJECT_NEEDS_GTT;
> > > > @@ -819,7 +826,7 @@ static struct i915_vma *eb_lookup_vma(struct i915_execbuffer *eb, u32 handle)
> > > >   	do {
> > > >   		struct drm_i915_gem_object *obj;
> > > >   		struct i915_vma *vma;
> > > > -		int err;
> > > > +		int err = 0;
> > > >   		rcu_read_lock();
> > > >   		vma = radix_tree_lookup(&eb->gem_context->handles_vma, handle);
> > > > @@ -833,6 +840,26 @@ static struct i915_vma *eb_lookup_vma(struct i915_execbuffer *eb, u32 handle)
> > > >   		if (unlikely(!obj))
> > > >   			return ERR_PTR(-ENOENT);
> > > > +		/*
> > > > +		 * If the user has opted-in for protected-object tracking, make
> > > > +		 * sure the object encryption can be used.
> > > > +		 * We only need to do this when the object is first used with
> > > > +		 * this context, because the context itself will be banned when
> > > > +		 * the protected objects become invalid.
> > > > +		 */
> > > > +		if (i915_gem_context_uses_protected_content(eb->gem_context) &&
> > > > +		    i915_gem_object_is_protected(obj)) {
> > > > +			if (!intel_pxp_is_active(&vm->gt->pxp))
> > > > +				err = -ENODEV;
> > > > +			else if (!i915_gem_object_has_valid_protection(obj))
> > > > +				err = -ENOEXEC;
> > > > +
> > > > +			if (err) {
> > > > +				i915_gem_object_put(obj);
> > > > +				return ERR_PTR(err);
> > > > +			}
> > > > +		}
> > > > +
> > > >   		vma = i915_vma_instance(obj, vm, NULL);
> > > >   		if (IS_ERR(vma)) {
> > > >   			i915_gem_object_put(obj);
> > > > @@ -2752,6 +2779,17 @@ eb_select_engine(struct i915_execbuffer *eb)
> > > >   	intel_gt_pm_get(ce->engine->gt);
> > > > +	if (i915_gem_context_uses_protected_content(eb->gem_context)) {
> > > > +		err = intel_pxp_wait_for_arb_start(&ce->engine->gt->pxp);
> > > > +		if (err)
> > > > +			goto err;
> > > > +
> > > > +		if (i915_gem_context_invalidated(eb->gem_context)) {
> > > > +			err = -EACCES;
> > > Shouldn't the normal banned context handling takee care of anything that
> > > slips through? Rolling your own racy invalidation checks doesn't look like
> > > a good idea.
> > > 
> > > > +			goto err;
> > > > +		}
> > > > +	}
> > > > +
> > > >   	if (!test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
> > > >   		err = intel_context_alloc_state(ce);
> > > >   		if (err)
> > > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c
> > > > index 6fb9afb65034..658a42a7fa07 100644
> > > > --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
> > > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
> > > > @@ -25,6 +25,7 @@
> > > >   #include <linux/sched/mm.h>
> > > >   #include "display/intel_frontbuffer.h"
> > > > +#include "pxp/intel_pxp.h"
> > > >   #include "i915_drv.h"
> > > >   #include "i915_gem_clflush.h"
> > > >   #include "i915_gem_context.h"
> > > > @@ -73,6 +74,8 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj,
> > > >   	INIT_LIST_HEAD(&obj->lut_list);
> > > >   	spin_lock_init(&obj->lut_lock);
> > > > +	INIT_LIST_HEAD(&obj->pxp_link);
> > > > +
> > > >   	spin_lock_init(&obj->mmo.lock);
> > > >   	obj->mmo.offsets = RB_ROOT;
> > > > @@ -231,6 +234,9 @@ void __i915_gem_free_object(struct drm_i915_gem_object *obj)
> > > >   		spin_unlock(&obj->vma.lock);
> > > >   	}
> > > > +	if (i915_gem_object_has_valid_protection(obj))
> > > > +		intel_pxp_object_remove(obj);
> > > > +
> > > >   	__i915_gem_object_free_mmaps(obj);
> > > >   	GEM_BUG_ON(!list_empty(&obj->lut_list));
> > > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h
> > > > index 48112b9d76df..137ae2723514 100644
> > > > --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
> > > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
> > > > @@ -269,6 +269,18 @@ i915_gem_object_clear_tiling_quirk(struct drm_i915_gem_object *obj)
> > > >   	clear_bit(I915_TILING_QUIRK_BIT, &obj->flags);
> > > >   }
> > > > +static inline bool
> > > > +i915_gem_object_is_protected(const struct drm_i915_gem_object *obj)
> > > > +{
> > > > +	return obj->flags & I915_BO_PROTECTED;
> > > > +}
> > > > +
> > > > +static inline bool
> > > > +i915_gem_object_has_valid_protection(const struct drm_i915_gem_object *obj)
> > > > +{
> > > > +	return i915_gem_object_is_protected(obj) && !list_empty(&obj->pxp_link);
> > > > +}
> > > > +
> > > >   static inline bool
> > > >   i915_gem_object_type_has(const struct drm_i915_gem_object *obj,
> > > >   			 unsigned long flags)
> > > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> > > > index 2471f36aaff3..38e4a190607a 100644
> > > > --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> > > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> > > > @@ -298,6 +298,7 @@ struct drm_i915_gem_object {
> > > >   			     I915_BO_ALLOC_USER)
> > > >   #define I915_BO_READONLY         BIT(4)
> > > >   #define I915_TILING_QUIRK_BIT    5 /* unknown swizzling; do not release! */
> > > > +#define I915_BO_PROTECTED        BIT(6)
> > > >   	/**
> > > >   	 * @mem_flags - Mutable placement-related flags
> > > > @@ -537,6 +538,14 @@ struct drm_i915_gem_object {
> > > >   		bool created:1;
> > > >   	} ttm;
> > > > +	/*
> > > > +	 * When the PXP session is invalidated, we need to mark all protected
> > > > +	 * objects as invalid. To easily do so we add them all to a list. The
> > > > +	 * presence on the list is used to check if the encryption is valid or
> > > > +	 * not.
> > > > +	 */
> > > > +	struct list_head pxp_link;
> > This
> > - seems to be accessed locklessly, which needs giant amounts of comments
> >    and justifications to prove a) it's needed and b) it's correct against
> >    all races
> > - we already have a per-object lock in the form of dma_resv_lock. Why
> >    can't we use that to protect pxp object state?
> 
> This is always modified under pxp->lock. The only lockless access we do is a
> list_empty() check to see if the protection is valid, and that's because the
> check is inherently racy anyway (state can change at any point before or
> after we've checked) so adding a lock wouldn't really help. Note that the
> list can only be set at object creation time and it is only cleared either
> during the first invalidation or during object destruction.

Yeah, but every time we have races you need to think through whether
really nothing bad can ever happen. I pondered this a bit and came up with
the following idea:
- every time we get a pxp reset, we increment a generation counter. That
  should never race, because we should be able to sufficiently protect pxp
  state with some mutext.

- when we allocate a protect context or a protected buffer, we remember
  the current generation counter. This can race, but also, it doesn't
  matter because userspace is supposed allocate buffers after the context
  was allocated. This pxp_generation is invariant over the lifetime of an
  object/context, at least for now. We can sample this pxp_generation
  holding the same lock as the pxp reset, which avoids another pile of
  potentially confusion races.

- for execbuf context side we entirely rely on the existing context
  banning.

- for the buffer objects we compare the object's pxp_generation against
  the contexts. If they don't match we fail.

This means no locking to protected this, no additional races to ponder.
Also pretty easy way reset a buffer for the non-robust version (if that
ever happens), we just update the pxp_generation.
-Daniel

> 
> Daniele
> 
> > Looking needs to be done with extreme care, or we're just burrying
> > ourselves into something that cannot be understood and maintained anymore.
> > -Daniel
> > 
> > > > +
> > > >   	/** Record of address bit 17 of each page at last unbind. */
> > > >   	unsigned long *bit_17;
> > > > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
> > > > index b0c7edc10cc3..f418281e8c10 100644
> > > > --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
> > > > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
> > > > @@ -7,6 +7,7 @@
> > > >   #include "intel_pxp_irq.h"
> > > >   #include "intel_pxp_session.h"
> > > >   #include "intel_pxp_tee.h"
> > > > +#include "gem/i915_gem_context.h"
> > > >   #include "gt/intel_context.h"
> > > >   #include "i915_drv.h"
> > > > @@ -70,6 +71,9 @@ void intel_pxp_init(struct intel_pxp *pxp)
> > > >   	mutex_init(&pxp->tee_mutex);
> > > > +	spin_lock_init(&pxp->lock);
> > > > +	INIT_LIST_HEAD(&pxp->protected_objects);
> > > > +
> > > >   	/*
> > > >   	 * we'll use the completion to check if there is a termination pending,
> > > >   	 * so we start it as completed and we reinit it when a termination
> > > > @@ -166,3 +170,88 @@ void intel_pxp_fini_hw(struct intel_pxp *pxp)
> > > >   	intel_pxp_irq_disable(pxp);
> > > >   }
> > > > +
> > > > +int intel_pxp_object_add(struct drm_i915_gem_object *obj)
> > > > +{
> > > > +	struct intel_pxp *pxp = &to_i915(obj->base.dev)->gt.pxp;
> > > > +
> > > > +	if (!intel_pxp_is_enabled(pxp))
> > > > +		return -ENODEV;
> > > > +
> > > > +	if (!list_empty(&obj->pxp_link))
> > > > +		return -EEXIST;
> > > > +
> > > > +	spin_lock_irq(&pxp->lock);
> > > > +	list_add(&obj->pxp_link, &pxp->protected_objects);
> > > > +	spin_unlock_irq(&pxp->lock);
> > > > +
> > > > +	return 0;
> > > > +}
> > > > +
> > > > +void intel_pxp_object_remove(struct drm_i915_gem_object *obj)
> > > > +{
> > > > +	struct intel_pxp *pxp = &to_i915(obj->base.dev)->gt.pxp;
> > > > +
> > > > +	if (!intel_pxp_is_enabled(pxp))
> > > > +		return;
> > > > +
> > > > +	spin_lock_irq(&pxp->lock);
> > > > +	list_del_init(&obj->pxp_link);
> > > > +	spin_unlock_irq(&pxp->lock);
> > > > +}
> > > > +
> > > > +void intel_pxp_invalidate(struct intel_pxp *pxp)
> > > There is a lot of locking going on here. Please make sure it's all
> > > properly documented what the rules are in kerneldoc, even for existing
> > > stuff.
> > > 
> > > Especially anytime there's anything tricky going on, like:
> > > - kref_get_unless_zero
> > > - test_bit (that's an unorderd atomic, so either you don't actually need
> > >    the atomic, or you need a pile of barriers and comments about them)
> > > - hiddent atomic ops like intel_context_set_banned or
> > >    i915_gem_context_set_invalid also need great care, least because the
> > >    current rules aren't documented really. So step one here before using
> > >    them is documenting the rules of how banning works.
> > > 
> > > > +{
> > > > +	struct drm_i915_private *i915 = pxp_to_gt(pxp)->i915;
> > > > +	struct drm_i915_gem_object *obj, *tmp;
> > > > +	struct i915_gem_context *ctx, *cn;
> > > > +
> > > > +	/* delete objects that have been used with the invalidated session */
> > > > +	spin_lock_irq(&pxp->lock);
> > > > +	list_for_each_entry_safe(obj, tmp, &pxp->protected_objects, pxp_link) {
> > > > +		if (i915_gem_object_has_pages(obj))
> > > > +			list_del_init(&obj->pxp_link);
> > We have a per
> > > > +	}
> > > > +	spin_unlock_irq(&pxp->lock);
> > > > +
> > > > +	/* 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) {
> > > > +		struct i915_gem_engines_iter it;
> > > > +		struct intel_context *ce;
> > > > +
> > > > +		if (!kref_get_unless_zero(&ctx->ref))
> > > > +			continue;
> > > > +
> > > > +		if (likely(!i915_gem_context_uses_protected_content(ctx)) ||
> > > > +		    i915_gem_context_invalidated(ctx)) {
> > > > +			i915_gem_context_put(ctx);
> > > > +			continue;
> > > > +		}
> > > > +
> > > > +		spin_unlock_irq(&i915->gem.contexts.lock);
> > > > +
> > > > +		/*
> > > > +		 * Note that by the time we get here the HW keys are already
> > > > +		 * long gone, so any batch using them that's already on the
> > > > +		 * engines is very likely a lost cause (and it has probably
> > > > +		 * already hung the engine). Therefore, we skip attempting to
> > > > +		 * pull the running context out of the HW and we prioritize
> > > > +		 * bringing the session back as soon as possible.
> > > > +		 */
> > > > +		for_each_gem_engine(ce, i915_gem_context_lock_engines(ctx), it) {
> > > > +			/* only invalidate if at least one ce was allocated */
> > > > +			if (test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
> > > > +				intel_context_set_banned(ce);
> > > > +				i915_gem_context_set_invalid(ctx);
> > > > +			}
> > > > +		}
> > > > +		i915_gem_context_unlock_engines(ctx);
> > > > +
> > > > +		spin_lock_irq(&i915->gem.contexts.lock);
> > > > +		list_safe_reset_next(ctx, cn, link);
> > > > +		i915_gem_context_put(ctx);
> > > > +	}
> > > > +	spin_unlock_irq(&i915->gem.contexts.lock);
> > > > +}
> > > > +
> > > > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
> > > > index 074b3b980957..4f7647f34153 100644
> > > > --- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
> > > > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
> > > > @@ -9,6 +9,8 @@
> > > >   #include "gt/intel_gt_types.h"
> > > >   #include "intel_pxp_types.h"
> > > > +struct drm_i915_gem_object;
> > > > +
> > > >   static inline struct intel_gt *pxp_to_gt(const struct intel_pxp *pxp)
> > > >   {
> > > >   	return container_of(pxp, struct intel_gt, pxp);
> > > > @@ -33,6 +35,11 @@ void intel_pxp_fini_hw(struct intel_pxp *pxp);
> > > >   void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp);
> > > >   int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp);
> > > > +
> > > > +int intel_pxp_object_add(struct drm_i915_gem_object *obj);
> > > > +void intel_pxp_object_remove(struct drm_i915_gem_object *obj);
> > > > +
> > > > +void intel_pxp_invalidate(struct intel_pxp *pxp);
> > > >   #else
> > > >   static inline void intel_pxp_init(struct intel_pxp *pxp)
> > > >   {
> > > > @@ -46,6 +53,14 @@ static inline int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp)
> > > >   {
> > > >   	return 0;
> > > >   }
> > > > +
> > > > +static inline int intel_pxp_object_add(struct drm_i915_gem_object *obj)
> > > > +{
> > > > +	return 0;
> > > > +}
> > > > +static inline void intel_pxp_object_remove(struct drm_i915_gem_object *obj)
> > > > +{
> > > > +}
> > > >   #endif
> > > >   #endif /* __INTEL_PXP_H__ */
> > > > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> > > > index 67c30e534d50..0edd563a653d 100644
> > > > --- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> > > > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> > > > @@ -85,6 +85,9 @@ static int pxp_terminate_arb_session_and_global(struct intel_pxp *pxp)
> > > >   	/* must mark termination in progress calling this function */
> > > >   	GEM_WARN_ON(pxp->arb_is_valid);
> > > > +	/* invalidate protected objects */
> > > > +	intel_pxp_invalidate(pxp);
> > > > +
> > > >   	/* terminate the hw sessions */
> > > >   	ret = intel_pxp_terminate_session(pxp, ARB_SESSION);
> > > >   	if (ret) {
> > > > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
> > > > index 475e3312c287..be2bed3a2e4e 100644
> > > > --- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
> > > > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
> > > > @@ -7,7 +7,9 @@
> > > >   #define __INTEL_PXP_TYPES_H__
> > > >   #include <linux/completion.h>
> > > > +#include <linux/list.h>
> > > >   #include <linux/mutex.h>
> > > > +#include <linux/spinlock.h>
> > > >   #include <linux/types.h>
> > > >   #include <linux/workqueue.h>
> > > > @@ -43,6 +45,9 @@ struct intel_pxp {
> > > >   	u32 session_events; /* protected with gt->irq_lock */
> > > >   #define PXP_TERMINATION_REQUEST  BIT(0)
> > > >   #define PXP_TERMINATION_COMPLETE BIT(1)
> > > > +
> > > > +	spinlock_t lock; /* protects the objects list */
> > > > +	struct list_head protected_objects;
> > > >   };
> > > >   #endif /* __INTEL_PXP_TYPES_H__ */
> > > > diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
> > > > index 4393eef59d9b..2c9febdae6a5 100644
> > > > --- a/include/uapi/drm/i915_drm.h
> > > > +++ b/include/uapi/drm/i915_drm.h
> > > > @@ -1843,12 +1843,32 @@ struct drm_i915_gem_context_param {
> > > >    * attempted to use it, never re-use this context param number.
> > > >    */
> > > >   #define I915_CONTEXT_PARAM_RINGSIZE	0xc
> > > > +
> > > > +/*
> > > > + * I915_CONTEXT_PARAM_PROTECTED_CONTENT:
> > > > + *
> > > > + * Mark that the context makes use of protected content, which will result
> > > > + * in the context being invalidated when the protected content session is. The
> > > > + * invalidation is reported back to userspace via the RESET_STATS ioctl (see
> > > > + * relevant doc for details).
> > > > + * This flag can only be set at context creation time and, when set to true,
> > > > + * must be preceded by an explicit setting of I915_CONTEXT_PARAM_RECOVERABLE
> > > > + * to false. This flag can't be set to true in conjunction with setting the
> > > > + * I915_CONTEXT_PARAM_BANNABLE flag to false.
> > > > + *
> > > > + * In addition to the normal failure cases, setting this flag during context
> > > > + * creation can result in the following errors:
> > > > + *
> > > > + * -ENODEV: feature not available
> > > > + * -EPERM: trying to mark a recoverable or not bannable context as protected
> > > > + */
> > > > +#define I915_CONTEXT_PARAM_PROTECTED_CONTENT    0xd
> > > >   /* Must be kept compact -- no holes and well documented */
> > > >   	__u64 value;
> > > >   };
> > > > -/*
> > > > +/**
> > > >    * Context SSEU programming
> > > >    *
> > > >    * It may be necessary for either functional or performance reason to configure
> > > > @@ -2181,6 +2201,12 @@ struct drm_i915_reg_read {
> > > >   struct drm_i915_reset_stats {
> > > >   	__u32 ctx_id;
> > > >   	__u32 flags;
> > > > +	/*
> > > > +	 * contexts marked as using protected content are invalidated when the
> > > > +	 * protected content session dies. Submission of invalidated contexts
> > > > +	 * is rejected with -EACCES.
> > > > +	 */
> > > > +#define I915_CONTEXT_INVALIDATED 0x1
> > > >   	/* All resets since boot/module reload, for all contexts */
> > > >   	__u32 reset_count;
> > > > @@ -2959,8 +2985,12 @@ struct drm_i915_gem_create_ext {
> > > >   	 *
> > > >   	 * For I915_GEM_CREATE_EXT_MEMORY_REGIONS usage see
> > > >   	 * struct drm_i915_gem_create_ext_memory_regions.
> > > > +	 *
> > > > +	 * For I915_GEM_CREATE_EXT_PROTECTED_CONTENT usage see
> > > > +	 * struct drm_i915_gem_create_ext_protected_content.
> > > >   	 */
> > > >   #define I915_GEM_CREATE_EXT_MEMORY_REGIONS 0
> > > > +#define I915_GEM_CREATE_EXT_PROTECTED_CONTENT 1
> > > >   	__u64 extensions;
> > > >   };
> > > > @@ -3018,6 +3048,29 @@ struct drm_i915_gem_create_ext_memory_regions {
> > > >   	__u64 regions;
> > > >   };
> > > > +/**
> > > > + * struct drm_i915_gem_create_ext_protected_content - The
> > > > + * I915_OBJECT_PARAM_PROTECTED_CONTENT extension.
> > > > + *
> > > > + * If this extension is provided, buffer contents are expected to be protected
> > > > + * by PXP encryption and require decryption for scan out and processing. This
> > > > + * is only possible on platforms that have PXP enabled, on all other scenarios
> > > > + * using this extension will cause the ioctl to fail and return -ENODEV. The
> > > > + * flags parameter is reserved for future expansion and must currently be set
> > > > + * to zero.
> > > > + *
> > > > + * The buffer contents are considered invalid after a PXP session teardown.
> > > > + *
> > > > + * The encryption is guaranteed to be processed correctly only if the object
> > > > + * is submitted with a context created using the
> > > > + * I915_CONTEXT_PARAM_PROTECTED_CONTENT flag. This will also enable extra checks
> > > > + * at submission time on the validity of the objects involved.
> > > > + */
> > > > +struct drm_i915_gem_create_ext_protected_content {
> > > > +	struct i915_user_extension base;
> > > > +	__u32 flags;
> > > > +};
> > > > +
> > > >   /* ID of the protected content session managed by i915 when PXP is active */
> > > >   #define I915_PROTECTED_CONTENT_DEFAULT_SESSION 0xf
> > > > -- 
> > > > 2.32.0
> > > > 
> > > > _______________________________________________
> > > > Intel-gfx mailing list
> > > > Intel-gfx@lists.freedesktop.org
> > > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > > -- 
> > > Daniel Vetter
> > > Software Engineer, Intel Corporation
> > > http://blog.ffwll.ch
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Intel-gfx] [PATCH v6 10/15] drm/i915/pxp: interfaces for using protected objects
  2021-08-16 15:15       ` Daniel Vetter
@ 2021-08-16 15:58         ` Daniele Ceraolo Spurio
  2021-08-17  9:02           ` Daniel Vetter
  0 siblings, 1 reply; 64+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-08-16 15:58 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: intel-gfx, Daniel Vetter, Chris Wilson, dri-devel,
	Bommu Krishnaiah, Lionel Landwerlin



On 8/16/2021 8:15 AM, Daniel Vetter wrote:
> On Fri, Aug 13, 2021 at 08:18:02AM -0700, Daniele Ceraolo Spurio wrote:
>>
>> On 8/13/2021 7:37 AM, Daniel Vetter wrote:
>>> On Wed, Jul 28, 2021 at 07:01:01PM -0700, Daniele Ceraolo Spurio wrote:
>>>> This api allow user mode to create protected buffers and to mark
>>>> contexts as making use of such objects. Only when using contexts
>>>> marked in such a way is the execution guaranteed to work as expected.
>>>>
>>>> Contexts can only be marked as using protected content at creation time
>>>> (i.e. the parameter is immutable) and they must be both bannable and not
>>>> recoverable.
>>>>
>>>> All protected objects and contexts that have backing storage will be
>>>> considered invalid when the PXP session is destroyed and all new
>>>> submissions using them will be rejected. All intel contexts within the
>>>> invalidated gem contexts will be marked banned. A new flag has been
>>>> added to the RESET_STATS ioctl to report the context invalidation to
>>>> userspace.
>>>>
>>>> This patch was previously sent as 2 separate patches, which have been
>>>> squashed following a request to have all the uapi in a single patch.
>>>> I've retained the s-o-b from both.
>>>>
>>>> v5: squash patches, rebase on proto_ctx, update kerneldoc
>>>>
>>>> v6: rebase on obj create_ext changes
>>>>
>>>> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
>>>> Signed-off-by: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
>>>> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
>>>> Cc: Chris Wilson <chris@chris-wilson.co.uk>
>>>> Cc: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
>>>> Cc: Jason Ekstrand <jason@jlekstrand.net>
>>>> Cc: Daniel Vetter <daniel.vetter@intel.com>
>>>> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> #v5
>>>> ---
>>>>    drivers/gpu/drm/i915/gem/i915_gem_context.c   | 68 ++++++++++++--
>>>>    drivers/gpu/drm/i915/gem/i915_gem_context.h   | 18 ++++
>>>>    .../gpu/drm/i915/gem/i915_gem_context_types.h |  2 +
>>>>    drivers/gpu/drm/i915/gem/i915_gem_create.c    | 75 ++++++++++++----
>>>>    .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 40 ++++++++-
>>>>    drivers/gpu/drm/i915/gem/i915_gem_object.c    |  6 ++
>>>>    drivers/gpu/drm/i915/gem/i915_gem_object.h    | 12 +++
>>>>    .../gpu/drm/i915/gem/i915_gem_object_types.h  |  9 ++
>>>>    drivers/gpu/drm/i915/pxp/intel_pxp.c          | 89 +++++++++++++++++++
>>>>    drivers/gpu/drm/i915/pxp/intel_pxp.h          | 15 ++++
>>>>    drivers/gpu/drm/i915/pxp/intel_pxp_session.c  |  3 +
>>>>    drivers/gpu/drm/i915/pxp/intel_pxp_types.h    |  5 ++
>>>>    include/uapi/drm/i915_drm.h                   | 55 +++++++++++-
>>>>    13 files changed, 371 insertions(+), 26 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c
>>>> index cff72679ad7c..0cd3e2d06188 100644
>>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
>>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
>>>> @@ -77,6 +77,8 @@
>>>>    #include "gt/intel_gpu_commands.h"
>>>>    #include "gt/intel_ring.h"
>>>> +#include "pxp/intel_pxp.h"
>>>> +
>>>>    #include "i915_gem_context.h"
>>>>    #include "i915_trace.h"
>>>>    #include "i915_user_extensions.h"
>>>> @@ -241,6 +243,25 @@ static int proto_context_set_persistence(struct drm_i915_private *i915,
>>>>    	return 0;
>>>>    }
>>>> +static int proto_context_set_protected(struct drm_i915_private *i915,
>>>> +				       struct i915_gem_proto_context *pc,
>>>> +				       bool protected)
>>>> +{
>>>> +	int ret = 0;
>>>> +
>>>> +	if (!intel_pxp_is_enabled(&i915->gt.pxp))
>>>> +		ret = -ENODEV;
>>>> +	else if (!protected)
>>>> +		pc->user_flags &= ~BIT(UCONTEXT_PROTECTED);
>>>> +	else if ((pc->user_flags & BIT(UCONTEXT_RECOVERABLE)) ||
>>>> +		 !(pc->user_flags & BIT(UCONTEXT_BANNABLE)))
>>>> +		ret = -EPERM;
>>>> +	else
>>>> +		pc->user_flags |= BIT(UCONTEXT_PROTECTED);
>>>> +
>>>> +	return ret;
>>>> +}
>>>> +
>>>>    static struct i915_gem_proto_context *
>>>>    proto_context_create(struct drm_i915_private *i915, unsigned int flags)
>>>>    {
>>>> @@ -686,6 +707,8 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
>>>>    			ret = -EPERM;
>>>>    		else if (args->value)
>>>>    			pc->user_flags |= BIT(UCONTEXT_BANNABLE);
>>>> +		else if (pc->user_flags & BIT(UCONTEXT_PROTECTED))
>>>> +			ret = -EPERM;
>>>>    		else
>>>>    			pc->user_flags &= ~BIT(UCONTEXT_BANNABLE);
>>>>    		break;
>>>> @@ -693,10 +716,12 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
>>>>    	case I915_CONTEXT_PARAM_RECOVERABLE:
>>>>    		if (args->size)
>>>>    			ret = -EINVAL;
>>>> -		else if (args->value)
>>>> -			pc->user_flags |= BIT(UCONTEXT_RECOVERABLE);
>>>> -		else
>>>> +		else if (!args->value)
>>>>    			pc->user_flags &= ~BIT(UCONTEXT_RECOVERABLE);
>>>> +		else if (pc->user_flags & BIT(UCONTEXT_PROTECTED))
>>>> +			ret = -EPERM;
>>>> +		else
>>>> +			pc->user_flags |= BIT(UCONTEXT_RECOVERABLE);
>>>>    		break;
>>>>    	case I915_CONTEXT_PARAM_PRIORITY:
>>>> @@ -724,6 +749,11 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
>>>>    						    args->value);
>>>>    		break;
>>>> +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
>>>> +		ret = proto_context_set_protected(fpriv->dev_priv, pc,
>>>> +						  args->value);
>>>> +		break;
>>>> +
>>>>    	case I915_CONTEXT_PARAM_NO_ZEROMAP:
>>>>    	case I915_CONTEXT_PARAM_BAN_PERIOD:
>>>>    	case I915_CONTEXT_PARAM_RINGSIZE:
>>>> @@ -1798,6 +1828,18 @@ static int set_priority(struct i915_gem_context *ctx,
>>>>    	return 0;
>>>>    }
>>>> +static int get_protected(struct i915_gem_context *ctx,
>>>> +			 struct drm_i915_gem_context_param *args)
>>>> +{
>>>> +	if (!intel_pxp_is_enabled(&ctx->i915->gt.pxp))
>>>> +		return -ENODEV;
>>>> +
>>>> +	args->size = 0;
>>>> +	args->value = i915_gem_context_uses_protected_content(ctx);
>>>> +
>>>> +	return 0;
>>>> +}
>>>> +
>>>>    static int ctx_setparam(struct drm_i915_file_private *fpriv,
>>>>    			struct i915_gem_context *ctx,
>>>>    			struct drm_i915_gem_context_param *args)
>>>> @@ -1821,6 +1863,8 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
>>>>    			ret = -EPERM;
>>>>    		else if (args->value)
>>>>    			i915_gem_context_set_bannable(ctx);
>>>> +		else if (i915_gem_context_uses_protected_content(ctx))
>>>> +			ret = -EPERM; /* can't clear this for protected contexts */
>>>>    		else
>>>>    			i915_gem_context_clear_bannable(ctx);
>>>>    		break;
>>>> @@ -1828,10 +1872,12 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
>>>>    	case I915_CONTEXT_PARAM_RECOVERABLE:
>>>>    		if (args->size)
>>>>    			ret = -EINVAL;
>>>> -		else if (args->value)
>>>> -			i915_gem_context_set_recoverable(ctx);
>>>> -		else
>>>> +		else if (!args->value)
>>>>    			i915_gem_context_clear_recoverable(ctx);
>>>> +		else if (i915_gem_context_uses_protected_content(ctx))
>>>> +			ret = -EPERM; /* can't set this for protected contexts */
>>>> +		else
>>>> +			i915_gem_context_set_recoverable(ctx);
>>>>    		break;
>>>>    	case I915_CONTEXT_PARAM_PRIORITY:
>>>> @@ -1846,6 +1892,7 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
>>>>    		ret = set_persistence(ctx, args);
>>>>    		break;
>>>> +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
>>>>    	case I915_CONTEXT_PARAM_NO_ZEROMAP:
>>>>    	case I915_CONTEXT_PARAM_BAN_PERIOD:
>>>>    	case I915_CONTEXT_PARAM_RINGSIZE:
>>>> @@ -2174,6 +2221,10 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
>>>>    		args->value = i915_gem_context_is_persistent(ctx);
>>>>    		break;
>>>> +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
>>>> +		ret = get_protected(ctx, args);
>>>> +		break;
>>>> +
>>>>    	case I915_CONTEXT_PARAM_NO_ZEROMAP:
>>>>    	case I915_CONTEXT_PARAM_BAN_PERIOD:
>>>>    	case I915_CONTEXT_PARAM_ENGINES:
>>>> @@ -2250,6 +2301,11 @@ int i915_gem_context_reset_stats_ioctl(struct drm_device *dev,
>>>>    	args->batch_active = atomic_read(&ctx->guilty_count);
>>>>    	args->batch_pending = atomic_read(&ctx->active_count);
>>>> +	/* re-use args->flags for output flags */
>>>> +	args->flags = 0;
>>>> +	if (i915_gem_context_invalidated(ctx))
>>>> +		args->flags |= I915_CONTEXT_INVALIDATED;
>>>> +
>>>>    	i915_gem_context_put(ctx);
>>>>    	return 0;
>>>>    }
>>>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.h b/drivers/gpu/drm/i915/gem/i915_gem_context.h
>>>> index 18060536b0c2..d932a70122fa 100644
>>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_context.h
>>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.h
>>>> @@ -108,6 +108,24 @@ i915_gem_context_clear_user_engines(struct i915_gem_context *ctx)
>>>>    	clear_bit(CONTEXT_USER_ENGINES, &ctx->flags);
>>>>    }
>>>> +static inline bool
>>>> +i915_gem_context_invalidated(const struct i915_gem_context *ctx)
>>>> +{
>>>> +	return test_bit(CONTEXT_INVALID, &ctx->flags);
>>>> +}
>>>> +
>>>> +static inline void
>>>> +i915_gem_context_set_invalid(struct i915_gem_context *ctx)
>>>> +{
>>>> +	set_bit(CONTEXT_INVALID, &ctx->flags);
>>> Do we _really_ need a new bit in this already very complex state
>>> machinery, and can't we reuse the BANNED flag instead?
>>>
>>> This ctx->flags is atomic, unorderd, and that means you need barriers and
>>> everything.
>>>
>>> If you don't actually need the atomic state bit machinery because you're
>>> using simple locking, then pls use your own boolean, and document by which
>>> lock it's protected.
>> The BANNED flag is at the intel_context level, while I needed something at
>> the gem_context level to report out. Can make it a bool if you prefer.
>> The invalidation process is inherently racy (the teardown can always occur
>> after we've checked the flag) so no amount of locking can help there. The
>> flag itself is only set once and never cleared, so no risk of a set and
>> clear racing.
> Yes the invalidate is racy, but we still need to make guarantees
> internally in the kernel that nothing escapes and falls through cracks.

We can't make that guarantee, because we get the invalidation interrupt 
after the HW has already processed all the invalidations. A protected 
object might already be in use on an engine (in which case it is too 
late to pull it out) or have been submitted for a flip when we get the 
interrupt; we could also end up using the invalidated objects before we 
manage to process the interrupt. The whole invalidation tracking is best 
effort by HW design, AFAIU it was deemed acceptable to potentially get 1 
corrupted frame as long as we do our best to keep the window short.

>
> Wrt reporting out, this should be exactly the same flow as a gpu reset
> that results in a banned gem context. We really shouldn't duplicate
> infrastructure here.

AFAICS there is no banning of gem_context (unless it is named something 
different). There is banning of intel_context and full on banning of the 
file. There was an explicit request from mesa to add something new at 
the reset_stats level because what we already had didn't work. If there 
is a different solution that works for them I'm happy to switch (+ 
Lionel for comments).

>
>
>>>> +}
>>>> +
>>>> +static inline bool
>>>> +i915_gem_context_uses_protected_content(const struct i915_gem_context *ctx)
>>>> +{
>>>> +	return test_bit(UCONTEXT_PROTECTED, &ctx->user_flags);
>>> For immutable state (I really hope this is immutable) pls don't reuse the
>>> atomic bitfield of mutable state, but create a flag of your own.
>> It is immutable. Should we have a ctx->immutable_flags, or better a bool?
> Yeah just make it a bool, and add a kerneldoc comment that it's immutable
> and never changes.

Ok. The fact that this is immutable is already in the doc for the 
create_ext, but I'll add it next to the variable as well.

>
>>> Also please document all the rules around how this is set/changed in the
>>> kerneldoc header comments for the data structure. Finally if you never set
>>> it except at creation.
>>>
>>>> +}
>>>> +
>>>>    /* i915_gem_context.c */
>>>>    void i915_gem_init__contexts(struct drm_i915_private *i915);
>>>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
>>>> index 94c03a97cb77..1aa2290aa3c7 100644
>>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
>>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
>>>> @@ -301,6 +301,7 @@ struct i915_gem_context {
>>>>    #define UCONTEXT_BANNABLE		2
>>>>    #define UCONTEXT_RECOVERABLE		3
>>>>    #define UCONTEXT_PERSISTENCE		4
>>>> +#define UCONTEXT_PROTECTED		5
>>>>    	/**
>>>>    	 * @flags: small set of booleans
>>>> @@ -308,6 +309,7 @@ struct i915_gem_context {
>>>>    	unsigned long flags;
>>>>    #define CONTEXT_CLOSED			0
>>>>    #define CONTEXT_USER_ENGINES		1
>>>> +#define CONTEXT_INVALID			2
>>>>    	/** @mutex: guards everything that isn't engines or handles_vma */
>>>>    	struct mutex mutex;
>>>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c b/drivers/gpu/drm/i915/gem/i915_gem_create.c
>>>> index 23fee13a3384..0e48629316bb 100644
>>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
>>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
>>>> @@ -6,6 +6,7 @@
>>>>    #include "gem/i915_gem_ioctls.h"
>>>>    #include "gem/i915_gem_lmem.h"
>>>>    #include "gem/i915_gem_region.h"
>>>> +#include "pxp/intel_pxp.h"
>>>>    #include "i915_drv.h"
>>>>    #include "i915_trace.h"
>>>> @@ -82,21 +83,11 @@ static int i915_gem_publish(struct drm_i915_gem_object *obj,
>>>>    	return 0;
>>>>    }
>>>> -/**
>>>> - * Creates a new object using the same path as DRM_I915_GEM_CREATE_EXT
>>>> - * @i915: i915 private
>>>> - * @size: size of the buffer, in bytes
>>>> - * @placements: possible placement regions, in priority order
>>>> - * @n_placements: number of possible placement regions
>>>> - *
>>>> - * This function is exposed primarily for selftests and does very little
>>>> - * error checking.  It is assumed that the set of placement regions has
>>>> - * already been verified to be valid.
>>>> - */
>>>> -struct drm_i915_gem_object *
>>>> -__i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
>>>> -			      struct intel_memory_region **placements,
>>>> -			      unsigned int n_placements)
>>>> +static struct drm_i915_gem_object *
>>>> +__i915_gem_object_create_user_ext(struct drm_i915_private *i915, u64 size,
>>>> +				  struct intel_memory_region **placements,
>>>> +				  unsigned int n_placements,
>>>> +				  unsigned int ext_flags)
>>>>    {
>>>>    	struct intel_memory_region *mr = placements[0];
>>>>    	struct drm_i915_gem_object *obj;
>>>> @@ -135,6 +126,12 @@ __i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
>>>>    	GEM_BUG_ON(size != obj->base.size);
>>>> +	/* Add any flag set by create_ext options */
>>>> +	flags |= ext_flags;
>>>> +
>>>> +	if (i915_gem_object_is_protected(obj))
>>>> +		intel_pxp_object_add(obj);
>>>> +
>>>>    	trace_i915_gem_object_create(obj);
>>>>    	return obj;
>>>> @@ -145,6 +142,26 @@ __i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
>>>>    	return ERR_PTR(ret);
>>>>    }
>>>> +/**
>>>> + * Creates a new object using the same path as DRM_I915_GEM_CREATE_EXT
>>>> + * @i915: i915 private
>>>> + * @size: size of the buffer, in bytes
>>>> + * @placements: possible placement regions, in priority order
>>>> + * @n_placements: number of possible placement regions
>>>> + *
>>>> + * This function is exposed primarily for selftests and does very little
>>>> + * error checking.  It is assumed that the set of placement regions has
>>>> + * already been verified to be valid.
>>>> + */
>>>> +struct drm_i915_gem_object *
>>>> +__i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
>>>> +			      struct intel_memory_region **placements,
>>>> +			      unsigned int n_placements)
>>>> +{
>>>> +	return __i915_gem_object_create_user_ext(i915, size, placements,
>>>> +						 n_placements, 0);
>>>> +}
>>>> +
>>>>    int
>>>>    i915_gem_dumb_create(struct drm_file *file,
>>>>    		     struct drm_device *dev,
>>>> @@ -224,6 +241,7 @@ struct create_ext {
>>>>    	struct drm_i915_private *i915;
>>>>    	struct intel_memory_region *placements[INTEL_REGION_UNKNOWN];
>>>>    	unsigned int n_placements;
>>>> +	unsigned long flags;
>>>>    };
>>>>    static void repr_placements(char *buf, size_t size,
>>>> @@ -356,8 +374,28 @@ static int ext_set_placements(struct i915_user_extension __user *base,
>>>>    	return set_placements(&ext, data);
>>>>    }
>>>> +static int ext_set_protected(struct i915_user_extension __user *base, void *data)
>>>> +{
>>>> +	struct drm_i915_gem_create_ext_protected_content ext;
>>>> +	struct create_ext *ext_data = data;
>>>> +
>>>> +	if (copy_from_user(&ext, base, sizeof(ext)))
>>>> +		return -EFAULT;
>>>> +
>>>> +	if (ext.flags)
>>>> +		return -EINVAL;
>>>> +
>>>> +	if (!intel_pxp_is_enabled(&ext_data->i915->gt.pxp))
>>>> +		return -ENODEV;
>>>> +
>>>> +	ext_data->flags |= I915_BO_PROTECTED;
>>>> +
>>>> +	return 0;
>>>> +}
>>>> +
>>>>    static const i915_user_extension_fn create_extensions[] = {
>>>>    	[I915_GEM_CREATE_EXT_MEMORY_REGIONS] = ext_set_placements,
>>>> +	[I915_GEM_CREATE_EXT_PROTECTED_CONTENT] = ext_set_protected,
>>>>    };
>>>>    /**
>>>> @@ -392,9 +430,10 @@ i915_gem_create_ext_ioctl(struct drm_device *dev, void *data,
>>>>    		ext_data.n_placements = 1;
>>>>    	}
>>>> -	obj = __i915_gem_object_create_user(i915, args->size,
>>>> -					    ext_data.placements,
>>>> -					    ext_data.n_placements);
>>>> +	obj = __i915_gem_object_create_user_ext(i915, args->size,
>>>> +						ext_data.placements,
>>>> +						ext_data.n_placements,
>>>> +						ext_data.flags);
>>>>    	if (IS_ERR(obj))
>>>>    		return PTR_ERR(obj);
>>>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>>>> index 1ed7475de454..04f33d163340 100644
>>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>>>> @@ -21,6 +21,8 @@
>>>>    #include "gt/intel_gt_pm.h"
>>>>    #include "gt/intel_ring.h"
>>>> +#include "pxp/intel_pxp.h"
>>>> +
>>>>    #include "i915_drv.h"
>>>>    #include "i915_gem_clflush.h"
>>>>    #include "i915_gem_context.h"
>>>> @@ -751,6 +753,11 @@ static int eb_select_context(struct i915_execbuffer *eb)
>>>>    	if (unlikely(IS_ERR(ctx)))
>>>>    		return PTR_ERR(ctx);
>>>> +	if (i915_gem_context_invalidated(ctx)) {
>>>> +		i915_gem_context_put(ctx);
>>>> +		return -EACCES;
>>>> +	}
>>>> +
>>>>    	eb->gem_context = ctx;
>>>>    	if (rcu_access_pointer(ctx->vm))
>>>>    		eb->invalid_flags |= EXEC_OBJECT_NEEDS_GTT;
>>>> @@ -819,7 +826,7 @@ static struct i915_vma *eb_lookup_vma(struct i915_execbuffer *eb, u32 handle)
>>>>    	do {
>>>>    		struct drm_i915_gem_object *obj;
>>>>    		struct i915_vma *vma;
>>>> -		int err;
>>>> +		int err = 0;
>>>>    		rcu_read_lock();
>>>>    		vma = radix_tree_lookup(&eb->gem_context->handles_vma, handle);
>>>> @@ -833,6 +840,26 @@ static struct i915_vma *eb_lookup_vma(struct i915_execbuffer *eb, u32 handle)
>>>>    		if (unlikely(!obj))
>>>>    			return ERR_PTR(-ENOENT);
>>>> +		/*
>>>> +		 * If the user has opted-in for protected-object tracking, make
>>>> +		 * sure the object encryption can be used.
>>>> +		 * We only need to do this when the object is first used with
>>>> +		 * this context, because the context itself will be banned when
>>>> +		 * the protected objects become invalid.
>>>> +		 */
>>>> +		if (i915_gem_context_uses_protected_content(eb->gem_context) &&
>>>> +		    i915_gem_object_is_protected(obj)) {
>>>> +			if (!intel_pxp_is_active(&vm->gt->pxp))
>>>> +				err = -ENODEV;
>>>> +			else if (!i915_gem_object_has_valid_protection(obj))
>>>> +				err = -ENOEXEC;
>>>> +
>>>> +			if (err) {
>>>> +				i915_gem_object_put(obj);
>>>> +				return ERR_PTR(err);
>>>> +			}
>>>> +		}
>>>> +
>>>>    		vma = i915_vma_instance(obj, vm, NULL);
>>>>    		if (IS_ERR(vma)) {
>>>>    			i915_gem_object_put(obj);
>>>> @@ -2752,6 +2779,17 @@ eb_select_engine(struct i915_execbuffer *eb)
>>>>    	intel_gt_pm_get(ce->engine->gt);
>>>> +	if (i915_gem_context_uses_protected_content(eb->gem_context)) {
>>>> +		err = intel_pxp_wait_for_arb_start(&ce->engine->gt->pxp);
>>>> +		if (err)
>>>> +			goto err;
>>>> +
>>>> +		if (i915_gem_context_invalidated(eb->gem_context)) {
>>>> +			err = -EACCES;
>>> Shouldn't the normal banned context handling takee care of anything that
>>> slips through? Rolling your own racy invalidation checks doesn't look like
>>> a good idea.
>> This is to bail out early and report the error to userspace. If the
>> invalidation flag gets set after this check then we'll still catch it later
>> as you said, but IMO there is value in bailing out early when possible,
>> especially since it is a low-effort check. The invalidation flag can't be
>> cleared, so no risk of rejecting something that shouldn't be.
> Nah, that just papers over races and means you now have to validate more
> code for correctness - the later catching still must happen, but it's now
> much harder to trigger.
>
> Also, the context banning should do this for us already. Maybe a good idea
> to audit and document that, to make sure it's working correctly and we're
> using it correctly for pxp, but this wheel should exist and we don't need
> a new one.

Ok, I can rely on the intel_context being banned directly (it's checked 
earlier) but as mentioned above we do need but-in from mesa to drop the 
new invalidation flag at the gem_context level.

Daniele

>
> Except if the uapi promise is that we send back a different errno, but
> that again should be integrated into the context banning stuff.
> -Daniel
>
>> Daniele
>>
>>>> +			goto err;
>>>> +		}
>>>> +	}
>>>> +
>>>>    	if (!test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
>>>>    		err = intel_context_alloc_state(ce);
>>>>    		if (err)
>>>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c
>>>> index 6fb9afb65034..658a42a7fa07 100644
>>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
>>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
>>>> @@ -25,6 +25,7 @@
>>>>    #include <linux/sched/mm.h>
>>>>    #include "display/intel_frontbuffer.h"
>>>> +#include "pxp/intel_pxp.h"
>>>>    #include "i915_drv.h"
>>>>    #include "i915_gem_clflush.h"
>>>>    #include "i915_gem_context.h"
>>>> @@ -73,6 +74,8 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj,
>>>>    	INIT_LIST_HEAD(&obj->lut_list);
>>>>    	spin_lock_init(&obj->lut_lock);
>>>> +	INIT_LIST_HEAD(&obj->pxp_link);
>>>> +
>>>>    	spin_lock_init(&obj->mmo.lock);
>>>>    	obj->mmo.offsets = RB_ROOT;
>>>> @@ -231,6 +234,9 @@ void __i915_gem_free_object(struct drm_i915_gem_object *obj)
>>>>    		spin_unlock(&obj->vma.lock);
>>>>    	}
>>>> +	if (i915_gem_object_has_valid_protection(obj))
>>>> +		intel_pxp_object_remove(obj);
>>>> +
>>>>    	__i915_gem_object_free_mmaps(obj);
>>>>    	GEM_BUG_ON(!list_empty(&obj->lut_list));
>>>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h
>>>> index 48112b9d76df..137ae2723514 100644
>>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
>>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
>>>> @@ -269,6 +269,18 @@ i915_gem_object_clear_tiling_quirk(struct drm_i915_gem_object *obj)
>>>>    	clear_bit(I915_TILING_QUIRK_BIT, &obj->flags);
>>>>    }
>>>> +static inline bool
>>>> +i915_gem_object_is_protected(const struct drm_i915_gem_object *obj)
>>>> +{
>>>> +	return obj->flags & I915_BO_PROTECTED;
>>>> +}
>>>> +
>>>> +static inline bool
>>>> +i915_gem_object_has_valid_protection(const struct drm_i915_gem_object *obj)
>>>> +{
>>>> +	return i915_gem_object_is_protected(obj) && !list_empty(&obj->pxp_link);
>>>> +}
>>>> +
>>>>    static inline bool
>>>>    i915_gem_object_type_has(const struct drm_i915_gem_object *obj,
>>>>    			 unsigned long flags)
>>>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
>>>> index 2471f36aaff3..38e4a190607a 100644
>>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
>>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
>>>> @@ -298,6 +298,7 @@ struct drm_i915_gem_object {
>>>>    			     I915_BO_ALLOC_USER)
>>>>    #define I915_BO_READONLY         BIT(4)
>>>>    #define I915_TILING_QUIRK_BIT    5 /* unknown swizzling; do not release! */
>>>> +#define I915_BO_PROTECTED        BIT(6)
>>>>    	/**
>>>>    	 * @mem_flags - Mutable placement-related flags
>>>> @@ -537,6 +538,14 @@ struct drm_i915_gem_object {
>>>>    		bool created:1;
>>>>    	} ttm;
>>>> +	/*
>>>> +	 * When the PXP session is invalidated, we need to mark all protected
>>>> +	 * objects as invalid. To easily do so we add them all to a list. The
>>>> +	 * presence on the list is used to check if the encryption is valid or
>>>> +	 * not.
>>>> +	 */
>>>> +	struct list_head pxp_link;
>>>> +
>>>>    	/** Record of address bit 17 of each page at last unbind. */
>>>>    	unsigned long *bit_17;
>>>> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
>>>> index b0c7edc10cc3..f418281e8c10 100644
>>>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
>>>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
>>>> @@ -7,6 +7,7 @@
>>>>    #include "intel_pxp_irq.h"
>>>>    #include "intel_pxp_session.h"
>>>>    #include "intel_pxp_tee.h"
>>>> +#include "gem/i915_gem_context.h"
>>>>    #include "gt/intel_context.h"
>>>>    #include "i915_drv.h"
>>>> @@ -70,6 +71,9 @@ void intel_pxp_init(struct intel_pxp *pxp)
>>>>    	mutex_init(&pxp->tee_mutex);
>>>> +	spin_lock_init(&pxp->lock);
>>>> +	INIT_LIST_HEAD(&pxp->protected_objects);
>>>> +
>>>>    	/*
>>>>    	 * we'll use the completion to check if there is a termination pending,
>>>>    	 * so we start it as completed and we reinit it when a termination
>>>> @@ -166,3 +170,88 @@ void intel_pxp_fini_hw(struct intel_pxp *pxp)
>>>>    	intel_pxp_irq_disable(pxp);
>>>>    }
>>>> +
>>>> +int intel_pxp_object_add(struct drm_i915_gem_object *obj)
>>>> +{
>>>> +	struct intel_pxp *pxp = &to_i915(obj->base.dev)->gt.pxp;
>>>> +
>>>> +	if (!intel_pxp_is_enabled(pxp))
>>>> +		return -ENODEV;
>>>> +
>>>> +	if (!list_empty(&obj->pxp_link))
>>>> +		return -EEXIST;
>>>> +
>>>> +	spin_lock_irq(&pxp->lock);
>>>> +	list_add(&obj->pxp_link, &pxp->protected_objects);
>>>> +	spin_unlock_irq(&pxp->lock);
>>>> +
>>>> +	return 0;
>>>> +}
>>>> +
>>>> +void intel_pxp_object_remove(struct drm_i915_gem_object *obj)
>>>> +{
>>>> +	struct intel_pxp *pxp = &to_i915(obj->base.dev)->gt.pxp;
>>>> +
>>>> +	if (!intel_pxp_is_enabled(pxp))
>>>> +		return;
>>>> +
>>>> +	spin_lock_irq(&pxp->lock);
>>>> +	list_del_init(&obj->pxp_link);
>>>> +	spin_unlock_irq(&pxp->lock);
>>>> +}
>>>> +
>>>> +void intel_pxp_invalidate(struct intel_pxp *pxp)
>>> There is a lot of locking going on here. Please make sure it's all
>>> properly documented what the rules are in kerneldoc, even for existing
>>> stuff.
>>>
>>> Especially anytime there's anything tricky going on, like:
>>> - kref_get_unless_zero
>>> - test_bit (that's an unorderd atomic, so either you don't actually need
>>>     the atomic, or you need a pile of barriers and comments about them)
>>> - hiddent atomic ops like intel_context_set_banned or
>>>     i915_gem_context_set_invalid also need great care, least because the
>>>     current rules aren't documented really. So step one here before using
>>>     them is documenting the rules of how banning works.
>>>
>>>> +{
>>>> +	struct drm_i915_private *i915 = pxp_to_gt(pxp)->i915;
>>>> +	struct drm_i915_gem_object *obj, *tmp;
>>>> +	struct i915_gem_context *ctx, *cn;
>>>> +
>>>> +	/* delete objects that have been used with the invalidated session */
>>>> +	spin_lock_irq(&pxp->lock);
>>>> +	list_for_each_entry_safe(obj, tmp, &pxp->protected_objects, pxp_link) {
>>>> +		if (i915_gem_object_has_pages(obj))
>>>> +			list_del_init(&obj->pxp_link);
>>>> +	}
>>>> +	spin_unlock_irq(&pxp->lock);
>>>> +
>>>> +	/* 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) {
>>>> +		struct i915_gem_engines_iter it;
>>>> +		struct intel_context *ce;
>>>> +
>>>> +		if (!kref_get_unless_zero(&ctx->ref))
>>>> +			continue;
>>>> +
>>>> +		if (likely(!i915_gem_context_uses_protected_content(ctx)) ||
>>>> +		    i915_gem_context_invalidated(ctx)) {
>>>> +			i915_gem_context_put(ctx);
>>>> +			continue;
>>>> +		}
>>>> +
>>>> +		spin_unlock_irq(&i915->gem.contexts.lock);
>>>> +
>>>> +		/*
>>>> +		 * Note that by the time we get here the HW keys are already
>>>> +		 * long gone, so any batch using them that's already on the
>>>> +		 * engines is very likely a lost cause (and it has probably
>>>> +		 * already hung the engine). Therefore, we skip attempting to
>>>> +		 * pull the running context out of the HW and we prioritize
>>>> +		 * bringing the session back as soon as possible.
>>>> +		 */
>>>> +		for_each_gem_engine(ce, i915_gem_context_lock_engines(ctx), it) {
>>>> +			/* only invalidate if at least one ce was allocated */
>>>> +			if (test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
>>>> +				intel_context_set_banned(ce);
>>>> +				i915_gem_context_set_invalid(ctx);
>>>> +			}
>>>> +		}
>>>> +		i915_gem_context_unlock_engines(ctx);
>>>> +
>>>> +		spin_lock_irq(&i915->gem.contexts.lock);
>>>> +		list_safe_reset_next(ctx, cn, link);
>>>> +		i915_gem_context_put(ctx);
>>>> +	}
>>>> +	spin_unlock_irq(&i915->gem.contexts.lock);
>>>> +}
>>>> +
>>>> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
>>>> index 074b3b980957..4f7647f34153 100644
>>>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
>>>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
>>>> @@ -9,6 +9,8 @@
>>>>    #include "gt/intel_gt_types.h"
>>>>    #include "intel_pxp_types.h"
>>>> +struct drm_i915_gem_object;
>>>> +
>>>>    static inline struct intel_gt *pxp_to_gt(const struct intel_pxp *pxp)
>>>>    {
>>>>    	return container_of(pxp, struct intel_gt, pxp);
>>>> @@ -33,6 +35,11 @@ void intel_pxp_fini_hw(struct intel_pxp *pxp);
>>>>    void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp);
>>>>    int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp);
>>>> +
>>>> +int intel_pxp_object_add(struct drm_i915_gem_object *obj);
>>>> +void intel_pxp_object_remove(struct drm_i915_gem_object *obj);
>>>> +
>>>> +void intel_pxp_invalidate(struct intel_pxp *pxp);
>>>>    #else
>>>>    static inline void intel_pxp_init(struct intel_pxp *pxp)
>>>>    {
>>>> @@ -46,6 +53,14 @@ static inline int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp)
>>>>    {
>>>>    	return 0;
>>>>    }
>>>> +
>>>> +static inline int intel_pxp_object_add(struct drm_i915_gem_object *obj)
>>>> +{
>>>> +	return 0;
>>>> +}
>>>> +static inline void intel_pxp_object_remove(struct drm_i915_gem_object *obj)
>>>> +{
>>>> +}
>>>>    #endif
>>>>    #endif /* __INTEL_PXP_H__ */
>>>> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
>>>> index 67c30e534d50..0edd563a653d 100644
>>>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
>>>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
>>>> @@ -85,6 +85,9 @@ static int pxp_terminate_arb_session_and_global(struct intel_pxp *pxp)
>>>>    	/* must mark termination in progress calling this function */
>>>>    	GEM_WARN_ON(pxp->arb_is_valid);
>>>> +	/* invalidate protected objects */
>>>> +	intel_pxp_invalidate(pxp);
>>>> +
>>>>    	/* terminate the hw sessions */
>>>>    	ret = intel_pxp_terminate_session(pxp, ARB_SESSION);
>>>>    	if (ret) {
>>>> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
>>>> index 475e3312c287..be2bed3a2e4e 100644
>>>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
>>>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
>>>> @@ -7,7 +7,9 @@
>>>>    #define __INTEL_PXP_TYPES_H__
>>>>    #include <linux/completion.h>
>>>> +#include <linux/list.h>
>>>>    #include <linux/mutex.h>
>>>> +#include <linux/spinlock.h>
>>>>    #include <linux/types.h>
>>>>    #include <linux/workqueue.h>
>>>> @@ -43,6 +45,9 @@ struct intel_pxp {
>>>>    	u32 session_events; /* protected with gt->irq_lock */
>>>>    #define PXP_TERMINATION_REQUEST  BIT(0)
>>>>    #define PXP_TERMINATION_COMPLETE BIT(1)
>>>> +
>>>> +	spinlock_t lock; /* protects the objects list */
>>>> +	struct list_head protected_objects;
>>>>    };
>>>>    #endif /* __INTEL_PXP_TYPES_H__ */
>>>> diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
>>>> index 4393eef59d9b..2c9febdae6a5 100644
>>>> --- a/include/uapi/drm/i915_drm.h
>>>> +++ b/include/uapi/drm/i915_drm.h
>>>> @@ -1843,12 +1843,32 @@ struct drm_i915_gem_context_param {
>>>>     * attempted to use it, never re-use this context param number.
>>>>     */
>>>>    #define I915_CONTEXT_PARAM_RINGSIZE	0xc
>>>> +
>>>> +/*
>>>> + * I915_CONTEXT_PARAM_PROTECTED_CONTENT:
>>>> + *
>>>> + * Mark that the context makes use of protected content, which will result
>>>> + * in the context being invalidated when the protected content session is. The
>>>> + * invalidation is reported back to userspace via the RESET_STATS ioctl (see
>>>> + * relevant doc for details).
>>>> + * This flag can only be set at context creation time and, when set to true,
>>>> + * must be preceded by an explicit setting of I915_CONTEXT_PARAM_RECOVERABLE
>>>> + * to false. This flag can't be set to true in conjunction with setting the
>>>> + * I915_CONTEXT_PARAM_BANNABLE flag to false.
>>>> + *
>>>> + * In addition to the normal failure cases, setting this flag during context
>>>> + * creation can result in the following errors:
>>>> + *
>>>> + * -ENODEV: feature not available
>>>> + * -EPERM: trying to mark a recoverable or not bannable context as protected
>>>> + */
>>>> +#define I915_CONTEXT_PARAM_PROTECTED_CONTENT    0xd
>>>>    /* Must be kept compact -- no holes and well documented */
>>>>    	__u64 value;
>>>>    };
>>>> -/*
>>>> +/**
>>>>     * Context SSEU programming
>>>>     *
>>>>     * It may be necessary for either functional or performance reason to configure
>>>> @@ -2181,6 +2201,12 @@ struct drm_i915_reg_read {
>>>>    struct drm_i915_reset_stats {
>>>>    	__u32 ctx_id;
>>>>    	__u32 flags;
>>>> +	/*
>>>> +	 * contexts marked as using protected content are invalidated when the
>>>> +	 * protected content session dies. Submission of invalidated contexts
>>>> +	 * is rejected with -EACCES.
>>>> +	 */
>>>> +#define I915_CONTEXT_INVALIDATED 0x1
>>>>    	/* All resets since boot/module reload, for all contexts */
>>>>    	__u32 reset_count;
>>>> @@ -2959,8 +2985,12 @@ struct drm_i915_gem_create_ext {
>>>>    	 *
>>>>    	 * For I915_GEM_CREATE_EXT_MEMORY_REGIONS usage see
>>>>    	 * struct drm_i915_gem_create_ext_memory_regions.
>>>> +	 *
>>>> +	 * For I915_GEM_CREATE_EXT_PROTECTED_CONTENT usage see
>>>> +	 * struct drm_i915_gem_create_ext_protected_content.
>>>>    	 */
>>>>    #define I915_GEM_CREATE_EXT_MEMORY_REGIONS 0
>>>> +#define I915_GEM_CREATE_EXT_PROTECTED_CONTENT 1
>>>>    	__u64 extensions;
>>>>    };
>>>> @@ -3018,6 +3048,29 @@ struct drm_i915_gem_create_ext_memory_regions {
>>>>    	__u64 regions;
>>>>    };
>>>> +/**
>>>> + * struct drm_i915_gem_create_ext_protected_content - The
>>>> + * I915_OBJECT_PARAM_PROTECTED_CONTENT extension.
>>>> + *
>>>> + * If this extension is provided, buffer contents are expected to be protected
>>>> + * by PXP encryption and require decryption for scan out and processing. This
>>>> + * is only possible on platforms that have PXP enabled, on all other scenarios
>>>> + * using this extension will cause the ioctl to fail and return -ENODEV. The
>>>> + * flags parameter is reserved for future expansion and must currently be set
>>>> + * to zero.
>>>> + *
>>>> + * The buffer contents are considered invalid after a PXP session teardown.
>>>> + *
>>>> + * The encryption is guaranteed to be processed correctly only if the object
>>>> + * is submitted with a context created using the
>>>> + * I915_CONTEXT_PARAM_PROTECTED_CONTENT flag. This will also enable extra checks
>>>> + * at submission time on the validity of the objects involved.
>>>> + */
>>>> +struct drm_i915_gem_create_ext_protected_content {
>>>> +	struct i915_user_extension base;
>>>> +	__u32 flags;
>>>> +};
>>>> +
>>>>    /* ID of the protected content session managed by i915 when PXP is active */
>>>>    #define I915_PROTECTED_CONTENT_DEFAULT_SESSION 0xf
>>>> -- 
>>>> 2.32.0
>>>>
>>>> _______________________________________________
>>>> Intel-gfx mailing list
>>>> Intel-gfx@lists.freedesktop.org
>>>> https://lists.freedesktop.org/mailman/listinfo/intel-gfx


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Intel-gfx] [PATCH v6 10/15] drm/i915/pxp: interfaces for using protected objects
  2021-08-16 15:58         ` Daniele Ceraolo Spurio
@ 2021-08-17  9:02           ` Daniel Vetter
  0 siblings, 0 replies; 64+ messages in thread
From: Daniel Vetter @ 2021-08-17  9:02 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio
  Cc: Daniel Vetter, intel-gfx, Daniel Vetter, Chris Wilson, dri-devel,
	Bommu Krishnaiah, Lionel Landwerlin

On Mon, Aug 16, 2021 at 08:58:49AM -0700, Daniele Ceraolo Spurio wrote:
> 
> 
> On 8/16/2021 8:15 AM, Daniel Vetter wrote:
> > On Fri, Aug 13, 2021 at 08:18:02AM -0700, Daniele Ceraolo Spurio wrote:
> > > 
> > > On 8/13/2021 7:37 AM, Daniel Vetter wrote:
> > > > On Wed, Jul 28, 2021 at 07:01:01PM -0700, Daniele Ceraolo Spurio wrote:
> > > > > This api allow user mode to create protected buffers and to mark
> > > > > contexts as making use of such objects. Only when using contexts
> > > > > marked in such a way is the execution guaranteed to work as expected.
> > > > > 
> > > > > Contexts can only be marked as using protected content at creation time
> > > > > (i.e. the parameter is immutable) and they must be both bannable and not
> > > > > recoverable.
> > > > > 
> > > > > All protected objects and contexts that have backing storage will be
> > > > > considered invalid when the PXP session is destroyed and all new
> > > > > submissions using them will be rejected. All intel contexts within the
> > > > > invalidated gem contexts will be marked banned. A new flag has been
> > > > > added to the RESET_STATS ioctl to report the context invalidation to
> > > > > userspace.
> > > > > 
> > > > > This patch was previously sent as 2 separate patches, which have been
> > > > > squashed following a request to have all the uapi in a single patch.
> > > > > I've retained the s-o-b from both.
> > > > > 
> > > > > v5: squash patches, rebase on proto_ctx, update kerneldoc
> > > > > 
> > > > > v6: rebase on obj create_ext changes
> > > > > 
> > > > > Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
> > > > > Signed-off-by: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
> > > > > Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > > > > Cc: Chris Wilson <chris@chris-wilson.co.uk>
> > > > > Cc: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
> > > > > Cc: Jason Ekstrand <jason@jlekstrand.net>
> > > > > Cc: Daniel Vetter <daniel.vetter@intel.com>
> > > > > Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> #v5
> > > > > ---
> > > > >    drivers/gpu/drm/i915/gem/i915_gem_context.c   | 68 ++++++++++++--
> > > > >    drivers/gpu/drm/i915/gem/i915_gem_context.h   | 18 ++++
> > > > >    .../gpu/drm/i915/gem/i915_gem_context_types.h |  2 +
> > > > >    drivers/gpu/drm/i915/gem/i915_gem_create.c    | 75 ++++++++++++----
> > > > >    .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 40 ++++++++-
> > > > >    drivers/gpu/drm/i915/gem/i915_gem_object.c    |  6 ++
> > > > >    drivers/gpu/drm/i915/gem/i915_gem_object.h    | 12 +++
> > > > >    .../gpu/drm/i915/gem/i915_gem_object_types.h  |  9 ++
> > > > >    drivers/gpu/drm/i915/pxp/intel_pxp.c          | 89 +++++++++++++++++++
> > > > >    drivers/gpu/drm/i915/pxp/intel_pxp.h          | 15 ++++
> > > > >    drivers/gpu/drm/i915/pxp/intel_pxp_session.c  |  3 +
> > > > >    drivers/gpu/drm/i915/pxp/intel_pxp_types.h    |  5 ++
> > > > >    include/uapi/drm/i915_drm.h                   | 55 +++++++++++-
> > > > >    13 files changed, 371 insertions(+), 26 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> > > > > index cff72679ad7c..0cd3e2d06188 100644
> > > > > --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
> > > > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> > > > > @@ -77,6 +77,8 @@
> > > > >    #include "gt/intel_gpu_commands.h"
> > > > >    #include "gt/intel_ring.h"
> > > > > +#include "pxp/intel_pxp.h"
> > > > > +
> > > > >    #include "i915_gem_context.h"
> > > > >    #include "i915_trace.h"
> > > > >    #include "i915_user_extensions.h"
> > > > > @@ -241,6 +243,25 @@ static int proto_context_set_persistence(struct drm_i915_private *i915,
> > > > >    	return 0;
> > > > >    }
> > > > > +static int proto_context_set_protected(struct drm_i915_private *i915,
> > > > > +				       struct i915_gem_proto_context *pc,
> > > > > +				       bool protected)
> > > > > +{
> > > > > +	int ret = 0;
> > > > > +
> > > > > +	if (!intel_pxp_is_enabled(&i915->gt.pxp))
> > > > > +		ret = -ENODEV;
> > > > > +	else if (!protected)
> > > > > +		pc->user_flags &= ~BIT(UCONTEXT_PROTECTED);
> > > > > +	else if ((pc->user_flags & BIT(UCONTEXT_RECOVERABLE)) ||
> > > > > +		 !(pc->user_flags & BIT(UCONTEXT_BANNABLE)))
> > > > > +		ret = -EPERM;
> > > > > +	else
> > > > > +		pc->user_flags |= BIT(UCONTEXT_PROTECTED);
> > > > > +
> > > > > +	return ret;
> > > > > +}
> > > > > +
> > > > >    static struct i915_gem_proto_context *
> > > > >    proto_context_create(struct drm_i915_private *i915, unsigned int flags)
> > > > >    {
> > > > > @@ -686,6 +707,8 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
> > > > >    			ret = -EPERM;
> > > > >    		else if (args->value)
> > > > >    			pc->user_flags |= BIT(UCONTEXT_BANNABLE);
> > > > > +		else if (pc->user_flags & BIT(UCONTEXT_PROTECTED))
> > > > > +			ret = -EPERM;
> > > > >    		else
> > > > >    			pc->user_flags &= ~BIT(UCONTEXT_BANNABLE);
> > > > >    		break;
> > > > > @@ -693,10 +716,12 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
> > > > >    	case I915_CONTEXT_PARAM_RECOVERABLE:
> > > > >    		if (args->size)
> > > > >    			ret = -EINVAL;
> > > > > -		else if (args->value)
> > > > > -			pc->user_flags |= BIT(UCONTEXT_RECOVERABLE);
> > > > > -		else
> > > > > +		else if (!args->value)
> > > > >    			pc->user_flags &= ~BIT(UCONTEXT_RECOVERABLE);
> > > > > +		else if (pc->user_flags & BIT(UCONTEXT_PROTECTED))
> > > > > +			ret = -EPERM;
> > > > > +		else
> > > > > +			pc->user_flags |= BIT(UCONTEXT_RECOVERABLE);
> > > > >    		break;
> > > > >    	case I915_CONTEXT_PARAM_PRIORITY:
> > > > > @@ -724,6 +749,11 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv,
> > > > >    						    args->value);
> > > > >    		break;
> > > > > +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
> > > > > +		ret = proto_context_set_protected(fpriv->dev_priv, pc,
> > > > > +						  args->value);
> > > > > +		break;
> > > > > +
> > > > >    	case I915_CONTEXT_PARAM_NO_ZEROMAP:
> > > > >    	case I915_CONTEXT_PARAM_BAN_PERIOD:
> > > > >    	case I915_CONTEXT_PARAM_RINGSIZE:
> > > > > @@ -1798,6 +1828,18 @@ static int set_priority(struct i915_gem_context *ctx,
> > > > >    	return 0;
> > > > >    }
> > > > > +static int get_protected(struct i915_gem_context *ctx,
> > > > > +			 struct drm_i915_gem_context_param *args)
> > > > > +{
> > > > > +	if (!intel_pxp_is_enabled(&ctx->i915->gt.pxp))
> > > > > +		return -ENODEV;
> > > > > +
> > > > > +	args->size = 0;
> > > > > +	args->value = i915_gem_context_uses_protected_content(ctx);
> > > > > +
> > > > > +	return 0;
> > > > > +}
> > > > > +
> > > > >    static int ctx_setparam(struct drm_i915_file_private *fpriv,
> > > > >    			struct i915_gem_context *ctx,
> > > > >    			struct drm_i915_gem_context_param *args)
> > > > > @@ -1821,6 +1863,8 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
> > > > >    			ret = -EPERM;
> > > > >    		else if (args->value)
> > > > >    			i915_gem_context_set_bannable(ctx);
> > > > > +		else if (i915_gem_context_uses_protected_content(ctx))
> > > > > +			ret = -EPERM; /* can't clear this for protected contexts */
> > > > >    		else
> > > > >    			i915_gem_context_clear_bannable(ctx);
> > > > >    		break;
> > > > > @@ -1828,10 +1872,12 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
> > > > >    	case I915_CONTEXT_PARAM_RECOVERABLE:
> > > > >    		if (args->size)
> > > > >    			ret = -EINVAL;
> > > > > -		else if (args->value)
> > > > > -			i915_gem_context_set_recoverable(ctx);
> > > > > -		else
> > > > > +		else if (!args->value)
> > > > >    			i915_gem_context_clear_recoverable(ctx);
> > > > > +		else if (i915_gem_context_uses_protected_content(ctx))
> > > > > +			ret = -EPERM; /* can't set this for protected contexts */
> > > > > +		else
> > > > > +			i915_gem_context_set_recoverable(ctx);
> > > > >    		break;
> > > > >    	case I915_CONTEXT_PARAM_PRIORITY:
> > > > > @@ -1846,6 +1892,7 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
> > > > >    		ret = set_persistence(ctx, args);
> > > > >    		break;
> > > > > +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
> > > > >    	case I915_CONTEXT_PARAM_NO_ZEROMAP:
> > > > >    	case I915_CONTEXT_PARAM_BAN_PERIOD:
> > > > >    	case I915_CONTEXT_PARAM_RINGSIZE:
> > > > > @@ -2174,6 +2221,10 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
> > > > >    		args->value = i915_gem_context_is_persistent(ctx);
> > > > >    		break;
> > > > > +	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
> > > > > +		ret = get_protected(ctx, args);
> > > > > +		break;
> > > > > +
> > > > >    	case I915_CONTEXT_PARAM_NO_ZEROMAP:
> > > > >    	case I915_CONTEXT_PARAM_BAN_PERIOD:
> > > > >    	case I915_CONTEXT_PARAM_ENGINES:
> > > > > @@ -2250,6 +2301,11 @@ int i915_gem_context_reset_stats_ioctl(struct drm_device *dev,
> > > > >    	args->batch_active = atomic_read(&ctx->guilty_count);
> > > > >    	args->batch_pending = atomic_read(&ctx->active_count);
> > > > > +	/* re-use args->flags for output flags */
> > > > > +	args->flags = 0;
> > > > > +	if (i915_gem_context_invalidated(ctx))
> > > > > +		args->flags |= I915_CONTEXT_INVALIDATED;
> > > > > +
> > > > >    	i915_gem_context_put(ctx);
> > > > >    	return 0;
> > > > >    }
> > > > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.h b/drivers/gpu/drm/i915/gem/i915_gem_context.h
> > > > > index 18060536b0c2..d932a70122fa 100644
> > > > > --- a/drivers/gpu/drm/i915/gem/i915_gem_context.h
> > > > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.h
> > > > > @@ -108,6 +108,24 @@ i915_gem_context_clear_user_engines(struct i915_gem_context *ctx)
> > > > >    	clear_bit(CONTEXT_USER_ENGINES, &ctx->flags);
> > > > >    }
> > > > > +static inline bool
> > > > > +i915_gem_context_invalidated(const struct i915_gem_context *ctx)
> > > > > +{
> > > > > +	return test_bit(CONTEXT_INVALID, &ctx->flags);
> > > > > +}
> > > > > +
> > > > > +static inline void
> > > > > +i915_gem_context_set_invalid(struct i915_gem_context *ctx)
> > > > > +{
> > > > > +	set_bit(CONTEXT_INVALID, &ctx->flags);
> > > > Do we _really_ need a new bit in this already very complex state
> > > > machinery, and can't we reuse the BANNED flag instead?
> > > > 
> > > > This ctx->flags is atomic, unorderd, and that means you need barriers and
> > > > everything.
> > > > 
> > > > If you don't actually need the atomic state bit machinery because you're
> > > > using simple locking, then pls use your own boolean, and document by which
> > > > lock it's protected.
> > > The BANNED flag is at the intel_context level, while I needed something at
> > > the gem_context level to report out. Can make it a bool if you prefer.
> > > The invalidation process is inherently racy (the teardown can always occur
> > > after we've checked the flag) so no amount of locking can help there. The
> > > flag itself is only set once and never cleared, so no risk of a set and
> > > clear racing.
> > Yes the invalidate is racy, but we still need to make guarantees
> > internally in the kernel that nothing escapes and falls through cracks.
> 
> We can't make that guarantee, because we get the invalidation interrupt
> after the HW has already processed all the invalidations. A protected object
> might already be in use on an engine (in which case it is too late to pull
> it out) or have been submitted for a flip when we get the interrupt; we
> could also end up using the invalidated objects before we manage to process
> the interrupt. The whole invalidation tracking is best effort by HW design,
> AFAIU it was deemed acceptable to potentially get 1 corrupted frame as long
> as we do our best to keep the window short.

That's not what I meant with races, but the races in our book-keeping. If
we ban a context someone needs to clean up all the pending requests. If
one slips through and then non one cleans that up, we have a potential
problem. Since the context banning stuff has this solved already
(hopefully at least, would be good to document how it works exactly) it
shouldn't be a problem.

> > Wrt reporting out, this should be exactly the same flow as a gpu reset
> > that results in a banned gem context. We really shouldn't duplicate
> > infrastructure here.
> 
> AFAICS there is no banning of gem_context (unless it is named something
> different). There is banning of intel_context and full on banning of the
> file. There was an explicit request from mesa to add something new at the
> reset_stats level because what we already had didn't work. If there is a
> different solution that works for them I'm happy to switch (+ Lionel for
> comments).

Hm the only case where I see a difference between banning gem context and
banning each intel_context is when you use legacy engine map, where we
lazily instantiate stuff. Mesa shouldn't be using that anymore, so banning
all the intel_context should be equivalent. Maybe we should require the
new engine map stuff.

But I guess it wasn't so what exactly escaped here?

There's two concerns I have:
- When I discussed our entire context uapi with Jason a while ago we
  agreed that the gem context should be as much as possible a pure
  container, without semantics. The real thing should be the
  intel_contexts underneath.
- Locking gets really nasty when we have to go backwards from
  intel_context to gem context (it currently is, I have some plans to fix
  that up). So if you add uapi guarantees where we have to go backwards,
  things get potentially very interesting. Not impossible, but definitely
  more fun than I maybe want.

Cheers, Daniel

> 
> > 
> > 
> > > > > +}
> > > > > +
> > > > > +static inline bool
> > > > > +i915_gem_context_uses_protected_content(const struct i915_gem_context *ctx)
> > > > > +{
> > > > > +	return test_bit(UCONTEXT_PROTECTED, &ctx->user_flags);
> > > > For immutable state (I really hope this is immutable) pls don't reuse the
> > > > atomic bitfield of mutable state, but create a flag of your own.
> > > It is immutable. Should we have a ctx->immutable_flags, or better a bool?
> > Yeah just make it a bool, and add a kerneldoc comment that it's immutable
> > and never changes.
> 
> Ok. The fact that this is immutable is already in the doc for the
> create_ext, but I'll add it next to the variable as well.
> 
> > 
> > > > Also please document all the rules around how this is set/changed in the
> > > > kerneldoc header comments for the data structure. Finally if you never set
> > > > it except at creation.
> > > > 
> > > > > +}
> > > > > +
> > > > >    /* i915_gem_context.c */
> > > > >    void i915_gem_init__contexts(struct drm_i915_private *i915);
> > > > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
> > > > > index 94c03a97cb77..1aa2290aa3c7 100644
> > > > > --- a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
> > > > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
> > > > > @@ -301,6 +301,7 @@ struct i915_gem_context {
> > > > >    #define UCONTEXT_BANNABLE		2
> > > > >    #define UCONTEXT_RECOVERABLE		3
> > > > >    #define UCONTEXT_PERSISTENCE		4
> > > > > +#define UCONTEXT_PROTECTED		5
> > > > >    	/**
> > > > >    	 * @flags: small set of booleans
> > > > > @@ -308,6 +309,7 @@ struct i915_gem_context {
> > > > >    	unsigned long flags;
> > > > >    #define CONTEXT_CLOSED			0
> > > > >    #define CONTEXT_USER_ENGINES		1
> > > > > +#define CONTEXT_INVALID			2
> > > > >    	/** @mutex: guards everything that isn't engines or handles_vma */
> > > > >    	struct mutex mutex;
> > > > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c b/drivers/gpu/drm/i915/gem/i915_gem_create.c
> > > > > index 23fee13a3384..0e48629316bb 100644
> > > > > --- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
> > > > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
> > > > > @@ -6,6 +6,7 @@
> > > > >    #include "gem/i915_gem_ioctls.h"
> > > > >    #include "gem/i915_gem_lmem.h"
> > > > >    #include "gem/i915_gem_region.h"
> > > > > +#include "pxp/intel_pxp.h"
> > > > >    #include "i915_drv.h"
> > > > >    #include "i915_trace.h"
> > > > > @@ -82,21 +83,11 @@ static int i915_gem_publish(struct drm_i915_gem_object *obj,
> > > > >    	return 0;
> > > > >    }
> > > > > -/**
> > > > > - * Creates a new object using the same path as DRM_I915_GEM_CREATE_EXT
> > > > > - * @i915: i915 private
> > > > > - * @size: size of the buffer, in bytes
> > > > > - * @placements: possible placement regions, in priority order
> > > > > - * @n_placements: number of possible placement regions
> > > > > - *
> > > > > - * This function is exposed primarily for selftests and does very little
> > > > > - * error checking.  It is assumed that the set of placement regions has
> > > > > - * already been verified to be valid.
> > > > > - */
> > > > > -struct drm_i915_gem_object *
> > > > > -__i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
> > > > > -			      struct intel_memory_region **placements,
> > > > > -			      unsigned int n_placements)
> > > > > +static struct drm_i915_gem_object *
> > > > > +__i915_gem_object_create_user_ext(struct drm_i915_private *i915, u64 size,
> > > > > +				  struct intel_memory_region **placements,
> > > > > +				  unsigned int n_placements,
> > > > > +				  unsigned int ext_flags)
> > > > >    {
> > > > >    	struct intel_memory_region *mr = placements[0];
> > > > >    	struct drm_i915_gem_object *obj;
> > > > > @@ -135,6 +126,12 @@ __i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
> > > > >    	GEM_BUG_ON(size != obj->base.size);
> > > > > +	/* Add any flag set by create_ext options */
> > > > > +	flags |= ext_flags;
> > > > > +
> > > > > +	if (i915_gem_object_is_protected(obj))
> > > > > +		intel_pxp_object_add(obj);
> > > > > +
> > > > >    	trace_i915_gem_object_create(obj);
> > > > >    	return obj;
> > > > > @@ -145,6 +142,26 @@ __i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
> > > > >    	return ERR_PTR(ret);
> > > > >    }
> > > > > +/**
> > > > > + * Creates a new object using the same path as DRM_I915_GEM_CREATE_EXT
> > > > > + * @i915: i915 private
> > > > > + * @size: size of the buffer, in bytes
> > > > > + * @placements: possible placement regions, in priority order
> > > > > + * @n_placements: number of possible placement regions
> > > > > + *
> > > > > + * This function is exposed primarily for selftests and does very little
> > > > > + * error checking.  It is assumed that the set of placement regions has
> > > > > + * already been verified to be valid.
> > > > > + */
> > > > > +struct drm_i915_gem_object *
> > > > > +__i915_gem_object_create_user(struct drm_i915_private *i915, u64 size,
> > > > > +			      struct intel_memory_region **placements,
> > > > > +			      unsigned int n_placements)
> > > > > +{
> > > > > +	return __i915_gem_object_create_user_ext(i915, size, placements,
> > > > > +						 n_placements, 0);
> > > > > +}
> > > > > +
> > > > >    int
> > > > >    i915_gem_dumb_create(struct drm_file *file,
> > > > >    		     struct drm_device *dev,
> > > > > @@ -224,6 +241,7 @@ struct create_ext {
> > > > >    	struct drm_i915_private *i915;
> > > > >    	struct intel_memory_region *placements[INTEL_REGION_UNKNOWN];
> > > > >    	unsigned int n_placements;
> > > > > +	unsigned long flags;
> > > > >    };
> > > > >    static void repr_placements(char *buf, size_t size,
> > > > > @@ -356,8 +374,28 @@ static int ext_set_placements(struct i915_user_extension __user *base,
> > > > >    	return set_placements(&ext, data);
> > > > >    }
> > > > > +static int ext_set_protected(struct i915_user_extension __user *base, void *data)
> > > > > +{
> > > > > +	struct drm_i915_gem_create_ext_protected_content ext;
> > > > > +	struct create_ext *ext_data = data;
> > > > > +
> > > > > +	if (copy_from_user(&ext, base, sizeof(ext)))
> > > > > +		return -EFAULT;
> > > > > +
> > > > > +	if (ext.flags)
> > > > > +		return -EINVAL;
> > > > > +
> > > > > +	if (!intel_pxp_is_enabled(&ext_data->i915->gt.pxp))
> > > > > +		return -ENODEV;
> > > > > +
> > > > > +	ext_data->flags |= I915_BO_PROTECTED;
> > > > > +
> > > > > +	return 0;
> > > > > +}
> > > > > +
> > > > >    static const i915_user_extension_fn create_extensions[] = {
> > > > >    	[I915_GEM_CREATE_EXT_MEMORY_REGIONS] = ext_set_placements,
> > > > > +	[I915_GEM_CREATE_EXT_PROTECTED_CONTENT] = ext_set_protected,
> > > > >    };
> > > > >    /**
> > > > > @@ -392,9 +430,10 @@ i915_gem_create_ext_ioctl(struct drm_device *dev, void *data,
> > > > >    		ext_data.n_placements = 1;
> > > > >    	}
> > > > > -	obj = __i915_gem_object_create_user(i915, args->size,
> > > > > -					    ext_data.placements,
> > > > > -					    ext_data.n_placements);
> > > > > +	obj = __i915_gem_object_create_user_ext(i915, args->size,
> > > > > +						ext_data.placements,
> > > > > +						ext_data.n_placements,
> > > > > +						ext_data.flags);
> > > > >    	if (IS_ERR(obj))
> > > > >    		return PTR_ERR(obj);
> > > > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> > > > > index 1ed7475de454..04f33d163340 100644
> > > > > --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> > > > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> > > > > @@ -21,6 +21,8 @@
> > > > >    #include "gt/intel_gt_pm.h"
> > > > >    #include "gt/intel_ring.h"
> > > > > +#include "pxp/intel_pxp.h"
> > > > > +
> > > > >    #include "i915_drv.h"
> > > > >    #include "i915_gem_clflush.h"
> > > > >    #include "i915_gem_context.h"
> > > > > @@ -751,6 +753,11 @@ static int eb_select_context(struct i915_execbuffer *eb)
> > > > >    	if (unlikely(IS_ERR(ctx)))
> > > > >    		return PTR_ERR(ctx);
> > > > > +	if (i915_gem_context_invalidated(ctx)) {
> > > > > +		i915_gem_context_put(ctx);
> > > > > +		return -EACCES;
> > > > > +	}
> > > > > +
> > > > >    	eb->gem_context = ctx;
> > > > >    	if (rcu_access_pointer(ctx->vm))
> > > > >    		eb->invalid_flags |= EXEC_OBJECT_NEEDS_GTT;
> > > > > @@ -819,7 +826,7 @@ static struct i915_vma *eb_lookup_vma(struct i915_execbuffer *eb, u32 handle)
> > > > >    	do {
> > > > >    		struct drm_i915_gem_object *obj;
> > > > >    		struct i915_vma *vma;
> > > > > -		int err;
> > > > > +		int err = 0;
> > > > >    		rcu_read_lock();
> > > > >    		vma = radix_tree_lookup(&eb->gem_context->handles_vma, handle);
> > > > > @@ -833,6 +840,26 @@ static struct i915_vma *eb_lookup_vma(struct i915_execbuffer *eb, u32 handle)
> > > > >    		if (unlikely(!obj))
> > > > >    			return ERR_PTR(-ENOENT);
> > > > > +		/*
> > > > > +		 * If the user has opted-in for protected-object tracking, make
> > > > > +		 * sure the object encryption can be used.
> > > > > +		 * We only need to do this when the object is first used with
> > > > > +		 * this context, because the context itself will be banned when
> > > > > +		 * the protected objects become invalid.
> > > > > +		 */
> > > > > +		if (i915_gem_context_uses_protected_content(eb->gem_context) &&
> > > > > +		    i915_gem_object_is_protected(obj)) {
> > > > > +			if (!intel_pxp_is_active(&vm->gt->pxp))
> > > > > +				err = -ENODEV;
> > > > > +			else if (!i915_gem_object_has_valid_protection(obj))
> > > > > +				err = -ENOEXEC;
> > > > > +
> > > > > +			if (err) {
> > > > > +				i915_gem_object_put(obj);
> > > > > +				return ERR_PTR(err);
> > > > > +			}
> > > > > +		}
> > > > > +
> > > > >    		vma = i915_vma_instance(obj, vm, NULL);
> > > > >    		if (IS_ERR(vma)) {
> > > > >    			i915_gem_object_put(obj);
> > > > > @@ -2752,6 +2779,17 @@ eb_select_engine(struct i915_execbuffer *eb)
> > > > >    	intel_gt_pm_get(ce->engine->gt);
> > > > > +	if (i915_gem_context_uses_protected_content(eb->gem_context)) {
> > > > > +		err = intel_pxp_wait_for_arb_start(&ce->engine->gt->pxp);
> > > > > +		if (err)
> > > > > +			goto err;
> > > > > +
> > > > > +		if (i915_gem_context_invalidated(eb->gem_context)) {
> > > > > +			err = -EACCES;
> > > > Shouldn't the normal banned context handling takee care of anything that
> > > > slips through? Rolling your own racy invalidation checks doesn't look like
> > > > a good idea.
> > > This is to bail out early and report the error to userspace. If the
> > > invalidation flag gets set after this check then we'll still catch it later
> > > as you said, but IMO there is value in bailing out early when possible,
> > > especially since it is a low-effort check. The invalidation flag can't be
> > > cleared, so no risk of rejecting something that shouldn't be.
> > Nah, that just papers over races and means you now have to validate more
> > code for correctness - the later catching still must happen, but it's now
> > much harder to trigger.
> > 
> > Also, the context banning should do this for us already. Maybe a good idea
> > to audit and document that, to make sure it's working correctly and we're
> > using it correctly for pxp, but this wheel should exist and we don't need
> > a new one.
> 
> Ok, I can rely on the intel_context being banned directly (it's checked
> earlier) but as mentioned above we do need but-in from mesa to drop the new
> invalidation flag at the gem_context level.
> 
> Daniele
> 
> > 
> > Except if the uapi promise is that we send back a different errno, but
> > that again should be integrated into the context banning stuff.
> > -Daniel
> > 
> > > Daniele
> > > 
> > > > > +			goto err;
> > > > > +		}
> > > > > +	}
> > > > > +
> > > > >    	if (!test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
> > > > >    		err = intel_context_alloc_state(ce);
> > > > >    		if (err)
> > > > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c
> > > > > index 6fb9afb65034..658a42a7fa07 100644
> > > > > --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
> > > > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
> > > > > @@ -25,6 +25,7 @@
> > > > >    #include <linux/sched/mm.h>
> > > > >    #include "display/intel_frontbuffer.h"
> > > > > +#include "pxp/intel_pxp.h"
> > > > >    #include "i915_drv.h"
> > > > >    #include "i915_gem_clflush.h"
> > > > >    #include "i915_gem_context.h"
> > > > > @@ -73,6 +74,8 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj,
> > > > >    	INIT_LIST_HEAD(&obj->lut_list);
> > > > >    	spin_lock_init(&obj->lut_lock);
> > > > > +	INIT_LIST_HEAD(&obj->pxp_link);
> > > > > +
> > > > >    	spin_lock_init(&obj->mmo.lock);
> > > > >    	obj->mmo.offsets = RB_ROOT;
> > > > > @@ -231,6 +234,9 @@ void __i915_gem_free_object(struct drm_i915_gem_object *obj)
> > > > >    		spin_unlock(&obj->vma.lock);
> > > > >    	}
> > > > > +	if (i915_gem_object_has_valid_protection(obj))
> > > > > +		intel_pxp_object_remove(obj);
> > > > > +
> > > > >    	__i915_gem_object_free_mmaps(obj);
> > > > >    	GEM_BUG_ON(!list_empty(&obj->lut_list));
> > > > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h
> > > > > index 48112b9d76df..137ae2723514 100644
> > > > > --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
> > > > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
> > > > > @@ -269,6 +269,18 @@ i915_gem_object_clear_tiling_quirk(struct drm_i915_gem_object *obj)
> > > > >    	clear_bit(I915_TILING_QUIRK_BIT, &obj->flags);
> > > > >    }
> > > > > +static inline bool
> > > > > +i915_gem_object_is_protected(const struct drm_i915_gem_object *obj)
> > > > > +{
> > > > > +	return obj->flags & I915_BO_PROTECTED;
> > > > > +}
> > > > > +
> > > > > +static inline bool
> > > > > +i915_gem_object_has_valid_protection(const struct drm_i915_gem_object *obj)
> > > > > +{
> > > > > +	return i915_gem_object_is_protected(obj) && !list_empty(&obj->pxp_link);
> > > > > +}
> > > > > +
> > > > >    static inline bool
> > > > >    i915_gem_object_type_has(const struct drm_i915_gem_object *obj,
> > > > >    			 unsigned long flags)
> > > > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> > > > > index 2471f36aaff3..38e4a190607a 100644
> > > > > --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> > > > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> > > > > @@ -298,6 +298,7 @@ struct drm_i915_gem_object {
> > > > >    			     I915_BO_ALLOC_USER)
> > > > >    #define I915_BO_READONLY         BIT(4)
> > > > >    #define I915_TILING_QUIRK_BIT    5 /* unknown swizzling; do not release! */
> > > > > +#define I915_BO_PROTECTED        BIT(6)
> > > > >    	/**
> > > > >    	 * @mem_flags - Mutable placement-related flags
> > > > > @@ -537,6 +538,14 @@ struct drm_i915_gem_object {
> > > > >    		bool created:1;
> > > > >    	} ttm;
> > > > > +	/*
> > > > > +	 * When the PXP session is invalidated, we need to mark all protected
> > > > > +	 * objects as invalid. To easily do so we add them all to a list. The
> > > > > +	 * presence on the list is used to check if the encryption is valid or
> > > > > +	 * not.
> > > > > +	 */
> > > > > +	struct list_head pxp_link;
> > > > > +
> > > > >    	/** Record of address bit 17 of each page at last unbind. */
> > > > >    	unsigned long *bit_17;
> > > > > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
> > > > > index b0c7edc10cc3..f418281e8c10 100644
> > > > > --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
> > > > > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
> > > > > @@ -7,6 +7,7 @@
> > > > >    #include "intel_pxp_irq.h"
> > > > >    #include "intel_pxp_session.h"
> > > > >    #include "intel_pxp_tee.h"
> > > > > +#include "gem/i915_gem_context.h"
> > > > >    #include "gt/intel_context.h"
> > > > >    #include "i915_drv.h"
> > > > > @@ -70,6 +71,9 @@ void intel_pxp_init(struct intel_pxp *pxp)
> > > > >    	mutex_init(&pxp->tee_mutex);
> > > > > +	spin_lock_init(&pxp->lock);
> > > > > +	INIT_LIST_HEAD(&pxp->protected_objects);
> > > > > +
> > > > >    	/*
> > > > >    	 * we'll use the completion to check if there is a termination pending,
> > > > >    	 * so we start it as completed and we reinit it when a termination
> > > > > @@ -166,3 +170,88 @@ void intel_pxp_fini_hw(struct intel_pxp *pxp)
> > > > >    	intel_pxp_irq_disable(pxp);
> > > > >    }
> > > > > +
> > > > > +int intel_pxp_object_add(struct drm_i915_gem_object *obj)
> > > > > +{
> > > > > +	struct intel_pxp *pxp = &to_i915(obj->base.dev)->gt.pxp;
> > > > > +
> > > > > +	if (!intel_pxp_is_enabled(pxp))
> > > > > +		return -ENODEV;
> > > > > +
> > > > > +	if (!list_empty(&obj->pxp_link))
> > > > > +		return -EEXIST;
> > > > > +
> > > > > +	spin_lock_irq(&pxp->lock);
> > > > > +	list_add(&obj->pxp_link, &pxp->protected_objects);
> > > > > +	spin_unlock_irq(&pxp->lock);
> > > > > +
> > > > > +	return 0;
> > > > > +}
> > > > > +
> > > > > +void intel_pxp_object_remove(struct drm_i915_gem_object *obj)
> > > > > +{
> > > > > +	struct intel_pxp *pxp = &to_i915(obj->base.dev)->gt.pxp;
> > > > > +
> > > > > +	if (!intel_pxp_is_enabled(pxp))
> > > > > +		return;
> > > > > +
> > > > > +	spin_lock_irq(&pxp->lock);
> > > > > +	list_del_init(&obj->pxp_link);
> > > > > +	spin_unlock_irq(&pxp->lock);
> > > > > +}
> > > > > +
> > > > > +void intel_pxp_invalidate(struct intel_pxp *pxp)
> > > > There is a lot of locking going on here. Please make sure it's all
> > > > properly documented what the rules are in kerneldoc, even for existing
> > > > stuff.
> > > > 
> > > > Especially anytime there's anything tricky going on, like:
> > > > - kref_get_unless_zero
> > > > - test_bit (that's an unorderd atomic, so either you don't actually need
> > > >     the atomic, or you need a pile of barriers and comments about them)
> > > > - hiddent atomic ops like intel_context_set_banned or
> > > >     i915_gem_context_set_invalid also need great care, least because the
> > > >     current rules aren't documented really. So step one here before using
> > > >     them is documenting the rules of how banning works.
> > > > 
> > > > > +{
> > > > > +	struct drm_i915_private *i915 = pxp_to_gt(pxp)->i915;
> > > > > +	struct drm_i915_gem_object *obj, *tmp;
> > > > > +	struct i915_gem_context *ctx, *cn;
> > > > > +
> > > > > +	/* delete objects that have been used with the invalidated session */
> > > > > +	spin_lock_irq(&pxp->lock);
> > > > > +	list_for_each_entry_safe(obj, tmp, &pxp->protected_objects, pxp_link) {
> > > > > +		if (i915_gem_object_has_pages(obj))
> > > > > +			list_del_init(&obj->pxp_link);
> > > > > +	}
> > > > > +	spin_unlock_irq(&pxp->lock);
> > > > > +
> > > > > +	/* 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) {
> > > > > +		struct i915_gem_engines_iter it;
> > > > > +		struct intel_context *ce;
> > > > > +
> > > > > +		if (!kref_get_unless_zero(&ctx->ref))
> > > > > +			continue;
> > > > > +
> > > > > +		if (likely(!i915_gem_context_uses_protected_content(ctx)) ||
> > > > > +		    i915_gem_context_invalidated(ctx)) {
> > > > > +			i915_gem_context_put(ctx);
> > > > > +			continue;
> > > > > +		}
> > > > > +
> > > > > +		spin_unlock_irq(&i915->gem.contexts.lock);
> > > > > +
> > > > > +		/*
> > > > > +		 * Note that by the time we get here the HW keys are already
> > > > > +		 * long gone, so any batch using them that's already on the
> > > > > +		 * engines is very likely a lost cause (and it has probably
> > > > > +		 * already hung the engine). Therefore, we skip attempting to
> > > > > +		 * pull the running context out of the HW and we prioritize
> > > > > +		 * bringing the session back as soon as possible.
> > > > > +		 */
> > > > > +		for_each_gem_engine(ce, i915_gem_context_lock_engines(ctx), it) {
> > > > > +			/* only invalidate if at least one ce was allocated */
> > > > > +			if (test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
> > > > > +				intel_context_set_banned(ce);
> > > > > +				i915_gem_context_set_invalid(ctx);
> > > > > +			}
> > > > > +		}
> > > > > +		i915_gem_context_unlock_engines(ctx);
> > > > > +
> > > > > +		spin_lock_irq(&i915->gem.contexts.lock);
> > > > > +		list_safe_reset_next(ctx, cn, link);
> > > > > +		i915_gem_context_put(ctx);
> > > > > +	}
> > > > > +	spin_unlock_irq(&i915->gem.contexts.lock);
> > > > > +}
> > > > > +
> > > > > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
> > > > > index 074b3b980957..4f7647f34153 100644
> > > > > --- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
> > > > > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
> > > > > @@ -9,6 +9,8 @@
> > > > >    #include "gt/intel_gt_types.h"
> > > > >    #include "intel_pxp_types.h"
> > > > > +struct drm_i915_gem_object;
> > > > > +
> > > > >    static inline struct intel_gt *pxp_to_gt(const struct intel_pxp *pxp)
> > > > >    {
> > > > >    	return container_of(pxp, struct intel_gt, pxp);
> > > > > @@ -33,6 +35,11 @@ void intel_pxp_fini_hw(struct intel_pxp *pxp);
> > > > >    void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp);
> > > > >    int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp);
> > > > > +
> > > > > +int intel_pxp_object_add(struct drm_i915_gem_object *obj);
> > > > > +void intel_pxp_object_remove(struct drm_i915_gem_object *obj);
> > > > > +
> > > > > +void intel_pxp_invalidate(struct intel_pxp *pxp);
> > > > >    #else
> > > > >    static inline void intel_pxp_init(struct intel_pxp *pxp)
> > > > >    {
> > > > > @@ -46,6 +53,14 @@ static inline int intel_pxp_wait_for_arb_start(struct intel_pxp *pxp)
> > > > >    {
> > > > >    	return 0;
> > > > >    }
> > > > > +
> > > > > +static inline int intel_pxp_object_add(struct drm_i915_gem_object *obj)
> > > > > +{
> > > > > +	return 0;
> > > > > +}
> > > > > +static inline void intel_pxp_object_remove(struct drm_i915_gem_object *obj)
> > > > > +{
> > > > > +}
> > > > >    #endif
> > > > >    #endif /* __INTEL_PXP_H__ */
> > > > > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> > > > > index 67c30e534d50..0edd563a653d 100644
> > > > > --- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> > > > > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> > > > > @@ -85,6 +85,9 @@ static int pxp_terminate_arb_session_and_global(struct intel_pxp *pxp)
> > > > >    	/* must mark termination in progress calling this function */
> > > > >    	GEM_WARN_ON(pxp->arb_is_valid);
> > > > > +	/* invalidate protected objects */
> > > > > +	intel_pxp_invalidate(pxp);
> > > > > +
> > > > >    	/* terminate the hw sessions */
> > > > >    	ret = intel_pxp_terminate_session(pxp, ARB_SESSION);
> > > > >    	if (ret) {
> > > > > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
> > > > > index 475e3312c287..be2bed3a2e4e 100644
> > > > > --- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
> > > > > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
> > > > > @@ -7,7 +7,9 @@
> > > > >    #define __INTEL_PXP_TYPES_H__
> > > > >    #include <linux/completion.h>
> > > > > +#include <linux/list.h>
> > > > >    #include <linux/mutex.h>
> > > > > +#include <linux/spinlock.h>
> > > > >    #include <linux/types.h>
> > > > >    #include <linux/workqueue.h>
> > > > > @@ -43,6 +45,9 @@ struct intel_pxp {
> > > > >    	u32 session_events; /* protected with gt->irq_lock */
> > > > >    #define PXP_TERMINATION_REQUEST  BIT(0)
> > > > >    #define PXP_TERMINATION_COMPLETE BIT(1)
> > > > > +
> > > > > +	spinlock_t lock; /* protects the objects list */
> > > > > +	struct list_head protected_objects;
> > > > >    };
> > > > >    #endif /* __INTEL_PXP_TYPES_H__ */
> > > > > diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
> > > > > index 4393eef59d9b..2c9febdae6a5 100644
> > > > > --- a/include/uapi/drm/i915_drm.h
> > > > > +++ b/include/uapi/drm/i915_drm.h
> > > > > @@ -1843,12 +1843,32 @@ struct drm_i915_gem_context_param {
> > > > >     * attempted to use it, never re-use this context param number.
> > > > >     */
> > > > >    #define I915_CONTEXT_PARAM_RINGSIZE	0xc
> > > > > +
> > > > > +/*
> > > > > + * I915_CONTEXT_PARAM_PROTECTED_CONTENT:
> > > > > + *
> > > > > + * Mark that the context makes use of protected content, which will result
> > > > > + * in the context being invalidated when the protected content session is. The
> > > > > + * invalidation is reported back to userspace via the RESET_STATS ioctl (see
> > > > > + * relevant doc for details).
> > > > > + * This flag can only be set at context creation time and, when set to true,
> > > > > + * must be preceded by an explicit setting of I915_CONTEXT_PARAM_RECOVERABLE
> > > > > + * to false. This flag can't be set to true in conjunction with setting the
> > > > > + * I915_CONTEXT_PARAM_BANNABLE flag to false.
> > > > > + *
> > > > > + * In addition to the normal failure cases, setting this flag during context
> > > > > + * creation can result in the following errors:
> > > > > + *
> > > > > + * -ENODEV: feature not available
> > > > > + * -EPERM: trying to mark a recoverable or not bannable context as protected
> > > > > + */
> > > > > +#define I915_CONTEXT_PARAM_PROTECTED_CONTENT    0xd
> > > > >    /* Must be kept compact -- no holes and well documented */
> > > > >    	__u64 value;
> > > > >    };
> > > > > -/*
> > > > > +/**
> > > > >     * Context SSEU programming
> > > > >     *
> > > > >     * It may be necessary for either functional or performance reason to configure
> > > > > @@ -2181,6 +2201,12 @@ struct drm_i915_reg_read {
> > > > >    struct drm_i915_reset_stats {
> > > > >    	__u32 ctx_id;
> > > > >    	__u32 flags;
> > > > > +	/*
> > > > > +	 * contexts marked as using protected content are invalidated when the
> > > > > +	 * protected content session dies. Submission of invalidated contexts
> > > > > +	 * is rejected with -EACCES.
> > > > > +	 */
> > > > > +#define I915_CONTEXT_INVALIDATED 0x1
> > > > >    	/* All resets since boot/module reload, for all contexts */
> > > > >    	__u32 reset_count;
> > > > > @@ -2959,8 +2985,12 @@ struct drm_i915_gem_create_ext {
> > > > >    	 *
> > > > >    	 * For I915_GEM_CREATE_EXT_MEMORY_REGIONS usage see
> > > > >    	 * struct drm_i915_gem_create_ext_memory_regions.
> > > > > +	 *
> > > > > +	 * For I915_GEM_CREATE_EXT_PROTECTED_CONTENT usage see
> > > > > +	 * struct drm_i915_gem_create_ext_protected_content.
> > > > >    	 */
> > > > >    #define I915_GEM_CREATE_EXT_MEMORY_REGIONS 0
> > > > > +#define I915_GEM_CREATE_EXT_PROTECTED_CONTENT 1
> > > > >    	__u64 extensions;
> > > > >    };
> > > > > @@ -3018,6 +3048,29 @@ struct drm_i915_gem_create_ext_memory_regions {
> > > > >    	__u64 regions;
> > > > >    };
> > > > > +/**
> > > > > + * struct drm_i915_gem_create_ext_protected_content - The
> > > > > + * I915_OBJECT_PARAM_PROTECTED_CONTENT extension.
> > > > > + *
> > > > > + * If this extension is provided, buffer contents are expected to be protected
> > > > > + * by PXP encryption and require decryption for scan out and processing. This
> > > > > + * is only possible on platforms that have PXP enabled, on all other scenarios
> > > > > + * using this extension will cause the ioctl to fail and return -ENODEV. The
> > > > > + * flags parameter is reserved for future expansion and must currently be set
> > > > > + * to zero.
> > > > > + *
> > > > > + * The buffer contents are considered invalid after a PXP session teardown.
> > > > > + *
> > > > > + * The encryption is guaranteed to be processed correctly only if the object
> > > > > + * is submitted with a context created using the
> > > > > + * I915_CONTEXT_PARAM_PROTECTED_CONTENT flag. This will also enable extra checks
> > > > > + * at submission time on the validity of the objects involved.
> > > > > + */
> > > > > +struct drm_i915_gem_create_ext_protected_content {
> > > > > +	struct i915_user_extension base;
> > > > > +	__u32 flags;
> > > > > +};
> > > > > +
> > > > >    /* ID of the protected content session managed by i915 when PXP is active */
> > > > >    #define I915_PROTECTED_CONTENT_DEFAULT_SESSION 0xf
> > > > > -- 
> > > > > 2.32.0
> > > > > 
> > > > > _______________________________________________
> > > > > Intel-gfx mailing list
> > > > > Intel-gfx@lists.freedesktop.org
> > > > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Intel-gfx] [PATCH v6 13/15] drm/i915/pxp: Add plane decryption support
  2021-08-12  8:17   ` Anshuman Gupta
@ 2021-08-23  7:50     ` Shankar, Uma
  0 siblings, 0 replies; 64+ messages in thread
From: Shankar, Uma @ 2021-08-23  7:50 UTC (permalink / raw)
  To: Gupta, Anshuman, intel-gfx
  Cc: Bommu, Krishnaiah, Huang Sean Z, Gaurav, Kumar,
	Ville Syrjälä,
	Ceraolo Spurio, Daniele, Li, Juston, Vivi, Rodrigo



> -----Original Message-----
> From: Gupta, Anshuman <anshuman.gupta@intel.com>
> Sent: Thursday, August 12, 2021 1:47 PM
> To: intel-gfx@lists.freedesktop.org
> Cc: Shankar, Uma <uma.shankar@intel.com>; Gupta, Anshuman
> <anshuman.gupta@intel.com>; Bommu, Krishnaiah
> <krishnaiah.bommu@intel.com>; Huang Sean Z <sean.z.huang@intel.com>; Gaurav,
> Kumar <kumar.gaurav@intel.com>; Ville Syrjälä <ville.syrjala@linux.intel.com>;
> Ceraolo Spurio, Daniele <daniele.ceraolospurio@intel.com>; Li, Juston
> <juston.li@intel.com>; Vivi, Rodrigo <rodrigo.vivi@intel.com>
> Subject: [PATCH v6 13/15] drm/i915/pxp: Add plane decryption support
> 
> Add support to enable/disable PLANE_SURF Decryption Request bit.
> It requires only to enable plane decryption support when following condition met.
> 1. PXP session is enabled.
> 2. Buffer object is protected.
> 
> v2:
> - Used gen fb obj user_flags instead gem_object_metadata. [Krishna]
> 
> v3:
> - intel_pxp_gem_object_status() API changes.
> 
> v4: use intel_pxp_is_active (Daniele)
> 
> v5: rebase and use the new protected object status checker (Daniele)
> 
> v6: used plane state for plane_decryption to handle async flip
>     as suggested by Ville.
> 
> v7: check pxp session while plane decrypt state computation. [Ville]
>     removed pointless code. [Ville]
> 
> v8 (Daniele): update PXP check
> 
> v9: move decrypt check after icl_check_nv12_planes() when overlays
>     have fb set (Juston)

Looks Good to me.
Reviewed-by: Uma Shankar <uma.shankar@intel.com>

> Cc: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
> Cc: Huang Sean Z <sean.z.huang@intel.com>
> Cc: Gaurav Kumar <kumar.gaurav@intel.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Anshuman Gupta <anshuman.gupta@intel.com>
> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
> Signed-off-by: Juston Li <juston.li@intel.com>
> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_display.c  | 27 +++++++++++++++++++
>  .../drm/i915/display/intel_display_types.h    |  3 +++
>  .../drm/i915/display/skl_universal_plane.c    | 15 ++++++++---
>  drivers/gpu/drm/i915/i915_reg.h               |  1 +
>  4 files changed, 43 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> b/drivers/gpu/drm/i915/display/intel_display.c
> index b25c596f6f7e..accdd6614681 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -70,6 +70,8 @@
>  #include "gt/intel_rps.h"
>  #include "gt/gen8_ppgtt.h"
> 
> +#include "pxp/intel_pxp.h"
> +
>  #include "g4x_dp.h"
>  #include "g4x_hdmi.h"
>  #include "i915_drv.h"
> @@ -9610,13 +9612,24 @@ static int intel_bigjoiner_add_affected_planes(struct
> intel_atomic_state *state)
>  	return 0;
>  }
> 
> +static int bo_has_valid_encryption(const struct drm_i915_gem_object
> +*obj) {
> +        struct drm_i915_private *i915 = to_i915(obj->base.dev);
> +
> +        return i915_gem_object_has_valid_protection(obj) &&
> +               intel_pxp_is_active(&i915->gt.pxp);
> +}
> +
>  static int intel_atomic_check_planes(struct intel_atomic_state *state)  {
>  	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
>  	struct intel_crtc_state *old_crtc_state, *new_crtc_state;
>  	struct intel_plane_state *plane_state;
>  	struct intel_plane *plane;
> +	struct intel_plane_state *new_plane_state;
> +	struct intel_plane_state *old_plane_state;
>  	struct intel_crtc *crtc;
> +	const struct drm_framebuffer *fb;
>  	int i, ret;
> 
>  	ret = icl_add_linked_planes(state);
> @@ -9664,6 +9677,16 @@ static int intel_atomic_check_planes(struct
> intel_atomic_state *state)
>  			return ret;
>  	}
> 
> +	for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
> +		new_plane_state = intel_atomic_get_new_plane_state(state,
> plane);
> +		old_plane_state = intel_atomic_get_old_plane_state(state, plane);
> +		fb = new_plane_state->hw.fb;
> +		if (fb)
> +			new_plane_state->decrypt =
> bo_has_valid_encryption(intel_fb_obj(fb));
> +		else
> +			new_plane_state->decrypt = old_plane_state->decrypt;
> +        }
> +
>  	return 0;
>  }
> 
> @@ -9950,6 +9973,10 @@ static int intel_atomic_check_async(struct
> intel_atomic_state *state)
>  			drm_dbg_kms(&i915->drm, "Color range cannot be
> changed in async flip\n");
>  			return -EINVAL;
>  		}
> +
> +		/* plane decryption is allow to change only in synchronous flips */
> +		if (old_plane_state->decrypt != new_plane_state->decrypt)
> +			return -EINVAL;
>  	}
> 
>  	return 0;
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h
> b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 6beeeeba1bed..53b5db3c6228 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -629,6 +629,9 @@ struct intel_plane_state {
> 
>  	struct intel_fb_view view;
> 
> +	/* Plane pxp decryption state */
> +	bool decrypt;
> +
>  	/* plane control register */
>  	u32 ctl;
> 
> diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c
> b/drivers/gpu/drm/i915/display/skl_universal_plane.c
> index 724e7b04f3b6..55e3f093b951 100644
> --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
> +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
> @@ -18,6 +18,7 @@
>  #include "intel_sprite.h"
>  #include "skl_scaler.h"
>  #include "skl_universal_plane.h"
> +#include "pxp/intel_pxp.h"
> 
>  static const u32 skl_plane_formats[] = {
>  	DRM_FORMAT_C8,
> @@ -1024,7 +1025,7 @@ skl_program_plane(struct intel_plane *plane,
>  	u8 alpha = plane_state->hw.alpha >> 8;
>  	u32 plane_color_ctl = 0, aux_dist = 0;
>  	unsigned long irqflags;
> -	u32 keymsk, keymax;
> +	u32 keymsk, keymax, plane_surf;
>  	u32 plane_ctl = plane_state->ctl;
> 
>  	plane_ctl |= skl_plane_ctl_crtc(crtc_state); @@ -1113,8 +1114,16 @@
> skl_program_plane(struct intel_plane *plane,
>  	 * the control register just before the surface register.
>  	 */
>  	intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), plane_ctl);
> -	intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id),
> -			  intel_plane_ggtt_offset(plane_state) + surf_addr);
> +	plane_surf = intel_plane_ggtt_offset(plane_state) + surf_addr;
> +
> +	/*
> +	 * FIXME: pxp session invalidation can hit any time even at time of commit
> +	 * or after the commit, display content will be garbage.
> +	 */
> +	if (plane_state->decrypt)
> +		plane_surf |= PLANE_SURF_DECRYPT;
> +
> +	intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), plane_surf);
> 
>  	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);  } diff --git
> a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index
> f76eaed8e855..57f22f54d9f7 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -7347,6 +7347,7 @@ enum {
>  #define _PLANE_SURF_3(pipe)	_PIPE(pipe, _PLANE_SURF_3_A,
> _PLANE_SURF_3_B)
>  #define PLANE_SURF(pipe, plane)	\
>  	_MMIO_PLANE(plane, _PLANE_SURF_1(pipe), _PLANE_SURF_2(pipe))
> +#define   PLANE_SURF_DECRYPT			REG_BIT(2)
> 
>  #define _PLANE_OFFSET_1_B			0x711a4
>  #define _PLANE_OFFSET_2_B			0x712a4
> --
> 2.26.2


^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Intel-gfx] [PATCH v6 14/15] drm/i915/pxp: black pixels on pxp disabled
  2021-08-12  8:20   ` Anshuman Gupta
@ 2021-08-23  7:56     ` Shankar, Uma
  0 siblings, 0 replies; 64+ messages in thread
From: Shankar, Uma @ 2021-08-23  7:56 UTC (permalink / raw)
  To: Gupta, Anshuman, intel-gfx
  Cc: Ville Syrjälä,
	Gaurav,  Kumar, Ceraolo Spurio, Daniele, Li, Juston, Vivi,
	 Rodrigo



> -----Original Message-----
> From: Gupta, Anshuman <anshuman.gupta@intel.com>
> Sent: Thursday, August 12, 2021 1:50 PM
> To: intel-gfx@lists.freedesktop.org
> Cc: Shankar, Uma <uma.shankar@intel.com>; Gupta, Anshuman
> <anshuman.gupta@intel.com>; Ville Syrjälä <ville.syrjala@linux.intel.com>; Gaurav,
> Kumar <kumar.gaurav@intel.com>; Ceraolo Spurio, Daniele
> <daniele.ceraolospurio@intel.com>; Li, Juston <juston.li@intel.com>; Vivi, Rodrigo
> <rodrigo.vivi@intel.com>
> Subject: [PATCH v6 14/15] drm/i915/pxp: black pixels on pxp disabled
> 
> When protected sufaces has flipped and pxp session is disabled, display black pixels
> by using plane color CTM correction.
> 
> v2:
> - Display black pixels in async flip too.
> 
> v3:
> - Removed the black pixels logic for async flip. [Ville]
> - Used plane state to force black pixels. [Ville]
> 
> v4 (Daniele): update pxp_is_borked check.
> 
> v5: rebase on top of v9 plane decryption moving the decrypt check
>     (Juston)

Looks Good to me.
Reviewed-by: Uma Shankar <uma.shankar@intel.com>

> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Gaurav Kumar <kumar.gaurav@intel.com>
> Cc: Shankar Uma <uma.shankar@intel.com>
> Signed-off-by: Anshuman Gupta <anshuman.gupta@intel.com>
> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
> Signed-off-by: Juston Li <juston.li@intel.com>
> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_display.c  | 12 ++++-
>  .../drm/i915/display/intel_display_types.h    |  3 ++
>  .../drm/i915/display/skl_universal_plane.c    | 36 ++++++++++++++-
>  drivers/gpu/drm/i915/i915_reg.h               | 46 +++++++++++++++++++
>  4 files changed, 94 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> b/drivers/gpu/drm/i915/display/intel_display.c
> index accdd6614681..c6babb47471e 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -9620,6 +9620,11 @@ static int bo_has_valid_encryption(const struct
> drm_i915_gem_object *obj)
>                 intel_pxp_is_active(&i915->gt.pxp);
>  }
> 
> +static bool pxp_is_borked(const struct drm_i915_gem_object *obj) {
> +	return i915_gem_object_is_protected(obj) &&
> +!bo_has_valid_encryption(obj); }
> +
>  static int intel_atomic_check_planes(struct intel_atomic_state *state)  {
>  	struct drm_i915_private *dev_priv = to_i915(state->base.dev); @@ -
> 9681,10 +9686,13 @@ static int intel_atomic_check_planes(struct
> intel_atomic_state *state)
>  		new_plane_state = intel_atomic_get_new_plane_state(state,
> plane);
>  		old_plane_state = intel_atomic_get_old_plane_state(state, plane);
>  		fb = new_plane_state->hw.fb;
> -		if (fb)
> +		if (fb) {
>  			new_plane_state->decrypt =
> bo_has_valid_encryption(intel_fb_obj(fb));
> -		else
> +			new_plane_state->force_black =
> pxp_is_borked(intel_fb_obj(fb));
> +		} else {
>  			new_plane_state->decrypt = old_plane_state->decrypt;
> +			new_plane_state->force_black = old_plane_state-
> >force_black;
> +		}
>          }
> 
>  	return 0;
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h
> b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 53b5db3c6228..0fe03ef57023 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -632,6 +632,9 @@ struct intel_plane_state {
>  	/* Plane pxp decryption state */
>  	bool decrypt;
> 
> +	/* Plane state to display black pixels when pxp is borked */
> +	bool force_black;
> +
>  	/* plane control register */
>  	u32 ctl;
> 
> diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c
> b/drivers/gpu/drm/i915/display/skl_universal_plane.c
> index 55e3f093b951..c4adcb3e12b3 100644
> --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
> +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
> @@ -1002,6 +1002,33 @@ static u32 skl_surf_address(const struct
> intel_plane_state *plane_state,
>  	}
>  }
> 
> +static void intel_load_plane_csc_black(struct intel_plane *intel_plane)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(intel_plane->base.dev);
> +	enum pipe pipe = intel_plane->pipe;
> +	enum plane_id plane = intel_plane->id;
> +	u16 postoff = 0;
> +
> +	drm_dbg_kms(&dev_priv->drm, "plane color CTM to black  %s:%d\n",
> +		    intel_plane->base.name, plane);
> +	intel_de_write_fw(dev_priv, PLANE_CSC_COEFF(pipe, plane, 0), 0);
> +	intel_de_write_fw(dev_priv, PLANE_CSC_COEFF(pipe, plane, 1), 0);
> +
> +	intel_de_write_fw(dev_priv, PLANE_CSC_COEFF(pipe, plane, 2), 0);
> +	intel_de_write_fw(dev_priv, PLANE_CSC_COEFF(pipe, plane, 3), 0);
> +
> +	intel_de_write_fw(dev_priv, PLANE_CSC_COEFF(pipe, plane, 4), 0);
> +	intel_de_write_fw(dev_priv, PLANE_CSC_COEFF(pipe, plane, 5), 0);
> +
> +	intel_de_write_fw(dev_priv, PLANE_CSC_PREOFF(pipe, plane, 0), 0);
> +	intel_de_write_fw(dev_priv, PLANE_CSC_PREOFF(pipe, plane, 1), 0);
> +	intel_de_write_fw(dev_priv, PLANE_CSC_PREOFF(pipe, plane, 2), 0);
> +
> +	intel_de_write_fw(dev_priv, PLANE_CSC_POSTOFF(pipe, plane, 0), postoff);
> +	intel_de_write_fw(dev_priv, PLANE_CSC_POSTOFF(pipe, plane, 1), postoff);
> +	intel_de_write_fw(dev_priv, PLANE_CSC_POSTOFF(pipe, plane, 2),
> +postoff); }
> +
>  static void
>  skl_program_plane(struct intel_plane *plane,
>  		  const struct intel_crtc_state *crtc_state, @@ -1115,14 +1142,21
> @@ skl_program_plane(struct intel_plane *plane,
>  	 */
>  	intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), plane_ctl);
>  	plane_surf = intel_plane_ggtt_offset(plane_state) + surf_addr;
> +	plane_color_ctl = intel_de_read_fw(dev_priv, PLANE_COLOR_CTL(pipe,
> +plane_id));
> 
>  	/*
>  	 * FIXME: pxp session invalidation can hit any time even at time of commit
>  	 * or after the commit, display content will be garbage.
>  	 */
> -	if (plane_state->decrypt)
> +	if (plane_state->decrypt) {
>  		plane_surf |= PLANE_SURF_DECRYPT;
> +	} else if (plane_state->force_black) {
> +		intel_load_plane_csc_black(plane);
> +		plane_color_ctl |= PLANE_COLOR_PLANE_CSC_ENABLE;
> +	}
> 
> +	intel_de_write_fw(dev_priv, PLANE_COLOR_CTL(pipe, plane_id),
> +			  plane_color_ctl);
>  	intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), plane_surf);
> 
>  	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); diff --git
> a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index
> 57f22f54d9f7..db714ea91997 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -7224,6 +7224,7 @@ enum {
>  #define _PLANE_COLOR_CTL_3_A			0x703CC /* GLK+ */
>  #define   PLANE_COLOR_PIPE_GAMMA_ENABLE		(1 << 30) /* Pre-ICL */
>  #define   PLANE_COLOR_YUV_RANGE_CORRECTION_DISABLE	(1 << 28)
> +#define   PLANE_COLOR_PLANE_CSC_ENABLE			REG_BIT(21) /*
> ICL+ */
>  #define   PLANE_COLOR_INPUT_CSC_ENABLE		(1 << 20) /* ICL+ */
>  #define   PLANE_COLOR_PIPE_CSC_ENABLE		(1 << 23) /* Pre-ICL */
>  #define   PLANE_COLOR_CSC_MODE_BYPASS			(0 << 17)
> @@ -11341,6 +11342,51 @@ enum skl_power_gate {
>  					_PAL_PREC_MULTI_SEG_DATA_A, \
>  					_PAL_PREC_MULTI_SEG_DATA_B)
> 
> +#define _MMIO_PLANE_GAMC(plane, i, a, b)  _MMIO(_PIPE(plane, a, b) +
> +(i) * 4)
> +
> +/* Plane CSC Registers */
> +#define _PLANE_CSC_RY_GY_1_A	0x70210
> +#define _PLANE_CSC_RY_GY_2_A	0x70310
> +
> +#define _PLANE_CSC_RY_GY_1_B	0x71210
> +#define _PLANE_CSC_RY_GY_2_B	0x71310
> +
> +#define _PLANE_CSC_RY_GY_1(pipe)	_PIPE(pipe, _PLANE_CSC_RY_GY_1_A, \
> +					      _PLANE_CSC_RY_GY_1_B)
> +#define _PLANE_CSC_RY_GY_2(pipe)	_PIPE(pipe,
> _PLANE_INPUT_CSC_RY_GY_2_A, \
> +					      _PLANE_INPUT_CSC_RY_GY_2_B)
> +#define PLANE_CSC_COEFF(pipe, plane, index)	_MMIO_PLANE(plane, \
> +
> _PLANE_CSC_RY_GY_1(pipe) +  (index) * 4, \
> +
> _PLANE_CSC_RY_GY_2(pipe) + (index) * 4)
> +
> +#define _PLANE_CSC_PREOFF_HI_1_A		0x70228
> +#define _PLANE_CSC_PREOFF_HI_2_A		0x70328
> +
> +#define _PLANE_CSC_PREOFF_HI_1_B		0x71228
> +#define _PLANE_CSC_PREOFF_HI_2_B		0x71328
> +
> +#define _PLANE_CSC_PREOFF_HI_1(pipe)	_PIPE(pipe,
> _PLANE_CSC_PREOFF_HI_1_A, \
> +					      _PLANE_CSC_PREOFF_HI_1_B)
> +#define _PLANE_CSC_PREOFF_HI_2(pipe)	_PIPE(pipe,
> _PLANE_CSC_PREOFF_HI_2_A, \
> +					      _PLANE_CSC_PREOFF_HI_2_B)
> +#define PLANE_CSC_PREOFF(pipe, plane, index)	_MMIO_PLANE(plane,
> _PLANE_CSC_PREOFF_HI_1(pipe) + \
> +							    (index) * 4,
> _PLANE_CSC_PREOFF_HI_2(pipe) + \
> +							    (index) * 4)
> +
> +#define _PLANE_CSC_POSTOFF_HI_1_A		0x70234
> +#define _PLANE_CSC_POSTOFF_HI_2_A		0x70334
> +
> +#define _PLANE_CSC_POSTOFF_HI_1_B		0x71234
> +#define _PLANE_CSC_POSTOFF_HI_2_B		0x71334
> +
> +#define _PLANE_CSC_POSTOFF_HI_1(pipe)	_PIPE(pipe,
> _PLANE_CSC_POSTOFF_HI_1_A, \
> +					      _PLANE_CSC_POSTOFF_HI_1_B)
> +#define _PLANE_CSC_POSTOFF_HI_2(pipe)	_PIPE(pipe,
> _PLANE_CSC_POSTOFF_HI_2_A, \
> +					      _PLANE_CSC_POSTOFF_HI_2_B)
> +#define PLANE_CSC_POSTOFF(pipe, plane, index)	_MMIO_PLANE(plane,
> _PLANE_CSC_POSTOFF_HI_1(pipe) + \
> +							    (index) * 4,
> _PLANE_CSC_POSTOFF_HI_2(pipe) + \
> +							    (index) * 4)
> +
>  /* pipe CSC & degamma/gamma LUTs on CHV */
>  #define _CGM_PIPE_A_CSC_COEFF01	(VLV_DISPLAY_BASE + 0x67900)
>  #define _CGM_PIPE_A_CSC_COEFF23	(VLV_DISPLAY_BASE + 0x67904)
> --
> 2.26.2


^ permalink raw reply	[flat|nested] 64+ messages in thread

end of thread, other threads:[~2021-08-23  7:57 UTC | newest]

Thread overview: 64+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-29  2:00 [PATCH v6 00/15] drm/i915: Introduce Intel PXP Daniele Ceraolo Spurio
2021-07-29  2:00 ` [Intel-gfx] " Daniele Ceraolo Spurio
2021-07-29  2:00 ` [PATCH v6 01/15] drm/i915/pxp: Define PXP component interface Daniele Ceraolo Spurio
2021-07-29  2:00   ` [Intel-gfx] " Daniele Ceraolo Spurio
2021-08-13  7:51   ` Jani Nikula
2021-07-29  2:00 ` [PATCH v6 02/15] mei: pxp: export pavp client to me client bus Daniele Ceraolo Spurio
2021-07-29  2:00   ` [Intel-gfx] " Daniele Ceraolo Spurio
2021-07-29 20:45   ` Rodrigo Vivi
2021-07-29 20:45     ` [Intel-gfx] " Rodrigo Vivi
2021-07-29  2:00 ` [PATCH v6 03/15] drm/i915/pxp: define PXP device flag and kconfig Daniele Ceraolo Spurio
2021-07-29  2:00   ` [Intel-gfx] " Daniele Ceraolo Spurio
2021-07-29  2:00 ` [PATCH v6 04/15] drm/i915/pxp: allocate a vcs context for pxp usage Daniele Ceraolo Spurio
2021-07-29  2:00   ` [Intel-gfx] " Daniele Ceraolo Spurio
2021-07-29  2:00 ` [PATCH v6 05/15] drm/i915/pxp: Implement funcs to create the TEE channel Daniele Ceraolo Spurio
2021-07-29  2:00   ` [Intel-gfx] " Daniele Ceraolo Spurio
2021-07-29  2:00 ` [PATCH v6 06/15] drm/i915/pxp: set KCR reg init Daniele Ceraolo Spurio
2021-07-29  2:00   ` [Intel-gfx] " Daniele Ceraolo Spurio
2021-07-29  2:00 ` [PATCH v6 07/15] drm/i915/pxp: Create the arbitrary session after boot Daniele Ceraolo Spurio
2021-07-29  2:00   ` [Intel-gfx] " Daniele Ceraolo Spurio
2021-07-29  2:00 ` [PATCH v6 08/15] drm/i915/pxp: Implement arb session teardown Daniele Ceraolo Spurio
2021-07-29  2:00   ` [Intel-gfx] " Daniele Ceraolo Spurio
2021-07-29  2:01 ` [PATCH v6 09/15] drm/i915/pxp: Implement PXP irq handler Daniele Ceraolo Spurio
2021-07-29  2:01   ` [Intel-gfx] " Daniele Ceraolo Spurio
2021-08-13 14:28   ` Daniel Vetter
2021-07-29  2:01 ` [PATCH v6 10/15] drm/i915/pxp: interfaces for using protected objects Daniele Ceraolo Spurio
2021-07-29  2:01   ` [Intel-gfx] " Daniele Ceraolo Spurio
2021-07-29 11:10   ` Rodrigo Vivi
2021-07-29 11:10     ` [Intel-gfx] " Rodrigo Vivi
2021-07-29 15:17     ` Daniele Ceraolo Spurio
2021-07-29 15:17       ` [Intel-gfx] " Daniele Ceraolo Spurio
2021-07-29 20:40       ` Rodrigo Vivi
2021-07-29 20:40         ` [Intel-gfx] " Rodrigo Vivi
2021-08-13 14:37   ` Daniel Vetter
2021-08-13 14:42     ` Daniel Vetter
2021-08-13 15:24       ` Daniele Ceraolo Spurio
2021-08-16 15:29         ` Daniel Vetter
2021-08-13 15:18     ` Daniele Ceraolo Spurio
2021-08-16 15:15       ` Daniel Vetter
2021-08-16 15:58         ` Daniele Ceraolo Spurio
2021-08-17  9:02           ` Daniel Vetter
2021-07-29  2:01 ` [PATCH v6 11/15] drm/i915/pxp: start the arb session on demand Daniele Ceraolo Spurio
2021-07-29  2:01   ` [Intel-gfx] " Daniele Ceraolo Spurio
2021-07-29  2:01 ` [PATCH v6 12/15] drm/i915/pxp: Enable PXP power management Daniele Ceraolo Spurio
2021-07-29  2:01   ` [Intel-gfx] " Daniele Ceraolo Spurio
2021-07-29  2:01 ` [PATCH v6 13/15] drm/i915/pxp: Add plane decryption support Daniele Ceraolo Spurio
2021-07-29  2:01   ` [Intel-gfx] " Daniele Ceraolo Spurio
2021-08-12  8:17   ` Anshuman Gupta
2021-08-23  7:50     ` Shankar, Uma
2021-07-29  2:01 ` [PATCH v6 14/15] drm/i915/pxp: black pixels on pxp disabled Daniele Ceraolo Spurio
2021-07-29  2:01   ` [Intel-gfx] " Daniele Ceraolo Spurio
2021-08-12  8:20   ` Anshuman Gupta
2021-08-23  7:56     ` Shankar, Uma
2021-07-29  2:01 ` [PATCH v6 15/15] drm/i915/pxp: enable PXP for integrated Gen12 Daniele Ceraolo Spurio
2021-07-29  2:01   ` [Intel-gfx] " Daniele Ceraolo Spurio
2021-07-29  3:16 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Introduce Intel PXP (rev2) Patchwork
2021-07-29  3:17 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2021-07-29  3:21 ` [Intel-gfx] ✗ Fi.CI.DOCS: " Patchwork
2021-07-29  3:43 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2021-07-29  9:55 ` [Intel-gfx] ✓ Fi.CI.IGT: " Patchwork
2021-08-12 12:07 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Introduce Intel PXP (rev4) Patchwork
2021-08-12 12:09 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2021-08-12 12:13 ` [Intel-gfx] ✗ Fi.CI.DOCS: " Patchwork
2021-08-12 12:37 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2021-08-12 14:59 ` [Intel-gfx] ✗ Fi.CI.IGT: failure " Patchwork

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.