intel-gfx.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* [Intel-gfx] [PATCH v2 00/16] Introduce Intel PXP
@ 2021-03-01 19:31 Daniele Ceraolo Spurio
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 01/16] drm/i915/pxp: Define PXP component interface Daniele Ceraolo Spurio
                   ` (19 more replies)
  0 siblings, 20 replies; 47+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-03-01 19:31 UTC (permalink / raw)
  To: intel-gfx; +Cc: Alan Previn, Gaurav Kumar, Chris Wilson

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.

Several major functional changes compared to v1:
- Termination is issued on runtime resume as well.
- Protected objects and contexts are marked as invalid on termination.
  Invalid contexts are reported to userspace via RESET_STATS.
- Trying to flip an invalid objects results in a black frame.

I've done more testing compared to v1 (initial IGTs from Alan will be
hitting the ML soon), but I still haven't stress-tested with userspace
applications, so there might be bugs. I'll make sure to run more testing
and fix everything before merge, but in the meantime I wanted to get
forward with the reviews given that the current tests give me enough
confidence that this isn't completely broken.

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>

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

Bommu Krishnaiah (2):
  drm/i915/uapi: introduce drm_i915_gem_create_ext
  drm/i915/pxp: User interface for Protected buffer

Daniele Ceraolo Spurio (6):
  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 during the boot time
  drm/i915/pxp: interface for creation of protected contexts
  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 +
 .../drm/i915/display/skl_universal_plane.c    |  50 +++-
 drivers/gpu/drm/i915/gem/i915_gem_context.c   |  59 ++++-
 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    |  68 +++++-
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c    |  23 ++
 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  |  13 +
 drivers/gpu/drm/i915/gt/intel_engine.h        |  10 +
 drivers/gpu/drm/i915/gt/intel_engine_cs.c     |  19 +-
 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         |  14 +-
 drivers/gpu/drm/i915/gt/intel_gt_types.h      |   3 +
 drivers/gpu/drm/i915/i915_drv.c               |   4 +-
 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          | 215 ++++++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp.h          |  70 ++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c      | 166 +++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h      |  15 ++
 drivers/gpu/drm/i915/pxp/intel_pxp_irq.c      | 153 ++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_irq.h      |  33 +++
 drivers/gpu/drm/i915/pxp/intel_pxp_pm.c       |  99 ++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_pm.h       |  33 +++
 drivers/gpu/drm/i915/pxp/intel_pxp_session.c  | 140 +++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_session.h  |  18 ++
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c      | 199 +++++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.h      |  17 ++
 drivers/gpu/drm/i915/pxp/intel_pxp_types.h    |  38 +++
 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                | 230 ++++++++++++++++++
 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                   |  92 +++++++
 44 files changed, 1972 insertions(+), 21 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_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.29.2

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

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

* [Intel-gfx] [PATCH v2 01/16] drm/i915/pxp: Define PXP component interface
  2021-03-01 19:31 [Intel-gfx] [PATCH v2 00/16] Introduce Intel PXP Daniele Ceraolo Spurio
@ 2021-03-01 19:31 ` Daniele Ceraolo Spurio
  2021-03-03 19:51   ` Rodrigo Vivi
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 02/16] mei: pxp: export pavp client to me client bus Daniele Ceraolo Spurio
                   ` (18 subsequent siblings)
  19 siblings, 1 reply; 47+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-03-01 19:31 UTC (permalink / raw)
  To: intel-gfx

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>
---
 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.29.2

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

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

* [Intel-gfx] [PATCH v2 02/16] mei: pxp: export pavp client to me client bus
  2021-03-01 19:31 [Intel-gfx] [PATCH v2 00/16] Introduce Intel PXP Daniele Ceraolo Spurio
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 01/16] drm/i915/pxp: Define PXP component interface Daniele Ceraolo Spurio
@ 2021-03-01 19:31 ` Daniele Ceraolo Spurio
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 03/16] drm/i915/pxp: define PXP device flag and kconfig Daniele Ceraolo Spurio
                   ` (17 subsequent siblings)
  19 siblings, 0 replies; 47+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-03-01 19:31 UTC (permalink / raw)
  To: intel-gfx; +Cc: Tomas Winkler, Vitaly Lubart

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

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

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>
---
 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 | 230 +++++++++++++++++++++++++++++++++
 drivers/misc/mei/pxp/mei_pxp.h |  18 +++
 6 files changed, 271 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..42021920bc84
--- /dev/null
+++ b/drivers/misc/mei/pxp/mei_pxp.c
@@ -0,0 +1,230 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright © 2020 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;
+
+	dev_dbg(dev, "%s\n", __func__);
+	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);
+
+	dev_dbg(dev, "%s\n", __func__);
+	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 (subcomponent != I915_COMPONENT_PXP)
+		return 0;
+
+	if (strcmp(dev->driver->name, "i915") == 0) {
+		base = base->parent;
+		if (!base)
+			return 0;
+
+		base = base->parent;
+		dev = dev->parent;
+		return (base && dev && dev == base);
+	}
+
+	return 0;
+}
+
+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 int mei_pxp_remove(struct mei_cl_device *cldev)
+{
+	struct i915_pxp_component *comp_master = mei_cldev_get_drvdata(cldev);
+
+	component_master_del(&cldev->dev, &mei_component_master_ops);
+	kfree(comp_master);
+	mei_cldev_set_drvdata(cldev, NULL);
+
+	return mei_cldev_disable(cldev);
+}
+
+/* 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.29.2

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

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

* [Intel-gfx] [PATCH v2 03/16] drm/i915/pxp: define PXP device flag and kconfig
  2021-03-01 19:31 [Intel-gfx] [PATCH v2 00/16] Introduce Intel PXP Daniele Ceraolo Spurio
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 01/16] drm/i915/pxp: Define PXP component interface Daniele Ceraolo Spurio
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 02/16] mei: pxp: export pavp client to me client bus Daniele Ceraolo Spurio
@ 2021-03-01 19:31 ` Daniele Ceraolo Spurio
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 04/16] drm/i915/pxp: allocate a vcs context for pxp usage Daniele Ceraolo Spurio
                   ` (16 subsequent siblings)
  19 siblings, 0 replies; 47+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-03-01 19:31 UTC (permalink / raw)
  To: intel-gfx

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

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 1e1cb245fca7..c55e58bdbe0b 100644
--- a/drivers/gpu/drm/i915/Kconfig
+++ b/drivers/gpu/drm/i915/Kconfig
@@ -130,6 +130,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 y
+	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 f8413b3b9da8..ae3d92acddfd 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1742,6 +1742,10 @@ tgl_stepping_get(struct drm_i915_private *dev_priv)
 
 #define HAS_VRR(i915)	(INTEL_GEN(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 d44f64b57b7a..8cd9cb841c3e 100644
--- a/drivers/gpu/drm/i915/intel_device_info.h
+++ b/drivers/gpu/drm/i915/intel_device_info.h
@@ -126,6 +126,7 @@ enum intel_ppgtt_type {
 	func(has_logical_ring_elsq); \
 	func(has_master_unit_irq); \
 	func(has_pooled_eu); \
+	func(has_pxp); \
 	func(has_rc6); \
 	func(has_rc6p); \
 	func(has_rps); \
-- 
2.29.2

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

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

* [Intel-gfx] [PATCH v2 04/16] drm/i915/pxp: allocate a vcs context for pxp usage
  2021-03-01 19:31 [Intel-gfx] [PATCH v2 00/16] Introduce Intel PXP Daniele Ceraolo Spurio
                   ` (2 preceding siblings ...)
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 03/16] drm/i915/pxp: define PXP device flag and kconfig Daniele Ceraolo Spurio
@ 2021-03-01 19:31 ` Daniele Ceraolo Spurio
  2021-03-03 22:17   ` Chris Wilson
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 05/16] drm/i915/pxp: set KCR reg init during the boot time Daniele Ceraolo Spurio
                   ` (15 subsequent siblings)
  19 siblings, 1 reply; 47+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-03-01 19:31 UTC (permalink / raw)
  To: intel-gfx; +Cc: 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)

Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/Makefile              |  4 ++
 drivers/gpu/drm/i915/gt/intel_engine.h     | 10 ++++
 drivers/gpu/drm/i915/gt/intel_engine_cs.c  | 19 ++++---
 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       | 64 ++++++++++++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp.h       | 35 ++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_types.h | 15 +++++
 8 files changed, 146 insertions(+), 9 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_types.h

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 4554f10a0fc7..8bcdd708d5c9 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -270,6 +270,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 c530839627bb..4719cdf541cf 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine.h
@@ -21,6 +21,7 @@
 
 struct drm_printer;
 struct intel_gt;
+struct lock_class_key;
 
 /* Early gen2 devices have a cacheline of just 32 bytes, using 64 is overkill,
  * but keeps the logic simple. Indeed, the whole purpose of this macro is just
@@ -170,6 +171,8 @@ intel_write_status_page(struct intel_engine_cs *engine, int reg, u32 value)
 #define I915_GEM_HWS_PREEMPT_ADDR	(I915_GEM_HWS_PREEMPT * sizeof(u32))
 #define I915_GEM_HWS_SEQNO		0x40
 #define I915_GEM_HWS_SEQNO_ADDR		(I915_GEM_HWS_SEQNO * 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
@@ -232,6 +235,13 @@ ktime_t intel_engine_get_busy_time(struct intel_engine_cs *engine,
 
 u32 intel_engine_context_size(struct intel_gt *gt, u8 class);
 
+struct intel_context *
+intel_engine_pinned_context_create(struct intel_engine_cs *engine,
+				   unsigned int hwsp,
+				   struct lock_class_key *key,
+				   const char *name);
+void intel_engine_pinned_context_destroy(struct intel_context *ce);
+
 void intel_engine_init_active(struct intel_engine_cs *engine,
 			      unsigned int subclass);
 #define ENGINE_PHYSICAL	0
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
index 577ebd4a324f..5fb7c6202146 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
@@ -770,11 +770,11 @@ static int measure_breadcrumb_dw(struct intel_context *ce)
 	return dw;
 }
 
-static struct intel_context *
-create_pinned_context(struct intel_engine_cs *engine,
-		      unsigned int hwsp,
-		      struct lock_class_key *key,
-		      const char *name)
+struct intel_context *
+intel_engine_pinned_context_create(struct intel_engine_cs *engine,
+				   unsigned int hwsp,
+				   struct lock_class_key *key,
+				   const char *name)
 {
 	struct intel_context *ce;
 	int err;
@@ -803,7 +803,7 @@ create_pinned_context(struct intel_engine_cs *engine,
 	return ce;
 }
 
-static void destroy_pinned_context(struct intel_context *ce)
+void intel_engine_pinned_context_destroy(struct intel_context *ce)
 {
 	struct intel_engine_cs *engine = ce->engine;
 	struct i915_vma *hwsp = engine->status_page.vma;
@@ -823,8 +823,9 @@ create_kernel_context(struct intel_engine_cs *engine)
 {
 	static struct lock_class_key kernel;
 
-	return create_pinned_context(engine, I915_GEM_HWS_SEQNO_ADDR,
-				     &kernel, "kernel_context");
+	return intel_engine_pinned_context_create(engine,
+						  I915_GEM_HWS_SEQNO_ADDR,
+						  &kernel, "kernel_context");
 }
 
 /**
@@ -928,7 +929,7 @@ void intel_engine_cleanup_common(struct intel_engine_cs *engine)
 		fput(engine->default_state);
 
 	if (engine->kernel_context)
-		destroy_pinned_context(engine->kernel_context);
+		intel_engine_pinned_context_destroy(engine->kernel_context);
 
 	GEM_BUG_ON(!llist_empty(&engine->barrier_tasks));
 	cleanup_status_page(engine);
diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c b/drivers/gpu/drm/i915/gt/intel_gt.c
index ca76f93bc03d..daf61db620d6 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt.c
@@ -20,6 +20,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)
 {
@@ -624,6 +625,8 @@ int intel_gt_init(struct intel_gt *gt)
 	if (err)
 		goto err_gt;
 
+	intel_pxp_init(&gt->pxp);
+
 	goto out_fw;
 err_gt:
 	__intel_gt_disable(gt);
@@ -658,6 +661,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 626af37c7790..324d267eee15 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_types.h
@@ -23,6 +23,7 @@
 #include "intel_rc6_types.h"
 #include "intel_rps_types.h"
 #include "intel_wakeref.h"
+#include "pxp/intel_pxp_types.h"
 
 struct drm_i915_private;
 struct i915_ggtt;
@@ -145,6 +146,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..c2b1c8ff845d
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -0,0 +1,64 @@
+// 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_pinned_context_create(engine,
+						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_pinned_context_destroy(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");
+
+	return;
+}
+
+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.29.2

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

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

* [Intel-gfx] [PATCH v2 05/16] drm/i915/pxp: set KCR reg init during the boot time
  2021-03-01 19:31 [Intel-gfx] [PATCH v2 00/16] Introduce Intel PXP Daniele Ceraolo Spurio
                   ` (3 preceding siblings ...)
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 04/16] drm/i915/pxp: allocate a vcs context for pxp usage Daniele Ceraolo Spurio
@ 2021-03-01 19:31 ` Daniele Ceraolo Spurio
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 06/16] drm/i915/pxp: Implement funcs to create the TEE channel Daniele Ceraolo Spurio
                   ` (14 subsequent siblings)
  19 siblings, 0 replies; 47+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-03-01 19:31 UTC (permalink / raw)
  To: intel-gfx; +Cc: Sean Z, Huang

Set the KCR init during the boot time, which is required by hardware,
to allow us doing further protection operation such as sending commands
to GPU or TEE.

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 | 29 +++++++++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index c2b1c8ff845d..9b2a67f8ab8e 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -6,6 +6,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;
@@ -46,19 +64,28 @@ void intel_pxp_init(struct intel_pxp *pxp)
 	if (!HAS_PXP(gt->i915))
 		return;
 
+	kcr_pxp_enable(gt);
+
 	ret = create_vcs_context(pxp);
 	if (ret)
-		return;
+		goto out_kcr;
 
 	drm_info(&gt->i915->drm, "Protected Xe Path (PXP) protected content support initialized\n");
 
 	return;
+
+out_kcr:
+	kcr_pxp_disable(gt);
 }
 
 void intel_pxp_fini(struct intel_pxp *pxp)
 {
+	struct intel_gt *gt = pxp_to_gt(pxp);
+
 	if (!intel_pxp_is_enabled(pxp))
 		return;
 
 	destroy_vcs_context(pxp);
+
+	kcr_pxp_disable(gt);
 }
-- 
2.29.2

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

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

* [Intel-gfx] [PATCH v2 06/16] drm/i915/pxp: Implement funcs to create the TEE channel
  2021-03-01 19:31 [Intel-gfx] [PATCH v2 00/16] Introduce Intel PXP Daniele Ceraolo Spurio
                   ` (4 preceding siblings ...)
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 05/16] drm/i915/pxp: set KCR reg init during the boot time Daniele Ceraolo Spurio
@ 2021-03-01 19:31 ` Daniele Ceraolo Spurio
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 07/16] drm/i915/pxp: Create the arbitrary session after boot Daniele Ceraolo Spurio
                   ` (13 subsequent siblings)
  19 siblings, 0 replies; 47+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-03-01 19:31 UTC (permalink / raw)
  To: intel-gfx; +Cc: Huang, Sean Z, Huang, Chris Wilson

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)

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>
---
 drivers/gpu/drm/i915/Makefile              |  3 +-
 drivers/gpu/drm/i915/pxp/intel_pxp.c       | 10 +++
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c   | 78 ++++++++++++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.h   | 14 ++++
 drivers/gpu/drm/i915/pxp/intel_pxp_types.h |  3 +
 5 files changed, 107 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 8bcdd708d5c9..7745f73ce3dc 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -272,7 +272,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 9b2a67f8ab8e..a4497cd38609 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"
 
@@ -70,10 +71,16 @@ void intel_pxp_init(struct intel_pxp *pxp)
 	if (ret)
 		goto out_kcr;
 
+	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);
 out_kcr:
 	kcr_pxp_disable(gt);
 }
@@ -85,7 +92,10 @@ 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);
 
 	kcr_pxp_disable(gt);
+
 }
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..3225a90dc5af
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
@@ -0,0 +1,78 @@
+// 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.29.2

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

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

* [Intel-gfx] [PATCH v2 07/16] drm/i915/pxp: Create the arbitrary session after boot
  2021-03-01 19:31 [Intel-gfx] [PATCH v2 00/16] Introduce Intel PXP Daniele Ceraolo Spurio
                   ` (5 preceding siblings ...)
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 06/16] drm/i915/pxp: Implement funcs to create the TEE channel Daniele Ceraolo Spurio
@ 2021-03-01 19:31 ` Daniele Ceraolo Spurio
  2021-03-03 22:08   ` Chris Wilson
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 08/16] drm/i915/pxp: Implement arb session teardown Daniele Ceraolo Spurio
                   ` (12 subsequent siblings)
  19 siblings, 1 reply; 47+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-03-01 19:31 UTC (permalink / raw)
  To: intel-gfx; +Cc: Huang, Sean Z, Huang, Chris Wilson

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)

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>
---
 drivers/gpu/drm/i915/Makefile                |   1 +
 drivers/gpu/drm/i915/pxp/intel_pxp.c         |   2 +
 drivers/gpu/drm/i915/pxp/intel_pxp.h         |   5 +
 drivers/gpu/drm/i915/pxp/intel_pxp_session.c |  82 +++++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_session.h |  16 +++
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c     | 102 +++++++++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.h     |   3 +
 drivers/gpu/drm/i915/pxp/intel_pxp_types.h   |   6 ++
 include/uapi/drm/i915_drm.h                  |   4 +
 9 files changed, 221 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

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 7745f73ce3dc..d6d510e4875e 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -273,6 +273,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 a4497cd38609..cbec9395bde9 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -65,6 +65,8 @@ void intel_pxp_init(struct intel_pxp *pxp)
 	if (!HAS_PXP(gt->i915))
 		return;
 
+	mutex_init(&pxp->mutex);
+
 	kcr_pxp_enable(gt);
 
 	ret = create_vcs_context(pxp);
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
index e87550fb9821..3bede9306481 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_in_play;
+}
+
 #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..6abc59a63e51
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
@@ -0,0 +1,82 @@
+// 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);
+}
+
+bool intel_pxp_arb_session_is_in_play(struct intel_pxp *pxp)
+{
+	return intel_pxp_session_is_in_play(pxp, ARB_SESSION);
+}
+
+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;
+
+	lockdep_assert_held(&pxp->mutex);
+
+	pxp->arb_is_in_play = 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");
+		pxp->arb_is_in_play = true;
+		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_in_play = 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..6fc4a2370c44
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.h
@@ -0,0 +1,16 @@
+/* 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;
+
+bool intel_pxp_arb_session_is_in_play(struct intel_pxp *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 3225a90dc5af..dc3850b372c5 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
@@ -8,13 +8,73 @@
 #include "drm/i915_component.h"
 #include "i915_drv.h"
 #include "intel_pxp.h"
+#include "intel_pxp_session.h"
 #include "intel_pxp_tee.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;
+
 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;
+
+	lockdep_assert_held(&pxp->mutex);
+
+	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");
+		return ret;
+	}
+
+	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");
+		return ret;
+	}
+
+	if (ret > msg_out_max_size) {
+		drm_err(&i915->drm,
+			"Failed to receive PXP TEE message due to unexpected output size\n");
+		return -ENOSPC;
+	}
+
+	if (msg_out_rcv_size)
+		*msg_out_rcv_size = ret;
+
+	return 0;
+}
 
 /**
  * i915_pxp_tee_component_bind - bind function to pass the function pointers to pxp_tee
@@ -29,11 +89,26 @@ 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);
+	int ret = 0;
 
 	pxp->pxp_component = data;
 	pxp->pxp_component->tee_dev = tee_kdev;
 
+	mutex_lock(&pxp->mutex);
+
+	/* Create arb session only if tee is ready, during system boot or sleep/resume */
+	if (!intel_pxp_arb_session_is_in_play(pxp))
+		ret = intel_pxp_create_arb_session(pxp);
+
+	mutex_unlock(&pxp->mutex);
+
+	if (ret) {
+		drm_err(&i915->drm, "Failed to create arb session ret=[%d]\n", ret);
+		return ret;
+	}
+
 	return 0;
 }
 
@@ -76,3 +151,30 @@ 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;
+
+	lockdep_assert_held(&pxp->mutex);
+
+	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_types.h b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
index 3e95d21513e8..e05cd3564eba 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/types.h>
+#include <linux/mutex.h>
+
 struct intel_context;
 struct i915_pxp_component;
 
@@ -13,6 +16,9 @@ struct intel_pxp {
 	struct i915_pxp_component *pxp_component;
 
 	struct intel_context *ce;
+
+	struct mutex mutex;
+	bool arb_is_in_play;
 };
 
 #endif /* __INTEL_PXP_TYPES_H__ */
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 1987e2ea79a3..56c6bfe6c2d0 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -2376,6 +2376,10 @@ struct drm_i915_query_perf_config {
 	__u8 data[];
 };
 
+
+/* 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.29.2

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

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

* [Intel-gfx] [PATCH v2 08/16] drm/i915/pxp: Implement arb session teardown
  2021-03-01 19:31 [Intel-gfx] [PATCH v2 00/16] Introduce Intel PXP Daniele Ceraolo Spurio
                   ` (6 preceding siblings ...)
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 07/16] drm/i915/pxp: Create the arbitrary session after boot Daniele Ceraolo Spurio
@ 2021-03-01 19:31 ` Daniele Ceraolo Spurio
  2021-03-03 22:04   ` Chris Wilson
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 09/16] drm/i915/pxp: Implement PXP irq handler Daniele Ceraolo Spurio
                   ` (11 subsequent siblings)
  19 siblings, 1 reply; 47+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-03-01 19:31 UTC (permalink / raw)
  To: intel-gfx; +Cc: Huang, Sean Z, Huang, Chris Wilson

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)

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>
---
 drivers/gpu/drm/i915/Makefile                |   1 +
 drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c     | 166 +++++++++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h     |  15 ++
 drivers/gpu/drm/i915/pxp/intel_pxp_session.c |  38 +++++
 drivers/gpu/drm/i915/pxp/intel_pxp_session.h |   1 +
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c     |   5 +-
 6 files changed, 225 insertions(+), 1 deletion(-)
 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 d6d510e4875e..8b605f326039 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -273,6 +273,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/pxp/intel_pxp_cmd.c b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c
new file mode 100644
index 000000000000..ffab09839cd3
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c
@@ -0,0 +1,166 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright(c) 2020, Intel Corporation. All rights reserved.
+ */
+
+#include "intel_pxp.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"
+
+/* PXP GPU command definitions */
+
+/* MI_SET_APPID */
+#define   MI_SET_APPID_SESSION_ID(x)    ((x) << 0)
+
+/* MI_FLUSH_DW */
+#define   MI_FLUSH_DW_DW0_PROTECTED_MEMORY_ENABLE   BIT(22)
+
+/* MI_WAIT */
+#define   MFX_WAIT_DW0_PXP_SYNC_CONTROL_FLAG BIT(9)
+#define   MFX_WAIT_DW0_MFX_SYNC_CONTROL_FLAG  BIT(8)
+
+/* CRYPTO_KEY_EXCHANGE */
+#define CRYPTO_KEY_EXCHANGE ((0x3 << 29) | (0x01609 << 16))
+
+/* 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_DW0_PROTECTED_MEMORY_ENABLE;
+	*cs++ = 0;
+	*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_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 WAIT_LEN 2
+#define __SESSION_TERMINATION_LEN (SELECTION_LEN + TERMINATION_LEN)
+#define SESSION_TERMINATION_LEN(x) (__SESSION_TERMINATION_LEN * (x) + WAIT_LEN)
+
+static struct i915_request *pxp_request_create(struct intel_context *ce)
+{
+	struct i915_request *rq;
+
+	intel_context_enter(ce);
+	rq = __i915_request_create(ce, GFP_KERNEL);
+	intel_context_exit(ce);
+
+	return rq;
+}
+
+static void pxp_request_commit(struct i915_request *rq)
+{
+	struct i915_sched_attr attr = { .priority = I915_PRIORITY_MAX };
+
+	trace_i915_request_add(rq);
+	__i915_request_commit(rq);
+	__i915_request_queue(rq, &attr);
+}
+
+int intel_pxp_submit_session_termination(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;
+
+	intel_engine_pm_get(ce->engine);
+	mutex_lock(&ce->timeline->mutex);
+
+	rq = pxp_request_create(ce);
+	if (IS_ERR(rq)) {
+		mutex_unlock(&ce->timeline->mutex);
+		err = PTR_ERR(rq);
+		goto out_pm;
+	}
+
+	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));
+	if (IS_ERR(cs)) {
+		err = PTR_ERR(cs);
+		goto out_rq;
+	}
+
+	cs = pxp_emit_session_selection(cs, id);
+	cs = pxp_emit_inline_termination(cs);
+	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);
+
+	mutex_unlock(&ce->timeline->mutex);
+
+	if (!err && i915_request_wait(rq, 0, HZ / 5) < 0)
+		err = -ETIME;
+
+	i915_request_put(rq);
+
+out_pm:
+	intel_engine_pm_put(ce->engine);
+
+	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..7c33b66f0812
--- /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_submit_session_termination(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 6abc59a63e51..ddbfac75686a 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);
@@ -80,3 +84,37 @@ int intel_pxp_create_arb_session(struct intel_pxp *pxp)
 
 	return 0;
 }
+
+/**
+ * intel_pxp_arb_terminate_session_with_global_terminate - Terminate the arb hw
+ * session.
+ * @pxp: pointer to pxp struct.
+ *
+ * Return: 0 if terminate is successful, error code otherwise
+ */
+int intel_pxp_arb_terminate_session_with_global_terminate(struct intel_pxp *pxp)
+{
+	int ret;
+	struct intel_gt *gt = pxp_to_gt(pxp);
+
+	lockdep_assert_held(&pxp->mutex);
+
+	pxp->arb_is_in_play = false;
+
+	/* terminate the hw sessions */
+	ret = intel_pxp_submit_session_termination(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 6fc4a2370c44..07c97df7a509 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.h
@@ -12,5 +12,6 @@ struct intel_pxp;
 
 bool intel_pxp_arb_session_is_in_play(struct intel_pxp *pxp);
 int intel_pxp_create_arb_session(struct intel_pxp *pxp);
+int intel_pxp_arb_terminate_session_with_global_terminate(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 dc3850b372c5..fd9a69248dd8 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
@@ -99,7 +99,10 @@ static int i915_pxp_tee_component_bind(struct device *i915_kdev,
 	mutex_lock(&pxp->mutex);
 
 	/* Create arb session only if tee is ready, during system boot or sleep/resume */
-	if (!intel_pxp_arb_session_is_in_play(pxp))
+	if (intel_pxp_arb_session_is_in_play(pxp))
+		ret = intel_pxp_arb_terminate_session_with_global_terminate(pxp);
+
+	if (!ret)
 		ret = intel_pxp_create_arb_session(pxp);
 
 	mutex_unlock(&pxp->mutex);
-- 
2.29.2

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

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

* [Intel-gfx] [PATCH v2 09/16] drm/i915/pxp: Implement PXP irq handler
  2021-03-01 19:31 [Intel-gfx] [PATCH v2 00/16] Introduce Intel PXP Daniele Ceraolo Spurio
                   ` (7 preceding siblings ...)
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 08/16] drm/i915/pxp: Implement arb session teardown Daniele Ceraolo Spurio
@ 2021-03-01 19:31 ` Daniele Ceraolo Spurio
  2021-03-03 21:18   ` Chris Wilson
                     ` (2 more replies)
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 10/16] drm/i915/pxp: Enable PXP power management Daniele Ceraolo Spurio
                   ` (10 subsequent siblings)
  19 siblings, 3 replies; 47+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-03-01 19:31 UTC (permalink / raw)
  To: intel-gfx; +Cc: Huang, Sean Z, Huang, Chris Wilson

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.

v2: use struct completion instead of bool (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>
---
 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         |  34 +++++
 drivers/gpu/drm/i915/pxp/intel_pxp.h         |  16 ++
 drivers/gpu/drm/i915/pxp/intel_pxp_irq.c     | 151 +++++++++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_irq.h     |  33 ++++
 drivers/gpu/drm/i915/pxp/intel_pxp_session.c |   9 +-
 drivers/gpu/drm/i915/pxp/intel_pxp_session.h |   1 +
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c     |  10 +-
 drivers/gpu/drm/i915/pxp/intel_pxp_types.h   |   8 +
 11 files changed, 268 insertions(+), 3 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 8b605f326039..5e9bd34dec38 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -274,6 +274,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 d29126c458ba..0d3585efe2b8 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);
 }
@@ -190,6 +194,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 e5dd0203991b..97a6d0c638ec 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -7958,6 +7958,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 cbec9395bde9..0ca1c2c16972 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_tee.h"
 #include "gt/intel_context.h"
 #include "i915_drv.h"
@@ -67,12 +69,23 @@ void intel_pxp_init(struct intel_pxp *pxp)
 
 	mutex_init(&pxp->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);
+
 	kcr_pxp_enable(gt);
 
 	ret = create_vcs_context(pxp);
 	if (ret)
 		goto out_kcr;
 
+	intel_pxp_irq_init(pxp);
+	intel_pxp_irq_enable(pxp);
+
 	ret = intel_pxp_tee_component_init(pxp);
 	if (ret)
 		goto out_context;
@@ -94,10 +107,31 @@ void intel_pxp_fini(struct intel_pxp *pxp)
 	if (!intel_pxp_is_enabled(pxp))
 		return;
 
+	intel_pxp_irq_disable(pxp);
+
 	intel_pxp_tee_component_fini(pxp);
 
 	destroy_vcs_context(pxp);
 
 	kcr_pxp_disable(gt);
+}
 
+int intel_pxp_wait_for_termination_completion(struct intel_pxp *pxp)
+{
+	int ret;
+
+	if (!intel_pxp_is_enabled(pxp))
+		return 0;
+
+	ret = wait_for_completion_timeout(&pxp->termination,
+					  msecs_to_jiffies(100));
+
+	/* the wait returns 0 on failure */
+	if (ret)
+		ret = 0;
+	else
+		ret = -ETIMEDOUT;
+
+	return ret;
 }
+
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
index 3bede9306481..89cf66c9bef3 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
@@ -9,6 +9,15 @@
 #include "gt/intel_gt_types.h"
 #include "intel_pxp_types.h"
 
+#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)
+
 static inline struct intel_gt *pxp_to_gt(const struct intel_pxp *pxp)
 {
 	return container_of(pxp, struct intel_gt, pxp);
@@ -27,6 +36,8 @@ static inline bool intel_pxp_is_active(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);
+
+int intel_pxp_wait_for_termination_completion(struct intel_pxp *pxp);
 #else
 static inline void intel_pxp_init(struct intel_pxp *pxp)
 {
@@ -35,6 +46,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_termination_completion(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..40115bf0b6bb
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
@@ -0,0 +1,151 @@
+// 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"
+
+static int pxp_terminate(struct intel_pxp *pxp)
+{
+	int ret = 0;
+
+	mutex_lock(&pxp->mutex);
+
+	pxp->global_state_attacked = true;
+
+	ret = intel_pxp_arb_terminate_session_with_global_terminate(pxp);
+
+	mutex_unlock(&pxp->mutex);
+
+	return ret;
+}
+
+static int pxp_terminate_complete(struct intel_pxp *pxp)
+{
+	int ret = 0;
+
+	mutex_lock(&pxp->mutex);
+
+	if (pxp->global_state_attacked) {
+		pxp->global_state_attacked = false;
+
+		/* Re-create the arb session after teardown handle complete */
+		ret = intel_pxp_create_arb_session(pxp);
+	}
+
+	mutex_unlock(&pxp->mutex);
+
+	complete_all(&pxp->termination);
+
+	return ret;
+}
+
+static void intel_pxp_irq_work(struct work_struct *work)
+{
+	struct intel_pxp *pxp = container_of(work, typeof(*pxp), irq_work);
+	struct intel_gt *gt = pxp_to_gt(pxp);
+	u32 events = 0;
+
+	spin_lock_irq(&gt->irq_lock);
+	events = fetch_and_zero(&pxp->current_events);
+	spin_unlock_irq(&gt->irq_lock);
+
+	if (!events)
+		return;
+
+	if (events & (GEN12_DISPLAY_PXP_STATE_TERMINATED_INTERRUPT |
+		      GEN12_DISPLAY_APP_TERMINATED_PER_FW_REQ_INTERRUPT))
+		pxp_terminate(pxp);
+
+	if (events & GEN12_DISPLAY_STATE_RESET_COMPLETE_INTERRUPT)
+		pxp_terminate_complete(pxp);
+
+	/*
+	 * we expect the terminate complete to arrive quickly after emitting
+	 * the terminate, so check back on it
+	 */
+	if (pxp->irq_enabled)
+		queue_work(system_unbound_wq, &pxp->irq_work);
+}
+
+/**
+ * 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;
+
+	/* immediately mark PXP as inactive on termination */
+	if (iir & (GEN12_DISPLAY_PXP_STATE_TERMINATED_INTERRUPT |
+		   GEN12_DISPLAY_APP_TERMINATED_PER_FW_REQ_INTERRUPT))
+		intel_pxp_mark_termination_in_progress(pxp);
+
+	pxp->current_events |= iir;
+	queue_work(system_unbound_wq, &pxp->irq_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_init(struct intel_pxp *pxp)
+{
+	INIT_WORK(&pxp->irq_work, intel_pxp_irq_work);
+}
+
+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);
+
+	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->irq_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..7a875831636d
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.h
@@ -0,0 +1,33 @@
+/* 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;
+
+#ifdef CONFIG_DRM_I915_PXP
+void intel_pxp_irq_init(struct intel_pxp *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
+void intel_pxp_irq_init(struct intel_pxp *pxp)
+{
+}
+void intel_pxp_irq_enable(struct intel_pxp *pxp)
+{
+}
+void intel_pxp_irq_disable(struct intel_pxp *pxp)
+{
+}
+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 ddbfac75686a..488006a0cf39 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
@@ -99,8 +99,6 @@ int intel_pxp_arb_terminate_session_with_global_terminate(struct intel_pxp *pxp)
 
 	lockdep_assert_held(&pxp->mutex);
 
-	pxp->arb_is_in_play = false;
-
 	/* terminate the hw sessions */
 	ret = intel_pxp_submit_session_termination(pxp, ARB_SESSION);
 	if (ret) {
@@ -118,3 +116,10 @@ int intel_pxp_arb_terminate_session_with_global_terminate(struct intel_pxp *pxp)
 
 	return ret;
 }
+
+void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp)
+{
+	pxp->arb_is_in_play = false;
+	reinit_completion(&pxp->termination);
+}
+
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.h b/drivers/gpu/drm/i915/pxp/intel_pxp_session.h
index 07c97df7a509..931169f795ab 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.h
@@ -13,5 +13,6 @@ struct intel_pxp;
 bool intel_pxp_arb_session_is_in_play(struct intel_pxp *pxp);
 int intel_pxp_create_arb_session(struct intel_pxp *pxp);
 int intel_pxp_arb_terminate_session_with_global_terminate(struct intel_pxp *pxp);
+void intel_pxp_mark_termination_in_progress(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 fd9a69248dd8..b84f675c588e 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
@@ -99,9 +99,17 @@ static int i915_pxp_tee_component_bind(struct device *i915_kdev,
 	mutex_lock(&pxp->mutex);
 
 	/* Create arb session only if tee is ready, during system boot or sleep/resume */
-	if (intel_pxp_arb_session_is_in_play(pxp))
+	if (intel_pxp_arb_session_is_in_play(pxp)) {
+		intel_pxp_mark_termination_in_progress(pxp);
 		ret = intel_pxp_arb_terminate_session_with_global_terminate(pxp);
 
+		if (!ret) {
+			mutex_unlock(&pxp->mutex);
+			ret = intel_pxp_wait_for_termination_completion(pxp);
+			mutex_lock(&pxp->mutex);
+		}
+	}
+
 	if (!ret)
 		ret = intel_pxp_create_arb_session(pxp);
 
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
index e05cd3564eba..5e5ee7225a72 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/types.h>
 #include <linux/mutex.h>
+#include <linux/workqueue.h>
 
 struct intel_context;
 struct i915_pxp_component;
@@ -19,6 +21,12 @@ struct intel_pxp {
 
 	struct mutex mutex;
 	bool arb_is_in_play;
+	bool global_state_attacked;
+	struct completion termination;
+
+	struct work_struct irq_work;
+	bool irq_enabled;
+	u32 current_events; /* protected with gt->irq_lock */
 };
 
 #endif /* __INTEL_PXP_TYPES_H__ */
-- 
2.29.2

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

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

* [Intel-gfx] [PATCH v2 10/16] drm/i915/pxp: Enable PXP power management
  2021-03-01 19:31 [Intel-gfx] [PATCH v2 00/16] Introduce Intel PXP Daniele Ceraolo Spurio
                   ` (8 preceding siblings ...)
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 09/16] drm/i915/pxp: Implement PXP irq handler Daniele Ceraolo Spurio
@ 2021-03-01 19:31 ` Daniele Ceraolo Spurio
  2021-03-03 22:52   ` Chris Wilson
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 11/16] drm/i915/pxp: interface for creation of protected contexts Daniele Ceraolo Spurio
                   ` (9 subsequent siblings)
  19 siblings, 1 reply; 47+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-03-01 19:31 UTC (permalink / raw)
  To: intel-gfx; +Cc: Huang, Sean Z, Huang, Chris Wilson

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
software session state was marked as alive after resume. So to
handle such case, PXP should unconditionally terminate the hardware
sessions and cleanup all the software states after the power cycle.

v2: runtime suspend also invalidates the keys

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>
---
 drivers/gpu/drm/i915/Makefile                |  1 +
 drivers/gpu/drm/i915/gt/intel_gt_pm.c        | 14 ++-
 drivers/gpu/drm/i915/i915_drv.c              |  2 +
 drivers/gpu/drm/i915/pxp/intel_pxp_irq.c     | 10 +-
 drivers/gpu/drm/i915/pxp/intel_pxp_pm.c      | 99 ++++++++++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_pm.h      | 33 +++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_session.c | 28 ++++--
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c     |  8 ++
 drivers/gpu/drm/i915/pxp/intel_pxp_types.h   |  1 +
 9 files changed, 183 insertions(+), 13 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 5e9bd34dec38..1a175c7f2a4e 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -275,6 +275,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 0bd303d2823e..16f03651a6b7 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_pm.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_pm.c
@@ -19,6 +19,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)
 {
@@ -260,6 +261,8 @@ int intel_gt_resume(struct intel_gt *gt)
 
 	intel_uc_resume(&gt->uc);
 
+	intel_pxp_pm_resume(&gt->pxp);
+
 	user_forcewake(gt, false);
 
 out_fw:
@@ -294,6 +297,7 @@ void intel_gt_suspend_prepare(struct intel_gt *gt)
 	user_forcewake(gt, true);
 	wait_for_suspend(gt);
 
+	intel_pxp_pm_prepare_suspend(&gt->pxp);
 	intel_uc_suspend(&gt->uc);
 }
 
@@ -344,6 +348,7 @@ void intel_gt_suspend_late(struct intel_gt *gt)
 
 void intel_gt_runtime_suspend(struct intel_gt *gt)
 {
+	intel_pxp_runtime_suspend(&gt->pxp);
 	intel_uc_runtime_suspend(&gt->uc);
 
 	GT_TRACE(gt, "\n");
@@ -351,11 +356,18 @@ 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)
+		ret = intel_pxp_runtime_resume(&gt->pxp);
+
+	return ret;
 }
 
 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 3edd5e47ad68..d0a39ec29d50 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_drm_client.h"
 #include "i915_drv.h"
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
index 40115bf0b6bb..5b03b17eaa48 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
@@ -125,11 +125,13 @@ 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) {
+
+	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;
-	}
+
+	__pxp_set_interrupts(gt, GEN12_PXP_INTERRUPTS);
+	pxp->irq_enabled = true;
+
 	spin_unlock_irq(&gt->irq_lock);
 }
 
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..0dd2e100bab5
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c
@@ -0,0 +1,99 @@
+// 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"
+
+static void __pxp_suspend(struct intel_pxp *pxp)
+{
+	if (!intel_pxp_is_enabled(pxp))
+		return;
+
+	intel_pxp_irq_disable(pxp);
+
+	pxp->global_state_attacked = false;
+	pxp->arb_is_in_play = false;
+	pxp->global_state_in_suspend = true;
+}
+
+void intel_pxp_pm_prepare_suspend(struct intel_pxp *pxp)
+{
+	__pxp_suspend(pxp);
+}
+
+int intel_pxp_pm_resume(struct intel_pxp *pxp)
+{
+	struct intel_gt *gt = pxp_to_gt(pxp);
+	int ret = 0;
+
+	if (!intel_pxp_is_enabled(pxp))
+		return 0;
+
+	intel_pxp_irq_enable(pxp);
+
+	if (!pxp->global_state_in_suspend)
+		return 0;
+
+	mutex_lock(&pxp->mutex);
+
+	/*
+	 * Note: we won't re-create the session as part of the irq generated by
+	 * this termination because pxp->global_state_attacked is not set. The
+	 * session will be recreated as part of the mei component re-binding.
+	 */
+	intel_pxp_mark_termination_in_progress(pxp);
+	ret = intel_pxp_arb_terminate_session_with_global_terminate(pxp);
+	if (ret) {
+		drm_err(&gt->i915->drm,
+			"Failed to terminate the arb session on resume\n");
+	} else {
+		pxp->global_state_in_suspend = false;
+	}
+
+	mutex_unlock(&pxp->mutex);
+
+	if (!ret) {
+		ret = intel_pxp_wait_for_termination_completion(pxp);
+		if (ret) {
+			drm_err(&gt->i915->drm,
+				"Didn't recevive the PXP termination irq\n");
+		}
+	}
+
+	return ret;
+}
+
+void intel_pxp_runtime_suspend(struct intel_pxp *pxp)
+{
+	__pxp_suspend(pxp);
+}
+
+int intel_pxp_runtime_resume(struct intel_pxp *pxp)
+{
+	struct intel_gt *gt = pxp_to_gt(pxp);
+	int ret;
+
+	if (!intel_pxp_is_enabled(pxp))
+		return 0;
+
+	intel_pxp_irq_enable(pxp);
+	pxp->global_state_in_suspend = false;
+
+	/*
+	 * if the display loses power during runtime suspend it will cause the
+	 * session to become invalid, so to be safe we always re-create it. The
+	 * MEI module is still bound, so this is the same as a teardown event,
+	 * hence we can just pretend we received the irq.
+	 */
+	intel_pxp_mark_termination_in_progress(pxp);
+
+	spin_lock_irq(&gt->irq_lock);
+	intel_pxp_irq_handler(pxp, GEN12_DISPLAY_PXP_STATE_TERMINATED_INTERRUPT);
+	spin_unlock_irq(&gt->irq_lock);
+
+	return ret;
+}
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..9feb84c0aa14
--- /dev/null
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.h
@@ -0,0 +1,33 @@
+/* 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_pm_prepare_suspend(struct intel_pxp *pxp);
+int intel_pxp_pm_resume(struct intel_pxp *pxp);
+void intel_pxp_runtime_suspend(struct intel_pxp *pxp);
+int intel_pxp_runtime_resume(struct intel_pxp *pxp);
+#else
+static inline void intel_pxp_pm_prepare_suspend(struct intel_pxp *pxp)
+{
+}
+static inline int intel_pxp_pm_resume(struct intel_pxp *pxp)
+{
+	return 0;
+}
+static inline void intel_pxp_runtime_suspend(struct intel_pxp *pxp)
+{
+}
+static inline int intel_pxp_runtime_resume(struct intel_pxp *pxp)
+{
+	return 0;
+}
+#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 488006a0cf39..bb981d38c2fe 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
@@ -25,8 +25,14 @@ static bool intel_pxp_session_is_in_play(struct intel_pxp *pxp, u32 id)
 	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 */
+	wakeref = intel_runtime_pm_get_if_in_use(gt->uncore->rpm);
+	if (!wakeref)
+		return false;
+
+	sip = intel_uncore_read(gt->uncore, GEN12_KCR_SIP);
+
+	intel_runtime_pm_put(gt->uncore->rpm, wakeref);
 
 	return sip & BIT(id);
 }
@@ -43,12 +49,18 @@ static int pxp_wait_for_session_state(struct intel_pxp *pxp, u32 id, bool in_pla
 	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(gt->uncore->rpm);
+	if (!wakeref)
+		return in_play ? -ENODEV : 0;
+
+	ret = intel_wait_for_register(gt->uncore,
+				      GEN12_KCR_SIP,
+				      mask,
+				      in_play ? mask : 0,
+				      100);
+
+	intel_runtime_pm_put(gt->uncore->rpm, wakeref);
 
 	return ret;
 }
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
index b84f675c588e..e1d3fe28535d 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
@@ -91,11 +91,17 @@ 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);
+	intel_wakeref_t wakeref;
 	int ret = 0;
 
 	pxp->pxp_component = data;
 	pxp->pxp_component->tee_dev = tee_kdev;
 
+	/* if we are suspended, the session will be re-created on resume */
+	wakeref = intel_runtime_pm_get_if_in_use(&i915->runtime_pm);
+	if (!wakeref)
+		return 0;
+
 	mutex_lock(&pxp->mutex);
 
 	/* Create arb session only if tee is ready, during system boot or sleep/resume */
@@ -120,6 +126,8 @@ static int i915_pxp_tee_component_bind(struct device *i915_kdev,
 		return ret;
 	}
 
+	intel_runtime_pm_put(&i915->runtime_pm, wakeref);
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
index 5e5ee7225a72..6f659a6f8f1c 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
@@ -22,6 +22,7 @@ struct intel_pxp {
 	struct mutex mutex;
 	bool arb_is_in_play;
 	bool global_state_attacked;
+	bool global_state_in_suspend;
 	struct completion termination;
 
 	struct work_struct irq_work;
-- 
2.29.2

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

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

* [Intel-gfx] [PATCH v2 11/16] drm/i915/pxp: interface for creation of protected contexts
  2021-03-01 19:31 [Intel-gfx] [PATCH v2 00/16] Introduce Intel PXP Daniele Ceraolo Spurio
                   ` (9 preceding siblings ...)
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 10/16] drm/i915/pxp: Enable PXP power management Daniele Ceraolo Spurio
@ 2021-03-01 19:31 ` Daniele Ceraolo Spurio
  2021-03-03 23:16   ` Chris Wilson
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 12/16] drm/i915/uapi: introduce drm_i915_gem_create_ext Daniele Ceraolo Spurio
                   ` (8 subsequent siblings)
  19 siblings, 1 reply; 47+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-03-01 19:31 UTC (permalink / raw)
  To: intel-gfx; +Cc: Chris Wilson

Usage of protected objects, coming in a follow-up patch, will be
restricted to protected contexts. Contexts can only be marked as
protected at creation time and they must be both bannable and not
recoverable.

When a PXP teardown occurs, all gem contexts marked as protected that
have been used at least once will be marked as invalid 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
invalidation to userspace.

v2: split to its own patch and improve doc (Chris), invalidate contexts
on teardown

Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_context.c   | 59 ++++++++++++++++++-
 drivers/gpu/drm/i915/gem/i915_gem_context.h   | 18 ++++++
 .../gpu/drm/i915/gem/i915_gem_context_types.h |  2 +
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 13 ++++
 drivers/gpu/drm/i915/pxp/intel_pxp.c          | 38 ++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp.h          |  1 +
 drivers/gpu/drm/i915/pxp/intel_pxp_session.c  |  3 +
 include/uapi/drm/i915_drm.h                   | 19 ++++++
 8 files changed, 150 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c
index ca37d93ef5e7..19ac24a3c42c 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
@@ -76,6 +76,8 @@
 #include "gt/intel_gpu_commands.h"
 #include "gt/intel_ring.h"
 
+#include "pxp/intel_pxp.h"
+
 #include "i915_drm_client.h"
 #include "i915_gem_context.h"
 #include "i915_globals.h"
@@ -2006,6 +2008,40 @@ static int set_priority(struct i915_gem_context *ctx,
 	return 0;
 }
 
+static int set_protected(struct i915_gem_context *ctx,
+			 const struct drm_i915_gem_context_param *args)
+{
+	int ret = 0;
+
+	if (!intel_pxp_is_enabled(&ctx->i915->gt.pxp))
+		ret = -ENODEV;
+	else if (ctx->client) /* can't change this after creation! */
+		ret = -EEXIST;
+	else if (args->size)
+		ret = -EINVAL;
+	else if (!args->value)
+		clear_bit(UCONTEXT_PROTECTED, &ctx->user_flags);
+	else if (i915_gem_context_is_recoverable(ctx) ||
+		 !i915_gem_context_is_bannable(ctx))
+		ret = -EPERM;
+	else
+		set_bit(UCONTEXT_PROTECTED, &ctx->user_flags);
+
+	return ret;
+}
+
+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_can_use_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)
@@ -2038,6 +2074,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_can_use_protected_content(ctx))
+			ret = -EPERM; /* can't clear this for protected contexts */
 		else
 			i915_gem_context_clear_bannable(ctx);
 		break;
@@ -2045,10 +2083,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_can_use_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:
@@ -2075,6 +2115,10 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
 		ret = set_ringsize(ctx, args);
 		break;
 
+	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
+		ret = set_protected(ctx, args);
+		break;
+
 	case I915_CONTEXT_PARAM_BAN_PERIOD:
 	default:
 		ret = -EINVAL;
@@ -2532,6 +2576,10 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
 		ret = get_ringsize(ctx, args);
 		break;
 
+	case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
+		ret = get_protected(ctx, args);
+		break;
+
 	case I915_CONTEXT_PARAM_BAN_PERIOD:
 	default:
 		ret = -EINVAL;
@@ -2592,6 +2640,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;
+
 	ret = 0;
 out:
 	rcu_read_unlock();
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.h b/drivers/gpu/drm/i915/gem/i915_gem_context.h
index b5c908f3f4f2..b04d4eeb0500 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_can_use_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 d5bc75508048..79a87268b8da 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
@@ -130,6 +130,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
@@ -137,6 +138,7 @@ struct i915_gem_context {
 	unsigned long flags;
 #define CONTEXT_CLOSED			0
 #define CONTEXT_USER_ENGINES		1
+#define CONTEXT_INVALID			2
 
 	struct mutex mutex;
 
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index fe170186dd42..e503c9f789c0 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"
@@ -726,6 +728,11 @@ static int eb_select_context(struct i915_execbuffer *eb)
 	if (unlikely(!ctx))
 		return -ENOENT;
 
+	if (i915_gem_context_invalidated(ctx)) {
+		i915_gem_context_put(ctx);
+		return -EIO;
+	}
+
 	eb->gem_context = ctx;
 	if (rcu_access_pointer(ctx->vm))
 		eb->invalid_flags |= EXEC_OBJECT_NEEDS_GTT;
@@ -2761,6 +2768,12 @@ eb_select_engine(struct i915_execbuffer *eb)
 
 	intel_gt_pm_get(ce->engine->gt);
 
+	if (i915_gem_context_can_use_protected_content(eb->gem_context)) {
+		err = intel_pxp_wait_for_termination_completion(&ce->engine->gt->pxp);
+		if (err)
+			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/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index 0ca1c2c16972..5912e4a12d94 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -6,6 +6,7 @@
 #include "intel_pxp.h"
 #include "intel_pxp_irq.h"
 #include "intel_pxp_tee.h"
+#include "gem/i915_gem_context.h"
 #include "gt/intel_context.h"
 #include "i915_drv.h"
 
@@ -135,3 +136,40 @@ int intel_pxp_wait_for_termination_completion(struct intel_pxp *pxp)
 	return ret;
 }
 
+void intel_pxp_invalidate(struct intel_pxp *pxp)
+{
+	struct drm_i915_private *i915 = pxp_to_gt(pxp)->i915;
+	struct i915_gem_context *ctx, *cn;
+
+	/* 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_can_use_protected_content(ctx)))
+			continue;
+
+		if (i915_gem_context_invalidated(ctx))
+			continue;
+
+		spin_unlock_irq(&i915->gem.contexts.lock);
+
+		for_each_gem_engine(ce, i915_gem_context_lock_engines(ctx), it) {
+			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 89cf66c9bef3..e36200833095 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
@@ -38,6 +38,7 @@ void intel_pxp_init(struct intel_pxp *pxp);
 void intel_pxp_fini(struct intel_pxp *pxp);
 
 int intel_pxp_wait_for_termination_completion(struct intel_pxp *pxp);
+void intel_pxp_invalidate(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_session.c b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
index bb981d38c2fe..527217b3db23 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
@@ -111,6 +111,9 @@ int intel_pxp_arb_terminate_session_with_global_terminate(struct intel_pxp *pxp)
 
 	lockdep_assert_held(&pxp->mutex);
 
+	/* invalidate protected objects */
+	intel_pxp_invalidate(pxp);
+
 	/* terminate the hw sessions */
 	ret = intel_pxp_submit_session_termination(pxp, ARB_SESSION);
 	if (ret) {
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 56c6bfe6c2d0..0f5456046c4c 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -1694,6 +1694,24 @@ struct drm_i915_gem_context_param {
  * Default is 16 KiB.
  */
 #define I915_CONTEXT_PARAM_RINGSIZE	0xc
+
+/*
+ * I915_CONTEXT_PARAM_PROTECTED_CONTENT:
+ *
+ * Enable usage of protected content with the context. 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.
+ *
+ * Given the numerous restriction on this flag, there are several unique 
+ * failure cases:
+ *
+ * -ENODEV: feature not available
+ * -EEXIST: trying to modify an existing context
+ * -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;
@@ -1924,6 +1942,7 @@ struct drm_i915_reg_read {
 struct drm_i915_reset_stats {
 	__u32 ctx_id;
 	__u32 flags;
+#define I915_CONTEXT_INVALIDATED 0x1
 
 	/* All resets since boot/module reload, for all contexts */
 	__u32 reset_count;
-- 
2.29.2

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

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

* [Intel-gfx] [PATCH v2 12/16] drm/i915/uapi: introduce drm_i915_gem_create_ext
  2021-03-01 19:31 [Intel-gfx] [PATCH v2 00/16] Introduce Intel PXP Daniele Ceraolo Spurio
                   ` (10 preceding siblings ...)
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 11/16] drm/i915/pxp: interface for creation of protected contexts Daniele Ceraolo Spurio
@ 2021-03-01 19:31 ` Daniele Ceraolo Spurio
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 13/16] drm/i915/pxp: User interface for Protected buffer Daniele Ceraolo Spurio
                   ` (7 subsequent siblings)
  19 siblings, 0 replies; 47+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-03-01 19:31 UTC (permalink / raw)
  To: intel-gfx; +Cc: Bommu Krishnaiah, Matthew Auld

From: Bommu Krishnaiah <krishnaiah.bommu@intel.com>

Same old gem_create but with now with extensions support. This is needed
to support various upcoming usecases. For now we use the extensions
mechanism to support PAVP.

Signed-off-by: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Matthew Auld <matthew.auld@intel.com>
Cc: Telukuntla Sreedhar <sreedhar.telukuntla@intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_create.c | 41 ++++++++++++++++++-
 drivers/gpu/drm/i915/i915_drv.c            |  2 +-
 include/uapi/drm/i915_drm.h                | 47 ++++++++++++++++++++++
 3 files changed, 88 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c b/drivers/gpu/drm/i915/gem/i915_gem_create.c
index 45d60e3d98e3..3ad3413c459f 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
@@ -7,6 +7,7 @@
 #include "gem/i915_gem_region.h"
 
 #include "i915_drv.h"
+#include "i915_user_extensions.h"
 
 static int
 i915_gem_create(struct drm_file *file,
@@ -91,6 +92,35 @@ i915_gem_dumb_create(struct drm_file *file,
 			       &args->size, &args->handle);
 }
 
+struct create_ext {
+	struct drm_i915_private *i915;
+};
+
+static int __create_setparam(struct drm_i915_gem_object_param *args,
+			     struct create_ext *ext_data)
+{
+	if (!(args->param & I915_OBJECT_PARAM)) {
+		DRM_DEBUG("Missing I915_OBJECT_PARAM namespace\n");
+		return -EINVAL;
+	}
+
+	return -EINVAL;
+}
+
+static int create_setparam(struct i915_user_extension __user *base, void *data)
+{
+	struct drm_i915_gem_create_ext_setparam ext;
+
+	if (copy_from_user(&ext, base, sizeof(ext)))
+		return -EFAULT;
+
+	return __create_setparam(&ext.param, data);
+}
+
+static const i915_user_extension_fn create_extensions[] = {
+	[I915_GEM_CREATE_EXT_SETPARAM] = create_setparam,
+};
+
 /**
  * Creates a new mm object and returns a handle to it.
  * @dev: drm device pointer
@@ -102,10 +132,19 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data,
 		      struct drm_file *file)
 {
 	struct drm_i915_private *i915 = to_i915(dev);
-	struct drm_i915_gem_create *args = data;
+	struct create_ext ext_data = { .i915 = i915 };
+	struct drm_i915_gem_create_ext *args = data;
+	int ret;
 
 	i915_gem_flush_free_objects(i915);
 
+	ret = i915_user_extensions(u64_to_user_ptr(args->extensions),
+				   create_extensions,
+				   ARRAY_SIZE(create_extensions),
+				   &ext_data);
+	if (ret)
+		return ret;
+
 	return i915_gem_create(file,
 			       intel_memory_region_by_type(i915,
 							   INTEL_MEMORY_SYSTEM),
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index d0a39ec29d50..a46b5672d4e7 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1713,7 +1713,7 @@ static const struct drm_ioctl_desc i915_ioctls[] = {
 	DRM_IOCTL_DEF_DRV(I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(I915_GEM_ENTERVT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
 	DRM_IOCTL_DEF_DRV(I915_GEM_LEAVEVT, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
-	DRM_IOCTL_DEF_DRV(I915_GEM_CREATE, i915_gem_create_ioctl, DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(I915_GEM_CREATE_EXT, i915_gem_create_ioctl, DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(I915_GEM_PREAD, i915_gem_pread_ioctl, DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(I915_GEM_PWRITE, i915_gem_pwrite_ioctl, DRM_RENDER_ALLOW),
 	DRM_IOCTL_DEF_DRV(I915_GEM_MMAP, i915_gem_mmap_ioctl, DRM_RENDER_ALLOW),
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 0f5456046c4c..9ebe8523aa0c 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -392,6 +392,7 @@ typedef struct _drm_i915_sarea {
 #define DRM_IOCTL_I915_GEM_ENTERVT	DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_ENTERVT)
 #define DRM_IOCTL_I915_GEM_LEAVEVT	DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_LEAVEVT)
 #define DRM_IOCTL_I915_GEM_CREATE	DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CREATE, struct drm_i915_gem_create)
+#define DRM_IOCTL_I915_GEM_CREATE_EXT   DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CREATE, struct drm_i915_gem_create_ext)
 #define DRM_IOCTL_I915_GEM_PREAD	DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PREAD, struct drm_i915_gem_pread)
 #define DRM_IOCTL_I915_GEM_PWRITE	DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PWRITE, struct drm_i915_gem_pwrite)
 #define DRM_IOCTL_I915_GEM_MMAP		DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP, struct drm_i915_gem_mmap)
@@ -729,6 +730,27 @@ struct drm_i915_gem_create {
 	__u32 pad;
 };
 
+struct drm_i915_gem_create_ext {
+	/**
+	 * Requested size for the object.
+	 *
+	 * The (page-aligned) allocated size for the object will be returned.
+	 */
+	__u64 size;
+	/**
+	 * Returned handle for the object.
+	 *
+	 * Object handles are nonzero.
+	 */
+	__u32 handle;
+	__u32 pad;
+#define I915_GEM_CREATE_EXT_SETPARAM (1u << 0)
+#define I915_GEM_CREATE_EXT_FLAGS_UNKNOWN \
+	(-(I915_GEM_CREATE_EXT_SETPARAM << 1))
+	__u64 extensions;
+
+};
+
 struct drm_i915_gem_pread {
 	/** Handle for the object being read. */
 	__u32 handle;
@@ -1717,6 +1739,31 @@ struct drm_i915_gem_context_param {
 	__u64 value;
 };
 
+struct drm_i915_gem_object_param {
+	/* Object handle (0 for I915_GEM_CREATE_EXT_SETPARAM) */
+	__u32 handle;
+
+	/* Data pointer size */
+	__u32 size;
+
+/*
+ * I915_OBJECT_PARAM:
+ *
+ * Select object namespace for the param.
+ */
+#define I915_OBJECT_PARAM  (1ull << 32)
+
+	__u64 param;
+
+	/* Data value or pointer */
+	__u64 data;
+};
+
+struct drm_i915_gem_create_ext_setparam {
+	struct i915_user_extension base;
+	struct drm_i915_gem_object_param param;
+};
+
 /**
  * Context SSEU programming
  *
-- 
2.29.2

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

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

* [Intel-gfx] [PATCH v2 13/16] drm/i915/pxp: User interface for Protected buffer
  2021-03-01 19:31 [Intel-gfx] [PATCH v2 00/16] Introduce Intel PXP Daniele Ceraolo Spurio
                   ` (11 preceding siblings ...)
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 12/16] drm/i915/uapi: introduce drm_i915_gem_create_ext Daniele Ceraolo Spurio
@ 2021-03-01 19:31 ` Daniele Ceraolo Spurio
  2021-03-03 20:39   ` Lionel Landwerlin
  2021-03-03 23:33   ` Chris Wilson
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 14/16] drm/i915/pxp: Add plane decryption support Daniele Ceraolo Spurio
                   ` (6 subsequent siblings)
  19 siblings, 2 replies; 47+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-03-01 19:31 UTC (permalink / raw)
  To: intel-gfx; +Cc: Huang Sean Z, Chris Wilson, Kondapally Kalyan, Bommu Krishnaiah

From: Bommu Krishnaiah <krishnaiah.bommu@intel.com>

This api allow user mode to create Protected buffers. Only contexts
marked as protected are allowed to operate on protected buffers.

We only allow setting the flags at creation time.

All protected objects that have backing storage will be considered
invalid when the session is destroyed and they won't be usable anymore.

This is a rework of the original code by Bommu Krishnaiah. I've
authorship unchanged since significant chunks have not been modified.

v2: split context changes, fix defines and improve documentation (Chris),
    add object invalidation logic

Signed-off-by: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Telukuntla Sreedhar <sreedhar.telukuntla@intel.com>
Cc: Kondapally Kalyan <kalyan.kondapally@intel.com>
Cc: Gupta Anshuman <Anshuman.Gupta@intel.com>
Cc: Huang Sean Z <sean.z.huang@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/gem/i915_gem_create.c    | 27 +++++++++++--
 .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 10 +++++
 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  | 13 ++++++
 drivers/gpu/drm/i915/pxp/intel_pxp.c          | 40 +++++++++++++++++++
 drivers/gpu/drm/i915/pxp/intel_pxp.h          | 13 ++++++
 drivers/gpu/drm/i915/pxp/intel_pxp_types.h    |  5 +++
 include/uapi/drm/i915_drm.h                   | 22 ++++++++++
 9 files changed, 145 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c b/drivers/gpu/drm/i915/gem/i915_gem_create.c
index 3ad3413c459f..d02e5938afbe 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
@@ -5,6 +5,7 @@
 
 #include "gem/i915_gem_ioctls.h"
 #include "gem/i915_gem_region.h"
+#include "pxp/intel_pxp.h"
 
 #include "i915_drv.h"
 #include "i915_user_extensions.h"
@@ -13,7 +14,8 @@ static int
 i915_gem_create(struct drm_file *file,
 		struct intel_memory_region *mr,
 		u64 *size_p,
-		u32 *handle_p)
+		u32 *handle_p,
+		u64 user_flags)
 {
 	struct drm_i915_gem_object *obj;
 	u32 handle;
@@ -35,12 +37,17 @@ i915_gem_create(struct drm_file *file,
 
 	GEM_BUG_ON(size != obj->base.size);
 
+	obj->user_flags = user_flags;
+
 	ret = drm_gem_handle_create(file, &obj->base, &handle);
 	/* drop reference from allocate - handle holds it now */
 	i915_gem_object_put(obj);
 	if (ret)
 		return ret;
 
+	if (user_flags & I915_GEM_OBJECT_PROTECTED)
+		intel_pxp_object_add(obj);
+
 	*handle_p = handle;
 	*size_p = size;
 	return 0;
@@ -89,11 +96,12 @@ i915_gem_dumb_create(struct drm_file *file,
 	return i915_gem_create(file,
 			       intel_memory_region_by_type(to_i915(dev),
 							   mem_type),
-			       &args->size, &args->handle);
+			       &args->size, &args->handle, 0);
 }
 
 struct create_ext {
 	struct drm_i915_private *i915;
+	unsigned long user_flags;
 };
 
 static int __create_setparam(struct drm_i915_gem_object_param *args,
@@ -104,6 +112,19 @@ static int __create_setparam(struct drm_i915_gem_object_param *args,
 		return -EINVAL;
 	}
 
+	switch (lower_32_bits(args->param)) {
+	case I915_OBJECT_PARAM_PROTECTED_CONTENT:
+		if (!intel_pxp_is_enabled(&ext_data->i915->gt.pxp))
+			return -ENODEV;
+		if (args->size) {
+			return -EINVAL;
+		} else if (args->data) {
+			ext_data->user_flags |= I915_GEM_OBJECT_PROTECTED;
+			return 0;
+		}
+	break;
+	}
+
 	return -EINVAL;
 }
 
@@ -148,5 +169,5 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data,
 	return i915_gem_create(file,
 			       intel_memory_region_by_type(i915,
 							   INTEL_MEMORY_SYSTEM),
-			       &args->size, &args->handle);
+			       &args->size, &args->handle, ext_data.user_flags);
 }
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index e503c9f789c0..d10c4fcb6aec 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -20,6 +20,7 @@
 #include "gt/intel_gt_buffer_pool.h"
 #include "gt/intel_gt_pm.h"
 #include "gt/intel_ring.h"
+#include "pxp/intel_pxp.h"
 
 #include "pxp/intel_pxp.h"
 
@@ -500,6 +501,15 @@ eb_validate_vma(struct i915_execbuffer *eb,
 		     entry->offset != gen8_canonical_addr(entry->offset & I915_GTT_PAGE_MASK)))
 		return -EINVAL;
 
+	if (i915_gem_object_is_protected(vma->obj)) {
+		if (!intel_pxp_is_active(&vma->vm->gt->pxp))
+			return -ENODEV;
+		if (!i915_gem_object_has_valid_protection(vma->obj))
+			return -EIO;
+		if (!i915_gem_context_can_use_protected_content(eb->gem_context))
+			return -EPERM;
+	}
+
 	/* pad_to_size was once a reserved field, so sanitize it */
 	if (entry->flags & EXEC_OBJECT_PAD_TO_SIZE) {
 		if (unlikely(offset_in_page(entry->pad_to_size)))
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c
index 6cdff5fc5882..b321f5484ae6 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"
@@ -72,6 +73,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;
 
@@ -120,6 +123,9 @@ static void i915_gem_close_object(struct drm_gem_object *gem, struct drm_file *f
 	struct i915_lut_handle *lut, *ln;
 	LIST_HEAD(close);
 
+	if (i915_gem_object_has_valid_protection(obj))
+		intel_pxp_object_remove(obj);
+
 	spin_lock(&obj->lut_lock);
 	list_for_each_entry_safe(lut, ln, &obj->lut_list, obj_link) {
 		struct i915_gem_context *ctx = lut->ctx;
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h
index 366d23afbb1a..a1fa7539c0f7 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
@@ -274,6 +274,18 @@ i915_gem_object_needs_async_cancel(const struct drm_i915_gem_object *obj)
 	return i915_gem_object_type_has(obj, I915_GEM_OBJECT_ASYNC_CANCEL);
 }
 
+static inline bool
+i915_gem_object_is_protected(const struct drm_i915_gem_object *obj)
+{
+	return obj->user_flags & I915_GEM_OBJECT_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_is_framebuffer(const struct drm_i915_gem_object *obj)
 {
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 0a1fdbac882e..6eee580c7aba 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
@@ -167,6 +167,11 @@ struct drm_i915_gem_object {
 	} mmo;
 
 	I915_SELFTEST_DECLARE(struct list_head st_link);
+	/**
+	 * @user_flags: small set of booleans set by the user
+	 */
+	unsigned long user_flags;
+#define I915_GEM_OBJECT_PROTECTED BIT(0)
 
 	unsigned long flags;
 #define I915_BO_ALLOC_CONTIGUOUS BIT(0)
@@ -290,6 +295,14 @@ struct drm_i915_gem_object {
 		bool dirty:1;
 	} mm;
 
+	/*
+	 * 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 5912e4a12d94..03151cd7f4b8 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -69,6 +69,8 @@ void intel_pxp_init(struct intel_pxp *pxp)
 		return;
 
 	mutex_init(&pxp->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,
@@ -136,11 +138,49 @@ int intel_pxp_wait_for_termination_completion(struct intel_pxp *pxp)
 	return ret;
 }
 
+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) {
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
index e36200833095..3315b07d271b 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;
+
 #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)
@@ -38,6 +40,9 @@ void intel_pxp_init(struct intel_pxp *pxp);
 void intel_pxp_fini(struct intel_pxp *pxp);
 
 int intel_pxp_wait_for_termination_completion(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)
@@ -52,6 +57,14 @@ static inline int intel_pxp_wait_for_termination_completion(struct intel_pxp *px
 {
 	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_types.h b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
index 6f659a6f8f1c..53a2a8acfe51 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
@@ -7,8 +7,10 @@
 #define __INTEL_PXP_TYPES_H__
 
 #include <linux/completion.h>
+#include <linux/list.h>
 #include <linux/types.h>
 #include <linux/mutex.h>
+#include <linux/spinlock.h>
 #include <linux/workqueue.h>
 
 struct intel_context;
@@ -28,6 +30,9 @@ struct intel_pxp {
 	struct work_struct irq_work;
 	bool irq_enabled;
 	u32 current_events; /* protected with gt->irq_lock */
+
+	struct spinlock lock;
+	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 9ebe8523aa0c..0f8b771a6d53 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -1753,6 +1753,28 @@ struct drm_i915_gem_object_param {
  */
 #define I915_OBJECT_PARAM  (1ull << 32)
 
+/*
+ * I915_OBJECT_PARAM_PROTECTED_CONTENT:
+ *
+ * If set to true, buffer contents is expected to be protected by PXP
+ * encryption and requires decryption for scan out and processing. This is
+ * only possible on platforms that have PXP enabled, on all other scenarios
+ * setting this flag will cause the ioctl to fail and return -ENODEV.
+ *
+ * Protected buffers can only be used with contexts created using the
+ * I915_CONTEXT_PARAM_PROTECTED_CONTENT flag. The buffer contents are
+ * considered invalid after a PXP session teardown.
+ *
+ * Given the restriction above, the following errors are possible when
+ * submitting a protected object in an execbuf call:
+ *
+ * -ENODEV: PXP session not currently active
+ * -EIO: buffer has become invalid after a teardown event
+ * -EPERM: buffer submitted using a context not marked as protected
+ */
+#define I915_OBJECT_PARAM_PROTECTED_CONTENT  0x0
+/* Must be kept compact -- no holes and well documented */
+
 	__u64 param;
 
 	/* Data value or pointer */
-- 
2.29.2

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

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

* [Intel-gfx] [PATCH v2 14/16] drm/i915/pxp: Add plane decryption support
  2021-03-01 19:31 [Intel-gfx] [PATCH v2 00/16] Introduce Intel PXP Daniele Ceraolo Spurio
                   ` (12 preceding siblings ...)
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 13/16] drm/i915/pxp: User interface for Protected buffer Daniele Ceraolo Spurio
@ 2021-03-01 19:31 ` Daniele Ceraolo Spurio
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 15/16] drm/i915/pxp: black pixels on pxp disabled Daniele Ceraolo Spurio
                   ` (5 subsequent siblings)
  19 siblings, 0 replies; 47+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-03-01 19:31 UTC (permalink / raw)
  To: intel-gfx; +Cc: Huang Sean Z, 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)

Cc: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
Cc: Huang Sean Z <sean.z.huang@intel.com>
Cc: Gaurav Kumar <kumar.gaurav@intel.com>
Signed-off-by: Anshuman Gupta <anshuman.gupta@intel.com>
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
---
 drivers/gpu/drm/i915/display/skl_universal_plane.c | 14 +++++++++++---
 drivers/gpu/drm/i915/i915_reg.h                    |  1 +
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index 1f335cb09149..e42f682cbb46 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -16,6 +16,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,
@@ -971,7 +972,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);
@@ -1051,8 +1052,15 @@ 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;
+
+	if (intel_pxp_is_active(&dev_priv->gt.pxp) &&
+	    i915_gem_object_has_valid_protection(intel_fb_obj(fb)))
+		plane_surf |= PLANE_SURF_DECRYPTION_ENABLED;
+	else
+		plane_surf &= ~PLANE_SURF_DECRYPTION_ENABLED;
+
+	intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), plane_surf);
 
 	if (plane_state->scaler_id >= 0)
 		skl_program_plane_scaler(plane, crtc_state, plane_state);
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 97a6d0c638ec..3fdbcfd59b0e 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -7223,6 +7223,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_DECRYPTION_ENABLED		REG_BIT(2)
 
 #define _PLANE_OFFSET_1_B			0x711a4
 #define _PLANE_OFFSET_2_B			0x712a4
-- 
2.29.2

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

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

* [Intel-gfx] [PATCH v2 15/16] drm/i915/pxp: black pixels on pxp disabled
  2021-03-01 19:31 [Intel-gfx] [PATCH v2 00/16] Introduce Intel PXP Daniele Ceraolo Spurio
                   ` (13 preceding siblings ...)
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 14/16] drm/i915/pxp: Add plane decryption support Daniele Ceraolo Spurio
@ 2021-03-01 19:31 ` Daniele Ceraolo Spurio
  2021-03-01 19:32 ` [Intel-gfx] [PATCH v2 16/16] drm/i915/pxp: enable PXP for integrated Gen12 Daniele Ceraolo Spurio
                   ` (4 subsequent siblings)
  19 siblings, 0 replies; 47+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-03-01 19:31 UTC (permalink / raw)
  To: intel-gfx; +Cc: 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.

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>
---
 .../drm/i915/display/skl_universal_plane.c    | 40 +++++++++++++++-
 drivers/gpu/drm/i915/i915_reg.h               | 46 +++++++++++++++++++
 2 files changed, 84 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index e42f682cbb46..39986eed50f3 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -949,6 +949,33 @@ skl_main_to_aux_plane(const struct drm_framebuffer *fb, int main_plane)
 		return 0;
 }
 
+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,
@@ -1053,13 +1080,22 @@ 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));
 
 	if (intel_pxp_is_active(&dev_priv->gt.pxp) &&
-	    i915_gem_object_has_valid_protection(intel_fb_obj(fb)))
+	    i915_gem_object_has_valid_protection(intel_fb_obj(fb))) {
 		plane_surf |= PLANE_SURF_DECRYPTION_ENABLED;
-	else
+		plane_color_ctl &= ~PLANE_COLOR_PLANE_CSC_ENABLE;
+	} else if (i915_gem_object_is_protected(intel_fb_obj(fb))) {
+		intel_load_plane_csc_black(plane);
+		plane_color_ctl |= PLANE_COLOR_PLANE_CSC_ENABLE;
+	} else {
 		plane_surf &= ~PLANE_SURF_DECRYPTION_ENABLED;
+		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);
 
 	if (plane_state->scaler_id >= 0)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 3fdbcfd59b0e..6b739fc59849 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -7102,6 +7102,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			(1 << 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)
@@ -11164,6 +11165,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.29.2

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

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

* [Intel-gfx] [PATCH v2 16/16] drm/i915/pxp: enable PXP for integrated Gen12
  2021-03-01 19:31 [Intel-gfx] [PATCH v2 00/16] Introduce Intel PXP Daniele Ceraolo Spurio
                   ` (14 preceding siblings ...)
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 15/16] drm/i915/pxp: black pixels on pxp disabled Daniele Ceraolo Spurio
@ 2021-03-01 19:32 ` Daniele Ceraolo Spurio
  2021-03-03 19:56   ` Rodrigo Vivi
  2021-03-01 20:00 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for Introduce Intel PXP (rev2) Patchwork
                   ` (3 subsequent siblings)
  19 siblings, 1 reply; 47+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-03-01 19:32 UTC (permalink / raw)
  To: intel-gfx

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>
---
 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 a9f24f2bda33..f380a92e5c7c 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -880,6 +880,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 = {
@@ -908,6 +909,7 @@ static const struct intel_device_info rkl_info = {
 	.memory_regions = REGION_SMEM | REGION_LMEM, \
 	.has_master_unit_irq = 1, \
 	.has_llc = 0, \
+	.has_pxp = 0, \
 	.has_snoop = 1, \
 	.is_dgfx = 1
 
-- 
2.29.2

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

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

* [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for Introduce Intel PXP (rev2)
  2021-03-01 19:31 [Intel-gfx] [PATCH v2 00/16] Introduce Intel PXP Daniele Ceraolo Spurio
                   ` (15 preceding siblings ...)
  2021-03-01 19:32 ` [Intel-gfx] [PATCH v2 16/16] drm/i915/pxp: enable PXP for integrated Gen12 Daniele Ceraolo Spurio
@ 2021-03-01 20:00 ` Patchwork
  2021-03-01 20:01 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
                   ` (2 subsequent siblings)
  19 siblings, 0 replies; 47+ messages in thread
From: Patchwork @ 2021-03-01 20:00 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio; +Cc: intel-gfx

== Series Details ==

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

== Summary ==

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

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

-:161: WARNING:TRACING_LOGGING: Unnecessary ftrace-like logging - prefer using ftrace
#161: FILE: drivers/misc/mei/pxp/mei_pxp.c:92:
+	dev_dbg(dev, "%s\n", __func__);

-:176: WARNING:TRACING_LOGGING: Unnecessary ftrace-like logging - prefer using ftrace
#176: FILE: drivers/misc/mei/pxp/mei_pxp.c:107:
+	dev_dbg(dev, "%s\n", __func__);

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

-:42: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'dev_priv' - possible side-effects?
#42: FILE: drivers/gpu/drm/i915/i915_drv.h:1745:
+#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
c827c2625593 drm/i915/pxp: allocate a vcs context for pxp usage
-:168: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#168: 
new file mode 100644

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

-:228: WARNING:RETURN_VOID: void function return statements are not generally useful
#228: FILE: drivers/gpu/drm/i915/pxp/intel_pxp.c:56:
+	return;
+}

total: 1 errors, 2 warnings, 0 checks, 233 lines checked
e8d17e3b42bd drm/i915/pxp: set KCR reg init during the boot time
5ae54e4b7228 drm/i915/pxp: Implement funcs to create the TEE channel
-:71: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#71: 
new file mode 100644

-:93: CHECK:LINE_SPACING: Please don't use multiple blank lines
#93: FILE: drivers/gpu/drm/i915/pxp/intel_pxp_tee.c:18:
+
+

total: 0 errors, 1 warnings, 1 checks, 145 lines checked
cf600c3c742a drm/i915/pxp: Create the arbitrary session after boot
-:65: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#65: 
new file mode 100644

-:341: CHECK:UNCOMMENTED_DEFINITION: struct mutex definition without comment
#341: FILE: drivers/gpu/drm/i915/pxp/intel_pxp_types.h:20:
+	struct mutex mutex;

-:354: CHECK:LINE_SPACING: Please don't use multiple blank lines
#354: FILE: include/uapi/drm/i915_drm.h:2379:
 
+

total: 0 errors, 1 warnings, 2 checks, 288 lines checked
8113993a2d3e drm/i915/pxp: Implement arb session teardown
-:30: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#30: 
new file mode 100644

-:65: ERROR:MULTISTATEMENT_MACRO_USE_DO_WHILE: Macros with multiple statements should be enclosed in a do - while loop
#65: FILE: drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c:31:
+#define MFX_WAIT_PXP \
+	MFX_WAIT | \
+	MFX_WAIT_DW0_PXP_SYNC_CONTROL_FLAG | \
+	MFX_WAIT_DW0_MFX_SYNC_CONTROL_FLAG;

-:65: WARNING:TRAILING_SEMICOLON: macros should not use a trailing semicolon
#65: FILE: drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c:31:
+#define MFX_WAIT_PXP \
+	MFX_WAIT | \
+	MFX_WAIT_DW0_PXP_SYNC_CONTROL_FLAG | \
+	MFX_WAIT_DW0_MFX_SYNC_CONTROL_FLAG;

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

-:368: CHECK:LINE_SPACING: Please use a blank line after function/struct/union/enum declarations
#368: FILE: drivers/gpu/drm/i915/pxp/intel_pxp_irq.h:22:
+}
+void intel_pxp_irq_enable(struct intel_pxp *pxp)

-:371: CHECK:LINE_SPACING: Please use a blank line after function/struct/union/enum declarations
#371: FILE: drivers/gpu/drm/i915/pxp/intel_pxp_irq.h:25:
+}
+void intel_pxp_irq_disable(struct intel_pxp *pxp)

-:374: CHECK:LINE_SPACING: Please use a blank line after function/struct/union/enum declarations
#374: FILE: drivers/gpu/drm/i915/pxp/intel_pxp_irq.h:28:
+}
+static inline void intel_pxp_irq_handler(struct intel_pxp *pxp, u16 iir)

total: 0 errors, 1 warnings, 3 checks, 384 lines checked
9e8f422996d7 drm/i915/pxp: Enable PXP power management
-:123: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#123: 
new file mode 100644

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

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

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

total: 0 errors, 1 warnings, 3 checks, 284 lines checked
0d03068b552a drm/i915/pxp: interface for creation of protected contexts
-:23: WARNING:BAD_SIGN_OFF: Duplicate signature
#23: 
Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>

-:322: ERROR:TRAILING_WHITESPACE: trailing whitespace
#322: FILE: include/uapi/drm/i915_drm.h:1707:
+ * Given the numerous restriction on this flag, there are several unique $

total: 1 errors, 1 warnings, 0 checks, 265 lines checked
e568c1b52ed7 drm/i915/uapi: introduce drm_i915_gem_create_ext
-:106: WARNING:LONG_LINE: line length of 120 exceeds 100 columns
#106: FILE: include/uapi/drm/i915_drm.h:395:
+#define DRM_IOCTL_I915_GEM_CREATE_EXT   DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CREATE, struct drm_i915_gem_create_ext)

total: 0 errors, 1 warnings, 0 checks, 135 lines checked
f99a324742e0 drm/i915/pxp: User interface for Protected buffer
-:317: CHECK:LINE_SPACING: Please use a blank line after function/struct/union/enum declarations
#317: FILE: drivers/gpu/drm/i915/pxp/intel_pxp.h:65:
+}
+static inline void intel_pxp_object_remove(struct drm_i915_gem_object *obj)

-:343: WARNING:USE_SPINLOCK_T: struct spinlock should be spinlock_t
#343: FILE: drivers/gpu/drm/i915/pxp/intel_pxp_types.h:34:
+	struct spinlock lock;

total: 0 errors, 1 warnings, 1 checks, 295 lines checked
de691ae4574f drm/i915/pxp: Add plane decryption support
13f73d6d4665 drm/i915/pxp: black pixels on pxp disabled
-:110: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'pipe' - possible side-effects?
#110: FILE: drivers/gpu/drm/i915/i915_reg.h:11181:
+#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)

-:110: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'index' - possible side-effects?
#110: FILE: drivers/gpu/drm/i915/i915_reg.h:11181:
+#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)

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

-:124: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'pipe' - possible side-effects?
#124: FILE: drivers/gpu/drm/i915/i915_reg.h:11195:
+#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)

-:124: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'index' - possible side-effects?
#124: FILE: drivers/gpu/drm/i915/i915_reg.h:11195:
+#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)

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

-:138: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'pipe' - possible side-effects?
#138: FILE: drivers/gpu/drm/i915/i915_reg.h:11209:
+#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)

-:138: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'index' - possible side-effects?
#138: FILE: drivers/gpu/drm/i915/i915_reg.h:11209:
+#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)

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

total: 0 errors, 3 warnings, 6 checks, 115 lines checked
4f113650134a 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] 47+ messages in thread

* [Intel-gfx] ✗ Fi.CI.SPARSE: warning for Introduce Intel PXP (rev2)
  2021-03-01 19:31 [Intel-gfx] [PATCH v2 00/16] Introduce Intel PXP Daniele Ceraolo Spurio
                   ` (16 preceding siblings ...)
  2021-03-01 20:00 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for Introduce Intel PXP (rev2) Patchwork
@ 2021-03-01 20:01 ` Patchwork
  2021-03-01 20:28 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
  2021-03-01 20:35 ` [Intel-gfx] ✓ Fi.CI.IGT: " Patchwork
  19 siblings, 0 replies; 47+ messages in thread
From: Patchwork @ 2021-03-01 20:01 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio; +Cc: intel-gfx

== Series Details ==

Series: Introduce Intel PXP (rev2)
URL   : https://patchwork.freedesktop.org/series/86798/
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/gt/intel_reset.c:1323:5: warning: context imbalance in 'intel_gt_reset_trylock' - different lock contexts for basic block
+drivers/gpu/drm/i915/gvt/mmio.c:295:23: warning: memcpy with byte count of 279040
+drivers/gpu/drm/i915/i915_perf.c:1437:15: warning: memset with byte count of 16777216
+drivers/gpu/drm/i915/i915_perf.c:1491:15: warning: memset with byte count of 16777216
+./drivers/gpu/drm/i915/pxp/intel_pxp_irq.h:19:6: warning: symbol 'intel_pxp_irq_init' was not declared. Should it be static?
+./drivers/gpu/drm/i915/pxp/intel_pxp_irq.h:22:6: warning: symbol 'intel_pxp_irq_enable' was not declared. Should it be static?
+./drivers/gpu/drm/i915/pxp/intel_pxp_irq.h:25:6: warning: symbol 'intel_pxp_irq_disable' was not declared. Should it be static?
+./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


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

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

* [Intel-gfx] ✓ Fi.CI.BAT: success for Introduce Intel PXP (rev2)
  2021-03-01 19:31 [Intel-gfx] [PATCH v2 00/16] Introduce Intel PXP Daniele Ceraolo Spurio
                   ` (17 preceding siblings ...)
  2021-03-01 20:01 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
@ 2021-03-01 20:28 ` Patchwork
  2021-03-01 20:35 ` [Intel-gfx] ✓ Fi.CI.IGT: " Patchwork
  19 siblings, 0 replies; 47+ messages in thread
From: Patchwork @ 2021-03-01 20:28 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio; +Cc: intel-gfx


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

== Series Details ==

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

== Summary ==

CI Bug Log - changes from CI_DRM_9818 -> Patchwork_19737
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

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

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

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

### IGT changes ###

#### Issues hit ####

  * igt@amdgpu/amd_basic@semaphore:
    - fi-icl-y:           NOTRUN -> [SKIP][1] ([fdo#109315]) +17 similar issues
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19737/fi-icl-y/igt@amdgpu/amd_basic@semaphore.html

  * igt@gem_exec_fence@basic-busy@bcs0:
    - fi-apl-guc:         NOTRUN -> [SKIP][2] ([fdo#109271]) +1 similar issue
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19737/fi-apl-guc/igt@gem_exec_fence@basic-busy@bcs0.html

  * igt@gem_exec_suspend@basic-s3:
    - fi-tgl-u2:          [PASS][3] -> [FAIL][4] ([i915#1888])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9818/fi-tgl-u2/igt@gem_exec_suspend@basic-s3.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19737/fi-tgl-u2/igt@gem_exec_suspend@basic-s3.html

  * igt@gem_huc_copy@huc-copy:
    - fi-icl-y:           NOTRUN -> [SKIP][5] ([i915#2190])
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19737/fi-icl-y/igt@gem_huc_copy@huc-copy.html

  * igt@i915_hangman@error-state-basic:
    - fi-apl-guc:         NOTRUN -> [DMESG-WARN][6] ([i915#1610])
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19737/fi-apl-guc/igt@i915_hangman@error-state-basic.html

  * igt@kms_chamelium@dp-crc-fast:
    - fi-icl-y:           NOTRUN -> [SKIP][7] ([fdo#109284] / [fdo#111827]) +8 similar issues
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19737/fi-icl-y/igt@kms_chamelium@dp-crc-fast.html

  * igt@kms_chamelium@hdmi-crc-fast:
    - fi-bsw-n3050:       NOTRUN -> [SKIP][8] ([fdo#109271] / [fdo#111827]) +8 similar issues
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19737/fi-bsw-n3050/igt@kms_chamelium@hdmi-crc-fast.html

  * igt@kms_force_connector_basic@force-load-detect:
    - fi-icl-y:           NOTRUN -> [SKIP][9] ([fdo#109285])
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19737/fi-icl-y/igt@kms_force_connector_basic@force-load-detect.html

  * igt@kms_pipe_crc_basic@compare-crc-sanitycheck-pipe-d:
    - fi-icl-y:           NOTRUN -> [SKIP][10] ([fdo#109278])
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19737/fi-icl-y/igt@kms_pipe_crc_basic@compare-crc-sanitycheck-pipe-d.html

  * igt@kms_pipe_crc_basic@hang-read-crc-pipe-a:
    - fi-bsw-n3050:       NOTRUN -> [SKIP][11] ([fdo#109271]) +39 similar issues
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19737/fi-bsw-n3050/igt@kms_pipe_crc_basic@hang-read-crc-pipe-a.html

  * igt@kms_psr@primary_mmap_gtt:
    - fi-icl-y:           NOTRUN -> [SKIP][12] ([fdo#110189]) +3 similar issues
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19737/fi-icl-y/igt@kms_psr@primary_mmap_gtt.html

  * igt@prime_self_import@basic-with_two_bos:
    - fi-tgl-y:           [PASS][13] -> [DMESG-WARN][14] ([i915#402])
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9818/fi-tgl-y/igt@prime_self_import@basic-with_two_bos.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19737/fi-tgl-y/igt@prime_self_import@basic-with_two_bos.html

  * igt@runner@aborted:
    - fi-apl-guc:         NOTRUN -> [FAIL][15] ([i915#2426])
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19737/fi-apl-guc/igt@runner@aborted.html

  
#### Possible fixes ####

  * igt@fbdev@read:
    - fi-tgl-y:           [DMESG-WARN][16] ([i915#402]) -> [PASS][17] +1 similar issue
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9818/fi-tgl-y/igt@fbdev@read.html
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19737/fi-tgl-y/igt@fbdev@read.html

  * igt@gem_exec_gttfill@basic:
    - fi-kbl-8809g:       [TIMEOUT][18] -> [PASS][19]
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9818/fi-kbl-8809g/igt@gem_exec_gttfill@basic.html
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19737/fi-kbl-8809g/igt@gem_exec_gttfill@basic.html

  * igt@gem_linear_blits@basic:
    - fi-kbl-8809g:       [TIMEOUT][20] ([i915#2502]) -> [PASS][21] +1 similar issue
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9818/fi-kbl-8809g/igt@gem_linear_blits@basic.html
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19737/fi-kbl-8809g/igt@gem_linear_blits@basic.html

  * igt@kms_chamelium@hdmi-edid-read:
    - fi-kbl-7500u:       [FAIL][22] ([i915#2128]) -> [PASS][23]
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9818/fi-kbl-7500u/igt@kms_chamelium@hdmi-edid-read.html
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_19737/fi-kbl-7500u/igt@kms_chamelium@hdmi-edid-read.html

  
  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#109278]: https://bugs.freedesktop.org/show_bug.cgi?id=109278
  [fdo#109284]: https://bugs.freedesktop.org/show_bug.cgi?id=109284
  [fdo#109285]: https://bugs.freedesktop.org/show_bug.cgi?id=109285
  [fdo#109315]: https://bugs.freedesktop.org/show_bug.cgi?id=109315
  [fdo#110189]: https://bugs.freedesktop.org/show_bug.cgi?id=110189
  [fdo#111827]: https://bugs.freedesktop.org/show_bug.cgi?id=111827
  [i915#1610]: https://gitlab.freedesktop.org/drm/intel/issues/1610
  [i915#1888]: https://gitlab.freedesktop.org/drm/intel/issues/1888
  [i915#2128]: https://gitlab.freedesktop.org/drm/intel/issues/2128
  [i915#2190]: https://gitlab.freedesktop.org/drm/intel/issues/2190
  [i915#2426]: https://gitlab.freedesktop.org/drm/intel/issues/2426
  [i915#2502]: https://gitlab.freedesktop.org/drm/intel/issues/2502
  [i915#402]: https://gitlab.freedesktop.org/drm/intel/issues/402


Participating hosts (42 -> 41)
------------------------------

  Additional (3): fi-icl-y fi-apl-guc fi-bsw-n3050 
  Missing    (4): fi-ctg-p8600 fi-ilk-m540 fi-bsw-cyan fi-bdw-samus 


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

  * Linux: CI_DRM_9818 -> Patchwork_19737

  CI-20190529: 20190529
  CI_DRM_9818: fb3b93df7979b1cf6b69ac801d1703c0bf1dde66 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_6016: 2107b0a53692fb329175bc16169c3699712187aa @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_19737: 4f113650134a412185b462d93608cbfc3c7bf818 @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

4f113650134a drm/i915/pxp: enable PXP for integrated Gen12
13f73d6d4665 drm/i915/pxp: black pixels on pxp disabled
de691ae4574f drm/i915/pxp: Add plane decryption support
f99a324742e0 drm/i915/pxp: User interface for Protected buffer
e568c1b52ed7 drm/i915/uapi: introduce drm_i915_gem_create_ext
0d03068b552a drm/i915/pxp: interface for creation of protected contexts
9e8f422996d7 drm/i915/pxp: Enable PXP power management
ebfeffa20951 drm/i915/pxp: Implement PXP irq handler
8113993a2d3e drm/i915/pxp: Implement arb session teardown
cf600c3c742a drm/i915/pxp: Create the arbitrary session after boot
5ae54e4b7228 drm/i915/pxp: Implement funcs to create the TEE channel
e8d17e3b42bd drm/i915/pxp: set KCR reg init during the boot time
c827c2625593 drm/i915/pxp: allocate a vcs context for pxp usage
82f987002778 drm/i915/pxp: define PXP device flag and kconfig
b39091843fc5 mei: pxp: export pavp client to me client bus
d3a311348975 drm/i915/pxp: Define PXP component interface

== Logs ==

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

[-- Attachment #1.2: Type: text/html, Size: 9094 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] 47+ messages in thread

* [Intel-gfx] ✓ Fi.CI.IGT: success for Introduce Intel PXP (rev2)
  2021-03-01 19:31 [Intel-gfx] [PATCH v2 00/16] Introduce Intel PXP Daniele Ceraolo Spurio
                   ` (18 preceding siblings ...)
  2021-03-01 20:28 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
@ 2021-03-01 20:35 ` Patchwork
  19 siblings, 0 replies; 47+ messages in thread
From: Patchwork @ 2021-03-01 20:35 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio; +Cc: intel-gfx


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

== Series Details ==

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

== Summary ==

CI Bug Log - changes from CI_DRM_9818_full -> Patchwork_19737_full
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

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


Changes
-------

  No changes found


Participating hosts (10 -> 8)
------------------------------

  Missing    (2): pig-kbl-iris pig-icl-1065g7 


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

  * CI: CI-20190529 -> None
  * Linux: CI_DRM_9818 -> Patchwork_19737
  * Piglit: piglit_4509 -> None

  CI-20190529: 20190529
  CI_DRM_9818: fb3b93df7979b1cf6b69ac801d1703c0bf1dde66 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_6016: 2107b0a53692fb329175bc16169c3699712187aa @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_19737: 4f113650134a412185b462d93608cbfc3c7bf818 @ git://anongit.freedesktop.org/gfx-ci/linux
  piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit

== Logs ==

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

[-- Attachment #1.2: Type: text/html, Size: 1810 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] 47+ messages in thread

* Re: [Intel-gfx] [PATCH v2 01/16] drm/i915/pxp: Define PXP component interface
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 01/16] drm/i915/pxp: Define PXP component interface Daniele Ceraolo Spurio
@ 2021-03-03 19:51   ` Rodrigo Vivi
  0 siblings, 0 replies; 47+ messages in thread
From: Rodrigo Vivi @ 2021-03-03 19:51 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio; +Cc: intel-gfx

On Mon, Mar 01, 2021 at 11:31:45AM -0800, Daniele Ceraolo Spurio 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>
> + */
> +
> +#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.29.2
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH v2 16/16] drm/i915/pxp: enable PXP for integrated Gen12
  2021-03-01 19:32 ` [Intel-gfx] [PATCH v2 16/16] drm/i915/pxp: enable PXP for integrated Gen12 Daniele Ceraolo Spurio
@ 2021-03-03 19:56   ` Rodrigo Vivi
  0 siblings, 0 replies; 47+ messages in thread
From: Rodrigo Vivi @ 2021-03-03 19:56 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio; +Cc: intel-gfx

On Mon, Mar 01, 2021 at 11:32:00AM -0800, Daniele Ceraolo Spurio wrote:
> 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 a9f24f2bda33..f380a92e5c7c 100644
> --- a/drivers/gpu/drm/i915/i915_pci.c
> +++ b/drivers/gpu/drm/i915/i915_pci.c
> @@ -880,6 +880,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 = {
> @@ -908,6 +909,7 @@ static const struct intel_device_info rkl_info = {
>  	.memory_regions = REGION_SMEM | REGION_LMEM, \
>  	.has_master_unit_irq = 1, \
>  	.has_llc = 0, \
> +	.has_pxp = 0, \
>  	.has_snoop = 1, \
>  	.is_dgfx = 1
>  
> -- 
> 2.29.2
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH v2 13/16] drm/i915/pxp: User interface for Protected buffer
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 13/16] drm/i915/pxp: User interface for Protected buffer Daniele Ceraolo Spurio
@ 2021-03-03 20:39   ` Lionel Landwerlin
  2021-03-03 21:59     ` Daniele Ceraolo Spurio
  2021-03-03 23:33   ` Chris Wilson
  1 sibling, 1 reply; 47+ messages in thread
From: Lionel Landwerlin @ 2021-03-03 20:39 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio, intel-gfx
  Cc: Bommu Krishnaiah, Kondapally Kalyan, Huang Sean Z, Chris Wilson

On 01/03/2021 21:31, Daniele Ceraolo Spurio wrote:
> From: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
>
> This api allow user mode to create Protected buffers. Only contexts
> marked as protected are allowed to operate on protected buffers.
>
> We only allow setting the flags at creation time.
>
> All protected objects that have backing storage will be considered
> invalid when the session is destroyed and they won't be usable anymore.
>
> This is a rework of the original code by Bommu Krishnaiah. I've
> authorship unchanged since significant chunks have not been modified.
>
> v2: split context changes, fix defines and improve documentation (Chris),
>      add object invalidation logic
>
> Signed-off-by: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
> Cc: Telukuntla Sreedhar <sreedhar.telukuntla@intel.com>
> Cc: Kondapally Kalyan <kalyan.kondapally@intel.com>
> Cc: Gupta Anshuman <Anshuman.Gupta@intel.com>
> Cc: Huang Sean Z <sean.z.huang@intel.com>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> ---
>   drivers/gpu/drm/i915/gem/i915_gem_create.c    | 27 +++++++++++--
>   .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 10 +++++
>   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  | 13 ++++++
>   drivers/gpu/drm/i915/pxp/intel_pxp.c          | 40 +++++++++++++++++++
>   drivers/gpu/drm/i915/pxp/intel_pxp.h          | 13 ++++++
>   drivers/gpu/drm/i915/pxp/intel_pxp_types.h    |  5 +++
>   include/uapi/drm/i915_drm.h                   | 22 ++++++++++
>   9 files changed, 145 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c b/drivers/gpu/drm/i915/gem/i915_gem_create.c
> index 3ad3413c459f..d02e5938afbe 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
> @@ -5,6 +5,7 @@
>   
>   #include "gem/i915_gem_ioctls.h"
>   #include "gem/i915_gem_region.h"
> +#include "pxp/intel_pxp.h"
>   
>   #include "i915_drv.h"
>   #include "i915_user_extensions.h"
> @@ -13,7 +14,8 @@ static int
>   i915_gem_create(struct drm_file *file,
>   		struct intel_memory_region *mr,
>   		u64 *size_p,
> -		u32 *handle_p)
> +		u32 *handle_p,
> +		u64 user_flags)
>   {
>   	struct drm_i915_gem_object *obj;
>   	u32 handle;
> @@ -35,12 +37,17 @@ i915_gem_create(struct drm_file *file,
>   
>   	GEM_BUG_ON(size != obj->base.size);
>   
> +	obj->user_flags = user_flags;
> +
>   	ret = drm_gem_handle_create(file, &obj->base, &handle);
>   	/* drop reference from allocate - handle holds it now */
>   	i915_gem_object_put(obj);
>   	if (ret)
>   		return ret;
>   
> +	if (user_flags & I915_GEM_OBJECT_PROTECTED)
> +		intel_pxp_object_add(obj);
> +
>   	*handle_p = handle;
>   	*size_p = size;
>   	return 0;
> @@ -89,11 +96,12 @@ i915_gem_dumb_create(struct drm_file *file,
>   	return i915_gem_create(file,
>   			       intel_memory_region_by_type(to_i915(dev),
>   							   mem_type),
> -			       &args->size, &args->handle);
> +			       &args->size, &args->handle, 0);
>   }
>   
>   struct create_ext {
>   	struct drm_i915_private *i915;
> +	unsigned long user_flags;
>   };
>   
>   static int __create_setparam(struct drm_i915_gem_object_param *args,
> @@ -104,6 +112,19 @@ static int __create_setparam(struct drm_i915_gem_object_param *args,
>   		return -EINVAL;
>   	}
>   
> +	switch (lower_32_bits(args->param)) {
> +	case I915_OBJECT_PARAM_PROTECTED_CONTENT:
> +		if (!intel_pxp_is_enabled(&ext_data->i915->gt.pxp))
> +			return -ENODEV;
> +		if (args->size) {
> +			return -EINVAL;
> +		} else if (args->data) {
> +			ext_data->user_flags |= I915_GEM_OBJECT_PROTECTED;
> +			return 0;
> +		}
> +	break;
> +	}
> +
>   	return -EINVAL;
>   }
>   
> @@ -148,5 +169,5 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data,
>   	return i915_gem_create(file,
>   			       intel_memory_region_by_type(i915,
>   							   INTEL_MEMORY_SYSTEM),
> -			       &args->size, &args->handle);
> +			       &args->size, &args->handle, ext_data.user_flags);
>   }
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> index e503c9f789c0..d10c4fcb6aec 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> @@ -20,6 +20,7 @@
>   #include "gt/intel_gt_buffer_pool.h"
>   #include "gt/intel_gt_pm.h"
>   #include "gt/intel_ring.h"
> +#include "pxp/intel_pxp.h"
>   
>   #include "pxp/intel_pxp.h"
>   
> @@ -500,6 +501,15 @@ eb_validate_vma(struct i915_execbuffer *eb,
>   		     entry->offset != gen8_canonical_addr(entry->offset & I915_GTT_PAGE_MASK)))
>   		return -EINVAL;
>   
> +	if (i915_gem_object_is_protected(vma->obj)) {
> +		if (!intel_pxp_is_active(&vma->vm->gt->pxp))
> +			return -ENODEV;
> +		if (!i915_gem_object_has_valid_protection(vma->obj))
> +			return -EIO;
> +		if (!i915_gem_context_can_use_protected_content(eb->gem_context))
> +			return -EPERM;


I think I'm running into this error.

When running vkcube protected under wayland, it takes down the entire 
session (Xorg & gnome-shell depending on which one is going to use the 
protected buffer first).

That's a bit harsh.


We probably don't want this. After all the point of encryption is that 
even if you can read the buffer you won't be able to make much of its 
content.

Also useful to know you're dealing for debugging ;)


-Lionel


> +	}
> +
>   	/* pad_to_size was once a reserved field, so sanitize it */
>   	if (entry->flags & EXEC_OBJECT_PAD_TO_SIZE) {
>   		if (unlikely(offset_in_page(entry->pad_to_size)))
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c
> index 6cdff5fc5882..b321f5484ae6 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"
> @@ -72,6 +73,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;
>   
> @@ -120,6 +123,9 @@ static void i915_gem_close_object(struct drm_gem_object *gem, struct drm_file *f
>   	struct i915_lut_handle *lut, *ln;
>   	LIST_HEAD(close);
>   
> +	if (i915_gem_object_has_valid_protection(obj))
> +		intel_pxp_object_remove(obj);
> +
>   	spin_lock(&obj->lut_lock);
>   	list_for_each_entry_safe(lut, ln, &obj->lut_list, obj_link) {
>   		struct i915_gem_context *ctx = lut->ctx;
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h
> index 366d23afbb1a..a1fa7539c0f7 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
> @@ -274,6 +274,18 @@ i915_gem_object_needs_async_cancel(const struct drm_i915_gem_object *obj)
>   	return i915_gem_object_type_has(obj, I915_GEM_OBJECT_ASYNC_CANCEL);
>   }
>   
> +static inline bool
> +i915_gem_object_is_protected(const struct drm_i915_gem_object *obj)
> +{
> +	return obj->user_flags & I915_GEM_OBJECT_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_is_framebuffer(const struct drm_i915_gem_object *obj)
>   {
> 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 0a1fdbac882e..6eee580c7aba 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> @@ -167,6 +167,11 @@ struct drm_i915_gem_object {
>   	} mmo;
>   
>   	I915_SELFTEST_DECLARE(struct list_head st_link);
> +	/**
> +	 * @user_flags: small set of booleans set by the user
> +	 */
> +	unsigned long user_flags;
> +#define I915_GEM_OBJECT_PROTECTED BIT(0)
>   
>   	unsigned long flags;
>   #define I915_BO_ALLOC_CONTIGUOUS BIT(0)
> @@ -290,6 +295,14 @@ struct drm_i915_gem_object {
>   		bool dirty:1;
>   	} mm;
>   
> +	/*
> +	 * 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 5912e4a12d94..03151cd7f4b8 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
> @@ -69,6 +69,8 @@ void intel_pxp_init(struct intel_pxp *pxp)
>   		return;
>   
>   	mutex_init(&pxp->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,
> @@ -136,11 +138,49 @@ int intel_pxp_wait_for_termination_completion(struct intel_pxp *pxp)
>   	return ret;
>   }
>   
> +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) {
> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
> index e36200833095..3315b07d271b 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;
> +
>   #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)
> @@ -38,6 +40,9 @@ void intel_pxp_init(struct intel_pxp *pxp);
>   void intel_pxp_fini(struct intel_pxp *pxp);
>   
>   int intel_pxp_wait_for_termination_completion(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)
> @@ -52,6 +57,14 @@ static inline int intel_pxp_wait_for_termination_completion(struct intel_pxp *px
>   {
>   	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_types.h b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
> index 6f659a6f8f1c..53a2a8acfe51 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
> @@ -7,8 +7,10 @@
>   #define __INTEL_PXP_TYPES_H__
>   
>   #include <linux/completion.h>
> +#include <linux/list.h>
>   #include <linux/types.h>
>   #include <linux/mutex.h>
> +#include <linux/spinlock.h>
>   #include <linux/workqueue.h>
>   
>   struct intel_context;
> @@ -28,6 +30,9 @@ struct intel_pxp {
>   	struct work_struct irq_work;
>   	bool irq_enabled;
>   	u32 current_events; /* protected with gt->irq_lock */
> +
> +	struct spinlock lock;
> +	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 9ebe8523aa0c..0f8b771a6d53 100644
> --- a/include/uapi/drm/i915_drm.h
> +++ b/include/uapi/drm/i915_drm.h
> @@ -1753,6 +1753,28 @@ struct drm_i915_gem_object_param {
>    */
>   #define I915_OBJECT_PARAM  (1ull << 32)
>   
> +/*
> + * I915_OBJECT_PARAM_PROTECTED_CONTENT:
> + *
> + * If set to true, buffer contents is expected to be protected by PXP
> + * encryption and requires decryption for scan out and processing. This is
> + * only possible on platforms that have PXP enabled, on all other scenarios
> + * setting this flag will cause the ioctl to fail and return -ENODEV.
> + *
> + * Protected buffers can only be used with contexts created using the
> + * I915_CONTEXT_PARAM_PROTECTED_CONTENT flag. The buffer contents are
> + * considered invalid after a PXP session teardown.
> + *
> + * Given the restriction above, the following errors are possible when
> + * submitting a protected object in an execbuf call:
> + *
> + * -ENODEV: PXP session not currently active
> + * -EIO: buffer has become invalid after a teardown event
> + * -EPERM: buffer submitted using a context not marked as protected
> + */
> +#define I915_OBJECT_PARAM_PROTECTED_CONTENT  0x0
> +/* Must be kept compact -- no holes and well documented */
> +
>   	__u64 param;
>   
>   	/* Data value or pointer */


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

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

* Re: [Intel-gfx] [PATCH v2 09/16] drm/i915/pxp: Implement PXP irq handler
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 09/16] drm/i915/pxp: Implement PXP irq handler Daniele Ceraolo Spurio
@ 2021-03-03 21:18   ` Chris Wilson
  2021-03-08 18:49     ` Daniele Ceraolo Spurio
  2021-03-03 22:42   ` Chris Wilson
  2021-03-03 22:45   ` Chris Wilson
  2 siblings, 1 reply; 47+ messages in thread
From: Chris Wilson @ 2021-03-03 21:18 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio, intel-gfx; +Cc: Huang, Huang, Sean Z

Quoting Daniele Ceraolo Spurio (2021-03-01 19:31:53)
> 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.
> 
> v2: use struct completion instead of bool (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>
> ---
>  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         |  34 +++++
>  drivers/gpu/drm/i915/pxp/intel_pxp.h         |  16 ++
>  drivers/gpu/drm/i915/pxp/intel_pxp_irq.c     | 151 +++++++++++++++++++
>  drivers/gpu/drm/i915/pxp/intel_pxp_irq.h     |  33 ++++
>  drivers/gpu/drm/i915/pxp/intel_pxp_session.c |   9 +-
>  drivers/gpu/drm/i915/pxp/intel_pxp_session.h |   1 +
>  drivers/gpu/drm/i915/pxp/intel_pxp_tee.c     |  10 +-
>  drivers/gpu/drm/i915/pxp/intel_pxp_types.h   |   8 +
>  11 files changed, 268 insertions(+), 3 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 8b605f326039..5e9bd34dec38 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -274,6 +274,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 d29126c458ba..0d3585efe2b8 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);
>  }
> @@ -190,6 +194,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 e5dd0203991b..97a6d0c638ec 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -7958,6 +7958,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 cbec9395bde9..0ca1c2c16972 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_tee.h"
>  #include "gt/intel_context.h"
>  #include "i915_drv.h"
> @@ -67,12 +69,23 @@ void intel_pxp_init(struct intel_pxp *pxp)
>  
>         mutex_init(&pxp->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);
> +
>         kcr_pxp_enable(gt);
>  
>         ret = create_vcs_context(pxp);
>         if (ret)
>                 goto out_kcr;
>  
> +       intel_pxp_irq_init(pxp);
> +       intel_pxp_irq_enable(pxp);
> +
>         ret = intel_pxp_tee_component_init(pxp);
>         if (ret)
>                 goto out_context;
> @@ -94,10 +107,31 @@ void intel_pxp_fini(struct intel_pxp *pxp)
>         if (!intel_pxp_is_enabled(pxp))
>                 return;
>  
> +       intel_pxp_irq_disable(pxp);
> +
>         intel_pxp_tee_component_fini(pxp);
>  
>         destroy_vcs_context(pxp);
>  
>         kcr_pxp_disable(gt);
> +}
>  
> +int intel_pxp_wait_for_termination_completion(struct intel_pxp *pxp)
> +{
> +       int ret;
> +
> +       if (!intel_pxp_is_enabled(pxp))
> +               return 0;
> +
> +       ret = wait_for_completion_timeout(&pxp->termination,
> +                                         msecs_to_jiffies(100));
> +
> +       /* the wait returns 0 on failure */
> +       if (ret)
> +               ret = 0;
> +       else
> +               ret = -ETIMEDOUT;
> +
> +       return ret;
>  }
> +
> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
> index 3bede9306481..89cf66c9bef3 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
> @@ -9,6 +9,15 @@
>  #include "gt/intel_gt_types.h"
>  #include "intel_pxp_types.h"
>  
> +#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)
> +
>  static inline struct intel_gt *pxp_to_gt(const struct intel_pxp *pxp)
>  {
>         return container_of(pxp, struct intel_gt, pxp);
> @@ -27,6 +36,8 @@ static inline bool intel_pxp_is_active(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);
> +
> +int intel_pxp_wait_for_termination_completion(struct intel_pxp *pxp);
>  #else
>  static inline void intel_pxp_init(struct intel_pxp *pxp)
>  {
> @@ -35,6 +46,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_termination_completion(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..40115bf0b6bb
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
> @@ -0,0 +1,151 @@
> +// 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"
> +
> +static int pxp_terminate(struct intel_pxp *pxp)
> +{
> +       int ret = 0;
> +
> +       mutex_lock(&pxp->mutex);
> +
> +       pxp->global_state_attacked = true;
> +
> +       ret = intel_pxp_arb_terminate_session_with_global_terminate(pxp);
> +
> +       mutex_unlock(&pxp->mutex);
> +
> +       return ret;
> +}
> +
> +static int pxp_terminate_complete(struct intel_pxp *pxp)
> +{
> +       int ret = 0;
> +
> +       mutex_lock(&pxp->mutex);
> +
> +       if (pxp->global_state_attacked) {
> +               pxp->global_state_attacked = false;
> +
> +               /* Re-create the arb session after teardown handle complete */
> +               ret = intel_pxp_create_arb_session(pxp);
> +       }

	/* Re-create the arb session after teardown handle complete */
	if (fetch_and_zero(&pxp->global_state_attacked))
		ret = intel_pxp_create_arb_session(pxp);

> +
> +       mutex_unlock(&pxp->mutex);
> +
> +       complete_all(&pxp->termination);
> +
> +       return ret;
> +}
> +
> +static void intel_pxp_irq_work(struct work_struct *work)
> +{
> +       struct intel_pxp *pxp = container_of(work, typeof(*pxp), irq_work);
> +       struct intel_gt *gt = pxp_to_gt(pxp);
> +       u32 events = 0;
> +
> +       spin_lock_irq(&gt->irq_lock);
> +       events = fetch_and_zero(&pxp->current_events);
> +       spin_unlock_irq(&gt->irq_lock);
> +
> +       if (!events)
> +               return;
> +
> +       if (events & (GEN12_DISPLAY_PXP_STATE_TERMINATED_INTERRUPT |
> +                     GEN12_DISPLAY_APP_TERMINATED_PER_FW_REQ_INTERRUPT))
> +               pxp_terminate(pxp);
> +
> +       if (events & GEN12_DISPLAY_STATE_RESET_COMPLETE_INTERRUPT)
> +               pxp_terminate_complete(pxp);
> +
> +       /*
> +        * we expect the terminate complete to arrive quickly after emitting
> +        * the terminate, so check back on it
> +        */
> +       if (pxp->irq_enabled)
> +               queue_work(system_unbound_wq, &pxp->irq_work);

pxp->current_events is only updated in the interrupt handler, so running
the work before the irq gains nothing.

> +}
> +
> +/**
> + * 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;
> +
> +       /* immediately mark PXP as inactive on termination */
> +       if (iir & (GEN12_DISPLAY_PXP_STATE_TERMINATED_INTERRUPT |
> +                  GEN12_DISPLAY_APP_TERMINATED_PER_FW_REQ_INTERRUPT))
> +               intel_pxp_mark_termination_in_progress(pxp);
> +
> +       pxp->current_events |= iir;
> +       queue_work(system_unbound_wq, &pxp->irq_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_init(struct intel_pxp *pxp)
> +{
> +       INIT_WORK(&pxp->irq_work, intel_pxp_irq_work);
> +}
> +
> +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);
> +
> +       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->irq_work);

As I read it, if the session was in play at the time of irq_disable and
there were inflight interrupts then the state of the session at the end
of this function is undefined.

Should the session be terminated prior to disabling irq (that would seem
appropriate for the driver flow)? Certainly at the point of
unregistering the driver from userspace, all user sessions should cease.

Is an assert like GEM_BUG_ON(!completion_done(&pxp->termination)); valid
here?
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH v2 13/16] drm/i915/pxp: User interface for Protected buffer
  2021-03-03 20:39   ` Lionel Landwerlin
@ 2021-03-03 21:59     ` Daniele Ceraolo Spurio
  2021-03-03 23:16       ` Lionel Landwerlin
  0 siblings, 1 reply; 47+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-03-03 21:59 UTC (permalink / raw)
  To: Lionel Landwerlin, intel-gfx
  Cc: Huang Sean Z, Chris Wilson, Kondapally Kalyan, Bommu Krishnaiah



On 3/3/2021 12:39 PM, Lionel Landwerlin wrote:
> On 01/03/2021 21:31, Daniele Ceraolo Spurio wrote:
>> From: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
>>
>> This api allow user mode to create Protected buffers. Only contexts
>> marked as protected are allowed to operate on protected buffers.
>>
>> We only allow setting the flags at creation time.
>>
>> All protected objects that have backing storage will be considered
>> invalid when the session is destroyed and they won't be usable anymore.
>>
>> This is a rework of the original code by Bommu Krishnaiah. I've
>> authorship unchanged since significant chunks have not been modified.
>>
>> v2: split context changes, fix defines and improve documentation 
>> (Chris),
>>      add object invalidation logic
>>
>> Signed-off-by: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
>> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
>> Cc: Telukuntla Sreedhar <sreedhar.telukuntla@intel.com>
>> Cc: Kondapally Kalyan <kalyan.kondapally@intel.com>
>> Cc: Gupta Anshuman <Anshuman.Gupta@intel.com>
>> Cc: Huang Sean Z <sean.z.huang@intel.com>
>> Cc: Chris Wilson <chris@chris-wilson.co.uk>
>> ---
>>   drivers/gpu/drm/i915/gem/i915_gem_create.c    | 27 +++++++++++--
>>   .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 10 +++++
>>   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  | 13 ++++++
>>   drivers/gpu/drm/i915/pxp/intel_pxp.c          | 40 +++++++++++++++++++
>>   drivers/gpu/drm/i915/pxp/intel_pxp.h          | 13 ++++++
>>   drivers/gpu/drm/i915/pxp/intel_pxp_types.h    |  5 +++
>>   include/uapi/drm/i915_drm.h                   | 22 ++++++++++
>>   9 files changed, 145 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c 
>> b/drivers/gpu/drm/i915/gem/i915_gem_create.c
>> index 3ad3413c459f..d02e5938afbe 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
>> @@ -5,6 +5,7 @@
>>     #include "gem/i915_gem_ioctls.h"
>>   #include "gem/i915_gem_region.h"
>> +#include "pxp/intel_pxp.h"
>>     #include "i915_drv.h"
>>   #include "i915_user_extensions.h"
>> @@ -13,7 +14,8 @@ static int
>>   i915_gem_create(struct drm_file *file,
>>           struct intel_memory_region *mr,
>>           u64 *size_p,
>> -        u32 *handle_p)
>> +        u32 *handle_p,
>> +        u64 user_flags)
>>   {
>>       struct drm_i915_gem_object *obj;
>>       u32 handle;
>> @@ -35,12 +37,17 @@ i915_gem_create(struct drm_file *file,
>>         GEM_BUG_ON(size != obj->base.size);
>>   +    obj->user_flags = user_flags;
>> +
>>       ret = drm_gem_handle_create(file, &obj->base, &handle);
>>       /* drop reference from allocate - handle holds it now */
>>       i915_gem_object_put(obj);
>>       if (ret)
>>           return ret;
>>   +    if (user_flags & I915_GEM_OBJECT_PROTECTED)
>> +        intel_pxp_object_add(obj);
>> +
>>       *handle_p = handle;
>>       *size_p = size;
>>       return 0;
>> @@ -89,11 +96,12 @@ i915_gem_dumb_create(struct drm_file *file,
>>       return i915_gem_create(file,
>>                      intel_memory_region_by_type(to_i915(dev),
>>                                  mem_type),
>> -                   &args->size, &args->handle);
>> +                   &args->size, &args->handle, 0);
>>   }
>>     struct create_ext {
>>       struct drm_i915_private *i915;
>> +    unsigned long user_flags;
>>   };
>>     static int __create_setparam(struct drm_i915_gem_object_param *args,
>> @@ -104,6 +112,19 @@ static int __create_setparam(struct 
>> drm_i915_gem_object_param *args,
>>           return -EINVAL;
>>       }
>>   +    switch (lower_32_bits(args->param)) {
>> +    case I915_OBJECT_PARAM_PROTECTED_CONTENT:
>> +        if (!intel_pxp_is_enabled(&ext_data->i915->gt.pxp))
>> +            return -ENODEV;
>> +        if (args->size) {
>> +            return -EINVAL;
>> +        } else if (args->data) {
>> +            ext_data->user_flags |= I915_GEM_OBJECT_PROTECTED;
>> +            return 0;
>> +        }
>> +    break;
>> +    }
>> +
>>       return -EINVAL;
>>   }
>>   @@ -148,5 +169,5 @@ i915_gem_create_ioctl(struct drm_device *dev, 
>> void *data,
>>       return i915_gem_create(file,
>>                      intel_memory_region_by_type(i915,
>>                                  INTEL_MEMORY_SYSTEM),
>> -                   &args->size, &args->handle);
>> +                   &args->size, &args->handle, ext_data.user_flags);
>>   }
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c 
>> b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>> index e503c9f789c0..d10c4fcb6aec 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>> @@ -20,6 +20,7 @@
>>   #include "gt/intel_gt_buffer_pool.h"
>>   #include "gt/intel_gt_pm.h"
>>   #include "gt/intel_ring.h"
>> +#include "pxp/intel_pxp.h"
>>     #include "pxp/intel_pxp.h"
>>   @@ -500,6 +501,15 @@ eb_validate_vma(struct i915_execbuffer *eb,
>>                entry->offset != gen8_canonical_addr(entry->offset & 
>> I915_GTT_PAGE_MASK)))
>>           return -EINVAL;
>>   +    if (i915_gem_object_is_protected(vma->obj)) {
>> +        if (!intel_pxp_is_active(&vma->vm->gt->pxp))
>> +            return -ENODEV;
>> +        if (!i915_gem_object_has_valid_protection(vma->obj))
>> +            return -EIO;
>> +        if 
>> (!i915_gem_context_can_use_protected_content(eb->gem_context))
>> +            return -EPERM;
>
>
> I think I'm running into this error.

The currently agreed design is that protected objects can only be used 
with explicitly marked contexts, although it's not an HW requirement so 
we can revisit it.

>
> When running vkcube protected under wayland, it takes down the entire 
> session (Xorg & gnome-shell depending on which one is going to use the 
> protected buffer first).

Are you saying that a single submission failure takes down the entire 
gnome session? that sounds like a larger problem than just this failure. 
Or am I misunderstanding your point?

>
> That's a bit harsh.
>
>
> We probably don't want this. After all the point of encryption is that 
> even if you can read the buffer you won't be able to make much of its 
> content.

As mentioned above we can change this since there is no HW requirement 
on contexts, but need some architectural agreement. Joonas and Rodrigo 
can comment more here.
Also note that submitting an instruction using encrypted data while the 
session is invalid can cause the HW to hang, which is part of the reason 
why we require the contexts using protected objects to be marked 
appropriately, so we can ban them on PXP teardown to avoid hangs.

Daniele

>
> Also useful to know you're dealing for debugging ;)
>
>
> -Lionel
>
>
>> +    }
>> +
>>       /* pad_to_size was once a reserved field, so sanitize it */
>>       if (entry->flags & EXEC_OBJECT_PAD_TO_SIZE) {
>>           if (unlikely(offset_in_page(entry->pad_to_size)))
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c 
>> b/drivers/gpu/drm/i915/gem/i915_gem_object.c
>> index 6cdff5fc5882..b321f5484ae6 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"
>> @@ -72,6 +73,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;
>>   @@ -120,6 +123,9 @@ static void i915_gem_close_object(struct 
>> drm_gem_object *gem, struct drm_file *f
>>       struct i915_lut_handle *lut, *ln;
>>       LIST_HEAD(close);
>>   +    if (i915_gem_object_has_valid_protection(obj))
>> +        intel_pxp_object_remove(obj);
>> +
>>       spin_lock(&obj->lut_lock);
>>       list_for_each_entry_safe(lut, ln, &obj->lut_list, obj_link) {
>>           struct i915_gem_context *ctx = lut->ctx;
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h 
>> b/drivers/gpu/drm/i915/gem/i915_gem_object.h
>> index 366d23afbb1a..a1fa7539c0f7 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
>> @@ -274,6 +274,18 @@ i915_gem_object_needs_async_cancel(const struct 
>> drm_i915_gem_object *obj)
>>       return i915_gem_object_type_has(obj, 
>> I915_GEM_OBJECT_ASYNC_CANCEL);
>>   }
>>   +static inline bool
>> +i915_gem_object_is_protected(const struct drm_i915_gem_object *obj)
>> +{
>> +    return obj->user_flags & I915_GEM_OBJECT_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_is_framebuffer(const struct drm_i915_gem_object *obj)
>>   {
>> 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 0a1fdbac882e..6eee580c7aba 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
>> @@ -167,6 +167,11 @@ struct drm_i915_gem_object {
>>       } mmo;
>>         I915_SELFTEST_DECLARE(struct list_head st_link);
>> +    /**
>> +     * @user_flags: small set of booleans set by the user
>> +     */
>> +    unsigned long user_flags;
>> +#define I915_GEM_OBJECT_PROTECTED BIT(0)
>>         unsigned long flags;
>>   #define I915_BO_ALLOC_CONTIGUOUS BIT(0)
>> @@ -290,6 +295,14 @@ struct drm_i915_gem_object {
>>           bool dirty:1;
>>       } mm;
>>   +    /*
>> +     * 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 5912e4a12d94..03151cd7f4b8 100644
>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
>> @@ -69,6 +69,8 @@ void intel_pxp_init(struct intel_pxp *pxp)
>>           return;
>>         mutex_init(&pxp->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,
>> @@ -136,11 +138,49 @@ int 
>> intel_pxp_wait_for_termination_completion(struct intel_pxp *pxp)
>>       return ret;
>>   }
>>   +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) {
>> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h 
>> b/drivers/gpu/drm/i915/pxp/intel_pxp.h
>> index e36200833095..3315b07d271b 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;
>> +
>>   #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)
>> @@ -38,6 +40,9 @@ void intel_pxp_init(struct intel_pxp *pxp);
>>   void intel_pxp_fini(struct intel_pxp *pxp);
>>     int intel_pxp_wait_for_termination_completion(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)
>> @@ -52,6 +57,14 @@ static inline int 
>> intel_pxp_wait_for_termination_completion(struct intel_pxp *px
>>   {
>>       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_types.h 
>> b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
>> index 6f659a6f8f1c..53a2a8acfe51 100644
>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
>> @@ -7,8 +7,10 @@
>>   #define __INTEL_PXP_TYPES_H__
>>     #include <linux/completion.h>
>> +#include <linux/list.h>
>>   #include <linux/types.h>
>>   #include <linux/mutex.h>
>> +#include <linux/spinlock.h>
>>   #include <linux/workqueue.h>
>>     struct intel_context;
>> @@ -28,6 +30,9 @@ struct intel_pxp {
>>       struct work_struct irq_work;
>>       bool irq_enabled;
>>       u32 current_events; /* protected with gt->irq_lock */
>> +
>> +    struct spinlock lock;
>> +    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 9ebe8523aa0c..0f8b771a6d53 100644
>> --- a/include/uapi/drm/i915_drm.h
>> +++ b/include/uapi/drm/i915_drm.h
>> @@ -1753,6 +1753,28 @@ struct drm_i915_gem_object_param {
>>    */
>>   #define I915_OBJECT_PARAM  (1ull << 32)
>>   +/*
>> + * I915_OBJECT_PARAM_PROTECTED_CONTENT:
>> + *
>> + * If set to true, buffer contents is expected to be protected by PXP
>> + * encryption and requires decryption for scan out and processing. 
>> This is
>> + * only possible on platforms that have PXP enabled, on all other 
>> scenarios
>> + * setting this flag will cause the ioctl to fail and return -ENODEV.
>> + *
>> + * Protected buffers can only be used with contexts created using the
>> + * I915_CONTEXT_PARAM_PROTECTED_CONTENT flag. The buffer contents are
>> + * considered invalid after a PXP session teardown.
>> + *
>> + * Given the restriction above, the following errors are possible when
>> + * submitting a protected object in an execbuf call:
>> + *
>> + * -ENODEV: PXP session not currently active
>> + * -EIO: buffer has become invalid after a teardown event
>> + * -EPERM: buffer submitted using a context not marked as protected
>> + */
>> +#define I915_OBJECT_PARAM_PROTECTED_CONTENT  0x0
>> +/* Must be kept compact -- no holes and well documented */
>> +
>>       __u64 param;
>>         /* Data value or pointer */
>
>

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

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

* Re: [Intel-gfx] [PATCH v2 08/16] drm/i915/pxp: Implement arb session teardown
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 08/16] drm/i915/pxp: Implement arb session teardown Daniele Ceraolo Spurio
@ 2021-03-03 22:04   ` Chris Wilson
  2021-03-04  0:29     ` Daniele Ceraolo Spurio
  0 siblings, 1 reply; 47+ messages in thread
From: Chris Wilson @ 2021-03-03 22:04 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio, intel-gfx; +Cc: Huang, Huang, Sean Z

Quoting Daniele Ceraolo Spurio (2021-03-01 19:31:52)
> 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)
> 
> 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>
> ---
>  drivers/gpu/drm/i915/Makefile                |   1 +
>  drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c     | 166 +++++++++++++++++++
>  drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h     |  15 ++
>  drivers/gpu/drm/i915/pxp/intel_pxp_session.c |  38 +++++
>  drivers/gpu/drm/i915/pxp/intel_pxp_session.h |   1 +
>  drivers/gpu/drm/i915/pxp/intel_pxp_tee.c     |   5 +-
>  6 files changed, 225 insertions(+), 1 deletion(-)
>  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 d6d510e4875e..8b605f326039 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -273,6 +273,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/pxp/intel_pxp_cmd.c b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c
> new file mode 100644
> index 000000000000..ffab09839cd3
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c
> @@ -0,0 +1,166 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright(c) 2020, Intel Corporation. All rights reserved.
> + */
> +
> +#include "intel_pxp.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"
> +
> +/* PXP GPU command definitions */
> +
> +/* MI_SET_APPID */
> +#define   MI_SET_APPID_SESSION_ID(x)    ((x) << 0)
> +
> +/* MI_FLUSH_DW */
> +#define   MI_FLUSH_DW_DW0_PROTECTED_MEMORY_ENABLE   BIT(22)
> +
> +/* MI_WAIT */
> +#define   MFX_WAIT_DW0_PXP_SYNC_CONTROL_FLAG BIT(9)
> +#define   MFX_WAIT_DW0_MFX_SYNC_CONTROL_FLAG  BIT(8)

We've been using REG_BIT() for the explicit (u32) casting.

> +/* CRYPTO_KEY_EXCHANGE */
> +#define CRYPTO_KEY_EXCHANGE ((0x3 << 29) | (0x01609 << 16))

#define __INSTR(client) ((client) << INSTR_CLIENT_SHIFT)

#define MI_INSTR(opcode, flags) \
	(__INSTR(INSTR_MI_CLIENT) | (opcode) << 23 | (flags))
#define RC_INTR(foo) (__INSTR(INSTR_RC_CLIENT) | (foo) << 16)

#define CRYPTO_KEY_EXCHANGE RC_INSTR(0x1609)

With a better (foo).

> +
> +/* 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;

One day someone will proofread bspec.

> +       /* pxp off */
> +       *cs++ = MI_FLUSH_DW;
> +       *cs++ = 0;
> +       *cs++ = 0;

Hmm. Can the immediate data be dropped? TIL.

> +       /* 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_DW0_PROTECTED_MEMORY_ENABLE;
> +       *cs++ = 0;
> +       *cs++ = 0;

Bspec says "after completion of the flush...", which says to me we
should not initiate the wait until after the flush, so we would need a
post-sync op here to stall the CS (or else we may complete the wait
before the operation is begun). I don't see any programming notes to
that effect, so could just be my paranoia from handling atomics.

> +       *cs++ = MFX_WAIT_PXP;

Fwiw, the bspec language would seem to imply that nothing should happen
with this wait at this point. Perhaps more reason to make the pxp-on
MI_FLUSH_DW be synchronous. (Though we will have a sync point at the
breadcrumb, so meh.)

> +
> +       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_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 WAIT_LEN 2

Dwords lengths ok.

> +#define __SESSION_TERMINATION_LEN (SELECTION_LEN + TERMINATION_LEN)
> +#define SESSION_TERMINATION_LEN(x) (__SESSION_TERMINATION_LEN * (x) + WAIT_LEN)
> +
> +static struct i915_request *pxp_request_create(struct intel_context *ce)
> +{
> +       struct i915_request *rq;
> +
> +       intel_context_enter(ce);
> +       rq = __i915_request_create(ce, GFP_KERNEL);
> +       intel_context_exit(ce);
> +
> +       return rq;
> +}
> +
> +static void pxp_request_commit(struct i915_request *rq)
> +{
> +       struct i915_sched_attr attr = { .priority = I915_PRIORITY_MAX };
> +
> +       trace_i915_request_add(rq);
> +       __i915_request_commit(rq);
> +       __i915_request_queue(rq, &attr);
> +}
> +
> +int intel_pxp_submit_session_termination(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;
> +
> +       intel_engine_pm_get(ce->engine);

As you are not using the engine->kernel_context, you can leave this out
and the normal intel_context_enter() acquire of the wakeref will cover
you.

You could then use the normal i915_request_create(), but we would still
have the custom i915_request_add, which would absorb the mutex_unlock so
would not look so unbalanced.

> +       mutex_lock(&ce->timeline->mutex);
> +
> +       rq = pxp_request_create(ce);
> +       if (IS_ERR(rq)) {
> +               mutex_unlock(&ce->timeline->mutex);
> +               err = PTR_ERR(rq);
> +               goto out_pm;
> +       }
> +
> +       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));
> +       if (IS_ERR(cs)) {
> +               err = PTR_ERR(cs);
> +               goto out_rq;
> +       }
> +
> +       cs = pxp_emit_session_selection(cs, id);
> +       cs = pxp_emit_inline_termination(cs);

I would wrap this pair with

	cs = pxp_emit_session_termination(cs, id);

so the correspondence with SESSION_TERMINATION_LEN() is clearer and I'd
be tempted then to add the WAIT_LEN explicitly.

> +       cs = pxp_emit_wait(cs);
> +
> +       intel_ring_advance(rq, cs);

Fwiw, this would be a good excuse to decouple invalidate/flush from the
breadcrumbs. Later, much later.

> +
> +out_rq:
> +       i915_request_get(rq);
> +
> +       if (unlikely(err))
> +               i915_request_set_error_once(rq, err);
> +
> +       pxp_request_commit(rq);
> +
> +       mutex_unlock(&ce->timeline->mutex);
> +
> +       if (!err && i915_request_wait(rq, 0, HZ / 5) < 0)
> +               err = -ETIME;

"intel_pxp_submit_session_termination" does not imply synchronous
behaviour to me.

intel_pxp_terminate_session() ?

> +
> +       i915_request_put(rq);
> +
> +out_pm:
> +       intel_engine_pm_put(ce->engine);
> +
> +       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..7c33b66f0812
> --- /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_submit_session_termination(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 6abc59a63e51..ddbfac75686a 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);
> @@ -80,3 +84,37 @@ int intel_pxp_create_arb_session(struct intel_pxp *pxp)
>  
>         return 0;
>  }
> +
> +/**
> + * intel_pxp_arb_terminate_session_with_global_terminate - Terminate the arb hw

terminate_session_and_global ? Just to remove the repetition?

> + * session.
> + * @pxp: pointer to pxp struct.
> + *
> + * Return: 0 if terminate is successful, error code otherwise
> + */
> +int intel_pxp_arb_terminate_session_with_global_terminate(struct intel_pxp *pxp)
> +{
> +       int ret;
> +       struct intel_gt *gt = pxp_to_gt(pxp);
> +
> +       lockdep_assert_held(&pxp->mutex);
> +
> +       pxp->arb_is_in_play = false;
> +
> +       /* terminate the hw sessions */
> +       ret = intel_pxp_submit_session_termination(pxp, ARB_SESSION);
> +       if (ret) {
> +               drm_err(&gt->i915->drm, "Failed to submit session termination\n");
> +               return ret;
> +       }

Should arb_is_in_play not be updated until after successful termination?

> +       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);

Are we happy that this is instantaneous and doesn't need an ack/wait?

> +       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 6fc4a2370c44..07c97df7a509 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.h
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.h
> @@ -12,5 +12,6 @@ struct intel_pxp;
>  
>  bool intel_pxp_arb_session_is_in_play(struct intel_pxp *pxp);
>  int intel_pxp_create_arb_session(struct intel_pxp *pxp);
> +int intel_pxp_arb_terminate_session_with_global_terminate(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 dc3850b372c5..fd9a69248dd8 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
> @@ -99,7 +99,10 @@ static int i915_pxp_tee_component_bind(struct device *i915_kdev,
>         mutex_lock(&pxp->mutex);
>  
>         /* Create arb session only if tee is ready, during system boot or sleep/resume */
> -       if (!intel_pxp_arb_session_is_in_play(pxp))
> +       if (intel_pxp_arb_session_is_in_play(pxp))
> +               ret = intel_pxp_arb_terminate_session_with_global_terminate(pxp);
> +
> +       if (!ret)
>                 ret = intel_pxp_create_arb_session(pxp);
>  
>         mutex_unlock(&pxp->mutex);
> -- 
> 2.29.2
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH v2 07/16] drm/i915/pxp: Create the arbitrary session after boot
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 07/16] drm/i915/pxp: Create the arbitrary session after boot Daniele Ceraolo Spurio
@ 2021-03-03 22:08   ` Chris Wilson
  2021-03-04  0:18     ` Daniele Ceraolo Spurio
  0 siblings, 1 reply; 47+ messages in thread
From: Chris Wilson @ 2021-03-03 22:08 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio, intel-gfx; +Cc: Huang, Huang, Sean Z

Quoting Daniele Ceraolo Spurio (2021-03-01 19:31:51)
> +static inline bool intel_pxp_is_active(const struct intel_pxp *pxp)
> +{
> +       return pxp->arb_is_in_play;
> +}

> +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);
> +}
> +
> +bool intel_pxp_arb_session_is_in_play(struct intel_pxp *pxp)
> +{
> +       return intel_pxp_session_is_in_play(pxp, ARB_SESSION);
> +}

So pxp->arb_is_in_play is not the same as intel_pxp_arb_session_is_in_play().

That's confusing.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH v2 04/16] drm/i915/pxp: allocate a vcs context for pxp usage
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 04/16] drm/i915/pxp: allocate a vcs context for pxp usage Daniele Ceraolo Spurio
@ 2021-03-03 22:17   ` Chris Wilson
  0 siblings, 0 replies; 47+ messages in thread
From: Chris Wilson @ 2021-03-03 22:17 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio, intel-gfx

Quoting Daniele Ceraolo Spurio (2021-03-01 19:31:48)
> @@ -232,6 +235,13 @@ ktime_t intel_engine_get_busy_time(struct intel_engine_cs *engine,
>  
>  u32 intel_engine_context_size(struct intel_gt *gt, u8 class);
>  
> +struct intel_context *
> +intel_engine_pinned_context_create(struct intel_engine_cs *engine,
> +                                  unsigned int hwsp,
> +                                  struct lock_class_key *key,
> +                                  const char *name);

intel_engine_create_pinned_context()

Other users would want to pass in vm and ring size (ring size may be
useful here as well for larger SESSION_TERMINATE_LEN())
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH v2 09/16] drm/i915/pxp: Implement PXP irq handler
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 09/16] drm/i915/pxp: Implement PXP irq handler Daniele Ceraolo Spurio
  2021-03-03 21:18   ` Chris Wilson
@ 2021-03-03 22:42   ` Chris Wilson
  2021-03-25 21:52     ` Daniele Ceraolo Spurio
  2021-03-03 22:45   ` Chris Wilson
  2 siblings, 1 reply; 47+ messages in thread
From: Chris Wilson @ 2021-03-03 22:42 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio, intel-gfx; +Cc: Huang, Huang, Sean Z

Quoting Daniele Ceraolo Spurio (2021-03-01 19:31:53)
> 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.

Why do we do the auto recreation after the teardown interrupt?

> 
> v2: use struct completion instead of bool (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>
> ---
>  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         |  34 +++++
>  drivers/gpu/drm/i915/pxp/intel_pxp.h         |  16 ++
>  drivers/gpu/drm/i915/pxp/intel_pxp_irq.c     | 151 +++++++++++++++++++
>  drivers/gpu/drm/i915/pxp/intel_pxp_irq.h     |  33 ++++
>  drivers/gpu/drm/i915/pxp/intel_pxp_session.c |   9 +-
>  drivers/gpu/drm/i915/pxp/intel_pxp_session.h |   1 +
>  drivers/gpu/drm/i915/pxp/intel_pxp_tee.c     |  10 +-
>  drivers/gpu/drm/i915/pxp/intel_pxp_types.h   |   8 +
>  11 files changed, 268 insertions(+), 3 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 8b605f326039..5e9bd34dec38 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -274,6 +274,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 d29126c458ba..0d3585efe2b8 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);
>  }
> @@ -190,6 +194,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 e5dd0203991b..97a6d0c638ec 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -7958,6 +7958,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 cbec9395bde9..0ca1c2c16972 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_tee.h"
>  #include "gt/intel_context.h"
>  #include "i915_drv.h"
> @@ -67,12 +69,23 @@ void intel_pxp_init(struct intel_pxp *pxp)
>  
>         mutex_init(&pxp->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);
> +
>         kcr_pxp_enable(gt);
>  
>         ret = create_vcs_context(pxp);
>         if (ret)
>                 goto out_kcr;
>  
> +       intel_pxp_irq_init(pxp);
> +       intel_pxp_irq_enable(pxp);
> +
>         ret = intel_pxp_tee_component_init(pxp);
>         if (ret)
>                 goto out_context;
> @@ -94,10 +107,31 @@ void intel_pxp_fini(struct intel_pxp *pxp)
>         if (!intel_pxp_is_enabled(pxp))
>                 return;
>  
> +       intel_pxp_irq_disable(pxp);
> +
>         intel_pxp_tee_component_fini(pxp);
>  
>         destroy_vcs_context(pxp);
>  
>         kcr_pxp_disable(gt);
> +}
>  
> +int intel_pxp_wait_for_termination_completion(struct intel_pxp *pxp)
> +{
> +       int ret;
> +
> +       if (!intel_pxp_is_enabled(pxp))
> +               return 0;
> +
> +       ret = wait_for_completion_timeout(&pxp->termination,
> +                                         msecs_to_jiffies(100));
> +
> +       /* the wait returns 0 on failure */
> +       if (ret)
> +               ret = 0;
> +       else
> +               ret = -ETIMEDOUT;
> +
> +       return ret;
>  }
> +
> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
> index 3bede9306481..89cf66c9bef3 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
> @@ -9,6 +9,15 @@
>  #include "gt/intel_gt_types.h"
>  #include "intel_pxp_types.h"
>  
> +#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)
> +
>  static inline struct intel_gt *pxp_to_gt(const struct intel_pxp *pxp)
>  {
>         return container_of(pxp, struct intel_gt, pxp);
> @@ -27,6 +36,8 @@ static inline bool intel_pxp_is_active(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);
> +
> +int intel_pxp_wait_for_termination_completion(struct intel_pxp *pxp);
>  #else
>  static inline void intel_pxp_init(struct intel_pxp *pxp)
>  {
> @@ -35,6 +46,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_termination_completion(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..40115bf0b6bb
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
> @@ -0,0 +1,151 @@
> +// 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"
> +
> +static int pxp_terminate(struct intel_pxp *pxp)
> +{
> +       int ret = 0;
> +
> +       mutex_lock(&pxp->mutex);
> +
> +       pxp->global_state_attacked = true;
> +
> +       ret = intel_pxp_arb_terminate_session_with_global_terminate(pxp);
> +
> +       mutex_unlock(&pxp->mutex);
> +
> +       return ret;
> +}
> +
> +static int pxp_terminate_complete(struct intel_pxp *pxp)
> +{
> +       int ret = 0;
> +
> +       mutex_lock(&pxp->mutex);
> +
> +       if (pxp->global_state_attacked) {
> +               pxp->global_state_attacked = false;
> +
> +               /* Re-create the arb session after teardown handle complete */
> +               ret = intel_pxp_create_arb_session(pxp);
> +       }
> +
> +       mutex_unlock(&pxp->mutex);
> +
> +       complete_all(&pxp->termination);
> +
> +       return ret;
> +}
> +
> +static void intel_pxp_irq_work(struct work_struct *work)
> +{
> +       struct intel_pxp *pxp = container_of(work, typeof(*pxp), irq_work);
> +       struct intel_gt *gt = pxp_to_gt(pxp);
> +       u32 events = 0;
> +
> +       spin_lock_irq(&gt->irq_lock);
> +       events = fetch_and_zero(&pxp->current_events);
> +       spin_unlock_irq(&gt->irq_lock);
> +
> +       if (!events)
> +               return;
> +
> +       if (events & (GEN12_DISPLAY_PXP_STATE_TERMINATED_INTERRUPT |
> +                     GEN12_DISPLAY_APP_TERMINATED_PER_FW_REQ_INTERRUPT))
> +               pxp_terminate(pxp);
> +
> +       if (events & GEN12_DISPLAY_STATE_RESET_COMPLETE_INTERRUPT)
> +               pxp_terminate_complete(pxp);
> +
> +       /*
> +        * we expect the terminate complete to arrive quickly after emitting
> +        * the terminate, so check back on it
> +        */
> +       if (pxp->irq_enabled)
> +               queue_work(system_unbound_wq, &pxp->irq_work);
> +}
> +
> +/**
> + * 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;
> +
> +       /* immediately mark PXP as inactive on termination */
> +       if (iir & (GEN12_DISPLAY_PXP_STATE_TERMINATED_INTERRUPT |
> +                  GEN12_DISPLAY_APP_TERMINATED_PER_FW_REQ_INTERRUPT))
> +               intel_pxp_mark_termination_in_progress(pxp);
> +
> +       pxp->current_events |= iir;
> +       queue_work(system_unbound_wq, &pxp->irq_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_init(struct intel_pxp *pxp)
> +{
> +       INIT_WORK(&pxp->irq_work, intel_pxp_irq_work);
> +}
> +
> +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);
> +
> +       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->irq_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..7a875831636d
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.h
> @@ -0,0 +1,33 @@
> +/* 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;
> +
> +#ifdef CONFIG_DRM_I915_PXP
> +void intel_pxp_irq_init(struct intel_pxp *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
> +void intel_pxp_irq_init(struct intel_pxp *pxp)
> +{
> +}
> +void intel_pxp_irq_enable(struct intel_pxp *pxp)
> +{
> +}
> +void intel_pxp_irq_disable(struct intel_pxp *pxp)
> +{
> +}
> +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 ddbfac75686a..488006a0cf39 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> @@ -99,8 +99,6 @@ int intel_pxp_arb_terminate_session_with_global_terminate(struct intel_pxp *pxp)
>  
>         lockdep_assert_held(&pxp->mutex);
>  
> -       pxp->arb_is_in_play = false;
> -
>         /* terminate the hw sessions */
>         ret = intel_pxp_submit_session_termination(pxp, ARB_SESSION);
>         if (ret) {
> @@ -118,3 +116,10 @@ int intel_pxp_arb_terminate_session_with_global_terminate(struct intel_pxp *pxp)
>  
>         return ret;
>  }
> +
> +void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp)
> +{
> +       pxp->arb_is_in_play = false;
> +       reinit_completion(&pxp->termination);
> +}
> +
> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.h b/drivers/gpu/drm/i915/pxp/intel_pxp_session.h
> index 07c97df7a509..931169f795ab 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.h
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.h
> @@ -13,5 +13,6 @@ struct intel_pxp;
>  bool intel_pxp_arb_session_is_in_play(struct intel_pxp *pxp);
>  int intel_pxp_create_arb_session(struct intel_pxp *pxp);
>  int intel_pxp_arb_terminate_session_with_global_terminate(struct intel_pxp *pxp);
> +void intel_pxp_mark_termination_in_progress(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 fd9a69248dd8..b84f675c588e 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
> @@ -99,9 +99,17 @@ static int i915_pxp_tee_component_bind(struct device *i915_kdev,
>         mutex_lock(&pxp->mutex);
>  
>         /* Create arb session only if tee is ready, during system boot or sleep/resume */
> -       if (intel_pxp_arb_session_is_in_play(pxp))
> +       if (intel_pxp_arb_session_is_in_play(pxp)) {
> +               intel_pxp_mark_termination_in_progress(pxp);
>                 ret = intel_pxp_arb_terminate_session_with_global_terminate(pxp);
>  
> +               if (!ret) {
> +                       mutex_unlock(&pxp->mutex);
> +                       ret = intel_pxp_wait_for_termination_completion(pxp);
> +                       mutex_lock(&pxp->mutex);

* shivers

This does not give off warm fuzzy feeling about the locking.
It's clear why you had to drop the lock to avoid blocking the interrupt
bh (the worker), but it's not actually clear that the locking needs to
be like that.

Oh well, s/if/while/ to cover the lock dropping.
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH v2 09/16] drm/i915/pxp: Implement PXP irq handler
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 09/16] drm/i915/pxp: Implement PXP irq handler Daniele Ceraolo Spurio
  2021-03-03 21:18   ` Chris Wilson
  2021-03-03 22:42   ` Chris Wilson
@ 2021-03-03 22:45   ` Chris Wilson
  2 siblings, 0 replies; 47+ messages in thread
From: Chris Wilson @ 2021-03-03 22:45 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio, intel-gfx; +Cc: Huang, Huang, Sean Z

Quoting Daniele Ceraolo Spurio (2021-03-01 19:31:53)
> +static int pxp_terminate(struct intel_pxp *pxp)
> +{
> +       int ret = 0;
> +
> +       mutex_lock(&pxp->mutex);
> +
> +       pxp->global_state_attacked = true;

global_state_attacked is serialised by pxp->work

> +
> +       ret = intel_pxp_arb_terminate_session_with_global_terminate(pxp);
> +
> +       mutex_unlock(&pxp->mutex);
> +
> +       return ret;

Fake error returns.

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

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

* Re: [Intel-gfx] [PATCH v2 10/16] drm/i915/pxp: Enable PXP power management
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 10/16] drm/i915/pxp: Enable PXP power management Daniele Ceraolo Spurio
@ 2021-03-03 22:52   ` Chris Wilson
  0 siblings, 0 replies; 47+ messages in thread
From: Chris Wilson @ 2021-03-03 22:52 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio, intel-gfx; +Cc: Huang, Huang, Sean Z

Quoting Daniele Ceraolo Spurio (2021-03-01 19:31:54)
> +int intel_pxp_runtime_resume(struct intel_pxp *pxp)
> +{
> +       struct intel_gt *gt = pxp_to_gt(pxp);
> +       int ret;
> +
> +       if (!intel_pxp_is_enabled(pxp))
> +               return 0;
> +
> +       intel_pxp_irq_enable(pxp);
> +       pxp->global_state_in_suspend = false;
> +
> +       /*
> +        * if the display loses power during runtime suspend it will cause the
> +        * session to become invalid, so to be safe we always re-create it. The
> +        * MEI module is still bound, so this is the same as a teardown event,
> +        * hence we can just pretend we received the irq.
> +        */
> +       intel_pxp_mark_termination_in_progress(pxp);
> +
> +       spin_lock_irq(&gt->irq_lock);
> +       intel_pxp_irq_handler(pxp, GEN12_DISPLAY_PXP_STATE_TERMINATED_INTERRUPT);
> +       spin_unlock_irq(&gt->irq_lock);
> +
> +       return ret;

return random() ?

> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> index 488006a0cf39..bb981d38c2fe 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> @@ -25,8 +25,14 @@ static bool intel_pxp_session_is_in_play(struct intel_pxp *pxp, u32 id)
>         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 */
> +       wakeref = intel_runtime_pm_get_if_in_use(gt->uncore->rpm);
> +       if (!wakeref)
> +               return false;
> +
> +       sip = intel_uncore_read(gt->uncore, GEN12_KCR_SIP);
> +
> +       intel_runtime_pm_put(gt->uncore->rpm, wakeref);

with_intel_runtime_pm_if_in_use(gt->uncore->rpm, wakeref)
	sip = intel_uncore_read(gt->uncore, GEN12_KCR_SIP);

>  
>         return sip & BIT(id);
>  }
> @@ -43,12 +49,18 @@ static int pxp_wait_for_session_state(struct intel_pxp *pxp, u32 id, bool in_pla
>         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(gt->uncore->rpm);
> +       if (!wakeref)
> +               return in_play ? -ENODEV : 0;
> +
> +       ret = intel_wait_for_register(gt->uncore,
> +                                     GEN12_KCR_SIP,
> +                                     mask,
> +                                     in_play ? mask : 0,
> +                                     100);
> +
> +       intel_runtime_pm_put(gt->uncore->rpm, wakeref);

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

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

* Re: [Intel-gfx] [PATCH v2 13/16] drm/i915/pxp: User interface for Protected buffer
  2021-03-03 21:59     ` Daniele Ceraolo Spurio
@ 2021-03-03 23:16       ` Lionel Landwerlin
  2021-03-03 23:25         ` Daniele Ceraolo Spurio
  0 siblings, 1 reply; 47+ messages in thread
From: Lionel Landwerlin @ 2021-03-03 23:16 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio, intel-gfx
  Cc: Huang Sean Z, Chris Wilson, Kondapally Kalyan, Bommu Krishnaiah

On 03/03/2021 23:59, Daniele Ceraolo Spurio wrote:
>
>
> On 3/3/2021 12:39 PM, Lionel Landwerlin wrote:
>> On 01/03/2021 21:31, Daniele Ceraolo Spurio wrote:
>>> From: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
>>>
>>> This api allow user mode to create Protected buffers. Only contexts
>>> marked as protected are allowed to operate on protected buffers.
>>>
>>> We only allow setting the flags at creation time.
>>>
>>> All protected objects that have backing storage will be considered
>>> invalid when the session is destroyed and they won't be usable anymore.
>>>
>>> This is a rework of the original code by Bommu Krishnaiah. I've
>>> authorship unchanged since significant chunks have not been modified.
>>>
>>> v2: split context changes, fix defines and improve documentation 
>>> (Chris),
>>>      add object invalidation logic
>>>
>>> Signed-off-by: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
>>> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
>>> Cc: Telukuntla Sreedhar <sreedhar.telukuntla@intel.com>
>>> Cc: Kondapally Kalyan <kalyan.kondapally@intel.com>
>>> Cc: Gupta Anshuman <Anshuman.Gupta@intel.com>
>>> Cc: Huang Sean Z <sean.z.huang@intel.com>
>>> Cc: Chris Wilson <chris@chris-wilson.co.uk>
>>> ---
>>>   drivers/gpu/drm/i915/gem/i915_gem_create.c    | 27 +++++++++++--
>>>   .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 10 +++++
>>>   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  | 13 ++++++
>>>   drivers/gpu/drm/i915/pxp/intel_pxp.c          | 40 
>>> +++++++++++++++++++
>>>   drivers/gpu/drm/i915/pxp/intel_pxp.h          | 13 ++++++
>>>   drivers/gpu/drm/i915/pxp/intel_pxp_types.h    |  5 +++
>>>   include/uapi/drm/i915_drm.h                   | 22 ++++++++++
>>>   9 files changed, 145 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c 
>>> b/drivers/gpu/drm/i915/gem/i915_gem_create.c
>>> index 3ad3413c459f..d02e5938afbe 100644
>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
>>> @@ -5,6 +5,7 @@
>>>     #include "gem/i915_gem_ioctls.h"
>>>   #include "gem/i915_gem_region.h"
>>> +#include "pxp/intel_pxp.h"
>>>     #include "i915_drv.h"
>>>   #include "i915_user_extensions.h"
>>> @@ -13,7 +14,8 @@ static int
>>>   i915_gem_create(struct drm_file *file,
>>>           struct intel_memory_region *mr,
>>>           u64 *size_p,
>>> -        u32 *handle_p)
>>> +        u32 *handle_p,
>>> +        u64 user_flags)
>>>   {
>>>       struct drm_i915_gem_object *obj;
>>>       u32 handle;
>>> @@ -35,12 +37,17 @@ i915_gem_create(struct drm_file *file,
>>>         GEM_BUG_ON(size != obj->base.size);
>>>   +    obj->user_flags = user_flags;
>>> +
>>>       ret = drm_gem_handle_create(file, &obj->base, &handle);
>>>       /* drop reference from allocate - handle holds it now */
>>>       i915_gem_object_put(obj);
>>>       if (ret)
>>>           return ret;
>>>   +    if (user_flags & I915_GEM_OBJECT_PROTECTED)
>>> +        intel_pxp_object_add(obj);
>>> +
>>>       *handle_p = handle;
>>>       *size_p = size;
>>>       return 0;
>>> @@ -89,11 +96,12 @@ i915_gem_dumb_create(struct drm_file *file,
>>>       return i915_gem_create(file,
>>>                      intel_memory_region_by_type(to_i915(dev),
>>>                                  mem_type),
>>> -                   &args->size, &args->handle);
>>> +                   &args->size, &args->handle, 0);
>>>   }
>>>     struct create_ext {
>>>       struct drm_i915_private *i915;
>>> +    unsigned long user_flags;
>>>   };
>>>     static int __create_setparam(struct drm_i915_gem_object_param 
>>> *args,
>>> @@ -104,6 +112,19 @@ static int __create_setparam(struct 
>>> drm_i915_gem_object_param *args,
>>>           return -EINVAL;
>>>       }
>>>   +    switch (lower_32_bits(args->param)) {
>>> +    case I915_OBJECT_PARAM_PROTECTED_CONTENT:
>>> +        if (!intel_pxp_is_enabled(&ext_data->i915->gt.pxp))
>>> +            return -ENODEV;
>>> +        if (args->size) {
>>> +            return -EINVAL;
>>> +        } else if (args->data) {
>>> +            ext_data->user_flags |= I915_GEM_OBJECT_PROTECTED;
>>> +            return 0;
>>> +        }
>>> +    break;
>>> +    }
>>> +
>>>       return -EINVAL;
>>>   }
>>>   @@ -148,5 +169,5 @@ i915_gem_create_ioctl(struct drm_device *dev, 
>>> void *data,
>>>       return i915_gem_create(file,
>>>                      intel_memory_region_by_type(i915,
>>>                                  INTEL_MEMORY_SYSTEM),
>>> -                   &args->size, &args->handle);
>>> +                   &args->size, &args->handle, ext_data.user_flags);
>>>   }
>>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c 
>>> b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>>> index e503c9f789c0..d10c4fcb6aec 100644
>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>>> @@ -20,6 +20,7 @@
>>>   #include "gt/intel_gt_buffer_pool.h"
>>>   #include "gt/intel_gt_pm.h"
>>>   #include "gt/intel_ring.h"
>>> +#include "pxp/intel_pxp.h"
>>>     #include "pxp/intel_pxp.h"
>>>   @@ -500,6 +501,15 @@ eb_validate_vma(struct i915_execbuffer *eb,
>>>                entry->offset != gen8_canonical_addr(entry->offset & 
>>> I915_GTT_PAGE_MASK)))
>>>           return -EINVAL;
>>>   +    if (i915_gem_object_is_protected(vma->obj)) {
>>> +        if (!intel_pxp_is_active(&vma->vm->gt->pxp))
>>> +            return -ENODEV;
>>> +        if (!i915_gem_object_has_valid_protection(vma->obj))
>>> +            return -EIO;
>>> +        if 
>>> (!i915_gem_context_can_use_protected_content(eb->gem_context))
>>> +            return -EPERM;
>>
>>
>> I think I'm running into this error.
>
> The currently agreed design is that protected objects can only be used 
> with explicitly marked contexts, although it's not an HW requirement 
> so we can revisit it.
>
>>
>> When running vkcube protected under wayland, it takes down the entire 
>> session (Xorg & gnome-shell depending on which one is going to use 
>> the protected buffer first).
>
> Are you saying that a single submission failure takes down the entire 
> gnome session? that sounds like a larger problem than just this 
> failure. Or am I misunderstanding your point?


We just need to hand that buffer to any other app and have it use it in 
execbuf and that will make it fail the execbuf.

Now how does the driver in the gnome-shell/Xorg process know what went 
wrong and what buffer caused it?

Could be any imported buffer. It's pretty hard to recover from this and 
most apps will just crash if the driver starts to fail for some reason.

You can see how that could make a lot of people's live terrible :/


-Lionel


>
>>
>> That's a bit harsh.
>>
>>
>> We probably don't want this. After all the point of encryption is 
>> that even if you can read the buffer you won't be able to make much 
>> of its content.
>
> As mentioned above we can change this since there is no HW requirement 
> on contexts, but need some architectural agreement. Joonas and Rodrigo 
> can comment more here.
> Also note that submitting an instruction using encrypted data while 
> the session is invalid can cause the HW to hang, which is part of the 
> reason why we require the contexts using protected objects to be 
> marked appropriately, so we can ban them on PXP teardown to avoid hangs.
>
> Daniele
>
>>
>> Also useful to know you're dealing for debugging ;)
>>
>>
>> -Lionel
>>
>>
>>> +    }
>>> +
>>>       /* pad_to_size was once a reserved field, so sanitize it */
>>>       if (entry->flags & EXEC_OBJECT_PAD_TO_SIZE) {
>>>           if (unlikely(offset_in_page(entry->pad_to_size)))
>>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c 
>>> b/drivers/gpu/drm/i915/gem/i915_gem_object.c
>>> index 6cdff5fc5882..b321f5484ae6 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"
>>> @@ -72,6 +73,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;
>>>   @@ -120,6 +123,9 @@ static void i915_gem_close_object(struct 
>>> drm_gem_object *gem, struct drm_file *f
>>>       struct i915_lut_handle *lut, *ln;
>>>       LIST_HEAD(close);
>>>   +    if (i915_gem_object_has_valid_protection(obj))
>>> +        intel_pxp_object_remove(obj);
>>> +
>>>       spin_lock(&obj->lut_lock);
>>>       list_for_each_entry_safe(lut, ln, &obj->lut_list, obj_link) {
>>>           struct i915_gem_context *ctx = lut->ctx;
>>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h 
>>> b/drivers/gpu/drm/i915/gem/i915_gem_object.h
>>> index 366d23afbb1a..a1fa7539c0f7 100644
>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
>>> @@ -274,6 +274,18 @@ i915_gem_object_needs_async_cancel(const struct 
>>> drm_i915_gem_object *obj)
>>>       return i915_gem_object_type_has(obj, 
>>> I915_GEM_OBJECT_ASYNC_CANCEL);
>>>   }
>>>   +static inline bool
>>> +i915_gem_object_is_protected(const struct drm_i915_gem_object *obj)
>>> +{
>>> +    return obj->user_flags & I915_GEM_OBJECT_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_is_framebuffer(const struct drm_i915_gem_object *obj)
>>>   {
>>> 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 0a1fdbac882e..6eee580c7aba 100644
>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
>>> @@ -167,6 +167,11 @@ struct drm_i915_gem_object {
>>>       } mmo;
>>>         I915_SELFTEST_DECLARE(struct list_head st_link);
>>> +    /**
>>> +     * @user_flags: small set of booleans set by the user
>>> +     */
>>> +    unsigned long user_flags;
>>> +#define I915_GEM_OBJECT_PROTECTED BIT(0)
>>>         unsigned long flags;
>>>   #define I915_BO_ALLOC_CONTIGUOUS BIT(0)
>>> @@ -290,6 +295,14 @@ struct drm_i915_gem_object {
>>>           bool dirty:1;
>>>       } mm;
>>>   +    /*
>>> +     * 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 5912e4a12d94..03151cd7f4b8 100644
>>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
>>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
>>> @@ -69,6 +69,8 @@ void intel_pxp_init(struct intel_pxp *pxp)
>>>           return;
>>>         mutex_init(&pxp->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,
>>> @@ -136,11 +138,49 @@ int 
>>> intel_pxp_wait_for_termination_completion(struct intel_pxp *pxp)
>>>       return ret;
>>>   }
>>>   +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) {
>>> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h 
>>> b/drivers/gpu/drm/i915/pxp/intel_pxp.h
>>> index e36200833095..3315b07d271b 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;
>>> +
>>>   #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)
>>> @@ -38,6 +40,9 @@ void intel_pxp_init(struct intel_pxp *pxp);
>>>   void intel_pxp_fini(struct intel_pxp *pxp);
>>>     int intel_pxp_wait_for_termination_completion(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)
>>> @@ -52,6 +57,14 @@ static inline int 
>>> intel_pxp_wait_for_termination_completion(struct intel_pxp *px
>>>   {
>>>       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_types.h 
>>> b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
>>> index 6f659a6f8f1c..53a2a8acfe51 100644
>>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
>>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
>>> @@ -7,8 +7,10 @@
>>>   #define __INTEL_PXP_TYPES_H__
>>>     #include <linux/completion.h>
>>> +#include <linux/list.h>
>>>   #include <linux/types.h>
>>>   #include <linux/mutex.h>
>>> +#include <linux/spinlock.h>
>>>   #include <linux/workqueue.h>
>>>     struct intel_context;
>>> @@ -28,6 +30,9 @@ struct intel_pxp {
>>>       struct work_struct irq_work;
>>>       bool irq_enabled;
>>>       u32 current_events; /* protected with gt->irq_lock */
>>> +
>>> +    struct spinlock lock;
>>> +    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 9ebe8523aa0c..0f8b771a6d53 100644
>>> --- a/include/uapi/drm/i915_drm.h
>>> +++ b/include/uapi/drm/i915_drm.h
>>> @@ -1753,6 +1753,28 @@ struct drm_i915_gem_object_param {
>>>    */
>>>   #define I915_OBJECT_PARAM  (1ull << 32)
>>>   +/*
>>> + * I915_OBJECT_PARAM_PROTECTED_CONTENT:
>>> + *
>>> + * If set to true, buffer contents is expected to be protected by PXP
>>> + * encryption and requires decryption for scan out and processing. 
>>> This is
>>> + * only possible on platforms that have PXP enabled, on all other 
>>> scenarios
>>> + * setting this flag will cause the ioctl to fail and return -ENODEV.
>>> + *
>>> + * Protected buffers can only be used with contexts created using the
>>> + * I915_CONTEXT_PARAM_PROTECTED_CONTENT flag. The buffer contents are
>>> + * considered invalid after a PXP session teardown.
>>> + *
>>> + * Given the restriction above, the following errors are possible when
>>> + * submitting a protected object in an execbuf call:
>>> + *
>>> + * -ENODEV: PXP session not currently active
>>> + * -EIO: buffer has become invalid after a teardown event
>>> + * -EPERM: buffer submitted using a context not marked as protected
>>> + */
>>> +#define I915_OBJECT_PARAM_PROTECTED_CONTENT  0x0
>>> +/* Must be kept compact -- no holes and well documented */
>>> +
>>>       __u64 param;
>>>         /* Data value or pointer */
>>
>>
>

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

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

* Re: [Intel-gfx] [PATCH v2 11/16] drm/i915/pxp: interface for creation of protected contexts
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 11/16] drm/i915/pxp: interface for creation of protected contexts Daniele Ceraolo Spurio
@ 2021-03-03 23:16   ` Chris Wilson
  2021-03-08 18:32     ` Daniele Ceraolo Spurio
  0 siblings, 1 reply; 47+ messages in thread
From: Chris Wilson @ 2021-03-03 23:16 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio, intel-gfx

Quoting Daniele Ceraolo Spurio (2021-03-01 19:31:55)
> Usage of protected objects, coming in a follow-up patch, will be
> restricted to protected contexts. Contexts can only be marked as
> protected at creation time and they must be both bannable and not
> recoverable.
> 
> When a PXP teardown occurs, all gem contexts marked as protected that
> have been used at least once will be marked as invalid 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
> invalidation to userspace.
> 
> v2: split to its own patch and improve doc (Chris), invalidate contexts
> on teardown
> 
> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
> ---
>  drivers/gpu/drm/i915/gem/i915_gem_context.c   | 59 ++++++++++++++++++-
>  drivers/gpu/drm/i915/gem/i915_gem_context.h   | 18 ++++++
>  .../gpu/drm/i915/gem/i915_gem_context_types.h |  2 +
>  .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 13 ++++
>  drivers/gpu/drm/i915/pxp/intel_pxp.c          | 38 ++++++++++++
>  drivers/gpu/drm/i915/pxp/intel_pxp.h          |  1 +
>  drivers/gpu/drm/i915/pxp/intel_pxp_session.c  |  3 +
>  include/uapi/drm/i915_drm.h                   | 19 ++++++
>  8 files changed, 150 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> index ca37d93ef5e7..19ac24a3c42c 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
> @@ -76,6 +76,8 @@
>  #include "gt/intel_gpu_commands.h"
>  #include "gt/intel_ring.h"
>  
> +#include "pxp/intel_pxp.h"
> +
>  #include "i915_drm_client.h"
>  #include "i915_gem_context.h"
>  #include "i915_globals.h"
> @@ -2006,6 +2008,40 @@ static int set_priority(struct i915_gem_context *ctx,
>         return 0;
>  }
>  
> +static int set_protected(struct i915_gem_context *ctx,
> +                        const struct drm_i915_gem_context_param *args)
> +{
> +       int ret = 0;
> +
> +       if (!intel_pxp_is_enabled(&ctx->i915->gt.pxp))
> +               ret = -ENODEV;
> +       else if (ctx->client) /* can't change this after creation! */
> +               ret = -EEXIST;
> +       else if (args->size)
> +               ret = -EINVAL;
> +       else if (!args->value)
> +               clear_bit(UCONTEXT_PROTECTED, &ctx->user_flags);
> +       else if (i915_gem_context_is_recoverable(ctx) ||
> +                !i915_gem_context_is_bannable(ctx))
> +               ret = -EPERM;
> +       else
> +               set_bit(UCONTEXT_PROTECTED, &ctx->user_flags);
> +
> +       return ret;
> +}
> +
> +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_can_use_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)
> @@ -2038,6 +2074,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_can_use_protected_content(ctx))
> +                       ret = -EPERM; /* can't clear this for protected contexts */
>                 else
>                         i915_gem_context_clear_bannable(ctx);
>                 break;
> @@ -2045,10 +2083,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_can_use_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:
> @@ -2075,6 +2115,10 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
>                 ret = set_ringsize(ctx, args);
>                 break;
>  
> +       case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
> +               ret = set_protected(ctx, args);
> +               break;
> +
>         case I915_CONTEXT_PARAM_BAN_PERIOD:
>         default:
>                 ret = -EINVAL;
> @@ -2532,6 +2576,10 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
>                 ret = get_ringsize(ctx, args);
>                 break;
>  
> +       case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
> +               ret = get_protected(ctx, args);
> +               break;
> +
>         case I915_CONTEXT_PARAM_BAN_PERIOD:
>         default:
>                 ret = -EINVAL;
> @@ -2592,6 +2640,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;
> +
>         ret = 0;
>  out:
>         rcu_read_unlock();
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.h b/drivers/gpu/drm/i915/gem/i915_gem_context.h
> index b5c908f3f4f2..b04d4eeb0500 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_can_use_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 d5bc75508048..79a87268b8da 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
> @@ -130,6 +130,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
> @@ -137,6 +138,7 @@ struct i915_gem_context {
>         unsigned long flags;
>  #define CONTEXT_CLOSED                 0
>  #define CONTEXT_USER_ENGINES           1
> +#define CONTEXT_INVALID                        2
>  
>         struct mutex mutex;
>  
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> index fe170186dd42..e503c9f789c0 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"
> @@ -726,6 +728,11 @@ static int eb_select_context(struct i915_execbuffer *eb)
>         if (unlikely(!ctx))
>                 return -ENOENT;
>  
> +       if (i915_gem_context_invalidated(ctx)) {
> +               i915_gem_context_put(ctx);
> +               return -EIO;
> +       }
> +
>         eb->gem_context = ctx;
>         if (rcu_access_pointer(ctx->vm))
>                 eb->invalid_flags |= EXEC_OBJECT_NEEDS_GTT;
> @@ -2761,6 +2768,12 @@ eb_select_engine(struct i915_execbuffer *eb)
>  
>         intel_gt_pm_get(ce->engine->gt);
>  
> +       if (i915_gem_context_can_use_protected_content(eb->gem_context)) {
> +               err = intel_pxp_wait_for_termination_completion(&ce->engine->gt->pxp);
> +               if (err)
> +                       goto err;

This should check for context_invalidated

> +       }
> +
>         if (!test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
>                 err = intel_context_alloc_state(ce);
>                 if (err)
> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
> index 0ca1c2c16972..5912e4a12d94 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
> @@ -6,6 +6,7 @@
>  #include "intel_pxp.h"
>  #include "intel_pxp_irq.h"
>  #include "intel_pxp_tee.h"
> +#include "gem/i915_gem_context.h"
>  #include "gt/intel_context.h"
>  #include "i915_drv.h"
>  
> @@ -135,3 +136,40 @@ int intel_pxp_wait_for_termination_completion(struct intel_pxp *pxp)
>         return ret;
>  }
>  
> +void intel_pxp_invalidate(struct intel_pxp *pxp)
> +{
> +       struct drm_i915_private *i915 = pxp_to_gt(pxp)->i915;
> +       struct i915_gem_context *ctx, *cn;
> +
> +       /* 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_can_use_protected_content(ctx)))
> +                       continue;
> +
> +               if (i915_gem_context_invalidated(ctx))
> +                       continue;
> +
> +               spin_unlock_irq(&i915->gem.contexts.lock);
> +
> +               for_each_gem_engine(ce, i915_gem_context_lock_engines(ctx), it) {

> +                       if (test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
> +                               intel_context_set_banned(ce);

That's a pair of unserialised operations. However, you can just set
banned before we even try to alloc. But at the moment, it's very
spurious to call intel_context_set_banned() as no action is performed to
flush the ban to the backend, and execbuf is primarily checking the GEM
context invalid bit. It looks a bit flimsy...

The impact of this loop would be to cancel all pending requests (but not
the inflight request), sounds like you should just call revoke_context
to remove the inflight context and pending requests from the HW.

> +                               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);

And then there's a race condition where we can create a new protect
context, submit an execbuf using the global session between the call to
intel_pxp_invalidate and terminate_session_and_global. That's covered by
irq_handler calling mark_termination_in_progress and execbuf waiting
for that termination to complete. Almost.

This will result in userspace context lost upon runtime suspend? That
can be quite catastrophic for the system...

> +}
> +
> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
> index 89cf66c9bef3..e36200833095 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
> @@ -38,6 +38,7 @@ void intel_pxp_init(struct intel_pxp *pxp);
>  void intel_pxp_fini(struct intel_pxp *pxp);
>  
>  int intel_pxp_wait_for_termination_completion(struct intel_pxp *pxp);
> +void intel_pxp_invalidate(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_session.c b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> index bb981d38c2fe..527217b3db23 100644
> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
> @@ -111,6 +111,9 @@ int intel_pxp_arb_terminate_session_with_global_terminate(struct intel_pxp *pxp)
>  
>         lockdep_assert_held(&pxp->mutex);
>  
> +       /* invalidate protected objects */
> +       intel_pxp_invalidate(pxp);
> +
>         /* terminate the hw sessions */
>         ret = intel_pxp_submit_session_termination(pxp, ARB_SESSION);
>         if (ret) {
> diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
> index 56c6bfe6c2d0..0f5456046c4c 100644
> --- a/include/uapi/drm/i915_drm.h
> +++ b/include/uapi/drm/i915_drm.h
> @@ -1694,6 +1694,24 @@ struct drm_i915_gem_context_param {
>   * Default is 16 KiB.
>   */
>  #define I915_CONTEXT_PARAM_RINGSIZE    0xc
> +
> +/*
> + * I915_CONTEXT_PARAM_PROTECTED_CONTENT:
> + *
> + * Enable usage of protected content with the context. 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.

I haven't seen any interaction with bannable here. Since you just ignore
the bannable flag.

> + *
> + * Given the numerous restriction on this flag, there are several unique 
> + * failure cases:
> + *
> + * -ENODEV: feature not available
> + * -EEXIST: trying to modify an existing context
> + * -EPERM: trying to mark a recoverable or not bannable context as protected

Also -EIO from execbuf. Do we want to pick EACCES?

> + */
> +#define I915_CONTEXT_PARAM_PROTECTED_CONTENT    0xd
>  /* Must be kept compact -- no holes and well documented */
>  
>         __u64 value;
> @@ -1924,6 +1942,7 @@ struct drm_i915_reg_read {
>  struct drm_i915_reset_stats {
>         __u32 ctx_id;
>         __u32 flags;
> +#define I915_CONTEXT_INVALIDATED 0x1

Mention the side effect for protected content contexts.

>  
>         /* All resets since boot/module reload, for all contexts */
>         __u32 reset_count;
> -- 
> 2.29.2
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH v2 13/16] drm/i915/pxp: User interface for Protected buffer
  2021-03-03 23:16       ` Lionel Landwerlin
@ 2021-03-03 23:25         ` Daniele Ceraolo Spurio
  2021-03-03 23:42           ` Lionel Landwerlin
  0 siblings, 1 reply; 47+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-03-03 23:25 UTC (permalink / raw)
  To: Lionel Landwerlin, intel-gfx
  Cc: Huang Sean Z, Chris Wilson, Kondapally Kalyan, Bommu Krishnaiah



On 3/3/2021 3:16 PM, Lionel Landwerlin wrote:
> On 03/03/2021 23:59, Daniele Ceraolo Spurio wrote:
>>
>>
>> On 3/3/2021 12:39 PM, Lionel Landwerlin wrote:
>>> On 01/03/2021 21:31, Daniele Ceraolo Spurio wrote:
>>>> From: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
>>>>
>>>> This api allow user mode to create Protected buffers. Only contexts
>>>> marked as protected are allowed to operate on protected buffers.
>>>>
>>>> We only allow setting the flags at creation time.
>>>>
>>>> All protected objects that have backing storage will be considered
>>>> invalid when the session is destroyed and they won't be usable 
>>>> anymore.
>>>>
>>>> This is a rework of the original code by Bommu Krishnaiah. I've
>>>> authorship unchanged since significant chunks have not been modified.
>>>>
>>>> v2: split context changes, fix defines and improve documentation 
>>>> (Chris),
>>>>      add object invalidation logic
>>>>
>>>> Signed-off-by: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
>>>> Signed-off-by: Daniele Ceraolo Spurio 
>>>> <daniele.ceraolospurio@intel.com>
>>>> Cc: Telukuntla Sreedhar <sreedhar.telukuntla@intel.com>
>>>> Cc: Kondapally Kalyan <kalyan.kondapally@intel.com>
>>>> Cc: Gupta Anshuman <Anshuman.Gupta@intel.com>
>>>> Cc: Huang Sean Z <sean.z.huang@intel.com>
>>>> Cc: Chris Wilson <chris@chris-wilson.co.uk>
>>>> ---
>>>>   drivers/gpu/drm/i915/gem/i915_gem_create.c    | 27 +++++++++++--
>>>>   .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 10 +++++
>>>>   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  | 13 ++++++
>>>>   drivers/gpu/drm/i915/pxp/intel_pxp.c          | 40 
>>>> +++++++++++++++++++
>>>>   drivers/gpu/drm/i915/pxp/intel_pxp.h          | 13 ++++++
>>>>   drivers/gpu/drm/i915/pxp/intel_pxp_types.h    |  5 +++
>>>>   include/uapi/drm/i915_drm.h                   | 22 ++++++++++
>>>>   9 files changed, 145 insertions(+), 3 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c 
>>>> b/drivers/gpu/drm/i915/gem/i915_gem_create.c
>>>> index 3ad3413c459f..d02e5938afbe 100644
>>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
>>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
>>>> @@ -5,6 +5,7 @@
>>>>     #include "gem/i915_gem_ioctls.h"
>>>>   #include "gem/i915_gem_region.h"
>>>> +#include "pxp/intel_pxp.h"
>>>>     #include "i915_drv.h"
>>>>   #include "i915_user_extensions.h"
>>>> @@ -13,7 +14,8 @@ static int
>>>>   i915_gem_create(struct drm_file *file,
>>>>           struct intel_memory_region *mr,
>>>>           u64 *size_p,
>>>> -        u32 *handle_p)
>>>> +        u32 *handle_p,
>>>> +        u64 user_flags)
>>>>   {
>>>>       struct drm_i915_gem_object *obj;
>>>>       u32 handle;
>>>> @@ -35,12 +37,17 @@ i915_gem_create(struct drm_file *file,
>>>>         GEM_BUG_ON(size != obj->base.size);
>>>>   +    obj->user_flags = user_flags;
>>>> +
>>>>       ret = drm_gem_handle_create(file, &obj->base, &handle);
>>>>       /* drop reference from allocate - handle holds it now */
>>>>       i915_gem_object_put(obj);
>>>>       if (ret)
>>>>           return ret;
>>>>   +    if (user_flags & I915_GEM_OBJECT_PROTECTED)
>>>> +        intel_pxp_object_add(obj);
>>>> +
>>>>       *handle_p = handle;
>>>>       *size_p = size;
>>>>       return 0;
>>>> @@ -89,11 +96,12 @@ i915_gem_dumb_create(struct drm_file *file,
>>>>       return i915_gem_create(file,
>>>> intel_memory_region_by_type(to_i915(dev),
>>>>                                  mem_type),
>>>> -                   &args->size, &args->handle);
>>>> +                   &args->size, &args->handle, 0);
>>>>   }
>>>>     struct create_ext {
>>>>       struct drm_i915_private *i915;
>>>> +    unsigned long user_flags;
>>>>   };
>>>>     static int __create_setparam(struct drm_i915_gem_object_param 
>>>> *args,
>>>> @@ -104,6 +112,19 @@ static int __create_setparam(struct 
>>>> drm_i915_gem_object_param *args,
>>>>           return -EINVAL;
>>>>       }
>>>>   +    switch (lower_32_bits(args->param)) {
>>>> +    case I915_OBJECT_PARAM_PROTECTED_CONTENT:
>>>> +        if (!intel_pxp_is_enabled(&ext_data->i915->gt.pxp))
>>>> +            return -ENODEV;
>>>> +        if (args->size) {
>>>> +            return -EINVAL;
>>>> +        } else if (args->data) {
>>>> +            ext_data->user_flags |= I915_GEM_OBJECT_PROTECTED;
>>>> +            return 0;
>>>> +        }
>>>> +    break;
>>>> +    }
>>>> +
>>>>       return -EINVAL;
>>>>   }
>>>>   @@ -148,5 +169,5 @@ i915_gem_create_ioctl(struct drm_device *dev, 
>>>> void *data,
>>>>       return i915_gem_create(file,
>>>>                      intel_memory_region_by_type(i915,
>>>>                                  INTEL_MEMORY_SYSTEM),
>>>> -                   &args->size, &args->handle);
>>>> +                   &args->size, &args->handle, ext_data.user_flags);
>>>>   }
>>>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c 
>>>> b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>>>> index e503c9f789c0..d10c4fcb6aec 100644
>>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>>>> @@ -20,6 +20,7 @@
>>>>   #include "gt/intel_gt_buffer_pool.h"
>>>>   #include "gt/intel_gt_pm.h"
>>>>   #include "gt/intel_ring.h"
>>>> +#include "pxp/intel_pxp.h"
>>>>     #include "pxp/intel_pxp.h"
>>>>   @@ -500,6 +501,15 @@ eb_validate_vma(struct i915_execbuffer *eb,
>>>>                entry->offset != gen8_canonical_addr(entry->offset & 
>>>> I915_GTT_PAGE_MASK)))
>>>>           return -EINVAL;
>>>>   +    if (i915_gem_object_is_protected(vma->obj)) {
>>>> +        if (!intel_pxp_is_active(&vma->vm->gt->pxp))
>>>> +            return -ENODEV;
>>>> +        if (!i915_gem_object_has_valid_protection(vma->obj))
>>>> +            return -EIO;
>>>> +        if 
>>>> (!i915_gem_context_can_use_protected_content(eb->gem_context))
>>>> +            return -EPERM;
>>>
>>>
>>> I think I'm running into this error.
>>
>> The currently agreed design is that protected objects can only be 
>> used with explicitly marked contexts, although it's not an HW 
>> requirement so we can revisit it.
>>
>>>
>>> When running vkcube protected under wayland, it takes down the 
>>> entire session (Xorg & gnome-shell depending on which one is going 
>>> to use the protected buffer first).
>>
>> Are you saying that a single submission failure takes down the entire 
>> gnome session? that sounds like a larger problem than just this 
>> failure. Or am I misunderstanding your point?
>
>
> We just need to hand that buffer to any other app and have it use it 
> in execbuf and that will make it fail the execbuf.
>
> Now how does the driver in the gnome-shell/Xorg process know what went 
> wrong and what buffer caused it?
>
> Could be any imported buffer. It's pretty hard to recover from this 
> and most apps will just crash if the driver starts to fail for some 
> reason.
>
> You can see how that could make a lot of people's live terrible :/

Don't other apps have to know that the buffer is encrypted to use it 
properly? Or is there a case where we want to use the object as if it 
wasn't encrypted?

Also, PXP submissions can become invalid at any point in time due to a 
teardown event, which causes the contents of the encrypted buffers to 
become garbage. If we can't fail the execbuf which includes an 
invalidated buffer we'd have to silently discard the submission.

Daniele

>
>
> -Lionel
>
>
>>
>>>
>>> That's a bit harsh.
>>>
>>>
>>> We probably don't want this. After all the point of encryption is 
>>> that even if you can read the buffer you won't be able to make much 
>>> of its content.
>>
>> As mentioned above we can change this since there is no HW 
>> requirement on contexts, but need some architectural agreement. 
>> Joonas and Rodrigo can comment more here.
>> Also note that submitting an instruction using encrypted data while 
>> the session is invalid can cause the HW to hang, which is part of the 
>> reason why we require the contexts using protected objects to be 
>> marked appropriately, so we can ban them on PXP teardown to avoid hangs.
>>
>> Daniele
>>
>>>
>>> Also useful to know you're dealing for debugging ;)
>>>
>>>
>>> -Lionel
>>>
>>>
>>>> +    }
>>>> +
>>>>       /* pad_to_size was once a reserved field, so sanitize it */
>>>>       if (entry->flags & EXEC_OBJECT_PAD_TO_SIZE) {
>>>>           if (unlikely(offset_in_page(entry->pad_to_size)))
>>>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c 
>>>> b/drivers/gpu/drm/i915/gem/i915_gem_object.c
>>>> index 6cdff5fc5882..b321f5484ae6 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"
>>>> @@ -72,6 +73,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;
>>>>   @@ -120,6 +123,9 @@ static void i915_gem_close_object(struct 
>>>> drm_gem_object *gem, struct drm_file *f
>>>>       struct i915_lut_handle *lut, *ln;
>>>>       LIST_HEAD(close);
>>>>   +    if (i915_gem_object_has_valid_protection(obj))
>>>> +        intel_pxp_object_remove(obj);
>>>> +
>>>>       spin_lock(&obj->lut_lock);
>>>>       list_for_each_entry_safe(lut, ln, &obj->lut_list, obj_link) {
>>>>           struct i915_gem_context *ctx = lut->ctx;
>>>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h 
>>>> b/drivers/gpu/drm/i915/gem/i915_gem_object.h
>>>> index 366d23afbb1a..a1fa7539c0f7 100644
>>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
>>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
>>>> @@ -274,6 +274,18 @@ i915_gem_object_needs_async_cancel(const 
>>>> struct drm_i915_gem_object *obj)
>>>>       return i915_gem_object_type_has(obj, 
>>>> I915_GEM_OBJECT_ASYNC_CANCEL);
>>>>   }
>>>>   +static inline bool
>>>> +i915_gem_object_is_protected(const struct drm_i915_gem_object *obj)
>>>> +{
>>>> +    return obj->user_flags & I915_GEM_OBJECT_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_is_framebuffer(const struct drm_i915_gem_object 
>>>> *obj)
>>>>   {
>>>> 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 0a1fdbac882e..6eee580c7aba 100644
>>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
>>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
>>>> @@ -167,6 +167,11 @@ struct drm_i915_gem_object {
>>>>       } mmo;
>>>>         I915_SELFTEST_DECLARE(struct list_head st_link);
>>>> +    /**
>>>> +     * @user_flags: small set of booleans set by the user
>>>> +     */
>>>> +    unsigned long user_flags;
>>>> +#define I915_GEM_OBJECT_PROTECTED BIT(0)
>>>>         unsigned long flags;
>>>>   #define I915_BO_ALLOC_CONTIGUOUS BIT(0)
>>>> @@ -290,6 +295,14 @@ struct drm_i915_gem_object {
>>>>           bool dirty:1;
>>>>       } mm;
>>>>   +    /*
>>>> +     * 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 5912e4a12d94..03151cd7f4b8 100644
>>>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
>>>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
>>>> @@ -69,6 +69,8 @@ void intel_pxp_init(struct intel_pxp *pxp)
>>>>           return;
>>>>         mutex_init(&pxp->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,
>>>> @@ -136,11 +138,49 @@ int 
>>>> intel_pxp_wait_for_termination_completion(struct intel_pxp *pxp)
>>>>       return ret;
>>>>   }
>>>>   +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) {
>>>> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h 
>>>> b/drivers/gpu/drm/i915/pxp/intel_pxp.h
>>>> index e36200833095..3315b07d271b 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;
>>>> +
>>>>   #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)
>>>> @@ -38,6 +40,9 @@ void intel_pxp_init(struct intel_pxp *pxp);
>>>>   void intel_pxp_fini(struct intel_pxp *pxp);
>>>>     int intel_pxp_wait_for_termination_completion(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)
>>>> @@ -52,6 +57,14 @@ static inline int 
>>>> intel_pxp_wait_for_termination_completion(struct intel_pxp *px
>>>>   {
>>>>       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_types.h 
>>>> b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
>>>> index 6f659a6f8f1c..53a2a8acfe51 100644
>>>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
>>>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
>>>> @@ -7,8 +7,10 @@
>>>>   #define __INTEL_PXP_TYPES_H__
>>>>     #include <linux/completion.h>
>>>> +#include <linux/list.h>
>>>>   #include <linux/types.h>
>>>>   #include <linux/mutex.h>
>>>> +#include <linux/spinlock.h>
>>>>   #include <linux/workqueue.h>
>>>>     struct intel_context;
>>>> @@ -28,6 +30,9 @@ struct intel_pxp {
>>>>       struct work_struct irq_work;
>>>>       bool irq_enabled;
>>>>       u32 current_events; /* protected with gt->irq_lock */
>>>> +
>>>> +    struct spinlock lock;
>>>> +    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 9ebe8523aa0c..0f8b771a6d53 100644
>>>> --- a/include/uapi/drm/i915_drm.h
>>>> +++ b/include/uapi/drm/i915_drm.h
>>>> @@ -1753,6 +1753,28 @@ struct drm_i915_gem_object_param {
>>>>    */
>>>>   #define I915_OBJECT_PARAM  (1ull << 32)
>>>>   +/*
>>>> + * I915_OBJECT_PARAM_PROTECTED_CONTENT:
>>>> + *
>>>> + * If set to true, buffer contents is expected to be protected by PXP
>>>> + * encryption and requires decryption for scan out and processing. 
>>>> This is
>>>> + * only possible on platforms that have PXP enabled, on all other 
>>>> scenarios
>>>> + * setting this flag will cause the ioctl to fail and return -ENODEV.
>>>> + *
>>>> + * Protected buffers can only be used with contexts created using the
>>>> + * I915_CONTEXT_PARAM_PROTECTED_CONTENT flag. The buffer contents are
>>>> + * considered invalid after a PXP session teardown.
>>>> + *
>>>> + * Given the restriction above, the following errors are possible 
>>>> when
>>>> + * submitting a protected object in an execbuf call:
>>>> + *
>>>> + * -ENODEV: PXP session not currently active
>>>> + * -EIO: buffer has become invalid after a teardown event
>>>> + * -EPERM: buffer submitted using a context not marked as protected
>>>> + */
>>>> +#define I915_OBJECT_PARAM_PROTECTED_CONTENT  0x0
>>>> +/* Must be kept compact -- no holes and well documented */
>>>> +
>>>>       __u64 param;
>>>>         /* Data value or pointer */
>>>
>>>
>>
>

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

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

* Re: [Intel-gfx] [PATCH v2 13/16] drm/i915/pxp: User interface for Protected buffer
  2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 13/16] drm/i915/pxp: User interface for Protected buffer Daniele Ceraolo Spurio
  2021-03-03 20:39   ` Lionel Landwerlin
@ 2021-03-03 23:33   ` Chris Wilson
  1 sibling, 0 replies; 47+ messages in thread
From: Chris Wilson @ 2021-03-03 23:33 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio, intel-gfx
  Cc: Kondapally Kalyan, Huang Sean Z, Bommu Krishnaiah

Quoting Daniele Ceraolo Spurio (2021-03-01 19:31:57)
> From: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
> 
> This api allow user mode to create Protected buffers. Only contexts
> marked as protected are allowed to operate on protected buffers.
> 
> We only allow setting the flags at creation time.
> 
> All protected objects that have backing storage will be considered
> invalid when the session is destroyed and they won't be usable anymore.
> 
> This is a rework of the original code by Bommu Krishnaiah. I've
> authorship unchanged since significant chunks have not been modified.
> 
> v2: split context changes, fix defines and improve documentation (Chris),
>     add object invalidation logic
> 
> Signed-off-by: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
> Cc: Telukuntla Sreedhar <sreedhar.telukuntla@intel.com>
> Cc: Kondapally Kalyan <kalyan.kondapally@intel.com>
> Cc: Gupta Anshuman <Anshuman.Gupta@intel.com>
> Cc: Huang Sean Z <sean.z.huang@intel.com>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> ---
>  drivers/gpu/drm/i915/gem/i915_gem_create.c    | 27 +++++++++++--
>  .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 10 +++++
>  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  | 13 ++++++
>  drivers/gpu/drm/i915/pxp/intel_pxp.c          | 40 +++++++++++++++++++
>  drivers/gpu/drm/i915/pxp/intel_pxp.h          | 13 ++++++
>  drivers/gpu/drm/i915/pxp/intel_pxp_types.h    |  5 +++
>  include/uapi/drm/i915_drm.h                   | 22 ++++++++++
>  9 files changed, 145 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c b/drivers/gpu/drm/i915/gem/i915_gem_create.c
> index 3ad3413c459f..d02e5938afbe 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
> @@ -5,6 +5,7 @@
>  
>  #include "gem/i915_gem_ioctls.h"
>  #include "gem/i915_gem_region.h"
> +#include "pxp/intel_pxp.h"
>  
>  #include "i915_drv.h"
>  #include "i915_user_extensions.h"
> @@ -13,7 +14,8 @@ static int
>  i915_gem_create(struct drm_file *file,
>                 struct intel_memory_region *mr,
>                 u64 *size_p,
> -               u32 *handle_p)
> +               u32 *handle_p,
> +               u64 user_flags)
>  {
>         struct drm_i915_gem_object *obj;
>         u32 handle;
> @@ -35,12 +37,17 @@ i915_gem_create(struct drm_file *file,
>  
>         GEM_BUG_ON(size != obj->base.size);
>  
> +       obj->user_flags = user_flags;
> +
>         ret = drm_gem_handle_create(file, &obj->base, &handle);
>         /* drop reference from allocate - handle holds it now */
>         i915_gem_object_put(obj);
>         if (ret)
>                 return ret;
>  
> +       if (user_flags & I915_GEM_OBJECT_PROTECTED)
> +               intel_pxp_object_add(obj);
> +
>         *handle_p = handle;
>         *size_p = size;
>         return 0;
> @@ -89,11 +96,12 @@ i915_gem_dumb_create(struct drm_file *file,
>         return i915_gem_create(file,
>                                intel_memory_region_by_type(to_i915(dev),
>                                                            mem_type),
> -                              &args->size, &args->handle);
> +                              &args->size, &args->handle, 0);
>  }
>  
>  struct create_ext {
>         struct drm_i915_private *i915;
> +       unsigned long user_flags;
>  };
>  
>  static int __create_setparam(struct drm_i915_gem_object_param *args,
> @@ -104,6 +112,19 @@ static int __create_setparam(struct drm_i915_gem_object_param *args,
>                 return -EINVAL;
>         }
>  
> +       switch (lower_32_bits(args->param)) {
> +       case I915_OBJECT_PARAM_PROTECTED_CONTENT:
> +               if (!intel_pxp_is_enabled(&ext_data->i915->gt.pxp))
> +                       return -ENODEV;
> +               if (args->size) {
> +                       return -EINVAL;
> +               } else if (args->data) {
> +                       ext_data->user_flags |= I915_GEM_OBJECT_PROTECTED;
> +                       return 0;
> +               }
> +       break;
> +       }
> +
>         return -EINVAL;
>  }
>  
> @@ -148,5 +169,5 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data,
>         return i915_gem_create(file,
>                                intel_memory_region_by_type(i915,
>                                                            INTEL_MEMORY_SYSTEM),
> -                              &args->size, &args->handle);
> +                              &args->size, &args->handle, ext_data.user_flags);
>  }
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> index e503c9f789c0..d10c4fcb6aec 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> @@ -20,6 +20,7 @@
>  #include "gt/intel_gt_buffer_pool.h"
>  #include "gt/intel_gt_pm.h"
>  #include "gt/intel_ring.h"
> +#include "pxp/intel_pxp.h"
>  
>  #include "pxp/intel_pxp.h"
>  

> @@ -120,6 +123,9 @@ static void i915_gem_close_object(struct drm_gem_object *gem, struct drm_file *f
>         struct i915_lut_handle *lut, *ln;
>         LIST_HEAD(close);
>  
> +       if (i915_gem_object_has_valid_protection(obj))
> +               intel_pxp_object_remove(obj);

This is called once for every handle in every fd, so a shared object will
be closed multiple times.

> @@ -500,6 +501,15 @@ eb_validate_vma(struct i915_execbuffer *eb,
>                      entry->offset != gen8_canonical_addr(entry->offset & I915_GTT_PAGE_MASK)))
>                 return -EINVAL;
>  

> +       if (i915_gem_object_is_protected(vma->obj)) {

Oh no, please not more cacheline to chase. Look to the vma. That also
helps with the problem of shared objects as you can check the closure of
the lut (i.e. the local reference of whether the protected vma is being used).

The bigger question is why though. This is to prevent reuse of protected
buffers in a new protected content context (because the earlier
invalidate would kill the previous context). In which case, you would
only need to do this check on new handles used by this context.

That also puts it in the position where the vma->obj has to be chased
anyway.

> +               if (!intel_pxp_is_active(&vma->vm->gt->pxp))
> +                       return -ENODEV;
> +               if (!i915_gem_object_has_valid_protection(vma->obj))
> +                       return -EIO;
> +               if (!i915_gem_context_can_use_protected_content(eb->gem_context))
> +                       return -EPERM;
> +       }


> +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);

pxp->lock is never used from irq context.

> @@ -28,6 +30,9 @@ struct intel_pxp {
>         struct work_struct irq_work;
>         bool irq_enabled;
>         u32 current_events; /* protected with gt->irq_lock */
> +
> +       struct spinlock lock;

struct spinlock is the odd one where spinlock_t is the preferred form.
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH v2 13/16] drm/i915/pxp: User interface for Protected buffer
  2021-03-03 23:25         ` Daniele Ceraolo Spurio
@ 2021-03-03 23:42           ` Lionel Landwerlin
  2021-03-04  0:10             ` Daniele Ceraolo Spurio
  0 siblings, 1 reply; 47+ messages in thread
From: Lionel Landwerlin @ 2021-03-03 23:42 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio, intel-gfx
  Cc: Huang Sean Z, Chris Wilson, Kondapally Kalyan, Bommu Krishnaiah

On 04/03/2021 01:25, Daniele Ceraolo Spurio wrote:
>
>
> On 3/3/2021 3:16 PM, Lionel Landwerlin wrote:
>> On 03/03/2021 23:59, Daniele Ceraolo Spurio wrote:
>>>
>>>
>>> On 3/3/2021 12:39 PM, Lionel Landwerlin wrote:
>>>> On 01/03/2021 21:31, Daniele Ceraolo Spurio wrote:
>>>>> From: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
>>>>>
>>>>> This api allow user mode to create Protected buffers. Only contexts
>>>>> marked as protected are allowed to operate on protected buffers.
>>>>>
>>>>> We only allow setting the flags at creation time.
>>>>>
>>>>> All protected objects that have backing storage will be considered
>>>>> invalid when the session is destroyed and they won't be usable 
>>>>> anymore.
>>>>>
>>>>> This is a rework of the original code by Bommu Krishnaiah. I've
>>>>> authorship unchanged since significant chunks have not been modified.
>>>>>
>>>>> v2: split context changes, fix defines and improve documentation 
>>>>> (Chris),
>>>>>      add object invalidation logic
>>>>>
>>>>> Signed-off-by: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
>>>>> Signed-off-by: Daniele Ceraolo Spurio 
>>>>> <daniele.ceraolospurio@intel.com>
>>>>> Cc: Telukuntla Sreedhar <sreedhar.telukuntla@intel.com>
>>>>> Cc: Kondapally Kalyan <kalyan.kondapally@intel.com>
>>>>> Cc: Gupta Anshuman <Anshuman.Gupta@intel.com>
>>>>> Cc: Huang Sean Z <sean.z.huang@intel.com>
>>>>> Cc: Chris Wilson <chris@chris-wilson.co.uk>
>>>>> ---
>>>>>   drivers/gpu/drm/i915/gem/i915_gem_create.c    | 27 +++++++++++--
>>>>>   .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 10 +++++
>>>>>   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  | 13 ++++++
>>>>>   drivers/gpu/drm/i915/pxp/intel_pxp.c          | 40 
>>>>> +++++++++++++++++++
>>>>>   drivers/gpu/drm/i915/pxp/intel_pxp.h          | 13 ++++++
>>>>>   drivers/gpu/drm/i915/pxp/intel_pxp_types.h    |  5 +++
>>>>>   include/uapi/drm/i915_drm.h                   | 22 ++++++++++
>>>>>   9 files changed, 145 insertions(+), 3 deletions(-)
>>>>>
>>>>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c 
>>>>> b/drivers/gpu/drm/i915/gem/i915_gem_create.c
>>>>> index 3ad3413c459f..d02e5938afbe 100644
>>>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
>>>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
>>>>> @@ -5,6 +5,7 @@
>>>>>     #include "gem/i915_gem_ioctls.h"
>>>>>   #include "gem/i915_gem_region.h"
>>>>> +#include "pxp/intel_pxp.h"
>>>>>     #include "i915_drv.h"
>>>>>   #include "i915_user_extensions.h"
>>>>> @@ -13,7 +14,8 @@ static int
>>>>>   i915_gem_create(struct drm_file *file,
>>>>>           struct intel_memory_region *mr,
>>>>>           u64 *size_p,
>>>>> -        u32 *handle_p)
>>>>> +        u32 *handle_p,
>>>>> +        u64 user_flags)
>>>>>   {
>>>>>       struct drm_i915_gem_object *obj;
>>>>>       u32 handle;
>>>>> @@ -35,12 +37,17 @@ i915_gem_create(struct drm_file *file,
>>>>>         GEM_BUG_ON(size != obj->base.size);
>>>>>   +    obj->user_flags = user_flags;
>>>>> +
>>>>>       ret = drm_gem_handle_create(file, &obj->base, &handle);
>>>>>       /* drop reference from allocate - handle holds it now */
>>>>>       i915_gem_object_put(obj);
>>>>>       if (ret)
>>>>>           return ret;
>>>>>   +    if (user_flags & I915_GEM_OBJECT_PROTECTED)
>>>>> +        intel_pxp_object_add(obj);
>>>>> +
>>>>>       *handle_p = handle;
>>>>>       *size_p = size;
>>>>>       return 0;
>>>>> @@ -89,11 +96,12 @@ i915_gem_dumb_create(struct drm_file *file,
>>>>>       return i915_gem_create(file,
>>>>> intel_memory_region_by_type(to_i915(dev),
>>>>>                                  mem_type),
>>>>> -                   &args->size, &args->handle);
>>>>> +                   &args->size, &args->handle, 0);
>>>>>   }
>>>>>     struct create_ext {
>>>>>       struct drm_i915_private *i915;
>>>>> +    unsigned long user_flags;
>>>>>   };
>>>>>     static int __create_setparam(struct drm_i915_gem_object_param 
>>>>> *args,
>>>>> @@ -104,6 +112,19 @@ static int __create_setparam(struct 
>>>>> drm_i915_gem_object_param *args,
>>>>>           return -EINVAL;
>>>>>       }
>>>>>   +    switch (lower_32_bits(args->param)) {
>>>>> +    case I915_OBJECT_PARAM_PROTECTED_CONTENT:
>>>>> +        if (!intel_pxp_is_enabled(&ext_data->i915->gt.pxp))
>>>>> +            return -ENODEV;
>>>>> +        if (args->size) {
>>>>> +            return -EINVAL;
>>>>> +        } else if (args->data) {
>>>>> +            ext_data->user_flags |= I915_GEM_OBJECT_PROTECTED;
>>>>> +            return 0;
>>>>> +        }
>>>>> +    break;
>>>>> +    }
>>>>> +
>>>>>       return -EINVAL;
>>>>>   }
>>>>>   @@ -148,5 +169,5 @@ i915_gem_create_ioctl(struct drm_device 
>>>>> *dev, void *data,
>>>>>       return i915_gem_create(file,
>>>>>                      intel_memory_region_by_type(i915,
>>>>>                                  INTEL_MEMORY_SYSTEM),
>>>>> -                   &args->size, &args->handle);
>>>>> +                   &args->size, &args->handle, ext_data.user_flags);
>>>>>   }
>>>>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c 
>>>>> b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>>>>> index e503c9f789c0..d10c4fcb6aec 100644
>>>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>>>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>>>>> @@ -20,6 +20,7 @@
>>>>>   #include "gt/intel_gt_buffer_pool.h"
>>>>>   #include "gt/intel_gt_pm.h"
>>>>>   #include "gt/intel_ring.h"
>>>>> +#include "pxp/intel_pxp.h"
>>>>>     #include "pxp/intel_pxp.h"
>>>>>   @@ -500,6 +501,15 @@ eb_validate_vma(struct i915_execbuffer *eb,
>>>>>                entry->offset != gen8_canonical_addr(entry->offset 
>>>>> & I915_GTT_PAGE_MASK)))
>>>>>           return -EINVAL;
>>>>>   +    if (i915_gem_object_is_protected(vma->obj)) {
>>>>> +        if (!intel_pxp_is_active(&vma->vm->gt->pxp))
>>>>> +            return -ENODEV;
>>>>> +        if (!i915_gem_object_has_valid_protection(vma->obj))
>>>>> +            return -EIO;
>>>>> +        if 
>>>>> (!i915_gem_context_can_use_protected_content(eb->gem_context))
>>>>> +            return -EPERM;
>>>>
>>>>
>>>> I think I'm running into this error.
>>>
>>> The currently agreed design is that protected objects can only be 
>>> used with explicitly marked contexts, although it's not an HW 
>>> requirement so we can revisit it.
>>>
>>>>
>>>> When running vkcube protected under wayland, it takes down the 
>>>> entire session (Xorg & gnome-shell depending on which one is going 
>>>> to use the protected buffer first).
>>>
>>> Are you saying that a single submission failure takes down the 
>>> entire gnome session? that sounds like a larger problem than just 
>>> this failure. Or am I misunderstanding your point?
>>
>>
>> We just need to hand that buffer to any other app and have it use it 
>> in execbuf and that will make it fail the execbuf.
>>
>> Now how does the driver in the gnome-shell/Xorg process know what 
>> went wrong and what buffer caused it?
>>
>> Could be any imported buffer. It's pretty hard to recover from this 
>> and most apps will just crash if the driver starts to fail for some 
>> reason.
>>
>> You can see how that could make a lot of people's live terrible :/
>
> Don't other apps have to know that the buffer is encrypted to use it 
> properly? Or is there a case where we want to use the object as if it 
> wasn't encrypted?
>
> Also, PXP submissions can become invalid at any point in time due to a 
> teardown event, which causes the contents of the encrypted buffers to 
> become garbage. If we can't fail the execbuf which includes an 
> invalidated buffer we'd have to silently discard the submission.


A malicious app could start sharing protected tagged buffer with no 
protected content in it, just to invalidate/crash others apps' context.

Can the failure be only reported to protected contexts?


-Lionel


>
> Daniele
>
>>
>>
>> -Lionel
>>
>>
>>>
>>>>
>>>> That's a bit harsh.
>>>>
>>>>
>>>> We probably don't want this. After all the point of encryption is 
>>>> that even if you can read the buffer you won't be able to make much 
>>>> of its content.
>>>
>>> As mentioned above we can change this since there is no HW 
>>> requirement on contexts, but need some architectural agreement. 
>>> Joonas and Rodrigo can comment more here.
>>> Also note that submitting an instruction using encrypted data while 
>>> the session is invalid can cause the HW to hang, which is part of 
>>> the reason why we require the contexts using protected objects to be 
>>> marked appropriately, so we can ban them on PXP teardown to avoid 
>>> hangs.
>>>
>>> Daniele
>>>
>>>>
>>>> Also useful to know you're dealing for debugging ;)
>>>>
>>>>
>>>> -Lionel
>>>>
>>>>
>>>>> +    }
>>>>> +
>>>>>       /* pad_to_size was once a reserved field, so sanitize it */
>>>>>       if (entry->flags & EXEC_OBJECT_PAD_TO_SIZE) {
>>>>>           if (unlikely(offset_in_page(entry->pad_to_size)))
>>>>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c 
>>>>> b/drivers/gpu/drm/i915/gem/i915_gem_object.c
>>>>> index 6cdff5fc5882..b321f5484ae6 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"
>>>>> @@ -72,6 +73,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;
>>>>>   @@ -120,6 +123,9 @@ static void i915_gem_close_object(struct 
>>>>> drm_gem_object *gem, struct drm_file *f
>>>>>       struct i915_lut_handle *lut, *ln;
>>>>>       LIST_HEAD(close);
>>>>>   +    if (i915_gem_object_has_valid_protection(obj))
>>>>> +        intel_pxp_object_remove(obj);
>>>>> +
>>>>>       spin_lock(&obj->lut_lock);
>>>>>       list_for_each_entry_safe(lut, ln, &obj->lut_list, obj_link) {
>>>>>           struct i915_gem_context *ctx = lut->ctx;
>>>>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h 
>>>>> b/drivers/gpu/drm/i915/gem/i915_gem_object.h
>>>>> index 366d23afbb1a..a1fa7539c0f7 100644
>>>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
>>>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
>>>>> @@ -274,6 +274,18 @@ i915_gem_object_needs_async_cancel(const 
>>>>> struct drm_i915_gem_object *obj)
>>>>>       return i915_gem_object_type_has(obj, 
>>>>> I915_GEM_OBJECT_ASYNC_CANCEL);
>>>>>   }
>>>>>   +static inline bool
>>>>> +i915_gem_object_is_protected(const struct drm_i915_gem_object *obj)
>>>>> +{
>>>>> +    return obj->user_flags & I915_GEM_OBJECT_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_is_framebuffer(const struct drm_i915_gem_object 
>>>>> *obj)
>>>>>   {
>>>>> 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 0a1fdbac882e..6eee580c7aba 100644
>>>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
>>>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
>>>>> @@ -167,6 +167,11 @@ struct drm_i915_gem_object {
>>>>>       } mmo;
>>>>>         I915_SELFTEST_DECLARE(struct list_head st_link);
>>>>> +    /**
>>>>> +     * @user_flags: small set of booleans set by the user
>>>>> +     */
>>>>> +    unsigned long user_flags;
>>>>> +#define I915_GEM_OBJECT_PROTECTED BIT(0)
>>>>>         unsigned long flags;
>>>>>   #define I915_BO_ALLOC_CONTIGUOUS BIT(0)
>>>>> @@ -290,6 +295,14 @@ struct drm_i915_gem_object {
>>>>>           bool dirty:1;
>>>>>       } mm;
>>>>>   +    /*
>>>>> +     * 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 5912e4a12d94..03151cd7f4b8 100644
>>>>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
>>>>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
>>>>> @@ -69,6 +69,8 @@ void intel_pxp_init(struct intel_pxp *pxp)
>>>>>           return;
>>>>>         mutex_init(&pxp->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,
>>>>> @@ -136,11 +138,49 @@ int 
>>>>> intel_pxp_wait_for_termination_completion(struct intel_pxp *pxp)
>>>>>       return ret;
>>>>>   }
>>>>>   +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) {
>>>>> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h 
>>>>> b/drivers/gpu/drm/i915/pxp/intel_pxp.h
>>>>> index e36200833095..3315b07d271b 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;
>>>>> +
>>>>>   #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)
>>>>> @@ -38,6 +40,9 @@ void intel_pxp_init(struct intel_pxp *pxp);
>>>>>   void intel_pxp_fini(struct intel_pxp *pxp);
>>>>>     int intel_pxp_wait_for_termination_completion(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)
>>>>> @@ -52,6 +57,14 @@ static inline int 
>>>>> intel_pxp_wait_for_termination_completion(struct intel_pxp *px
>>>>>   {
>>>>>       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_types.h 
>>>>> b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
>>>>> index 6f659a6f8f1c..53a2a8acfe51 100644
>>>>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
>>>>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
>>>>> @@ -7,8 +7,10 @@
>>>>>   #define __INTEL_PXP_TYPES_H__
>>>>>     #include <linux/completion.h>
>>>>> +#include <linux/list.h>
>>>>>   #include <linux/types.h>
>>>>>   #include <linux/mutex.h>
>>>>> +#include <linux/spinlock.h>
>>>>>   #include <linux/workqueue.h>
>>>>>     struct intel_context;
>>>>> @@ -28,6 +30,9 @@ struct intel_pxp {
>>>>>       struct work_struct irq_work;
>>>>>       bool irq_enabled;
>>>>>       u32 current_events; /* protected with gt->irq_lock */
>>>>> +
>>>>> +    struct spinlock lock;
>>>>> +    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 9ebe8523aa0c..0f8b771a6d53 100644
>>>>> --- a/include/uapi/drm/i915_drm.h
>>>>> +++ b/include/uapi/drm/i915_drm.h
>>>>> @@ -1753,6 +1753,28 @@ struct drm_i915_gem_object_param {
>>>>>    */
>>>>>   #define I915_OBJECT_PARAM  (1ull << 32)
>>>>>   +/*
>>>>> + * I915_OBJECT_PARAM_PROTECTED_CONTENT:
>>>>> + *
>>>>> + * If set to true, buffer contents is expected to be protected by 
>>>>> PXP
>>>>> + * encryption and requires decryption for scan out and 
>>>>> processing. This is
>>>>> + * only possible on platforms that have PXP enabled, on all other 
>>>>> scenarios
>>>>> + * setting this flag will cause the ioctl to fail and return 
>>>>> -ENODEV.
>>>>> + *
>>>>> + * Protected buffers can only be used with contexts created using 
>>>>> the
>>>>> + * I915_CONTEXT_PARAM_PROTECTED_CONTENT flag. The buffer contents 
>>>>> are
>>>>> + * considered invalid after a PXP session teardown.
>>>>> + *
>>>>> + * Given the restriction above, the following errors are possible 
>>>>> when
>>>>> + * submitting a protected object in an execbuf call:
>>>>> + *
>>>>> + * -ENODEV: PXP session not currently active
>>>>> + * -EIO: buffer has become invalid after a teardown event
>>>>> + * -EPERM: buffer submitted using a context not marked as protected
>>>>> + */
>>>>> +#define I915_OBJECT_PARAM_PROTECTED_CONTENT  0x0
>>>>> +/* Must be kept compact -- no holes and well documented */
>>>>> +
>>>>>       __u64 param;
>>>>>         /* Data value or pointer */
>>>>
>>>>
>>>
>>
>

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

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

* Re: [Intel-gfx] [PATCH v2 13/16] drm/i915/pxp: User interface for Protected buffer
  2021-03-03 23:42           ` Lionel Landwerlin
@ 2021-03-04  0:10             ` Daniele Ceraolo Spurio
  2021-03-04  1:24               ` Daniele Ceraolo Spurio
  0 siblings, 1 reply; 47+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-03-04  0:10 UTC (permalink / raw)
  To: Lionel Landwerlin, intel-gfx
  Cc: Huang Sean Z, Chris Wilson, Kondapally Kalyan, Bommu Krishnaiah



On 3/3/2021 3:42 PM, Lionel Landwerlin wrote:
> On 04/03/2021 01:25, Daniele Ceraolo Spurio wrote:
>>
>>
>> On 3/3/2021 3:16 PM, Lionel Landwerlin wrote:
>>> On 03/03/2021 23:59, Daniele Ceraolo Spurio wrote:
>>>>
>>>>
>>>> On 3/3/2021 12:39 PM, Lionel Landwerlin wrote:
>>>>> On 01/03/2021 21:31, Daniele Ceraolo Spurio wrote:
>>>>>> From: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
>>>>>>
>>>>>> This api allow user mode to create Protected buffers. Only contexts
>>>>>> marked as protected are allowed to operate on protected buffers.
>>>>>>
>>>>>> We only allow setting the flags at creation time.
>>>>>>
>>>>>> All protected objects that have backing storage will be considered
>>>>>> invalid when the session is destroyed and they won't be usable 
>>>>>> anymore.
>>>>>>
>>>>>> This is a rework of the original code by Bommu Krishnaiah. I've
>>>>>> authorship unchanged since significant chunks have not been 
>>>>>> modified.
>>>>>>
>>>>>> v2: split context changes, fix defines and improve documentation 
>>>>>> (Chris),
>>>>>>      add object invalidation logic
>>>>>>
>>>>>> Signed-off-by: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
>>>>>> Signed-off-by: Daniele Ceraolo Spurio 
>>>>>> <daniele.ceraolospurio@intel.com>
>>>>>> Cc: Telukuntla Sreedhar <sreedhar.telukuntla@intel.com>
>>>>>> Cc: Kondapally Kalyan <kalyan.kondapally@intel.com>
>>>>>> Cc: Gupta Anshuman <Anshuman.Gupta@intel.com>
>>>>>> Cc: Huang Sean Z <sean.z.huang@intel.com>
>>>>>> Cc: Chris Wilson <chris@chris-wilson.co.uk>
>>>>>> ---
>>>>>>   drivers/gpu/drm/i915/gem/i915_gem_create.c    | 27 +++++++++++--
>>>>>>   .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 10 +++++
>>>>>>   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  | 13 ++++++
>>>>>>   drivers/gpu/drm/i915/pxp/intel_pxp.c          | 40 
>>>>>> +++++++++++++++++++
>>>>>>   drivers/gpu/drm/i915/pxp/intel_pxp.h          | 13 ++++++
>>>>>>   drivers/gpu/drm/i915/pxp/intel_pxp_types.h    |  5 +++
>>>>>>   include/uapi/drm/i915_drm.h                   | 22 ++++++++++
>>>>>>   9 files changed, 145 insertions(+), 3 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c 
>>>>>> b/drivers/gpu/drm/i915/gem/i915_gem_create.c
>>>>>> index 3ad3413c459f..d02e5938afbe 100644
>>>>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
>>>>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
>>>>>> @@ -5,6 +5,7 @@
>>>>>>     #include "gem/i915_gem_ioctls.h"
>>>>>>   #include "gem/i915_gem_region.h"
>>>>>> +#include "pxp/intel_pxp.h"
>>>>>>     #include "i915_drv.h"
>>>>>>   #include "i915_user_extensions.h"
>>>>>> @@ -13,7 +14,8 @@ static int
>>>>>>   i915_gem_create(struct drm_file *file,
>>>>>>           struct intel_memory_region *mr,
>>>>>>           u64 *size_p,
>>>>>> -        u32 *handle_p)
>>>>>> +        u32 *handle_p,
>>>>>> +        u64 user_flags)
>>>>>>   {
>>>>>>       struct drm_i915_gem_object *obj;
>>>>>>       u32 handle;
>>>>>> @@ -35,12 +37,17 @@ i915_gem_create(struct drm_file *file,
>>>>>>         GEM_BUG_ON(size != obj->base.size);
>>>>>>   +    obj->user_flags = user_flags;
>>>>>> +
>>>>>>       ret = drm_gem_handle_create(file, &obj->base, &handle);
>>>>>>       /* drop reference from allocate - handle holds it now */
>>>>>>       i915_gem_object_put(obj);
>>>>>>       if (ret)
>>>>>>           return ret;
>>>>>>   +    if (user_flags & I915_GEM_OBJECT_PROTECTED)
>>>>>> +        intel_pxp_object_add(obj);
>>>>>> +
>>>>>>       *handle_p = handle;
>>>>>>       *size_p = size;
>>>>>>       return 0;
>>>>>> @@ -89,11 +96,12 @@ i915_gem_dumb_create(struct drm_file *file,
>>>>>>       return i915_gem_create(file,
>>>>>> intel_memory_region_by_type(to_i915(dev),
>>>>>>                                  mem_type),
>>>>>> -                   &args->size, &args->handle);
>>>>>> +                   &args->size, &args->handle, 0);
>>>>>>   }
>>>>>>     struct create_ext {
>>>>>>       struct drm_i915_private *i915;
>>>>>> +    unsigned long user_flags;
>>>>>>   };
>>>>>>     static int __create_setparam(struct drm_i915_gem_object_param 
>>>>>> *args,
>>>>>> @@ -104,6 +112,19 @@ static int __create_setparam(struct 
>>>>>> drm_i915_gem_object_param *args,
>>>>>>           return -EINVAL;
>>>>>>       }
>>>>>>   +    switch (lower_32_bits(args->param)) {
>>>>>> +    case I915_OBJECT_PARAM_PROTECTED_CONTENT:
>>>>>> +        if (!intel_pxp_is_enabled(&ext_data->i915->gt.pxp))
>>>>>> +            return -ENODEV;
>>>>>> +        if (args->size) {
>>>>>> +            return -EINVAL;
>>>>>> +        } else if (args->data) {
>>>>>> +            ext_data->user_flags |= I915_GEM_OBJECT_PROTECTED;
>>>>>> +            return 0;
>>>>>> +        }
>>>>>> +    break;
>>>>>> +    }
>>>>>> +
>>>>>>       return -EINVAL;
>>>>>>   }
>>>>>>   @@ -148,5 +169,5 @@ i915_gem_create_ioctl(struct drm_device 
>>>>>> *dev, void *data,
>>>>>>       return i915_gem_create(file,
>>>>>>                      intel_memory_region_by_type(i915,
>>>>>>                                  INTEL_MEMORY_SYSTEM),
>>>>>> -                   &args->size, &args->handle);
>>>>>> +                   &args->size, &args->handle, 
>>>>>> ext_data.user_flags);
>>>>>>   }
>>>>>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c 
>>>>>> b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>>>>>> index e503c9f789c0..d10c4fcb6aec 100644
>>>>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>>>>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>>>>>> @@ -20,6 +20,7 @@
>>>>>>   #include "gt/intel_gt_buffer_pool.h"
>>>>>>   #include "gt/intel_gt_pm.h"
>>>>>>   #include "gt/intel_ring.h"
>>>>>> +#include "pxp/intel_pxp.h"
>>>>>>     #include "pxp/intel_pxp.h"
>>>>>>   @@ -500,6 +501,15 @@ eb_validate_vma(struct i915_execbuffer *eb,
>>>>>>                entry->offset != gen8_canonical_addr(entry->offset 
>>>>>> & I915_GTT_PAGE_MASK)))
>>>>>>           return -EINVAL;
>>>>>>   +    if (i915_gem_object_is_protected(vma->obj)) {
>>>>>> +        if (!intel_pxp_is_active(&vma->vm->gt->pxp))
>>>>>> +            return -ENODEV;
>>>>>> +        if (!i915_gem_object_has_valid_protection(vma->obj))
>>>>>> +            return -EIO;
>>>>>> +        if 
>>>>>> (!i915_gem_context_can_use_protected_content(eb->gem_context))
>>>>>> +            return -EPERM;
>>>>>
>>>>>
>>>>> I think I'm running into this error.
>>>>
>>>> The currently agreed design is that protected objects can only be 
>>>> used with explicitly marked contexts, although it's not an HW 
>>>> requirement so we can revisit it.
>>>>
>>>>>
>>>>> When running vkcube protected under wayland, it takes down the 
>>>>> entire session (Xorg & gnome-shell depending on which one is going 
>>>>> to use the protected buffer first).
>>>>
>>>> Are you saying that a single submission failure takes down the 
>>>> entire gnome session? that sounds like a larger problem than just 
>>>> this failure. Or am I misunderstanding your point?
>>>
>>>
>>> We just need to hand that buffer to any other app and have it use it 
>>> in execbuf and that will make it fail the execbuf.
>>>
>>> Now how does the driver in the gnome-shell/Xorg process know what 
>>> went wrong and what buffer caused it?
>>>
>>> Could be any imported buffer. It's pretty hard to recover from this 
>>> and most apps will just crash if the driver starts to fail for some 
>>> reason.
>>>
>>> You can see how that could make a lot of people's live terrible :/
>>
>> Don't other apps have to know that the buffer is encrypted to use it 
>> properly? Or is there a case where we want to use the object as if it 
>> wasn't encrypted?
>>
>> Also, PXP submissions can become invalid at any point in time due to 
>> a teardown event, which causes the contents of the encrypted buffers 
>> to become garbage. If we can't fail the execbuf which includes an 
>> invalidated buffer we'd have to silently discard the submission.
>
>
> A malicious app could start sharing protected tagged buffer with no 
> protected content in it, just to invalidate/crash others apps' context.

I see your point, although on the other side failing the execbuf when 
malicious behavior is detected seems reasonable as well.

>
> Can the failure be only reported to protected contexts?

That would allow a non-protected context to use protected objects, which 
is something we wanted to avoid.
I see a few options here:

- live with the execbuf failure on incorrect or malicious behavior
- silently fail execbuf if protected objects are used with non-protected 
contexts
- remove the restriction on protected objects being usable only by 
protected contexts

Rodrigo, Joonas, any preference or other suggestion here?

Daniele

>
>
> -Lionel
>
>
>>
>> Daniele
>>
>>>
>>>
>>> -Lionel
>>>
>>>
>>>>
>>>>>
>>>>> That's a bit harsh.
>>>>>
>>>>>
>>>>> We probably don't want this. After all the point of encryption is 
>>>>> that even if you can read the buffer you won't be able to make 
>>>>> much of its content.
>>>>
>>>> As mentioned above we can change this since there is no HW 
>>>> requirement on contexts, but need some architectural agreement. 
>>>> Joonas and Rodrigo can comment more here.
>>>> Also note that submitting an instruction using encrypted data while 
>>>> the session is invalid can cause the HW to hang, which is part of 
>>>> the reason why we require the contexts using protected objects to 
>>>> be marked appropriately, so we can ban them on PXP teardown to 
>>>> avoid hangs.
>>>>
>>>> Daniele
>>>>
>>>>>
>>>>> Also useful to know you're dealing for debugging ;)
>>>>>
>>>>>
>>>>> -Lionel
>>>>>
>>>>>
>>>>>> +    }
>>>>>> +
>>>>>>       /* pad_to_size was once a reserved field, so sanitize it */
>>>>>>       if (entry->flags & EXEC_OBJECT_PAD_TO_SIZE) {
>>>>>>           if (unlikely(offset_in_page(entry->pad_to_size)))
>>>>>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c 
>>>>>> b/drivers/gpu/drm/i915/gem/i915_gem_object.c
>>>>>> index 6cdff5fc5882..b321f5484ae6 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"
>>>>>> @@ -72,6 +73,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;
>>>>>>   @@ -120,6 +123,9 @@ static void i915_gem_close_object(struct 
>>>>>> drm_gem_object *gem, struct drm_file *f
>>>>>>       struct i915_lut_handle *lut, *ln;
>>>>>>       LIST_HEAD(close);
>>>>>>   +    if (i915_gem_object_has_valid_protection(obj))
>>>>>> +        intel_pxp_object_remove(obj);
>>>>>> +
>>>>>>       spin_lock(&obj->lut_lock);
>>>>>>       list_for_each_entry_safe(lut, ln, &obj->lut_list, obj_link) {
>>>>>>           struct i915_gem_context *ctx = lut->ctx;
>>>>>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h 
>>>>>> b/drivers/gpu/drm/i915/gem/i915_gem_object.h
>>>>>> index 366d23afbb1a..a1fa7539c0f7 100644
>>>>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
>>>>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
>>>>>> @@ -274,6 +274,18 @@ i915_gem_object_needs_async_cancel(const 
>>>>>> struct drm_i915_gem_object *obj)
>>>>>>       return i915_gem_object_type_has(obj, 
>>>>>> I915_GEM_OBJECT_ASYNC_CANCEL);
>>>>>>   }
>>>>>>   +static inline bool
>>>>>> +i915_gem_object_is_protected(const struct drm_i915_gem_object *obj)
>>>>>> +{
>>>>>> +    return obj->user_flags & I915_GEM_OBJECT_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_is_framebuffer(const struct drm_i915_gem_object 
>>>>>> *obj)
>>>>>>   {
>>>>>> 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 0a1fdbac882e..6eee580c7aba 100644
>>>>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
>>>>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
>>>>>> @@ -167,6 +167,11 @@ struct drm_i915_gem_object {
>>>>>>       } mmo;
>>>>>>         I915_SELFTEST_DECLARE(struct list_head st_link);
>>>>>> +    /**
>>>>>> +     * @user_flags: small set of booleans set by the user
>>>>>> +     */
>>>>>> +    unsigned long user_flags;
>>>>>> +#define I915_GEM_OBJECT_PROTECTED BIT(0)
>>>>>>         unsigned long flags;
>>>>>>   #define I915_BO_ALLOC_CONTIGUOUS BIT(0)
>>>>>> @@ -290,6 +295,14 @@ struct drm_i915_gem_object {
>>>>>>           bool dirty:1;
>>>>>>       } mm;
>>>>>>   +    /*
>>>>>> +     * 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 5912e4a12d94..03151cd7f4b8 100644
>>>>>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
>>>>>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
>>>>>> @@ -69,6 +69,8 @@ void intel_pxp_init(struct intel_pxp *pxp)
>>>>>>           return;
>>>>>>         mutex_init(&pxp->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,
>>>>>> @@ -136,11 +138,49 @@ int 
>>>>>> intel_pxp_wait_for_termination_completion(struct intel_pxp *pxp)
>>>>>>       return ret;
>>>>>>   }
>>>>>>   +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) {
>>>>>> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h 
>>>>>> b/drivers/gpu/drm/i915/pxp/intel_pxp.h
>>>>>> index e36200833095..3315b07d271b 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;
>>>>>> +
>>>>>>   #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)
>>>>>> @@ -38,6 +40,9 @@ void intel_pxp_init(struct intel_pxp *pxp);
>>>>>>   void intel_pxp_fini(struct intel_pxp *pxp);
>>>>>>     int intel_pxp_wait_for_termination_completion(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)
>>>>>> @@ -52,6 +57,14 @@ static inline int 
>>>>>> intel_pxp_wait_for_termination_completion(struct intel_pxp *px
>>>>>>   {
>>>>>>       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_types.h 
>>>>>> b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
>>>>>> index 6f659a6f8f1c..53a2a8acfe51 100644
>>>>>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
>>>>>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
>>>>>> @@ -7,8 +7,10 @@
>>>>>>   #define __INTEL_PXP_TYPES_H__
>>>>>>     #include <linux/completion.h>
>>>>>> +#include <linux/list.h>
>>>>>>   #include <linux/types.h>
>>>>>>   #include <linux/mutex.h>
>>>>>> +#include <linux/spinlock.h>
>>>>>>   #include <linux/workqueue.h>
>>>>>>     struct intel_context;
>>>>>> @@ -28,6 +30,9 @@ struct intel_pxp {
>>>>>>       struct work_struct irq_work;
>>>>>>       bool irq_enabled;
>>>>>>       u32 current_events; /* protected with gt->irq_lock */
>>>>>> +
>>>>>> +    struct spinlock lock;
>>>>>> +    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 9ebe8523aa0c..0f8b771a6d53 100644
>>>>>> --- a/include/uapi/drm/i915_drm.h
>>>>>> +++ b/include/uapi/drm/i915_drm.h
>>>>>> @@ -1753,6 +1753,28 @@ struct drm_i915_gem_object_param {
>>>>>>    */
>>>>>>   #define I915_OBJECT_PARAM  (1ull << 32)
>>>>>>   +/*
>>>>>> + * I915_OBJECT_PARAM_PROTECTED_CONTENT:
>>>>>> + *
>>>>>> + * If set to true, buffer contents is expected to be protected 
>>>>>> by PXP
>>>>>> + * encryption and requires decryption for scan out and 
>>>>>> processing. This is
>>>>>> + * only possible on platforms that have PXP enabled, on all 
>>>>>> other scenarios
>>>>>> + * setting this flag will cause the ioctl to fail and return 
>>>>>> -ENODEV.
>>>>>> + *
>>>>>> + * Protected buffers can only be used with contexts created 
>>>>>> using the
>>>>>> + * I915_CONTEXT_PARAM_PROTECTED_CONTENT flag. The buffer 
>>>>>> contents are
>>>>>> + * considered invalid after a PXP session teardown.
>>>>>> + *
>>>>>> + * Given the restriction above, the following errors are 
>>>>>> possible when
>>>>>> + * submitting a protected object in an execbuf call:
>>>>>> + *
>>>>>> + * -ENODEV: PXP session not currently active
>>>>>> + * -EIO: buffer has become invalid after a teardown event
>>>>>> + * -EPERM: buffer submitted using a context not marked as protected
>>>>>> + */
>>>>>> +#define I915_OBJECT_PARAM_PROTECTED_CONTENT  0x0
>>>>>> +/* Must be kept compact -- no holes and well documented */
>>>>>> +
>>>>>>       __u64 param;
>>>>>>         /* Data value or pointer */
>>>>>
>>>>>
>>>>
>>>
>>
>

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

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

* Re: [Intel-gfx] [PATCH v2 07/16] drm/i915/pxp: Create the arbitrary session after boot
  2021-03-03 22:08   ` Chris Wilson
@ 2021-03-04  0:18     ` Daniele Ceraolo Spurio
  0 siblings, 0 replies; 47+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-03-04  0:18 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx; +Cc: Huang, Huang, Sean Z



On 3/3/2021 2:08 PM, Chris Wilson wrote:
> Quoting Daniele Ceraolo Spurio (2021-03-01 19:31:51)
>> +static inline bool intel_pxp_is_active(const struct intel_pxp *pxp)
>> +{
>> +       return pxp->arb_is_in_play;
>> +}
>> +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);
>> +}
>> +
>> +bool intel_pxp_arb_session_is_in_play(struct intel_pxp *pxp)
>> +{
>> +       return intel_pxp_session_is_in_play(pxp, ARB_SESSION);
>> +}
> So pxp->arb_is_in_play is not the same as intel_pxp_arb_session_is_in_play().
>
> That's confusing.

The HW is counfusing :)

The HW reporting that a session is in play does not mean that the 
session is actually valid. When a teardown occurs the session is still 
in play on the HW but the relevant keys are gone, so the session is not 
actually usable (and attempting to use it will likely cause hangs). 
intel_pxp_session_is_in_play() reflect the HW in_play state while 
pxp->arb_is_in_play reflect usability of the session. I'll rename the 
latter to pxp->arb_is_valid.

Daniele

> -Chris

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

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

* Re: [Intel-gfx] [PATCH v2 08/16] drm/i915/pxp: Implement arb session teardown
  2021-03-03 22:04   ` Chris Wilson
@ 2021-03-04  0:29     ` Daniele Ceraolo Spurio
  0 siblings, 0 replies; 47+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-03-04  0:29 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx; +Cc: Huang, Huang, Sean Z



On 3/3/2021 2:04 PM, Chris Wilson wrote:
> Quoting Daniele Ceraolo Spurio (2021-03-01 19:31:52)
>> 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)
>>
>> 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>
>> ---
>>   drivers/gpu/drm/i915/Makefile                |   1 +
>>   drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c     | 166 +++++++++++++++++++
>>   drivers/gpu/drm/i915/pxp/intel_pxp_cmd.h     |  15 ++
>>   drivers/gpu/drm/i915/pxp/intel_pxp_session.c |  38 +++++
>>   drivers/gpu/drm/i915/pxp/intel_pxp_session.h |   1 +
>>   drivers/gpu/drm/i915/pxp/intel_pxp_tee.c     |   5 +-
>>   6 files changed, 225 insertions(+), 1 deletion(-)
>>   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 d6d510e4875e..8b605f326039 100644
>> --- a/drivers/gpu/drm/i915/Makefile
>> +++ b/drivers/gpu/drm/i915/Makefile
>> @@ -273,6 +273,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/pxp/intel_pxp_cmd.c b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c
>> new file mode 100644
>> index 000000000000..ffab09839cd3
>> --- /dev/null
>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd.c
>> @@ -0,0 +1,166 @@
>> +// SPDX-License-Identifier: MIT
>> +/*
>> + * Copyright(c) 2020, Intel Corporation. All rights reserved.
>> + */
>> +
>> +#include "intel_pxp.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"
>> +
>> +/* PXP GPU command definitions */
>> +
>> +/* MI_SET_APPID */
>> +#define   MI_SET_APPID_SESSION_ID(x)    ((x) << 0)
>> +
>> +/* MI_FLUSH_DW */
>> +#define   MI_FLUSH_DW_DW0_PROTECTED_MEMORY_ENABLE   BIT(22)
>> +
>> +/* MI_WAIT */
>> +#define   MFX_WAIT_DW0_PXP_SYNC_CONTROL_FLAG BIT(9)
>> +#define   MFX_WAIT_DW0_MFX_SYNC_CONTROL_FLAG  BIT(8)
> We've been using REG_BIT() for the explicit (u32) casting.
>
>> +/* CRYPTO_KEY_EXCHANGE */
>> +#define CRYPTO_KEY_EXCHANGE ((0x3 << 29) | (0x01609 << 16))
> #define __INSTR(client) ((client) << INSTR_CLIENT_SHIFT)
>
> #define MI_INSTR(opcode, flags) \
> 	(__INSTR(INSTR_MI_CLIENT) | (opcode) << 23 | (flags))
> #define RC_INTR(foo) (__INSTR(INSTR_RC_CLIENT) | (foo) << 16)
>
> #define CRYPTO_KEY_EXCHANGE RC_INSTR(0x1609)
>
> With a better (foo).
>
>> +
>> +/* 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;
> One day someone will proofread bspec.
>
>> +       /* pxp off */
>> +       *cs++ = MI_FLUSH_DW;
>> +       *cs++ = 0;
>> +       *cs++ = 0;
> Hmm. Can the immediate data be dropped? TIL.
>
>> +       /* 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_DW0_PROTECTED_MEMORY_ENABLE;
>> +       *cs++ = 0;
>> +       *cs++ = 0;
> Bspec says "after completion of the flush...", which says to me we
> should not initiate the wait until after the flush, so we would need a
> post-sync op here to stall the CS (or else we may complete the wait
> before the operation is begun). I don't see any programming notes to
> that effect, so could just be my paranoia from handling atomics.

Better be paranoid, I'll add a post-sync op

>
>> +       *cs++ = MFX_WAIT_PXP;
> Fwiw, the bspec language would seem to imply that nothing should happen
> with this wait at this point. Perhaps more reason to make the pxp-on
> MI_FLUSH_DW be synchronous. (Though we will have a sync point at the
> breadcrumb, so meh.)
>
>> +
>> +       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_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 WAIT_LEN 2
> Dwords lengths ok.
>
>> +#define __SESSION_TERMINATION_LEN (SELECTION_LEN + TERMINATION_LEN)
>> +#define SESSION_TERMINATION_LEN(x) (__SESSION_TERMINATION_LEN * (x) + WAIT_LEN)
>> +
>> +static struct i915_request *pxp_request_create(struct intel_context *ce)
>> +{
>> +       struct i915_request *rq;
>> +
>> +       intel_context_enter(ce);
>> +       rq = __i915_request_create(ce, GFP_KERNEL);
>> +       intel_context_exit(ce);
>> +
>> +       return rq;
>> +}
>> +
>> +static void pxp_request_commit(struct i915_request *rq)
>> +{
>> +       struct i915_sched_attr attr = { .priority = I915_PRIORITY_MAX };
>> +
>> +       trace_i915_request_add(rq);
>> +       __i915_request_commit(rq);
>> +       __i915_request_queue(rq, &attr);
>> +}
>> +
>> +int intel_pxp_submit_session_termination(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;
>> +
>> +       intel_engine_pm_get(ce->engine);
> As you are not using the engine->kernel_context, you can leave this out
> and the normal intel_context_enter() acquire of the wakeref will cover
> you.
>
> You could then use the normal i915_request_create(), but we would still
> have the custom i915_request_add, which would absorb the mutex_unlock so
> would not look so unbalanced.

will change

>> +       mutex_lock(&ce->timeline->mutex);
>> +
>> +       rq = pxp_request_create(ce);
>> +       if (IS_ERR(rq)) {
>> +               mutex_unlock(&ce->timeline->mutex);
>> +               err = PTR_ERR(rq);
>> +               goto out_pm;
>> +       }
>> +
>> +       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));
>> +       if (IS_ERR(cs)) {
>> +               err = PTR_ERR(cs);
>> +               goto out_rq;
>> +       }
>> +
>> +       cs = pxp_emit_session_selection(cs, id);
>> +       cs = pxp_emit_inline_termination(cs);
> I would wrap this pair with
>
> 	cs = pxp_emit_session_termination(cs, id);

Agreed

> so the correspondence with SESSION_TERMINATION_LEN() is clearer and I'd
> be tempted then to add the WAIT_LEN explicitly.

ok

>> +       cs = pxp_emit_wait(cs);
>> +
>> +       intel_ring_advance(rq, cs);
> Fwiw, this would be a good excuse to decouple invalidate/flush from the
> breadcrumbs. Later, much later.
>
>> +
>> +out_rq:
>> +       i915_request_get(rq);
>> +
>> +       if (unlikely(err))
>> +               i915_request_set_error_once(rq, err);
>> +
>> +       pxp_request_commit(rq);
>> +
>> +       mutex_unlock(&ce->timeline->mutex);
>> +
>> +       if (!err && i915_request_wait(rq, 0, HZ / 5) < 0)
>> +               err = -ETIME;
> "intel_pxp_submit_session_termination" does not imply synchronous
> behaviour to me.
>
> intel_pxp_terminate_session() ?

agreed

>> +
>> +       i915_request_put(rq);
>> +
>> +out_pm:
>> +       intel_engine_pm_put(ce->engine);
>> +
>> +       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..7c33b66f0812
>> --- /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_submit_session_termination(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 6abc59a63e51..ddbfac75686a 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);
>> @@ -80,3 +84,37 @@ int intel_pxp_create_arb_session(struct intel_pxp *pxp)
>>   
>>          return 0;
>>   }
>> +
>> +/**
>> + * intel_pxp_arb_terminate_session_with_global_terminate - Terminate the arb hw
> terminate_session_and_global ? Just to remove the repetition?
agreed

>> + * session.
>> + * @pxp: pointer to pxp struct.
>> + *
>> + * Return: 0 if terminate is successful, error code otherwise
>> + */
>> +int intel_pxp_arb_terminate_session_with_global_terminate(struct intel_pxp *pxp)
>> +{
>> +       int ret;
>> +       struct intel_gt *gt = pxp_to_gt(pxp);
>> +
>> +       lockdep_assert_held(&pxp->mutex);
>> +
>> +       pxp->arb_is_in_play = false;
>> +
>> +       /* terminate the hw sessions */
>> +       ret = intel_pxp_submit_session_termination(pxp, ARB_SESSION);
>> +       if (ret) {
>> +               drm_err(&gt->i915->drm, "Failed to submit session termination\n");
>> +               return ret;
>> +       }
> Should arb_is_in_play not be updated until after successful termination?

That's a consequence of when I started using arb_is_in_play to mean that 
the session was valid and usable. As mentioned on the other patch I'll 
rename it.

>
>> +       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);
> Are we happy that this is instantaneous and doesn't need an ack/wait?

it's not, but we get an interrupt when the termination is complete.

Daniele

>
>> +       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 6fc4a2370c44..07c97df7a509 100644
>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.h
>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.h
>> @@ -12,5 +12,6 @@ struct intel_pxp;
>>   
>>   bool intel_pxp_arb_session_is_in_play(struct intel_pxp *pxp);
>>   int intel_pxp_create_arb_session(struct intel_pxp *pxp);
>> +int intel_pxp_arb_terminate_session_with_global_terminate(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 dc3850b372c5..fd9a69248dd8 100644
>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
>> @@ -99,7 +99,10 @@ static int i915_pxp_tee_component_bind(struct device *i915_kdev,
>>          mutex_lock(&pxp->mutex);
>>   
>>          /* Create arb session only if tee is ready, during system boot or sleep/resume */
>> -       if (!intel_pxp_arb_session_is_in_play(pxp))
>> +       if (intel_pxp_arb_session_is_in_play(pxp))
>> +               ret = intel_pxp_arb_terminate_session_with_global_terminate(pxp);
>> +
>> +       if (!ret)
>>                  ret = intel_pxp_create_arb_session(pxp);
>>   
>>          mutex_unlock(&pxp->mutex);
>> -- 
>> 2.29.2
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
>>

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

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

* Re: [Intel-gfx] [PATCH v2 13/16] drm/i915/pxp: User interface for Protected buffer
  2021-03-04  0:10             ` Daniele Ceraolo Spurio
@ 2021-03-04  1:24               ` Daniele Ceraolo Spurio
  2021-03-08 20:40                 ` Rodrigo Vivi
  0 siblings, 1 reply; 47+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-03-04  1:24 UTC (permalink / raw)
  To: Lionel Landwerlin, intel-gfx
  Cc: Bommu Krishnaiah, Kondapally Kalyan, Huang Sean Z, Chris Wilson



On 3/3/2021 4:10 PM, Daniele Ceraolo Spurio wrote:
>
>
> On 3/3/2021 3:42 PM, Lionel Landwerlin wrote:
>> On 04/03/2021 01:25, Daniele Ceraolo Spurio wrote:
>>>
>>>
>>> On 3/3/2021 3:16 PM, Lionel Landwerlin wrote:
>>>> On 03/03/2021 23:59, Daniele Ceraolo Spurio wrote:
>>>>>
>>>>>
>>>>> On 3/3/2021 12:39 PM, Lionel Landwerlin wrote:
>>>>>> On 01/03/2021 21:31, Daniele Ceraolo Spurio wrote:
>>>>>>> From: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
>>>>>>>
>>>>>>> This api allow user mode to create Protected buffers. Only contexts
>>>>>>> marked as protected are allowed to operate on protected buffers.
>>>>>>>
>>>>>>> We only allow setting the flags at creation time.
>>>>>>>
>>>>>>> All protected objects that have backing storage will be considered
>>>>>>> invalid when the session is destroyed and they won't be usable 
>>>>>>> anymore.
>>>>>>>
>>>>>>> This is a rework of the original code by Bommu Krishnaiah. I've
>>>>>>> authorship unchanged since significant chunks have not been 
>>>>>>> modified.
>>>>>>>
>>>>>>> v2: split context changes, fix defines and improve documentation 
>>>>>>> (Chris),
>>>>>>>      add object invalidation logic
>>>>>>>
>>>>>>> Signed-off-by: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
>>>>>>> Signed-off-by: Daniele Ceraolo Spurio 
>>>>>>> <daniele.ceraolospurio@intel.com>
>>>>>>> Cc: Telukuntla Sreedhar <sreedhar.telukuntla@intel.com>
>>>>>>> Cc: Kondapally Kalyan <kalyan.kondapally@intel.com>
>>>>>>> Cc: Gupta Anshuman <Anshuman.Gupta@intel.com>
>>>>>>> Cc: Huang Sean Z <sean.z.huang@intel.com>
>>>>>>> Cc: Chris Wilson <chris@chris-wilson.co.uk>
>>>>>>> ---
>>>>>>>   drivers/gpu/drm/i915/gem/i915_gem_create.c    | 27 +++++++++++--
>>>>>>>   .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 10 +++++
>>>>>>>   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  | 13 ++++++
>>>>>>>   drivers/gpu/drm/i915/pxp/intel_pxp.c          | 40 
>>>>>>> +++++++++++++++++++
>>>>>>>   drivers/gpu/drm/i915/pxp/intel_pxp.h          | 13 ++++++
>>>>>>>   drivers/gpu/drm/i915/pxp/intel_pxp_types.h    |  5 +++
>>>>>>>   include/uapi/drm/i915_drm.h                   | 22 ++++++++++
>>>>>>>   9 files changed, 145 insertions(+), 3 deletions(-)
>>>>>>>
>>>>>>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c 
>>>>>>> b/drivers/gpu/drm/i915/gem/i915_gem_create.c
>>>>>>> index 3ad3413c459f..d02e5938afbe 100644
>>>>>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
>>>>>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
>>>>>>> @@ -5,6 +5,7 @@
>>>>>>>     #include "gem/i915_gem_ioctls.h"
>>>>>>>   #include "gem/i915_gem_region.h"
>>>>>>> +#include "pxp/intel_pxp.h"
>>>>>>>     #include "i915_drv.h"
>>>>>>>   #include "i915_user_extensions.h"
>>>>>>> @@ -13,7 +14,8 @@ static int
>>>>>>>   i915_gem_create(struct drm_file *file,
>>>>>>>           struct intel_memory_region *mr,
>>>>>>>           u64 *size_p,
>>>>>>> -        u32 *handle_p)
>>>>>>> +        u32 *handle_p,
>>>>>>> +        u64 user_flags)
>>>>>>>   {
>>>>>>>       struct drm_i915_gem_object *obj;
>>>>>>>       u32 handle;
>>>>>>> @@ -35,12 +37,17 @@ i915_gem_create(struct drm_file *file,
>>>>>>>         GEM_BUG_ON(size != obj->base.size);
>>>>>>>   +    obj->user_flags = user_flags;
>>>>>>> +
>>>>>>>       ret = drm_gem_handle_create(file, &obj->base, &handle);
>>>>>>>       /* drop reference from allocate - handle holds it now */
>>>>>>>       i915_gem_object_put(obj);
>>>>>>>       if (ret)
>>>>>>>           return ret;
>>>>>>>   +    if (user_flags & I915_GEM_OBJECT_PROTECTED)
>>>>>>> +        intel_pxp_object_add(obj);
>>>>>>> +
>>>>>>>       *handle_p = handle;
>>>>>>>       *size_p = size;
>>>>>>>       return 0;
>>>>>>> @@ -89,11 +96,12 @@ i915_gem_dumb_create(struct drm_file *file,
>>>>>>>       return i915_gem_create(file,
>>>>>>> intel_memory_region_by_type(to_i915(dev),
>>>>>>>                                  mem_type),
>>>>>>> -                   &args->size, &args->handle);
>>>>>>> +                   &args->size, &args->handle, 0);
>>>>>>>   }
>>>>>>>     struct create_ext {
>>>>>>>       struct drm_i915_private *i915;
>>>>>>> +    unsigned long user_flags;
>>>>>>>   };
>>>>>>>     static int __create_setparam(struct 
>>>>>>> drm_i915_gem_object_param *args,
>>>>>>> @@ -104,6 +112,19 @@ static int __create_setparam(struct 
>>>>>>> drm_i915_gem_object_param *args,
>>>>>>>           return -EINVAL;
>>>>>>>       }
>>>>>>>   +    switch (lower_32_bits(args->param)) {
>>>>>>> +    case I915_OBJECT_PARAM_PROTECTED_CONTENT:
>>>>>>> +        if (!intel_pxp_is_enabled(&ext_data->i915->gt.pxp))
>>>>>>> +            return -ENODEV;
>>>>>>> +        if (args->size) {
>>>>>>> +            return -EINVAL;
>>>>>>> +        } else if (args->data) {
>>>>>>> +            ext_data->user_flags |= I915_GEM_OBJECT_PROTECTED;
>>>>>>> +            return 0;
>>>>>>> +        }
>>>>>>> +    break;
>>>>>>> +    }
>>>>>>> +
>>>>>>>       return -EINVAL;
>>>>>>>   }
>>>>>>>   @@ -148,5 +169,5 @@ i915_gem_create_ioctl(struct drm_device 
>>>>>>> *dev, void *data,
>>>>>>>       return i915_gem_create(file,
>>>>>>>                      intel_memory_region_by_type(i915,
>>>>>>>                                  INTEL_MEMORY_SYSTEM),
>>>>>>> -                   &args->size, &args->handle);
>>>>>>> +                   &args->size, &args->handle, 
>>>>>>> ext_data.user_flags);
>>>>>>>   }
>>>>>>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c 
>>>>>>> b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>>>>>>> index e503c9f789c0..d10c4fcb6aec 100644
>>>>>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>>>>>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>>>>>>> @@ -20,6 +20,7 @@
>>>>>>>   #include "gt/intel_gt_buffer_pool.h"
>>>>>>>   #include "gt/intel_gt_pm.h"
>>>>>>>   #include "gt/intel_ring.h"
>>>>>>> +#include "pxp/intel_pxp.h"
>>>>>>>     #include "pxp/intel_pxp.h"
>>>>>>>   @@ -500,6 +501,15 @@ eb_validate_vma(struct i915_execbuffer *eb,
>>>>>>>                entry->offset != 
>>>>>>> gen8_canonical_addr(entry->offset & I915_GTT_PAGE_MASK)))
>>>>>>>           return -EINVAL;
>>>>>>>   +    if (i915_gem_object_is_protected(vma->obj)) {
>>>>>>> +        if (!intel_pxp_is_active(&vma->vm->gt->pxp))
>>>>>>> +            return -ENODEV;
>>>>>>> +        if (!i915_gem_object_has_valid_protection(vma->obj))
>>>>>>> +            return -EIO;
>>>>>>> +        if 
>>>>>>> (!i915_gem_context_can_use_protected_content(eb->gem_context))
>>>>>>> +            return -EPERM;
>>>>>>
>>>>>>
>>>>>> I think I'm running into this error.
>>>>>
>>>>> The currently agreed design is that protected objects can only be 
>>>>> used with explicitly marked contexts, although it's not an HW 
>>>>> requirement so we can revisit it.
>>>>>
>>>>>>
>>>>>> When running vkcube protected under wayland, it takes down the 
>>>>>> entire session (Xorg & gnome-shell depending on which one is 
>>>>>> going to use the protected buffer first).
>>>>>
>>>>> Are you saying that a single submission failure takes down the 
>>>>> entire gnome session? that sounds like a larger problem than just 
>>>>> this failure. Or am I misunderstanding your point?
>>>>
>>>>
>>>> We just need to hand that buffer to any other app and have it use 
>>>> it in execbuf and that will make it fail the execbuf.
>>>>
>>>> Now how does the driver in the gnome-shell/Xorg process know what 
>>>> went wrong and what buffer caused it?
>>>>
>>>> Could be any imported buffer. It's pretty hard to recover from this 
>>>> and most apps will just crash if the driver starts to fail for some 
>>>> reason.
>>>>
>>>> You can see how that could make a lot of people's live terrible :/
>>>
>>> Don't other apps have to know that the buffer is encrypted to use it 
>>> properly? Or is there a case where we want to use the object as if 
>>> it wasn't encrypted?
>>>
>>> Also, PXP submissions can become invalid at any point in time due to 
>>> a teardown event, which causes the contents of the encrypted buffers 
>>> to become garbage. If we can't fail the execbuf which includes an 
>>> invalidated buffer we'd have to silently discard the submission.
>>
>>
>> A malicious app could start sharing protected tagged buffer with no 
>> protected content in it, just to invalidate/crash others apps' context.
>
> I see your point, although on the other side failing the execbuf when 
> malicious behavior is detected seems reasonable as well.
>
>>
>> Can the failure be only reported to protected contexts?
>
> That would allow a non-protected context to use protected objects, 
> which is something we wanted to avoid.
> I see a few options here:
>
> - live with the execbuf failure on incorrect or malicious behavior
> - silently fail execbuf if protected objects are used with 
> non-protected contexts
> - remove the restriction on protected objects being usable only by 
> protected contexts
>
> Rodrigo, Joonas, any preference or other suggestion here?
>

BTW, whatever we decide has to also consider the other failure cases in 
the check above:
- pxp not active, i.e. termination in progress
- invalid buffer (encrypted using old keys)

Both of those could currently cause an execbuf failure even if we ignore 
the protected context restriction, which IMO makes the third option 
above not viable.

Daniele

> Daniele
>
>>
>>
>> -Lionel
>>
>>
>>>
>>> Daniele
>>>
>>>>
>>>>
>>>> -Lionel
>>>>
>>>>
>>>>>
>>>>>>
>>>>>> That's a bit harsh.
>>>>>>
>>>>>>
>>>>>> We probably don't want this. After all the point of encryption is 
>>>>>> that even if you can read the buffer you won't be able to make 
>>>>>> much of its content.
>>>>>
>>>>> As mentioned above we can change this since there is no HW 
>>>>> requirement on contexts, but need some architectural agreement. 
>>>>> Joonas and Rodrigo can comment more here.
>>>>> Also note that submitting an instruction using encrypted data 
>>>>> while the session is invalid can cause the HW to hang, which is 
>>>>> part of the reason why we require the contexts using protected 
>>>>> objects to be marked appropriately, so we can ban them on PXP 
>>>>> teardown to avoid hangs.
>>>>>
>>>>> Daniele
>>>>>
>>>>>>
>>>>>> Also useful to know you're dealing for debugging ;)
>>>>>>
>>>>>>
>>>>>> -Lionel
>>>>>>
>>>>>>
>>>>>>> +    }
>>>>>>> +
>>>>>>>       /* pad_to_size was once a reserved field, so sanitize it */
>>>>>>>       if (entry->flags & EXEC_OBJECT_PAD_TO_SIZE) {
>>>>>>>           if (unlikely(offset_in_page(entry->pad_to_size)))
>>>>>>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c 
>>>>>>> b/drivers/gpu/drm/i915/gem/i915_gem_object.c
>>>>>>> index 6cdff5fc5882..b321f5484ae6 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"
>>>>>>> @@ -72,6 +73,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;
>>>>>>>   @@ -120,6 +123,9 @@ static void i915_gem_close_object(struct 
>>>>>>> drm_gem_object *gem, struct drm_file *f
>>>>>>>       struct i915_lut_handle *lut, *ln;
>>>>>>>       LIST_HEAD(close);
>>>>>>>   +    if (i915_gem_object_has_valid_protection(obj))
>>>>>>> +        intel_pxp_object_remove(obj);
>>>>>>> +
>>>>>>>       spin_lock(&obj->lut_lock);
>>>>>>>       list_for_each_entry_safe(lut, ln, &obj->lut_list, obj_link) {
>>>>>>>           struct i915_gem_context *ctx = lut->ctx;
>>>>>>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h 
>>>>>>> b/drivers/gpu/drm/i915/gem/i915_gem_object.h
>>>>>>> index 366d23afbb1a..a1fa7539c0f7 100644
>>>>>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
>>>>>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
>>>>>>> @@ -274,6 +274,18 @@ i915_gem_object_needs_async_cancel(const 
>>>>>>> struct drm_i915_gem_object *obj)
>>>>>>>       return i915_gem_object_type_has(obj, 
>>>>>>> I915_GEM_OBJECT_ASYNC_CANCEL);
>>>>>>>   }
>>>>>>>   +static inline bool
>>>>>>> +i915_gem_object_is_protected(const struct drm_i915_gem_object 
>>>>>>> *obj)
>>>>>>> +{
>>>>>>> +    return obj->user_flags & I915_GEM_OBJECT_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_is_framebuffer(const struct 
>>>>>>> drm_i915_gem_object *obj)
>>>>>>>   {
>>>>>>> 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 0a1fdbac882e..6eee580c7aba 100644
>>>>>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
>>>>>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
>>>>>>> @@ -167,6 +167,11 @@ struct drm_i915_gem_object {
>>>>>>>       } mmo;
>>>>>>>         I915_SELFTEST_DECLARE(struct list_head st_link);
>>>>>>> +    /**
>>>>>>> +     * @user_flags: small set of booleans set by the user
>>>>>>> +     */
>>>>>>> +    unsigned long user_flags;
>>>>>>> +#define I915_GEM_OBJECT_PROTECTED BIT(0)
>>>>>>>         unsigned long flags;
>>>>>>>   #define I915_BO_ALLOC_CONTIGUOUS BIT(0)
>>>>>>> @@ -290,6 +295,14 @@ struct drm_i915_gem_object {
>>>>>>>           bool dirty:1;
>>>>>>>       } mm;
>>>>>>>   +    /*
>>>>>>> +     * 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 5912e4a12d94..03151cd7f4b8 100644
>>>>>>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
>>>>>>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
>>>>>>> @@ -69,6 +69,8 @@ void intel_pxp_init(struct intel_pxp *pxp)
>>>>>>>           return;
>>>>>>>         mutex_init(&pxp->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,
>>>>>>> @@ -136,11 +138,49 @@ int 
>>>>>>> intel_pxp_wait_for_termination_completion(struct intel_pxp *pxp)
>>>>>>>       return ret;
>>>>>>>   }
>>>>>>>   +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) {
>>>>>>> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h 
>>>>>>> b/drivers/gpu/drm/i915/pxp/intel_pxp.h
>>>>>>> index e36200833095..3315b07d271b 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;
>>>>>>> +
>>>>>>>   #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)
>>>>>>> @@ -38,6 +40,9 @@ void intel_pxp_init(struct intel_pxp *pxp);
>>>>>>>   void intel_pxp_fini(struct intel_pxp *pxp);
>>>>>>>     int intel_pxp_wait_for_termination_completion(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)
>>>>>>> @@ -52,6 +57,14 @@ static inline int 
>>>>>>> intel_pxp_wait_for_termination_completion(struct intel_pxp *px
>>>>>>>   {
>>>>>>>       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_types.h 
>>>>>>> b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
>>>>>>> index 6f659a6f8f1c..53a2a8acfe51 100644
>>>>>>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
>>>>>>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
>>>>>>> @@ -7,8 +7,10 @@
>>>>>>>   #define __INTEL_PXP_TYPES_H__
>>>>>>>     #include <linux/completion.h>
>>>>>>> +#include <linux/list.h>
>>>>>>>   #include <linux/types.h>
>>>>>>>   #include <linux/mutex.h>
>>>>>>> +#include <linux/spinlock.h>
>>>>>>>   #include <linux/workqueue.h>
>>>>>>>     struct intel_context;
>>>>>>> @@ -28,6 +30,9 @@ struct intel_pxp {
>>>>>>>       struct work_struct irq_work;
>>>>>>>       bool irq_enabled;
>>>>>>>       u32 current_events; /* protected with gt->irq_lock */
>>>>>>> +
>>>>>>> +    struct spinlock lock;
>>>>>>> +    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 9ebe8523aa0c..0f8b771a6d53 100644
>>>>>>> --- a/include/uapi/drm/i915_drm.h
>>>>>>> +++ b/include/uapi/drm/i915_drm.h
>>>>>>> @@ -1753,6 +1753,28 @@ struct drm_i915_gem_object_param {
>>>>>>>    */
>>>>>>>   #define I915_OBJECT_PARAM  (1ull << 32)
>>>>>>>   +/*
>>>>>>> + * I915_OBJECT_PARAM_PROTECTED_CONTENT:
>>>>>>> + *
>>>>>>> + * If set to true, buffer contents is expected to be protected 
>>>>>>> by PXP
>>>>>>> + * encryption and requires decryption for scan out and 
>>>>>>> processing. This is
>>>>>>> + * only possible on platforms that have PXP enabled, on all 
>>>>>>> other scenarios
>>>>>>> + * setting this flag will cause the ioctl to fail and return 
>>>>>>> -ENODEV.
>>>>>>> + *
>>>>>>> + * Protected buffers can only be used with contexts created 
>>>>>>> using the
>>>>>>> + * I915_CONTEXT_PARAM_PROTECTED_CONTENT flag. The buffer 
>>>>>>> contents are
>>>>>>> + * considered invalid after a PXP session teardown.
>>>>>>> + *
>>>>>>> + * Given the restriction above, the following errors are 
>>>>>>> possible when
>>>>>>> + * submitting a protected object in an execbuf call:
>>>>>>> + *
>>>>>>> + * -ENODEV: PXP session not currently active
>>>>>>> + * -EIO: buffer has become invalid after a teardown event
>>>>>>> + * -EPERM: buffer submitted using a context not marked as 
>>>>>>> protected
>>>>>>> + */
>>>>>>> +#define I915_OBJECT_PARAM_PROTECTED_CONTENT  0x0
>>>>>>> +/* Must be kept compact -- no holes and well documented */
>>>>>>> +
>>>>>>>       __u64 param;
>>>>>>>         /* Data value or pointer */
>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* Re: [Intel-gfx] [PATCH v2 11/16] drm/i915/pxp: interface for creation of protected contexts
  2021-03-03 23:16   ` Chris Wilson
@ 2021-03-08 18:32     ` Daniele Ceraolo Spurio
  0 siblings, 0 replies; 47+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-03-08 18:32 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx



On 3/3/2021 3:16 PM, Chris Wilson wrote:
> Quoting Daniele Ceraolo Spurio (2021-03-01 19:31:55)
>> Usage of protected objects, coming in a follow-up patch, will be
>> restricted to protected contexts. Contexts can only be marked as
>> protected at creation time and they must be both bannable and not
>> recoverable.
>>
>> When a PXP teardown occurs, all gem contexts marked as protected that
>> have been used at least once will be marked as invalid 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
>> invalidation to userspace.
>>
>> v2: split to its own patch and improve doc (Chris), invalidate contexts
>> on teardown
>>
>> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
>> Cc: Chris Wilson <chris@chris-wilson.co.uk>
>> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
>> ---
>>   drivers/gpu/drm/i915/gem/i915_gem_context.c   | 59 ++++++++++++++++++-
>>   drivers/gpu/drm/i915/gem/i915_gem_context.h   | 18 ++++++
>>   .../gpu/drm/i915/gem/i915_gem_context_types.h |  2 +
>>   .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 13 ++++
>>   drivers/gpu/drm/i915/pxp/intel_pxp.c          | 38 ++++++++++++
>>   drivers/gpu/drm/i915/pxp/intel_pxp.h          |  1 +
>>   drivers/gpu/drm/i915/pxp/intel_pxp_session.c  |  3 +
>>   include/uapi/drm/i915_drm.h                   | 19 ++++++
>>   8 files changed, 150 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c
>> index ca37d93ef5e7..19ac24a3c42c 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c
>> @@ -76,6 +76,8 @@
>>   #include "gt/intel_gpu_commands.h"
>>   #include "gt/intel_ring.h"
>>   
>> +#include "pxp/intel_pxp.h"
>> +
>>   #include "i915_drm_client.h"
>>   #include "i915_gem_context.h"
>>   #include "i915_globals.h"
>> @@ -2006,6 +2008,40 @@ static int set_priority(struct i915_gem_context *ctx,
>>          return 0;
>>   }
>>   
>> +static int set_protected(struct i915_gem_context *ctx,
>> +                        const struct drm_i915_gem_context_param *args)
>> +{
>> +       int ret = 0;
>> +
>> +       if (!intel_pxp_is_enabled(&ctx->i915->gt.pxp))
>> +               ret = -ENODEV;
>> +       else if (ctx->client) /* can't change this after creation! */
>> +               ret = -EEXIST;
>> +       else if (args->size)
>> +               ret = -EINVAL;
>> +       else if (!args->value)
>> +               clear_bit(UCONTEXT_PROTECTED, &ctx->user_flags);
>> +       else if (i915_gem_context_is_recoverable(ctx) ||
>> +                !i915_gem_context_is_bannable(ctx))
>> +               ret = -EPERM;
>> +       else
>> +               set_bit(UCONTEXT_PROTECTED, &ctx->user_flags);
>> +
>> +       return ret;
>> +}
>> +
>> +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_can_use_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)
>> @@ -2038,6 +2074,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_can_use_protected_content(ctx))
>> +                       ret = -EPERM; /* can't clear this for protected contexts */
>>                  else
>>                          i915_gem_context_clear_bannable(ctx);
>>                  break;
>> @@ -2045,10 +2083,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_can_use_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:
>> @@ -2075,6 +2115,10 @@ static int ctx_setparam(struct drm_i915_file_private *fpriv,
>>                  ret = set_ringsize(ctx, args);
>>                  break;
>>   
>> +       case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
>> +               ret = set_protected(ctx, args);
>> +               break;
>> +
>>          case I915_CONTEXT_PARAM_BAN_PERIOD:
>>          default:
>>                  ret = -EINVAL;
>> @@ -2532,6 +2576,10 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
>>                  ret = get_ringsize(ctx, args);
>>                  break;
>>   
>> +       case I915_CONTEXT_PARAM_PROTECTED_CONTENT:
>> +               ret = get_protected(ctx, args);
>> +               break;
>> +
>>          case I915_CONTEXT_PARAM_BAN_PERIOD:
>>          default:
>>                  ret = -EINVAL;
>> @@ -2592,6 +2640,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;
>> +
>>          ret = 0;
>>   out:
>>          rcu_read_unlock();
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.h b/drivers/gpu/drm/i915/gem/i915_gem_context.h
>> index b5c908f3f4f2..b04d4eeb0500 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_can_use_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 d5bc75508048..79a87268b8da 100644
>> --- a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h
>> @@ -130,6 +130,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
>> @@ -137,6 +138,7 @@ struct i915_gem_context {
>>          unsigned long flags;
>>   #define CONTEXT_CLOSED                 0
>>   #define CONTEXT_USER_ENGINES           1
>> +#define CONTEXT_INVALID                        2
>>   
>>          struct mutex mutex;
>>   
>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>> index fe170186dd42..e503c9f789c0 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"
>> @@ -726,6 +728,11 @@ static int eb_select_context(struct i915_execbuffer *eb)
>>          if (unlikely(!ctx))
>>                  return -ENOENT;
>>   
>> +       if (i915_gem_context_invalidated(ctx)) {
>> +               i915_gem_context_put(ctx);
>> +               return -EIO;
>> +       }
>> +
>>          eb->gem_context = ctx;
>>          if (rcu_access_pointer(ctx->vm))
>>                  eb->invalid_flags |= EXEC_OBJECT_NEEDS_GTT;
>> @@ -2761,6 +2768,12 @@ eb_select_engine(struct i915_execbuffer *eb)
>>   
>>          intel_gt_pm_get(ce->engine->gt);
>>   
>> +       if (i915_gem_context_can_use_protected_content(eb->gem_context)) {
>> +               err = intel_pxp_wait_for_termination_completion(&ce->engine->gt->pxp);
>> +               if (err)
>> +                       goto err;
> This should check for context_invalidated
>
>> +       }
>> +
>>          if (!test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
>>                  err = intel_context_alloc_state(ce);
>>                  if (err)
>> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c
>> index 0ca1c2c16972..5912e4a12d94 100644
>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
>> @@ -6,6 +6,7 @@
>>   #include "intel_pxp.h"
>>   #include "intel_pxp_irq.h"
>>   #include "intel_pxp_tee.h"
>> +#include "gem/i915_gem_context.h"
>>   #include "gt/intel_context.h"
>>   #include "i915_drv.h"
>>   
>> @@ -135,3 +136,40 @@ int intel_pxp_wait_for_termination_completion(struct intel_pxp *pxp)
>>          return ret;
>>   }
>>   
>> +void intel_pxp_invalidate(struct intel_pxp *pxp)
>> +{
>> +       struct drm_i915_private *i915 = pxp_to_gt(pxp)->i915;
>> +       struct i915_gem_context *ctx, *cn;
>> +
>> +       /* 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_can_use_protected_content(ctx)))
>> +                       continue;
>> +
>> +               if (i915_gem_context_invalidated(ctx))
>> +                       continue;
>> +
>> +               spin_unlock_irq(&i915->gem.contexts.lock);
>> +
>> +               for_each_gem_engine(ce, i915_gem_context_lock_engines(ctx), it) {
>> +                       if (test_bit(CONTEXT_ALLOC_BIT, &ce->flags)) {
>> +                               intel_context_set_banned(ce);
> That's a pair of unserialised operations. However, you can just set
> banned before we even try to alloc. But at the moment, it's very

I wanted to avoid banning the intel_contexts if none of them had been 
allocated (i.e. gem_context created but not used).

> spurious to call intel_context_set_banned() as no action is performed to
> flush the ban to the backend, and execbuf is primarily checking the GEM
> context invalid bit. It looks a bit flimsy...
>
> The impact of this loop would be to cancel all pending requests (but not
> the inflight request), sounds like you should just call revoke_context
> to remove the inflight context and pending requests from the HW.

I agree it is flimsy, but the whole process is best effort so I didn't 
want to over-complicate it by taking out the inflight request. The 
moment we get the interrupt the keys are already invalid so it's most 
likely already too late to save the inflight request if it is using one 
of the sessions. I've tried to prioritize getting the session back up as 
soon as possible.

What's revoke_context? I can't find it.

>
>> +                               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);
> And then there's a race condition where we can create a new protect
> context, submit an execbuf using the global session between the call to
> intel_pxp_invalidate and terminate_session_and_global. That's covered by
> irq_handler calling mark_termination_in_progress and execbuf waiting
> for that termination to complete. Almost.

Why almost? what am I missing?

>
> This will result in userspace context lost upon runtime suspend? That
> can be quite catastrophic for the system...

Unfortunately S0ix kills the keys, so yes, unless we decide that we 
don't want to ban protected contexts when the keys are invalidated. That 
was a purely software design decision, the contexts are in no way tied 
to PXP in HW.

>
>> +}
>> +
>> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
>> index 89cf66c9bef3..e36200833095 100644
>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
>> @@ -38,6 +38,7 @@ void intel_pxp_init(struct intel_pxp *pxp);
>>   void intel_pxp_fini(struct intel_pxp *pxp);
>>   
>>   int intel_pxp_wait_for_termination_completion(struct intel_pxp *pxp);
>> +void intel_pxp_invalidate(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_session.c b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
>> index bb981d38c2fe..527217b3db23 100644
>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
>> @@ -111,6 +111,9 @@ int intel_pxp_arb_terminate_session_with_global_terminate(struct intel_pxp *pxp)
>>   
>>          lockdep_assert_held(&pxp->mutex);
>>   
>> +       /* invalidate protected objects */
>> +       intel_pxp_invalidate(pxp);
>> +
>>          /* terminate the hw sessions */
>>          ret = intel_pxp_submit_session_termination(pxp, ARB_SESSION);
>>          if (ret) {
>> diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
>> index 56c6bfe6c2d0..0f5456046c4c 100644
>> --- a/include/uapi/drm/i915_drm.h
>> +++ b/include/uapi/drm/i915_drm.h
>> @@ -1694,6 +1694,24 @@ struct drm_i915_gem_context_param {
>>    * Default is 16 KiB.
>>    */
>>   #define I915_CONTEXT_PARAM_RINGSIZE    0xc
>> +
>> +/*
>> + * I915_CONTEXT_PARAM_PROTECTED_CONTENT:
>> + *
>> + * Enable usage of protected content with the context. 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.
> I haven't seen any interaction with bannable here. Since you just ignore
> the bannable flag.

But I still want to stop userspace from setting the context as not 
bannable. Once I know that protected implies bannable I don't need to 
check the latter.

>
>> + *
>> + * Given the numerous restriction on this flag, there are several unique
>> + * failure cases:
>> + *
>> + * -ENODEV: feature not available
>> + * -EEXIST: trying to modify an existing context
>> + * -EPERM: trying to mark a recoverable or not bannable context as protected
> Also -EIO from execbuf. Do we want to pick EACCES?

instead of EIO? sounds reasonable.

>
>> + */
>> +#define I915_CONTEXT_PARAM_PROTECTED_CONTENT    0xd
>>   /* Must be kept compact -- no holes and well documented */
>>   
>>          __u64 value;
>> @@ -1924,6 +1942,7 @@ struct drm_i915_reg_read {
>>   struct drm_i915_reset_stats {
>>          __u32 ctx_id;
>>          __u32 flags;
>> +#define I915_CONTEXT_INVALIDATED 0x1
> Mention the side effect for protected content contexts.

ok.

>
>>   
>>          /* All resets since boot/module reload, for all contexts */
>>          __u32 reset_count;
>> -- 
>> 2.29.2
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
>>

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

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

* Re: [Intel-gfx] [PATCH v2 09/16] drm/i915/pxp: Implement PXP irq handler
  2021-03-03 21:18   ` Chris Wilson
@ 2021-03-08 18:49     ` Daniele Ceraolo Spurio
  0 siblings, 0 replies; 47+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-03-08 18:49 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx; +Cc: Huang, Sean Z



On 3/3/2021 1:18 PM, Chris Wilson wrote:
> Quoting Daniele Ceraolo Spurio (2021-03-01 19:31:53)
>> 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.
>>
>> v2: use struct completion instead of bool (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>
>> ---
>>   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         |  34 +++++
>>   drivers/gpu/drm/i915/pxp/intel_pxp.h         |  16 ++
>>   drivers/gpu/drm/i915/pxp/intel_pxp_irq.c     | 151 +++++++++++++++++++
>>   drivers/gpu/drm/i915/pxp/intel_pxp_irq.h     |  33 ++++
>>   drivers/gpu/drm/i915/pxp/intel_pxp_session.c |   9 +-
>>   drivers/gpu/drm/i915/pxp/intel_pxp_session.h |   1 +
>>   drivers/gpu/drm/i915/pxp/intel_pxp_tee.c     |  10 +-
>>   drivers/gpu/drm/i915/pxp/intel_pxp_types.h   |   8 +
>>   11 files changed, 268 insertions(+), 3 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 8b605f326039..5e9bd34dec38 100644
>> --- a/drivers/gpu/drm/i915/Makefile
>> +++ b/drivers/gpu/drm/i915/Makefile
>> @@ -274,6 +274,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 d29126c458ba..0d3585efe2b8 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);
>>   }
>> @@ -190,6 +194,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 e5dd0203991b..97a6d0c638ec 100644
>> --- a/drivers/gpu/drm/i915/i915_reg.h
>> +++ b/drivers/gpu/drm/i915/i915_reg.h
>> @@ -7958,6 +7958,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 cbec9395bde9..0ca1c2c16972 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_tee.h"
>>   #include "gt/intel_context.h"
>>   #include "i915_drv.h"
>> @@ -67,12 +69,23 @@ void intel_pxp_init(struct intel_pxp *pxp)
>>   
>>          mutex_init(&pxp->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);
>> +
>>          kcr_pxp_enable(gt);
>>   
>>          ret = create_vcs_context(pxp);
>>          if (ret)
>>                  goto out_kcr;
>>   
>> +       intel_pxp_irq_init(pxp);
>> +       intel_pxp_irq_enable(pxp);
>> +
>>          ret = intel_pxp_tee_component_init(pxp);
>>          if (ret)
>>                  goto out_context;
>> @@ -94,10 +107,31 @@ void intel_pxp_fini(struct intel_pxp *pxp)
>>          if (!intel_pxp_is_enabled(pxp))
>>                  return;
>>   
>> +       intel_pxp_irq_disable(pxp);
>> +
>>          intel_pxp_tee_component_fini(pxp);
>>   
>>          destroy_vcs_context(pxp);
>>   
>>          kcr_pxp_disable(gt);
>> +}
>>   
>> +int intel_pxp_wait_for_termination_completion(struct intel_pxp *pxp)
>> +{
>> +       int ret;
>> +
>> +       if (!intel_pxp_is_enabled(pxp))
>> +               return 0;
>> +
>> +       ret = wait_for_completion_timeout(&pxp->termination,
>> +                                         msecs_to_jiffies(100));
>> +
>> +       /* the wait returns 0 on failure */
>> +       if (ret)
>> +               ret = 0;
>> +       else
>> +               ret = -ETIMEDOUT;
>> +
>> +       return ret;
>>   }
>> +
>> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
>> index 3bede9306481..89cf66c9bef3 100644
>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
>> @@ -9,6 +9,15 @@
>>   #include "gt/intel_gt_types.h"
>>   #include "intel_pxp_types.h"
>>   
>> +#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)
>> +
>>   static inline struct intel_gt *pxp_to_gt(const struct intel_pxp *pxp)
>>   {
>>          return container_of(pxp, struct intel_gt, pxp);
>> @@ -27,6 +36,8 @@ static inline bool intel_pxp_is_active(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);
>> +
>> +int intel_pxp_wait_for_termination_completion(struct intel_pxp *pxp);
>>   #else
>>   static inline void intel_pxp_init(struct intel_pxp *pxp)
>>   {
>> @@ -35,6 +46,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_termination_completion(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..40115bf0b6bb
>> --- /dev/null
>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
>> @@ -0,0 +1,151 @@
>> +// 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"
>> +
>> +static int pxp_terminate(struct intel_pxp *pxp)
>> +{
>> +       int ret = 0;
>> +
>> +       mutex_lock(&pxp->mutex);
>> +
>> +       pxp->global_state_attacked = true;
>> +
>> +       ret = intel_pxp_arb_terminate_session_with_global_terminate(pxp);
>> +
>> +       mutex_unlock(&pxp->mutex);
>> +
>> +       return ret;
>> +}
>> +
>> +static int pxp_terminate_complete(struct intel_pxp *pxp)
>> +{
>> +       int ret = 0;
>> +
>> +       mutex_lock(&pxp->mutex);
>> +
>> +       if (pxp->global_state_attacked) {
>> +               pxp->global_state_attacked = false;
>> +
>> +               /* Re-create the arb session after teardown handle complete */
>> +               ret = intel_pxp_create_arb_session(pxp);
>> +       }
> 	/* Re-create the arb session after teardown handle complete */
> 	if (fetch_and_zero(&pxp->global_state_attacked))
> 		ret = intel_pxp_create_arb_session(pxp);
>
>> +
>> +       mutex_unlock(&pxp->mutex);
>> +
>> +       complete_all(&pxp->termination);
>> +
>> +       return ret;
>> +}
>> +
>> +static void intel_pxp_irq_work(struct work_struct *work)
>> +{
>> +       struct intel_pxp *pxp = container_of(work, typeof(*pxp), irq_work);
>> +       struct intel_gt *gt = pxp_to_gt(pxp);
>> +       u32 events = 0;
>> +
>> +       spin_lock_irq(&gt->irq_lock);
>> +       events = fetch_and_zero(&pxp->current_events);
>> +       spin_unlock_irq(&gt->irq_lock);
>> +
>> +       if (!events)
>> +               return;
>> +
>> +       if (events & (GEN12_DISPLAY_PXP_STATE_TERMINATED_INTERRUPT |
>> +                     GEN12_DISPLAY_APP_TERMINATED_PER_FW_REQ_INTERRUPT))
>> +               pxp_terminate(pxp);
>> +
>> +       if (events & GEN12_DISPLAY_STATE_RESET_COMPLETE_INTERRUPT)
>> +               pxp_terminate_complete(pxp);
>> +
>> +       /*
>> +        * we expect the terminate complete to arrive quickly after emitting
>> +        * the terminate, so check back on it
>> +        */
>> +       if (pxp->irq_enabled)
>> +               queue_work(system_unbound_wq, &pxp->irq_work);
> pxp->current_events is only updated in the interrupt handler, so running
> the work before the irq gains nothing.
>
>> +}
>> +
>> +/**
>> + * 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;
>> +
>> +       /* immediately mark PXP as inactive on termination */
>> +       if (iir & (GEN12_DISPLAY_PXP_STATE_TERMINATED_INTERRUPT |
>> +                  GEN12_DISPLAY_APP_TERMINATED_PER_FW_REQ_INTERRUPT))
>> +               intel_pxp_mark_termination_in_progress(pxp);
>> +
>> +       pxp->current_events |= iir;
>> +       queue_work(system_unbound_wq, &pxp->irq_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_init(struct intel_pxp *pxp)
>> +{
>> +       INIT_WORK(&pxp->irq_work, intel_pxp_irq_work);
>> +}
>> +
>> +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);
>> +
>> +       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->irq_work);
> As I read it, if the session was in play at the time of irq_disable and
> there were inflight interrupts then the state of the session at the end
> of this function is undefined.
>
> Should the session be terminated prior to disabling irq (that would seem
> appropriate for the driver flow)? Certainly at the point of
> unregistering the driver from userspace, all user sessions should cease.
>
> Is an assert like GEM_BUG_ON(!completion_done(&pxp->termination)); valid
> here?

I wanted to avoid doing a termination here because we have to do it 
anyway when we re-enable. I've checked with the archs and basically the 
HW state is undefined on resume (even the in_play register might be out 
of sync with actual HW state), so that termination is mandatory. I can 
add a check to make sure PXP is not considered active by the driver when 
we disable the interrupts, to make sure we're in a flow that will submit 
a termination to re-activate later.

Daniele

> -Chris

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

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

* Re: [Intel-gfx] [PATCH v2 13/16] drm/i915/pxp: User interface for Protected buffer
  2021-03-04  1:24               ` Daniele Ceraolo Spurio
@ 2021-03-08 20:40                 ` Rodrigo Vivi
  2021-03-08 21:01                   ` Lionel Landwerlin
  0 siblings, 1 reply; 47+ messages in thread
From: Rodrigo Vivi @ 2021-03-08 20:40 UTC (permalink / raw)
  To: Daniele Ceraolo Spurio, joonas.lahtinen, Joonas Lahtinen
  Cc: intel-gfx, Huang Sean Z, Chris Wilson, Kondapally Kalyan,
	Bommu Krishnaiah

On Wed, Mar 03, 2021 at 05:24:34PM -0800, Daniele Ceraolo Spurio wrote:
> 
> 
> On 3/3/2021 4:10 PM, Daniele Ceraolo Spurio wrote:
> > 
> > 
> > On 3/3/2021 3:42 PM, Lionel Landwerlin wrote:
> > > On 04/03/2021 01:25, Daniele Ceraolo Spurio wrote:
> > > > 
> > > > 
> > > > On 3/3/2021 3:16 PM, Lionel Landwerlin wrote:
> > > > > On 03/03/2021 23:59, Daniele Ceraolo Spurio wrote:
> > > > > > 
> > > > > > 
> > > > > > On 3/3/2021 12:39 PM, Lionel Landwerlin wrote:
> > > > > > > On 01/03/2021 21:31, Daniele Ceraolo Spurio wrote:
> > > > > > > > From: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
> > > > > > > > 
> > > > > > > > This api allow user mode to create Protected buffers. Only contexts
> > > > > > > > marked as protected are allowed to operate on protected buffers.
> > > > > > > > 
> > > > > > > > We only allow setting the flags at creation time.
> > > > > > > > 
> > > > > > > > All protected objects that have backing storage will be considered
> > > > > > > > invalid when the session is destroyed and they
> > > > > > > > won't be usable anymore.
> > > > > > > > 
> > > > > > > > This is a rework of the original code by Bommu Krishnaiah. I've
> > > > > > > > authorship unchanged since significant chunks
> > > > > > > > have not been modified.
> > > > > > > > 
> > > > > > > > v2: split context changes, fix defines and
> > > > > > > > improve documentation (Chris),
> > > > > > > >      add object invalidation logic
> > > > > > > > 
> > > > > > > > Signed-off-by: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
> > > > > > > > Signed-off-by: Daniele Ceraolo Spurio
> > > > > > > > <daniele.ceraolospurio@intel.com>
> > > > > > > > Cc: Telukuntla Sreedhar <sreedhar.telukuntla@intel.com>
> > > > > > > > Cc: Kondapally Kalyan <kalyan.kondapally@intel.com>
> > > > > > > > Cc: Gupta Anshuman <Anshuman.Gupta@intel.com>
> > > > > > > > Cc: Huang Sean Z <sean.z.huang@intel.com>
> > > > > > > > Cc: Chris Wilson <chris@chris-wilson.co.uk>
> > > > > > > > ---
> > > > > > > >   drivers/gpu/drm/i915/gem/i915_gem_create.c    | 27 +++++++++++--
> > > > > > > >   .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 10 +++++
> > > > > > > >   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  | 13 ++++++
> > > > > > > >   drivers/gpu/drm/i915/pxp/intel_pxp.c         
> > > > > > > > | 40 +++++++++++++++++++
> > > > > > > >   drivers/gpu/drm/i915/pxp/intel_pxp.h          | 13 ++++++
> > > > > > > >   drivers/gpu/drm/i915/pxp/intel_pxp_types.h    |  5 +++
> > > > > > > >   include/uapi/drm/i915_drm.h                   | 22 ++++++++++
> > > > > > > >   9 files changed, 145 insertions(+), 3 deletions(-)
> > > > > > > > 
> > > > > > > > diff --git
> > > > > > > > a/drivers/gpu/drm/i915/gem/i915_gem_create.c
> > > > > > > > b/drivers/gpu/drm/i915/gem/i915_gem_create.c
> > > > > > > > index 3ad3413c459f..d02e5938afbe 100644
> > > > > > > > --- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
> > > > > > > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
> > > > > > > > @@ -5,6 +5,7 @@
> > > > > > > >     #include "gem/i915_gem_ioctls.h"
> > > > > > > >   #include "gem/i915_gem_region.h"
> > > > > > > > +#include "pxp/intel_pxp.h"
> > > > > > > >     #include "i915_drv.h"
> > > > > > > >   #include "i915_user_extensions.h"
> > > > > > > > @@ -13,7 +14,8 @@ static int
> > > > > > > >   i915_gem_create(struct drm_file *file,
> > > > > > > >           struct intel_memory_region *mr,
> > > > > > > >           u64 *size_p,
> > > > > > > > -        u32 *handle_p)
> > > > > > > > +        u32 *handle_p,
> > > > > > > > +        u64 user_flags)
> > > > > > > >   {
> > > > > > > >       struct drm_i915_gem_object *obj;
> > > > > > > >       u32 handle;
> > > > > > > > @@ -35,12 +37,17 @@ i915_gem_create(struct drm_file *file,
> > > > > > > >         GEM_BUG_ON(size != obj->base.size);
> > > > > > > >   +    obj->user_flags = user_flags;
> > > > > > > > +
> > > > > > > >       ret = drm_gem_handle_create(file, &obj->base, &handle);
> > > > > > > >       /* drop reference from allocate - handle holds it now */
> > > > > > > >       i915_gem_object_put(obj);
> > > > > > > >       if (ret)
> > > > > > > >           return ret;
> > > > > > > >   +    if (user_flags & I915_GEM_OBJECT_PROTECTED)
> > > > > > > > +        intel_pxp_object_add(obj);
> > > > > > > > +
> > > > > > > >       *handle_p = handle;
> > > > > > > >       *size_p = size;
> > > > > > > >       return 0;
> > > > > > > > @@ -89,11 +96,12 @@ i915_gem_dumb_create(struct drm_file *file,
> > > > > > > >       return i915_gem_create(file,
> > > > > > > > intel_memory_region_by_type(to_i915(dev),
> > > > > > > >                                  mem_type),
> > > > > > > > -                   &args->size, &args->handle);
> > > > > > > > +                   &args->size, &args->handle, 0);
> > > > > > > >   }
> > > > > > > >     struct create_ext {
> > > > > > > >       struct drm_i915_private *i915;
> > > > > > > > +    unsigned long user_flags;
> > > > > > > >   };
> > > > > > > >     static int __create_setparam(struct
> > > > > > > > drm_i915_gem_object_param *args,
> > > > > > > > @@ -104,6 +112,19 @@ static int
> > > > > > > > __create_setparam(struct
> > > > > > > > drm_i915_gem_object_param *args,
> > > > > > > >           return -EINVAL;
> > > > > > > >       }
> > > > > > > >   +    switch (lower_32_bits(args->param)) {
> > > > > > > > +    case I915_OBJECT_PARAM_PROTECTED_CONTENT:
> > > > > > > > +        if (!intel_pxp_is_enabled(&ext_data->i915->gt.pxp))
> > > > > > > > +            return -ENODEV;
> > > > > > > > +        if (args->size) {
> > > > > > > > +            return -EINVAL;
> > > > > > > > +        } else if (args->data) {
> > > > > > > > +            ext_data->user_flags |= I915_GEM_OBJECT_PROTECTED;
> > > > > > > > +            return 0;
> > > > > > > > +        }
> > > > > > > > +    break;
> > > > > > > > +    }
> > > > > > > > +
> > > > > > > >       return -EINVAL;
> > > > > > > >   }
> > > > > > > >   @@ -148,5 +169,5 @@
> > > > > > > > i915_gem_create_ioctl(struct drm_device *dev,
> > > > > > > > void *data,
> > > > > > > >       return i915_gem_create(file,
> > > > > > > >                      intel_memory_region_by_type(i915,
> > > > > > > >                                  INTEL_MEMORY_SYSTEM),
> > > > > > > > -                   &args->size, &args->handle);
> > > > > > > > +                   &args->size, &args->handle,
> > > > > > > > ext_data.user_flags);
> > > > > > > >   }
> > > > > > > > diff --git
> > > > > > > > a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> > > > > > > > b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> > > > > > > > index e503c9f789c0..d10c4fcb6aec 100644
> > > > > > > > --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> > > > > > > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
> > > > > > > > @@ -20,6 +20,7 @@
> > > > > > > >   #include "gt/intel_gt_buffer_pool.h"
> > > > > > > >   #include "gt/intel_gt_pm.h"
> > > > > > > >   #include "gt/intel_ring.h"
> > > > > > > > +#include "pxp/intel_pxp.h"
> > > > > > > >     #include "pxp/intel_pxp.h"
> > > > > > > >   @@ -500,6 +501,15 @@ eb_validate_vma(struct i915_execbuffer *eb,
> > > > > > > >                entry->offset !=
> > > > > > > > gen8_canonical_addr(entry->offset &
> > > > > > > > I915_GTT_PAGE_MASK)))
> > > > > > > >           return -EINVAL;
> > > > > > > >   +    if (i915_gem_object_is_protected(vma->obj)) {
> > > > > > > > +        if (!intel_pxp_is_active(&vma->vm->gt->pxp))
> > > > > > > > +            return -ENODEV;
> > > > > > > > +        if (!i915_gem_object_has_valid_protection(vma->obj))
> > > > > > > > +            return -EIO;
> > > > > > > > +        if
> > > > > > > > (!i915_gem_context_can_use_protected_content(eb->gem_context))
> > > > > > > > +            return -EPERM;
> > > > > > > 
> > > > > > > 
> > > > > > > I think I'm running into this error.
> > > > > > 
> > > > > > The currently agreed design is that protected objects
> > > > > > can only be used with explicitly marked contexts,
> > > > > > although it's not an HW requirement so we can revisit
> > > > > > it.
> > > > > > 
> > > > > > > 
> > > > > > > When running vkcube protected under wayland, it
> > > > > > > takes down the entire session (Xorg & gnome-shell
> > > > > > > depending on which one is going to use the protected
> > > > > > > buffer first).
> > > > > > 
> > > > > > Are you saying that a single submission failure takes
> > > > > > down the entire gnome session? that sounds like a larger
> > > > > > problem than just this failure. Or am I misunderstanding
> > > > > > your point?
> > > > > 
> > > > > 
> > > > > We just need to hand that buffer to any other app and have
> > > > > it use it in execbuf and that will make it fail the execbuf.
> > > > > 
> > > > > Now how does the driver in the gnome-shell/Xorg process know
> > > > > what went wrong and what buffer caused it?
> > > > > 
> > > > > Could be any imported buffer. It's pretty hard to recover
> > > > > from this and most apps will just crash if the driver starts
> > > > > to fail for some reason.
> > > > > 
> > > > > You can see how that could make a lot of people's live terrible :/
> > > > 
> > > > Don't other apps have to know that the buffer is encrypted to
> > > > use it properly? Or is there a case where we want to use the
> > > > object as if it wasn't encrypted?
> > > > 
> > > > Also, PXP submissions can become invalid at any point in time
> > > > due to a teardown event, which causes the contents of the
> > > > encrypted buffers to become garbage. If we can't fail the
> > > > execbuf which includes an invalidated buffer we'd have to
> > > > silently discard the submission.
> > > 
> > > 
> > > A malicious app could start sharing protected tagged buffer with no
> > > protected content in it, just to invalidate/crash others apps'
> > > context.
> > 
> > I see your point, although on the other side failing the execbuf when
> > malicious behavior is detected seems reasonable as well.
> > 
> > > 
> > > Can the failure be only reported to protected contexts?
> > 
> > That would allow a non-protected context to use protected objects, which
> > is something we wanted to avoid.
> > I see a few options here:
> > 
> > - live with the execbuf failure on incorrect or malicious behavior

could you please expand this option a bit further?
Based on the scenario that Lionel described I'm not feeling this is viable...

> > - silently fail execbuf if protected objects are used with non-protected
> > contexts

I don't like to simply silent to ignore the execbuf with no indication.
How userspace will know it needs to resubmit the job?

> > - remove the restriction on protected objects being usable only by
> > protected contexts
> > 
> > Rodrigo, Joonas, any preference or other suggestion here?
> > 
> 
> BTW, whatever we decide has to also consider the other failure cases in the
> check above:
> - pxp not active, i.e. termination in progress
> - invalid buffer (encrypted using old keys)

yeap. That's the case on the current design.

Is an option to save that "token" with buffers and contexts?

Joonas?

> 
> Both of those could currently cause an execbuf failure even if we ignore the
> protected context restriction, which IMO makes the third option above not
> viable.
> 
> Daniele
> 
> > Daniele
> > 
> > > 
> > > 
> > > -Lionel
> > > 
> > > 
> > > > 
> > > > Daniele
> > > > 
> > > > > 
> > > > > 
> > > > > -Lionel
> > > > > 
> > > > > 
> > > > > > 
> > > > > > > 
> > > > > > > That's a bit harsh.
> > > > > > > 
> > > > > > > 
> > > > > > > We probably don't want this. After all the point of
> > > > > > > encryption is that even if you can read the buffer
> > > > > > > you won't be able to make much of its content.
> > > > > > 
> > > > > > As mentioned above we can change this since there is no
> > > > > > HW requirement on contexts, but need some architectural
> > > > > > agreement. Joonas and Rodrigo can comment more here.
> > > > > > Also note that submitting an instruction using encrypted
> > > > > > data while the session is invalid can cause the HW to
> > > > > > hang, which is part of the reason why we require the
> > > > > > contexts using protected objects to be marked
> > > > > > appropriately, so we can ban them on PXP teardown to
> > > > > > avoid hangs.
> > > > > > 
> > > > > > Daniele
> > > > > > 
> > > > > > > 
> > > > > > > Also useful to know you're dealing for debugging ;)
> > > > > > > 
> > > > > > > 
> > > > > > > -Lionel
> > > > > > > 
> > > > > > > 
> > > > > > > > +    }
> > > > > > > > +
> > > > > > > >       /* pad_to_size was once a reserved field, so sanitize it */
> > > > > > > >       if (entry->flags & EXEC_OBJECT_PAD_TO_SIZE) {
> > > > > > > >           if (unlikely(offset_in_page(entry->pad_to_size)))
> > > > > > > > diff --git
> > > > > > > > a/drivers/gpu/drm/i915/gem/i915_gem_object.c
> > > > > > > > b/drivers/gpu/drm/i915/gem/i915_gem_object.c
> > > > > > > > index 6cdff5fc5882..b321f5484ae6 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"
> > > > > > > > @@ -72,6 +73,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;
> > > > > > > >   @@ -120,6 +123,9 @@ static void
> > > > > > > > i915_gem_close_object(struct drm_gem_object
> > > > > > > > *gem, struct drm_file *f
> > > > > > > >       struct i915_lut_handle *lut, *ln;
> > > > > > > >       LIST_HEAD(close);
> > > > > > > >   +    if (i915_gem_object_has_valid_protection(obj))
> > > > > > > > +        intel_pxp_object_remove(obj);
> > > > > > > > +
> > > > > > > >       spin_lock(&obj->lut_lock);
> > > > > > > >       list_for_each_entry_safe(lut, ln, &obj->lut_list, obj_link) {
> > > > > > > >           struct i915_gem_context *ctx = lut->ctx;
> > > > > > > > diff --git
> > > > > > > > a/drivers/gpu/drm/i915/gem/i915_gem_object.h
> > > > > > > > b/drivers/gpu/drm/i915/gem/i915_gem_object.h
> > > > > > > > index 366d23afbb1a..a1fa7539c0f7 100644
> > > > > > > > --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
> > > > > > > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
> > > > > > > > @@ -274,6 +274,18 @@
> > > > > > > > i915_gem_object_needs_async_cancel(const struct
> > > > > > > > drm_i915_gem_object *obj)
> > > > > > > >       return i915_gem_object_type_has(obj,
> > > > > > > > I915_GEM_OBJECT_ASYNC_CANCEL);
> > > > > > > >   }
> > > > > > > >   +static inline bool
> > > > > > > > +i915_gem_object_is_protected(const struct
> > > > > > > > drm_i915_gem_object *obj)
> > > > > > > > +{
> > > > > > > > +    return obj->user_flags & I915_GEM_OBJECT_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_is_framebuffer(const struct
> > > > > > > > drm_i915_gem_object *obj)
> > > > > > > >   {
> > > > > > > > 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 0a1fdbac882e..6eee580c7aba 100644
> > > > > > > > --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> > > > > > > > +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
> > > > > > > > @@ -167,6 +167,11 @@ struct drm_i915_gem_object {
> > > > > > > >       } mmo;
> > > > > > > >         I915_SELFTEST_DECLARE(struct list_head st_link);
> > > > > > > > +    /**
> > > > > > > > +     * @user_flags: small set of booleans set by the user
> > > > > > > > +     */
> > > > > > > > +    unsigned long user_flags;
> > > > > > > > +#define I915_GEM_OBJECT_PROTECTED BIT(0)
> > > > > > > >         unsigned long flags;
> > > > > > > >   #define I915_BO_ALLOC_CONTIGUOUS BIT(0)
> > > > > > > > @@ -290,6 +295,14 @@ struct drm_i915_gem_object {
> > > > > > > >           bool dirty:1;
> > > > > > > >       } mm;
> > > > > > > >   +    /*
> > > > > > > > +     * 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 5912e4a12d94..03151cd7f4b8 100644
> > > > > > > > --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
> > > > > > > > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
> > > > > > > > @@ -69,6 +69,8 @@ void intel_pxp_init(struct intel_pxp *pxp)
> > > > > > > >           return;
> > > > > > > >         mutex_init(&pxp->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,
> > > > > > > > @@ -136,11 +138,49 @@ int
> > > > > > > > intel_pxp_wait_for_termination_completion(struct
> > > > > > > > intel_pxp *pxp)
> > > > > > > >       return ret;
> > > > > > > >   }
> > > > > > > >   +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) {
> > > > > > > > diff --git
> > > > > > > > a/drivers/gpu/drm/i915/pxp/intel_pxp.h
> > > > > > > > b/drivers/gpu/drm/i915/pxp/intel_pxp.h
> > > > > > > > index e36200833095..3315b07d271b 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;
> > > > > > > > +
> > > > > > > >   #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)
> > > > > > > > @@ -38,6 +40,9 @@ void intel_pxp_init(struct intel_pxp *pxp);
> > > > > > > >   void intel_pxp_fini(struct intel_pxp *pxp);
> > > > > > > >     int
> > > > > > > > intel_pxp_wait_for_termination_completion(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)
> > > > > > > > @@ -52,6 +57,14 @@ static inline int
> > > > > > > > intel_pxp_wait_for_termination_completion(struct
> > > > > > > > intel_pxp *px
> > > > > > > >   {
> > > > > > > >       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_types.h
> > > > > > > > b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
> > > > > > > > index 6f659a6f8f1c..53a2a8acfe51 100644
> > > > > > > > --- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
> > > > > > > > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
> > > > > > > > @@ -7,8 +7,10 @@
> > > > > > > >   #define __INTEL_PXP_TYPES_H__
> > > > > > > >     #include <linux/completion.h>
> > > > > > > > +#include <linux/list.h>
> > > > > > > >   #include <linux/types.h>
> > > > > > > >   #include <linux/mutex.h>
> > > > > > > > +#include <linux/spinlock.h>
> > > > > > > >   #include <linux/workqueue.h>
> > > > > > > >     struct intel_context;
> > > > > > > > @@ -28,6 +30,9 @@ struct intel_pxp {
> > > > > > > >       struct work_struct irq_work;
> > > > > > > >       bool irq_enabled;
> > > > > > > >       u32 current_events; /* protected with gt->irq_lock */
> > > > > > > > +
> > > > > > > > +    struct spinlock lock;
> > > > > > > > +    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 9ebe8523aa0c..0f8b771a6d53 100644
> > > > > > > > --- a/include/uapi/drm/i915_drm.h
> > > > > > > > +++ b/include/uapi/drm/i915_drm.h
> > > > > > > > @@ -1753,6 +1753,28 @@ struct drm_i915_gem_object_param {
> > > > > > > >    */
> > > > > > > >   #define I915_OBJECT_PARAM  (1ull << 32)
> > > > > > > >   +/*
> > > > > > > > + * I915_OBJECT_PARAM_PROTECTED_CONTENT:
> > > > > > > > + *
> > > > > > > > + * If set to true, buffer contents is expected
> > > > > > > > to be protected by PXP
> > > > > > > > + * encryption and requires decryption for scan
> > > > > > > > out and processing. This is
> > > > > > > > + * only possible on platforms that have PXP
> > > > > > > > enabled, on all other scenarios
> > > > > > > > + * setting this flag will cause the ioctl to
> > > > > > > > fail and return -ENODEV.
> > > > > > > > + *
> > > > > > > > + * Protected buffers can only be used with
> > > > > > > > contexts created using the
> > > > > > > > + * I915_CONTEXT_PARAM_PROTECTED_CONTENT flag.
> > > > > > > > The buffer contents are
> > > > > > > > + * considered invalid after a PXP session teardown.
> > > > > > > > + *
> > > > > > > > + * Given the restriction above, the following
> > > > > > > > errors are possible when
> > > > > > > > + * submitting a protected object in an execbuf call:
> > > > > > > > + *
> > > > > > > > + * -ENODEV: PXP session not currently active
> > > > > > > > + * -EIO: buffer has become invalid after a teardown event
> > > > > > > > + * -EPERM: buffer submitted using a context not
> > > > > > > > marked as protected
> > > > > > > > + */
> > > > > > > > +#define I915_OBJECT_PARAM_PROTECTED_CONTENT  0x0
> > > > > > > > +/* Must be kept compact -- no holes and well documented */
> > > > > > > > +
> > > > > > > >       __u64 param;
> > > > > > > >         /* Data value or pointer */
> > > > > > > 
> > > > > > > 
> > > > > > 
> > > > > 
> > > > 
> > > 
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH v2 13/16] drm/i915/pxp: User interface for Protected buffer
  2021-03-08 20:40                 ` Rodrigo Vivi
@ 2021-03-08 21:01                   ` Lionel Landwerlin
  2021-03-08 21:54                     ` Daniele Ceraolo Spurio
  0 siblings, 1 reply; 47+ messages in thread
From: Lionel Landwerlin @ 2021-03-08 21:01 UTC (permalink / raw)
  To: Rodrigo Vivi, Daniele Ceraolo Spurio, joonas.lahtinen, Joonas Lahtinen
  Cc: Bommu Krishnaiah, intel-gfx, Huang Sean Z, Chris Wilson,
	Kondapally Kalyan

On 08/03/2021 22:40, Rodrigo Vivi wrote:
> On Wed, Mar 03, 2021 at 05:24:34PM -0800, Daniele Ceraolo Spurio wrote:
>>
>> On 3/3/2021 4:10 PM, Daniele Ceraolo Spurio wrote:
>>>
>>> On 3/3/2021 3:42 PM, Lionel Landwerlin wrote:
>>>> On 04/03/2021 01:25, Daniele Ceraolo Spurio wrote:
>>>>>
>>>>> On 3/3/2021 3:16 PM, Lionel Landwerlin wrote:
>>>>>> On 03/03/2021 23:59, Daniele Ceraolo Spurio wrote:
>>>>>>>
>>>>>>> On 3/3/2021 12:39 PM, Lionel Landwerlin wrote:
>>>>>>>> On 01/03/2021 21:31, Daniele Ceraolo Spurio wrote:
>>>>>>>>> From: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
>>>>>>>>>
>>>>>>>>> This api allow user mode to create Protected buffers. Only contexts
>>>>>>>>> marked as protected are allowed to operate on protected buffers.
>>>>>>>>>
>>>>>>>>> We only allow setting the flags at creation time.
>>>>>>>>>
>>>>>>>>> All protected objects that have backing storage will be considered
>>>>>>>>> invalid when the session is destroyed and they
>>>>>>>>> won't be usable anymore.
>>>>>>>>>
>>>>>>>>> This is a rework of the original code by Bommu Krishnaiah. I've
>>>>>>>>> authorship unchanged since significant chunks
>>>>>>>>> have not been modified.
>>>>>>>>>
>>>>>>>>> v2: split context changes, fix defines and
>>>>>>>>> improve documentation (Chris),
>>>>>>>>>       add object invalidation logic
>>>>>>>>>
>>>>>>>>> Signed-off-by: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
>>>>>>>>> Signed-off-by: Daniele Ceraolo Spurio
>>>>>>>>> <daniele.ceraolospurio@intel.com>
>>>>>>>>> Cc: Telukuntla Sreedhar <sreedhar.telukuntla@intel.com>
>>>>>>>>> Cc: Kondapally Kalyan <kalyan.kondapally@intel.com>
>>>>>>>>> Cc: Gupta Anshuman <Anshuman.Gupta@intel.com>
>>>>>>>>> Cc: Huang Sean Z <sean.z.huang@intel.com>
>>>>>>>>> Cc: Chris Wilson <chris@chris-wilson.co.uk>
>>>>>>>>> ---
>>>>>>>>>    drivers/gpu/drm/i915/gem/i915_gem_create.c    | 27 +++++++++++--
>>>>>>>>>    .../gpu/drm/i915/gem/i915_gem_execbuffer.c    | 10 +++++
>>>>>>>>>    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  | 13 ++++++
>>>>>>>>>    drivers/gpu/drm/i915/pxp/intel_pxp.c
>>>>>>>>> | 40 +++++++++++++++++++
>>>>>>>>>    drivers/gpu/drm/i915/pxp/intel_pxp.h          | 13 ++++++
>>>>>>>>>    drivers/gpu/drm/i915/pxp/intel_pxp_types.h    |  5 +++
>>>>>>>>>    include/uapi/drm/i915_drm.h                   | 22 ++++++++++
>>>>>>>>>    9 files changed, 145 insertions(+), 3 deletions(-)
>>>>>>>>>
>>>>>>>>> diff --git
>>>>>>>>> a/drivers/gpu/drm/i915/gem/i915_gem_create.c
>>>>>>>>> b/drivers/gpu/drm/i915/gem/i915_gem_create.c
>>>>>>>>> index 3ad3413c459f..d02e5938afbe 100644
>>>>>>>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
>>>>>>>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
>>>>>>>>> @@ -5,6 +5,7 @@
>>>>>>>>>      #include "gem/i915_gem_ioctls.h"
>>>>>>>>>    #include "gem/i915_gem_region.h"
>>>>>>>>> +#include "pxp/intel_pxp.h"
>>>>>>>>>      #include "i915_drv.h"
>>>>>>>>>    #include "i915_user_extensions.h"
>>>>>>>>> @@ -13,7 +14,8 @@ static int
>>>>>>>>>    i915_gem_create(struct drm_file *file,
>>>>>>>>>            struct intel_memory_region *mr,
>>>>>>>>>            u64 *size_p,
>>>>>>>>> -        u32 *handle_p)
>>>>>>>>> +        u32 *handle_p,
>>>>>>>>> +        u64 user_flags)
>>>>>>>>>    {
>>>>>>>>>        struct drm_i915_gem_object *obj;
>>>>>>>>>        u32 handle;
>>>>>>>>> @@ -35,12 +37,17 @@ i915_gem_create(struct drm_file *file,
>>>>>>>>>          GEM_BUG_ON(size != obj->base.size);
>>>>>>>>>    +    obj->user_flags = user_flags;
>>>>>>>>> +
>>>>>>>>>        ret = drm_gem_handle_create(file, &obj->base, &handle);
>>>>>>>>>        /* drop reference from allocate - handle holds it now */
>>>>>>>>>        i915_gem_object_put(obj);
>>>>>>>>>        if (ret)
>>>>>>>>>            return ret;
>>>>>>>>>    +    if (user_flags & I915_GEM_OBJECT_PROTECTED)
>>>>>>>>> +        intel_pxp_object_add(obj);
>>>>>>>>> +
>>>>>>>>>        *handle_p = handle;
>>>>>>>>>        *size_p = size;
>>>>>>>>>        return 0;
>>>>>>>>> @@ -89,11 +96,12 @@ i915_gem_dumb_create(struct drm_file *file,
>>>>>>>>>        return i915_gem_create(file,
>>>>>>>>> intel_memory_region_by_type(to_i915(dev),
>>>>>>>>>                                   mem_type),
>>>>>>>>> -                   &args->size, &args->handle);
>>>>>>>>> +                   &args->size, &args->handle, 0);
>>>>>>>>>    }
>>>>>>>>>      struct create_ext {
>>>>>>>>>        struct drm_i915_private *i915;
>>>>>>>>> +    unsigned long user_flags;
>>>>>>>>>    };
>>>>>>>>>      static int __create_setparam(struct
>>>>>>>>> drm_i915_gem_object_param *args,
>>>>>>>>> @@ -104,6 +112,19 @@ static int
>>>>>>>>> __create_setparam(struct
>>>>>>>>> drm_i915_gem_object_param *args,
>>>>>>>>>            return -EINVAL;
>>>>>>>>>        }
>>>>>>>>>    +    switch (lower_32_bits(args->param)) {
>>>>>>>>> +    case I915_OBJECT_PARAM_PROTECTED_CONTENT:
>>>>>>>>> +        if (!intel_pxp_is_enabled(&ext_data->i915->gt.pxp))
>>>>>>>>> +            return -ENODEV;
>>>>>>>>> +        if (args->size) {
>>>>>>>>> +            return -EINVAL;
>>>>>>>>> +        } else if (args->data) {
>>>>>>>>> +            ext_data->user_flags |= I915_GEM_OBJECT_PROTECTED;
>>>>>>>>> +            return 0;
>>>>>>>>> +        }
>>>>>>>>> +    break;
>>>>>>>>> +    }
>>>>>>>>> +
>>>>>>>>>        return -EINVAL;
>>>>>>>>>    }
>>>>>>>>>    @@ -148,5 +169,5 @@
>>>>>>>>> i915_gem_create_ioctl(struct drm_device *dev,
>>>>>>>>> void *data,
>>>>>>>>>        return i915_gem_create(file,
>>>>>>>>>                       intel_memory_region_by_type(i915,
>>>>>>>>>                                   INTEL_MEMORY_SYSTEM),
>>>>>>>>> -                   &args->size, &args->handle);
>>>>>>>>> +                   &args->size, &args->handle,
>>>>>>>>> ext_data.user_flags);
>>>>>>>>>    }
>>>>>>>>> diff --git
>>>>>>>>> a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>>>>>>>>> b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>>>>>>>>> index e503c9f789c0..d10c4fcb6aec 100644
>>>>>>>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>>>>>>>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>>>>>>>>> @@ -20,6 +20,7 @@
>>>>>>>>>    #include "gt/intel_gt_buffer_pool.h"
>>>>>>>>>    #include "gt/intel_gt_pm.h"
>>>>>>>>>    #include "gt/intel_ring.h"
>>>>>>>>> +#include "pxp/intel_pxp.h"
>>>>>>>>>      #include "pxp/intel_pxp.h"
>>>>>>>>>    @@ -500,6 +501,15 @@ eb_validate_vma(struct i915_execbuffer *eb,
>>>>>>>>>                 entry->offset !=
>>>>>>>>> gen8_canonical_addr(entry->offset &
>>>>>>>>> I915_GTT_PAGE_MASK)))
>>>>>>>>>            return -EINVAL;
>>>>>>>>>    +    if (i915_gem_object_is_protected(vma->obj)) {
>>>>>>>>> +        if (!intel_pxp_is_active(&vma->vm->gt->pxp))
>>>>>>>>> +            return -ENODEV;
>>>>>>>>> +        if (!i915_gem_object_has_valid_protection(vma->obj))
>>>>>>>>> +            return -EIO;
>>>>>>>>> +        if
>>>>>>>>> (!i915_gem_context_can_use_protected_content(eb->gem_context))
>>>>>>>>> +            return -EPERM;
>>>>>>>>
>>>>>>>> I think I'm running into this error.
>>>>>>> The currently agreed design is that protected objects
>>>>>>> can only be used with explicitly marked contexts,
>>>>>>> although it's not an HW requirement so we can revisit
>>>>>>> it.
>>>>>>>
>>>>>>>> When running vkcube protected under wayland, it
>>>>>>>> takes down the entire session (Xorg & gnome-shell
>>>>>>>> depending on which one is going to use the protected
>>>>>>>> buffer first).
>>>>>>> Are you saying that a single submission failure takes
>>>>>>> down the entire gnome session? that sounds like a larger
>>>>>>> problem than just this failure. Or am I misunderstanding
>>>>>>> your point?
>>>>>>
>>>>>> We just need to hand that buffer to any other app and have
>>>>>> it use it in execbuf and that will make it fail the execbuf.
>>>>>>
>>>>>> Now how does the driver in the gnome-shell/Xorg process know
>>>>>> what went wrong and what buffer caused it?
>>>>>>
>>>>>> Could be any imported buffer. It's pretty hard to recover
>>>>>> from this and most apps will just crash if the driver starts
>>>>>> to fail for some reason.
>>>>>>
>>>>>> You can see how that could make a lot of people's live terrible :/
>>>>> Don't other apps have to know that the buffer is encrypted to
>>>>> use it properly? Or is there a case where we want to use the
>>>>> object as if it wasn't encrypted?
>>>>>
>>>>> Also, PXP submissions can become invalid at any point in time
>>>>> due to a teardown event, which causes the contents of the
>>>>> encrypted buffers to become garbage. If we can't fail the
>>>>> execbuf which includes an invalidated buffer we'd have to
>>>>> silently discard the submission.
>>>>
>>>> A malicious app could start sharing protected tagged buffer with no
>>>> protected content in it, just to invalidate/crash others apps'
>>>> context.
>>> I see your point, although on the other side failing the execbuf when
>>> malicious behavior is detected seems reasonable as well.
>>>
>>>> Can the failure be only reported to protected contexts?
>>> That would allow a non-protected context to use protected objects, which
>>> is something we wanted to avoid.
>>> I see a few options here:
>>>
>>> - live with the execbuf failure on incorrect or malicious behavior
> could you please expand this option a bit further?
> Based on the scenario that Lionel described I'm not feeling this is viable...
>
>>> - silently fail execbuf if protected objects are used with non-protected
>>> contexts
> I don't like to simply silent to ignore the execbuf with no indication.
> How userspace will know it needs to resubmit the job?


A normal/unprotected context wouldn't resubmit anyway because it 
wouldn't have the logic the handle this case.

Initially I thought that the failure would only appear on protected 
contexts, because they want to present protected content properly and so 
if anything goes wrong in the protected flow, they need to know.


But an application like gnome-shell/Xorg should probably not be affected 
if they don't support protected content.


-Lionel


>
>>> - remove the restriction on protected objects being usable only by
>>> protected contexts
>>>
>>> Rodrigo, Joonas, any preference or other suggestion here?
>>>
>> BTW, whatever we decide has to also consider the other failure cases in the
>> check above:
>> - pxp not active, i.e. termination in progress
>> - invalid buffer (encrypted using old keys)
> yeap. That's the case on the current design.
>
> Is an option to save that "token" with buffers and contexts?
>
> Joonas?
>
>> Both of those could currently cause an execbuf failure even if we ignore the
>> protected context restriction, which IMO makes the third option above not
>> viable.
>>
>> Daniele
>>
>>> Daniele
>>>
>>>>
>>>> -Lionel
>>>>
>>>>
>>>>> Daniele
>>>>>
>>>>>>
>>>>>> -Lionel
>>>>>>
>>>>>>
>>>>>>>> That's a bit harsh.
>>>>>>>>
>>>>>>>>
>>>>>>>> We probably don't want this. After all the point of
>>>>>>>> encryption is that even if you can read the buffer
>>>>>>>> you won't be able to make much of its content.
>>>>>>> As mentioned above we can change this since there is no
>>>>>>> HW requirement on contexts, but need some architectural
>>>>>>> agreement. Joonas and Rodrigo can comment more here.
>>>>>>> Also note that submitting an instruction using encrypted
>>>>>>> data while the session is invalid can cause the HW to
>>>>>>> hang, which is part of the reason why we require the
>>>>>>> contexts using protected objects to be marked
>>>>>>> appropriately, so we can ban them on PXP teardown to
>>>>>>> avoid hangs.
>>>>>>>
>>>>>>> Daniele
>>>>>>>
>>>>>>>> Also useful to know you're dealing for debugging ;)
>>>>>>>>
>>>>>>>>
>>>>>>>> -Lionel
>>>>>>>>
>>>>>>>>
>>>>>>>>> +    }
>>>>>>>>> +
>>>>>>>>>        /* pad_to_size was once a reserved field, so sanitize it */
>>>>>>>>>        if (entry->flags & EXEC_OBJECT_PAD_TO_SIZE) {
>>>>>>>>>            if (unlikely(offset_in_page(entry->pad_to_size)))
>>>>>>>>> diff --git
>>>>>>>>> a/drivers/gpu/drm/i915/gem/i915_gem_object.c
>>>>>>>>> b/drivers/gpu/drm/i915/gem/i915_gem_object.c
>>>>>>>>> index 6cdff5fc5882..b321f5484ae6 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"
>>>>>>>>> @@ -72,6 +73,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;
>>>>>>>>>    @@ -120,6 +123,9 @@ static void
>>>>>>>>> i915_gem_close_object(struct drm_gem_object
>>>>>>>>> *gem, struct drm_file *f
>>>>>>>>>        struct i915_lut_handle *lut, *ln;
>>>>>>>>>        LIST_HEAD(close);
>>>>>>>>>    +    if (i915_gem_object_has_valid_protection(obj))
>>>>>>>>> +        intel_pxp_object_remove(obj);
>>>>>>>>> +
>>>>>>>>>        spin_lock(&obj->lut_lock);
>>>>>>>>>        list_for_each_entry_safe(lut, ln, &obj->lut_list, obj_link) {
>>>>>>>>>            struct i915_gem_context *ctx = lut->ctx;
>>>>>>>>> diff --git
>>>>>>>>> a/drivers/gpu/drm/i915/gem/i915_gem_object.h
>>>>>>>>> b/drivers/gpu/drm/i915/gem/i915_gem_object.h
>>>>>>>>> index 366d23afbb1a..a1fa7539c0f7 100644
>>>>>>>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
>>>>>>>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
>>>>>>>>> @@ -274,6 +274,18 @@
>>>>>>>>> i915_gem_object_needs_async_cancel(const struct
>>>>>>>>> drm_i915_gem_object *obj)
>>>>>>>>>        return i915_gem_object_type_has(obj,
>>>>>>>>> I915_GEM_OBJECT_ASYNC_CANCEL);
>>>>>>>>>    }
>>>>>>>>>    +static inline bool
>>>>>>>>> +i915_gem_object_is_protected(const struct
>>>>>>>>> drm_i915_gem_object *obj)
>>>>>>>>> +{
>>>>>>>>> +    return obj->user_flags & I915_GEM_OBJECT_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_is_framebuffer(const struct
>>>>>>>>> drm_i915_gem_object *obj)
>>>>>>>>>    {
>>>>>>>>> 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 0a1fdbac882e..6eee580c7aba 100644
>>>>>>>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
>>>>>>>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
>>>>>>>>> @@ -167,6 +167,11 @@ struct drm_i915_gem_object {
>>>>>>>>>        } mmo;
>>>>>>>>>          I915_SELFTEST_DECLARE(struct list_head st_link);
>>>>>>>>> +    /**
>>>>>>>>> +     * @user_flags: small set of booleans set by the user
>>>>>>>>> +     */
>>>>>>>>> +    unsigned long user_flags;
>>>>>>>>> +#define I915_GEM_OBJECT_PROTECTED BIT(0)
>>>>>>>>>          unsigned long flags;
>>>>>>>>>    #define I915_BO_ALLOC_CONTIGUOUS BIT(0)
>>>>>>>>> @@ -290,6 +295,14 @@ struct drm_i915_gem_object {
>>>>>>>>>            bool dirty:1;
>>>>>>>>>        } mm;
>>>>>>>>>    +    /*
>>>>>>>>> +     * 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 5912e4a12d94..03151cd7f4b8 100644
>>>>>>>>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
>>>>>>>>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
>>>>>>>>> @@ -69,6 +69,8 @@ void intel_pxp_init(struct intel_pxp *pxp)
>>>>>>>>>            return;
>>>>>>>>>          mutex_init(&pxp->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,
>>>>>>>>> @@ -136,11 +138,49 @@ int
>>>>>>>>> intel_pxp_wait_for_termination_completion(struct
>>>>>>>>> intel_pxp *pxp)
>>>>>>>>>        return ret;
>>>>>>>>>    }
>>>>>>>>>    +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) {
>>>>>>>>> diff --git
>>>>>>>>> a/drivers/gpu/drm/i915/pxp/intel_pxp.h
>>>>>>>>> b/drivers/gpu/drm/i915/pxp/intel_pxp.h
>>>>>>>>> index e36200833095..3315b07d271b 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;
>>>>>>>>> +
>>>>>>>>>    #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)
>>>>>>>>> @@ -38,6 +40,9 @@ void intel_pxp_init(struct intel_pxp *pxp);
>>>>>>>>>    void intel_pxp_fini(struct intel_pxp *pxp);
>>>>>>>>>      int
>>>>>>>>> intel_pxp_wait_for_termination_completion(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)
>>>>>>>>> @@ -52,6 +57,14 @@ static inline int
>>>>>>>>> intel_pxp_wait_for_termination_completion(struct
>>>>>>>>> intel_pxp *px
>>>>>>>>>    {
>>>>>>>>>        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_types.h
>>>>>>>>> b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
>>>>>>>>> index 6f659a6f8f1c..53a2a8acfe51 100644
>>>>>>>>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
>>>>>>>>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
>>>>>>>>> @@ -7,8 +7,10 @@
>>>>>>>>>    #define __INTEL_PXP_TYPES_H__
>>>>>>>>>      #include <linux/completion.h>
>>>>>>>>> +#include <linux/list.h>
>>>>>>>>>    #include <linux/types.h>
>>>>>>>>>    #include <linux/mutex.h>
>>>>>>>>> +#include <linux/spinlock.h>
>>>>>>>>>    #include <linux/workqueue.h>
>>>>>>>>>      struct intel_context;
>>>>>>>>> @@ -28,6 +30,9 @@ struct intel_pxp {
>>>>>>>>>        struct work_struct irq_work;
>>>>>>>>>        bool irq_enabled;
>>>>>>>>>        u32 current_events; /* protected with gt->irq_lock */
>>>>>>>>> +
>>>>>>>>> +    struct spinlock lock;
>>>>>>>>> +    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 9ebe8523aa0c..0f8b771a6d53 100644
>>>>>>>>> --- a/include/uapi/drm/i915_drm.h
>>>>>>>>> +++ b/include/uapi/drm/i915_drm.h
>>>>>>>>> @@ -1753,6 +1753,28 @@ struct drm_i915_gem_object_param {
>>>>>>>>>     */
>>>>>>>>>    #define I915_OBJECT_PARAM  (1ull << 32)
>>>>>>>>>    +/*
>>>>>>>>> + * I915_OBJECT_PARAM_PROTECTED_CONTENT:
>>>>>>>>> + *
>>>>>>>>> + * If set to true, buffer contents is expected
>>>>>>>>> to be protected by PXP
>>>>>>>>> + * encryption and requires decryption for scan
>>>>>>>>> out and processing. This is
>>>>>>>>> + * only possible on platforms that have PXP
>>>>>>>>> enabled, on all other scenarios
>>>>>>>>> + * setting this flag will cause the ioctl to
>>>>>>>>> fail and return -ENODEV.
>>>>>>>>> + *
>>>>>>>>> + * Protected buffers can only be used with
>>>>>>>>> contexts created using the
>>>>>>>>> + * I915_CONTEXT_PARAM_PROTECTED_CONTENT flag.
>>>>>>>>> The buffer contents are
>>>>>>>>> + * considered invalid after a PXP session teardown.
>>>>>>>>> + *
>>>>>>>>> + * Given the restriction above, the following
>>>>>>>>> errors are possible when
>>>>>>>>> + * submitting a protected object in an execbuf call:
>>>>>>>>> + *
>>>>>>>>> + * -ENODEV: PXP session not currently active
>>>>>>>>> + * -EIO: buffer has become invalid after a teardown event
>>>>>>>>> + * -EPERM: buffer submitted using a context not
>>>>>>>>> marked as protected
>>>>>>>>> + */
>>>>>>>>> +#define I915_OBJECT_PARAM_PROTECTED_CONTENT  0x0
>>>>>>>>> +/* Must be kept compact -- no holes and well documented */
>>>>>>>>> +
>>>>>>>>>        __u64 param;
>>>>>>>>>          /* Data value or pointer */
>>>>>>>>
>>> _______________________________________________
>>> Intel-gfx mailing list
>>> Intel-gfx@lists.freedesktop.org
>>> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/intel-gfx


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

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

* Re: [Intel-gfx] [PATCH v2 13/16] drm/i915/pxp: User interface for Protected buffer
  2021-03-08 21:01                   ` Lionel Landwerlin
@ 2021-03-08 21:54                     ` Daniele Ceraolo Spurio
  0 siblings, 0 replies; 47+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-03-08 21:54 UTC (permalink / raw)
  To: Lionel Landwerlin, Rodrigo Vivi, joonas.lahtinen, Joonas Lahtinen
  Cc: Bommu Krishnaiah, intel-gfx, Huang Sean Z, Chris Wilson,
	Kondapally Kalyan



On 3/8/2021 1:01 PM, Lionel Landwerlin wrote:
> On 08/03/2021 22:40, Rodrigo Vivi wrote:
>> On Wed, Mar 03, 2021 at 05:24:34PM -0800, Daniele Ceraolo Spurio wrote:
>>>
>>> On 3/3/2021 4:10 PM, Daniele Ceraolo Spurio wrote:
>>>>
>>>> On 3/3/2021 3:42 PM, Lionel Landwerlin wrote:
>>>>> On 04/03/2021 01:25, Daniele Ceraolo Spurio wrote:
>>>>>>
>>>>>> On 3/3/2021 3:16 PM, Lionel Landwerlin wrote:
>>>>>>> On 03/03/2021 23:59, Daniele Ceraolo Spurio wrote:
>>>>>>>>
>>>>>>>> On 3/3/2021 12:39 PM, Lionel Landwerlin wrote:
>>>>>>>>> On 01/03/2021 21:31, Daniele Ceraolo Spurio wrote:
>>>>>>>>>> From: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
>>>>>>>>>>
>>>>>>>>>> This api allow user mode to create Protected buffers. Only 
>>>>>>>>>> contexts
>>>>>>>>>> marked as protected are allowed to operate on protected buffers.
>>>>>>>>>>
>>>>>>>>>> We only allow setting the flags at creation time.
>>>>>>>>>>
>>>>>>>>>> All protected objects that have backing storage will be 
>>>>>>>>>> considered
>>>>>>>>>> invalid when the session is destroyed and they
>>>>>>>>>> won't be usable anymore.
>>>>>>>>>>
>>>>>>>>>> This is a rework of the original code by Bommu Krishnaiah. I've
>>>>>>>>>> authorship unchanged since significant chunks
>>>>>>>>>> have not been modified.
>>>>>>>>>>
>>>>>>>>>> v2: split context changes, fix defines and
>>>>>>>>>> improve documentation (Chris),
>>>>>>>>>>       add object invalidation logic
>>>>>>>>>>
>>>>>>>>>> Signed-off-by: Bommu Krishnaiah <krishnaiah.bommu@intel.com>
>>>>>>>>>> Signed-off-by: Daniele Ceraolo Spurio
>>>>>>>>>> <daniele.ceraolospurio@intel.com>
>>>>>>>>>> Cc: Telukuntla Sreedhar <sreedhar.telukuntla@intel.com>
>>>>>>>>>> Cc: Kondapally Kalyan <kalyan.kondapally@intel.com>
>>>>>>>>>> Cc: Gupta Anshuman <Anshuman.Gupta@intel.com>
>>>>>>>>>> Cc: Huang Sean Z <sean.z.huang@intel.com>
>>>>>>>>>> Cc: Chris Wilson <chris@chris-wilson.co.uk>
>>>>>>>>>> ---
>>>>>>>>>>    drivers/gpu/drm/i915/gem/i915_gem_create.c | 27 +++++++++++--
>>>>>>>>>>    .../gpu/drm/i915/gem/i915_gem_execbuffer.c | 10 +++++
>>>>>>>>>>    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 | 13 ++++++
>>>>>>>>>>    drivers/gpu/drm/i915/pxp/intel_pxp.c
>>>>>>>>>> | 40 +++++++++++++++++++
>>>>>>>>>>    drivers/gpu/drm/i915/pxp/intel_pxp.h | 13 ++++++
>>>>>>>>>>    drivers/gpu/drm/i915/pxp/intel_pxp_types.h |  5 +++
>>>>>>>>>>    include/uapi/drm/i915_drm.h | 22 ++++++++++
>>>>>>>>>>    9 files changed, 145 insertions(+), 3 deletions(-)
>>>>>>>>>>
>>>>>>>>>> diff --git
>>>>>>>>>> a/drivers/gpu/drm/i915/gem/i915_gem_create.c
>>>>>>>>>> b/drivers/gpu/drm/i915/gem/i915_gem_create.c
>>>>>>>>>> index 3ad3413c459f..d02e5938afbe 100644
>>>>>>>>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_create.c
>>>>>>>>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c
>>>>>>>>>> @@ -5,6 +5,7 @@
>>>>>>>>>>      #include "gem/i915_gem_ioctls.h"
>>>>>>>>>>    #include "gem/i915_gem_region.h"
>>>>>>>>>> +#include "pxp/intel_pxp.h"
>>>>>>>>>>      #include "i915_drv.h"
>>>>>>>>>>    #include "i915_user_extensions.h"
>>>>>>>>>> @@ -13,7 +14,8 @@ static int
>>>>>>>>>>    i915_gem_create(struct drm_file *file,
>>>>>>>>>>            struct intel_memory_region *mr,
>>>>>>>>>>            u64 *size_p,
>>>>>>>>>> -        u32 *handle_p)
>>>>>>>>>> +        u32 *handle_p,
>>>>>>>>>> +        u64 user_flags)
>>>>>>>>>>    {
>>>>>>>>>>        struct drm_i915_gem_object *obj;
>>>>>>>>>>        u32 handle;
>>>>>>>>>> @@ -35,12 +37,17 @@ i915_gem_create(struct drm_file *file,
>>>>>>>>>>          GEM_BUG_ON(size != obj->base.size);
>>>>>>>>>>    +    obj->user_flags = user_flags;
>>>>>>>>>> +
>>>>>>>>>>        ret = drm_gem_handle_create(file, &obj->base, &handle);
>>>>>>>>>>        /* drop reference from allocate - handle holds it now */
>>>>>>>>>>        i915_gem_object_put(obj);
>>>>>>>>>>        if (ret)
>>>>>>>>>>            return ret;
>>>>>>>>>>    +    if (user_flags & I915_GEM_OBJECT_PROTECTED)
>>>>>>>>>> +        intel_pxp_object_add(obj);
>>>>>>>>>> +
>>>>>>>>>>        *handle_p = handle;
>>>>>>>>>>        *size_p = size;
>>>>>>>>>>        return 0;
>>>>>>>>>> @@ -89,11 +96,12 @@ i915_gem_dumb_create(struct drm_file *file,
>>>>>>>>>>        return i915_gem_create(file,
>>>>>>>>>> intel_memory_region_by_type(to_i915(dev),
>>>>>>>>>>                                   mem_type),
>>>>>>>>>> -                   &args->size, &args->handle);
>>>>>>>>>> +                   &args->size, &args->handle, 0);
>>>>>>>>>>    }
>>>>>>>>>>      struct create_ext {
>>>>>>>>>>        struct drm_i915_private *i915;
>>>>>>>>>> +    unsigned long user_flags;
>>>>>>>>>>    };
>>>>>>>>>>      static int __create_setparam(struct
>>>>>>>>>> drm_i915_gem_object_param *args,
>>>>>>>>>> @@ -104,6 +112,19 @@ static int
>>>>>>>>>> __create_setparam(struct
>>>>>>>>>> drm_i915_gem_object_param *args,
>>>>>>>>>>            return -EINVAL;
>>>>>>>>>>        }
>>>>>>>>>>    +    switch (lower_32_bits(args->param)) {
>>>>>>>>>> +    case I915_OBJECT_PARAM_PROTECTED_CONTENT:
>>>>>>>>>> +        if (!intel_pxp_is_enabled(&ext_data->i915->gt.pxp))
>>>>>>>>>> +            return -ENODEV;
>>>>>>>>>> +        if (args->size) {
>>>>>>>>>> +            return -EINVAL;
>>>>>>>>>> +        } else if (args->data) {
>>>>>>>>>> +            ext_data->user_flags |= I915_GEM_OBJECT_PROTECTED;
>>>>>>>>>> +            return 0;
>>>>>>>>>> +        }
>>>>>>>>>> +    break;
>>>>>>>>>> +    }
>>>>>>>>>> +
>>>>>>>>>>        return -EINVAL;
>>>>>>>>>>    }
>>>>>>>>>>    @@ -148,5 +169,5 @@
>>>>>>>>>> i915_gem_create_ioctl(struct drm_device *dev,
>>>>>>>>>> void *data,
>>>>>>>>>>        return i915_gem_create(file,
>>>>>>>>>> intel_memory_region_by_type(i915,
>>>>>>>>>> INTEL_MEMORY_SYSTEM),
>>>>>>>>>> -                   &args->size, &args->handle);
>>>>>>>>>> +                   &args->size, &args->handle,
>>>>>>>>>> ext_data.user_flags);
>>>>>>>>>>    }
>>>>>>>>>> diff --git
>>>>>>>>>> a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>>>>>>>>>> b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>>>>>>>>>> index e503c9f789c0..d10c4fcb6aec 100644
>>>>>>>>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>>>>>>>>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
>>>>>>>>>> @@ -20,6 +20,7 @@
>>>>>>>>>>    #include "gt/intel_gt_buffer_pool.h"
>>>>>>>>>>    #include "gt/intel_gt_pm.h"
>>>>>>>>>>    #include "gt/intel_ring.h"
>>>>>>>>>> +#include "pxp/intel_pxp.h"
>>>>>>>>>>      #include "pxp/intel_pxp.h"
>>>>>>>>>>    @@ -500,6 +501,15 @@ eb_validate_vma(struct 
>>>>>>>>>> i915_execbuffer *eb,
>>>>>>>>>>                 entry->offset !=
>>>>>>>>>> gen8_canonical_addr(entry->offset &
>>>>>>>>>> I915_GTT_PAGE_MASK)))
>>>>>>>>>>            return -EINVAL;
>>>>>>>>>>    +    if (i915_gem_object_is_protected(vma->obj)) {
>>>>>>>>>> +        if (!intel_pxp_is_active(&vma->vm->gt->pxp))
>>>>>>>>>> +            return -ENODEV;
>>>>>>>>>> +        if (!i915_gem_object_has_valid_protection(vma->obj))
>>>>>>>>>> +            return -EIO;
>>>>>>>>>> +        if
>>>>>>>>>> (!i915_gem_context_can_use_protected_content(eb->gem_context))
>>>>>>>>>> +            return -EPERM;
>>>>>>>>>
>>>>>>>>> I think I'm running into this error.
>>>>>>>> The currently agreed design is that protected objects
>>>>>>>> can only be used with explicitly marked contexts,
>>>>>>>> although it's not an HW requirement so we can revisit
>>>>>>>> it.
>>>>>>>>
>>>>>>>>> When running vkcube protected under wayland, it
>>>>>>>>> takes down the entire session (Xorg & gnome-shell
>>>>>>>>> depending on which one is going to use the protected
>>>>>>>>> buffer first).
>>>>>>>> Are you saying that a single submission failure takes
>>>>>>>> down the entire gnome session? that sounds like a larger
>>>>>>>> problem than just this failure. Or am I misunderstanding
>>>>>>>> your point?
>>>>>>>
>>>>>>> We just need to hand that buffer to any other app and have
>>>>>>> it use it in execbuf and that will make it fail the execbuf.
>>>>>>>
>>>>>>> Now how does the driver in the gnome-shell/Xorg process know
>>>>>>> what went wrong and what buffer caused it?
>>>>>>>
>>>>>>> Could be any imported buffer. It's pretty hard to recover
>>>>>>> from this and most apps will just crash if the driver starts
>>>>>>> to fail for some reason.
>>>>>>>
>>>>>>> You can see how that could make a lot of people's live terrible :/
>>>>>> Don't other apps have to know that the buffer is encrypted to
>>>>>> use it properly? Or is there a case where we want to use the
>>>>>> object as if it wasn't encrypted?
>>>>>>
>>>>>> Also, PXP submissions can become invalid at any point in time
>>>>>> due to a teardown event, which causes the contents of the
>>>>>> encrypted buffers to become garbage. If we can't fail the
>>>>>> execbuf which includes an invalidated buffer we'd have to
>>>>>> silently discard the submission.
>>>>>
>>>>> A malicious app could start sharing protected tagged buffer with no
>>>>> protected content in it, just to invalidate/crash others apps'
>>>>> context.
>>>> I see your point, although on the other side failing the execbuf when
>>>> malicious behavior is detected seems reasonable as well.
>>>>
>>>>> Can the failure be only reported to protected contexts?
>>>> That would allow a non-protected context to use protected objects, 
>>>> which
>>>> is something we wanted to avoid.
>>>> I see a few options here:
>>>>
>>>> - live with the execbuf failure on incorrect or malicious behavior
>> could you please expand this option a bit further?

This is basically leaving things as they are now in this series.

>> Based on the scenario that Lionel described I'm not feeling this is 
>> viable...
>>
>>>> - silently fail execbuf if protected objects are used with 
>>>> non-protected
>>>> contexts
>> I don't like to simply silent to ignore the execbuf with no indication.
>> How userspace will know it needs to resubmit the job?
>
>
> A normal/unprotected context wouldn't resubmit anyway because it 
> wouldn't have the logic the handle this case.
>
> Initially I thought that the failure would only appear on protected 
> contexts, because they want to present protected content properly and 
> so if anything goes wrong in the protected flow, they need to know.
>

The problem with only failing on protected contexts is that an app 
could, maliciously or erroneously, use an unprotected context to do 
protected operations (no restriction on that at the HW level), which 
would make tracking and banning protected submissions more complicated.

>
> But an application like gnome-shell/Xorg should probably not be 
> affected if they don't support protected content.
>
>
> -Lionel
>
>
>>
>>>> - remove the restriction on protected objects being usable only by
>>>> protected contexts
>>>>
>>>> Rodrigo, Joonas, any preference or other suggestion here?
>>>>
>>> BTW, whatever we decide has to also consider the other failure cases 
>>> in the
>>> check above:
>>> - pxp not active, i.e. termination in progress
>>> - invalid buffer (encrypted using old keys)
>> yeap. That's the case on the current design.
>>
>> Is an option to save that "token" with buffers and contexts?
>>

This still wouldn't help with the scenario Lionel described, where an 
app is unknowingly provided a protected or invalid buffer to use. No 
matter how we save or check it, the open is still if we want to allow 
that invalid submission or reject it.

Daniele

>> Joonas?
>>
>>> Both of those could currently cause an execbuf failure even if we 
>>> ignore the
>>> protected context restriction, which IMO makes the third option 
>>> above not
>>> viable.
>>>
>>> Daniele
>>>
>>>> Daniele
>>>>
>>>>>
>>>>> -Lionel
>>>>>
>>>>>
>>>>>> Daniele
>>>>>>
>>>>>>>
>>>>>>> -Lionel
>>>>>>>
>>>>>>>
>>>>>>>>> That's a bit harsh.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> We probably don't want this. After all the point of
>>>>>>>>> encryption is that even if you can read the buffer
>>>>>>>>> you won't be able to make much of its content.
>>>>>>>> As mentioned above we can change this since there is no
>>>>>>>> HW requirement on contexts, but need some architectural
>>>>>>>> agreement. Joonas and Rodrigo can comment more here.
>>>>>>>> Also note that submitting an instruction using encrypted
>>>>>>>> data while the session is invalid can cause the HW to
>>>>>>>> hang, which is part of the reason why we require the
>>>>>>>> contexts using protected objects to be marked
>>>>>>>> appropriately, so we can ban them on PXP teardown to
>>>>>>>> avoid hangs.
>>>>>>>>
>>>>>>>> Daniele
>>>>>>>>
>>>>>>>>> Also useful to know you're dealing for debugging ;)
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> -Lionel
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>> +    }
>>>>>>>>>> +
>>>>>>>>>>        /* pad_to_size was once a reserved field, so sanitize 
>>>>>>>>>> it */
>>>>>>>>>>        if (entry->flags & EXEC_OBJECT_PAD_TO_SIZE) {
>>>>>>>>>>            if (unlikely(offset_in_page(entry->pad_to_size)))
>>>>>>>>>> diff --git
>>>>>>>>>> a/drivers/gpu/drm/i915/gem/i915_gem_object.c
>>>>>>>>>> b/drivers/gpu/drm/i915/gem/i915_gem_object.c
>>>>>>>>>> index 6cdff5fc5882..b321f5484ae6 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"
>>>>>>>>>> @@ -72,6 +73,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;
>>>>>>>>>>    @@ -120,6 +123,9 @@ static void
>>>>>>>>>> i915_gem_close_object(struct drm_gem_object
>>>>>>>>>> *gem, struct drm_file *f
>>>>>>>>>>        struct i915_lut_handle *lut, *ln;
>>>>>>>>>>        LIST_HEAD(close);
>>>>>>>>>>    +    if (i915_gem_object_has_valid_protection(obj))
>>>>>>>>>> +        intel_pxp_object_remove(obj);
>>>>>>>>>> +
>>>>>>>>>>        spin_lock(&obj->lut_lock);
>>>>>>>>>>        list_for_each_entry_safe(lut, ln, &obj->lut_list, 
>>>>>>>>>> obj_link) {
>>>>>>>>>>            struct i915_gem_context *ctx = lut->ctx;
>>>>>>>>>> diff --git
>>>>>>>>>> a/drivers/gpu/drm/i915/gem/i915_gem_object.h
>>>>>>>>>> b/drivers/gpu/drm/i915/gem/i915_gem_object.h
>>>>>>>>>> index 366d23afbb1a..a1fa7539c0f7 100644
>>>>>>>>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h
>>>>>>>>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h
>>>>>>>>>> @@ -274,6 +274,18 @@
>>>>>>>>>> i915_gem_object_needs_async_cancel(const struct
>>>>>>>>>> drm_i915_gem_object *obj)
>>>>>>>>>>        return i915_gem_object_type_has(obj,
>>>>>>>>>> I915_GEM_OBJECT_ASYNC_CANCEL);
>>>>>>>>>>    }
>>>>>>>>>>    +static inline bool
>>>>>>>>>> +i915_gem_object_is_protected(const struct
>>>>>>>>>> drm_i915_gem_object *obj)
>>>>>>>>>> +{
>>>>>>>>>> +    return obj->user_flags & I915_GEM_OBJECT_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_is_framebuffer(const struct
>>>>>>>>>> drm_i915_gem_object *obj)
>>>>>>>>>>    {
>>>>>>>>>> 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 0a1fdbac882e..6eee580c7aba 100644
>>>>>>>>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
>>>>>>>>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h
>>>>>>>>>> @@ -167,6 +167,11 @@ struct drm_i915_gem_object {
>>>>>>>>>>        } mmo;
>>>>>>>>>>          I915_SELFTEST_DECLARE(struct list_head st_link);
>>>>>>>>>> +    /**
>>>>>>>>>> +     * @user_flags: small set of booleans set by the user
>>>>>>>>>> +     */
>>>>>>>>>> +    unsigned long user_flags;
>>>>>>>>>> +#define I915_GEM_OBJECT_PROTECTED BIT(0)
>>>>>>>>>>          unsigned long flags;
>>>>>>>>>>    #define I915_BO_ALLOC_CONTIGUOUS BIT(0)
>>>>>>>>>> @@ -290,6 +295,14 @@ struct drm_i915_gem_object {
>>>>>>>>>>            bool dirty:1;
>>>>>>>>>>        } mm;
>>>>>>>>>>    +    /*
>>>>>>>>>> +     * 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 5912e4a12d94..03151cd7f4b8 100644
>>>>>>>>>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
>>>>>>>>>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
>>>>>>>>>> @@ -69,6 +69,8 @@ void intel_pxp_init(struct intel_pxp *pxp)
>>>>>>>>>>            return;
>>>>>>>>>>          mutex_init(&pxp->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,
>>>>>>>>>> @@ -136,11 +138,49 @@ int
>>>>>>>>>> intel_pxp_wait_for_termination_completion(struct
>>>>>>>>>> intel_pxp *pxp)
>>>>>>>>>>        return ret;
>>>>>>>>>>    }
>>>>>>>>>>    +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) {
>>>>>>>>>> diff --git
>>>>>>>>>> a/drivers/gpu/drm/i915/pxp/intel_pxp.h
>>>>>>>>>> b/drivers/gpu/drm/i915/pxp/intel_pxp.h
>>>>>>>>>> index e36200833095..3315b07d271b 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;
>>>>>>>>>> +
>>>>>>>>>>    #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)
>>>>>>>>>> @@ -38,6 +40,9 @@ void intel_pxp_init(struct intel_pxp *pxp);
>>>>>>>>>>    void intel_pxp_fini(struct intel_pxp *pxp);
>>>>>>>>>>      int
>>>>>>>>>> intel_pxp_wait_for_termination_completion(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)
>>>>>>>>>> @@ -52,6 +57,14 @@ static inline int
>>>>>>>>>> intel_pxp_wait_for_termination_completion(struct
>>>>>>>>>> intel_pxp *px
>>>>>>>>>>    {
>>>>>>>>>>        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_types.h
>>>>>>>>>> b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
>>>>>>>>>> index 6f659a6f8f1c..53a2a8acfe51 100644
>>>>>>>>>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
>>>>>>>>>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
>>>>>>>>>> @@ -7,8 +7,10 @@
>>>>>>>>>>    #define __INTEL_PXP_TYPES_H__
>>>>>>>>>>      #include <linux/completion.h>
>>>>>>>>>> +#include <linux/list.h>
>>>>>>>>>>    #include <linux/types.h>
>>>>>>>>>>    #include <linux/mutex.h>
>>>>>>>>>> +#include <linux/spinlock.h>
>>>>>>>>>>    #include <linux/workqueue.h>
>>>>>>>>>>      struct intel_context;
>>>>>>>>>> @@ -28,6 +30,9 @@ struct intel_pxp {
>>>>>>>>>>        struct work_struct irq_work;
>>>>>>>>>>        bool irq_enabled;
>>>>>>>>>>        u32 current_events; /* protected with gt->irq_lock */
>>>>>>>>>> +
>>>>>>>>>> +    struct spinlock lock;
>>>>>>>>>> +    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 9ebe8523aa0c..0f8b771a6d53 100644
>>>>>>>>>> --- a/include/uapi/drm/i915_drm.h
>>>>>>>>>> +++ b/include/uapi/drm/i915_drm.h
>>>>>>>>>> @@ -1753,6 +1753,28 @@ struct drm_i915_gem_object_param {
>>>>>>>>>>     */
>>>>>>>>>>    #define I915_OBJECT_PARAM  (1ull << 32)
>>>>>>>>>>    +/*
>>>>>>>>>> + * I915_OBJECT_PARAM_PROTECTED_CONTENT:
>>>>>>>>>> + *
>>>>>>>>>> + * If set to true, buffer contents is expected
>>>>>>>>>> to be protected by PXP
>>>>>>>>>> + * encryption and requires decryption for scan
>>>>>>>>>> out and processing. This is
>>>>>>>>>> + * only possible on platforms that have PXP
>>>>>>>>>> enabled, on all other scenarios
>>>>>>>>>> + * setting this flag will cause the ioctl to
>>>>>>>>>> fail and return -ENODEV.
>>>>>>>>>> + *
>>>>>>>>>> + * Protected buffers can only be used with
>>>>>>>>>> contexts created using the
>>>>>>>>>> + * I915_CONTEXT_PARAM_PROTECTED_CONTENT flag.
>>>>>>>>>> The buffer contents are
>>>>>>>>>> + * considered invalid after a PXP session teardown.
>>>>>>>>>> + *
>>>>>>>>>> + * Given the restriction above, the following
>>>>>>>>>> errors are possible when
>>>>>>>>>> + * submitting a protected object in an execbuf call:
>>>>>>>>>> + *
>>>>>>>>>> + * -ENODEV: PXP session not currently active
>>>>>>>>>> + * -EIO: buffer has become invalid after a teardown event
>>>>>>>>>> + * -EPERM: buffer submitted using a context not
>>>>>>>>>> marked as protected
>>>>>>>>>> + */
>>>>>>>>>> +#define I915_OBJECT_PARAM_PROTECTED_CONTENT 0x0
>>>>>>>>>> +/* Must be kept compact -- no holes and well documented */
>>>>>>>>>> +
>>>>>>>>>>        __u64 param;
>>>>>>>>>>          /* Data value or pointer */
>>>>>>>>>
>>>> _______________________________________________
>>>> Intel-gfx mailing list
>>>> Intel-gfx@lists.freedesktop.org
>>>> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
>>> _______________________________________________
>>> Intel-gfx mailing list
>>> Intel-gfx@lists.freedesktop.org
>>> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
>

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

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

* Re: [Intel-gfx] [PATCH v2 09/16] drm/i915/pxp: Implement PXP irq handler
  2021-03-03 22:42   ` Chris Wilson
@ 2021-03-25 21:52     ` Daniele Ceraolo Spurio
  0 siblings, 0 replies; 47+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-03-25 21:52 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx



On 3/3/2021 2:42 PM, Chris Wilson wrote:
> Quoting Daniele Ceraolo Spurio (2021-03-01 19:31:53)
>> 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.
> Why do we do the auto recreation after the teardown interrupt?

Just realized I forgot to reply to this. The current design is for the 
arb session to always be running when the device is awake.
We could potentially refcount it via active protected objects, but 
that'll make the flow more complicated.

Daniele

>
>> v2: use struct completion instead of bool (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>
>> ---
>>   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         |  34 +++++
>>   drivers/gpu/drm/i915/pxp/intel_pxp.h         |  16 ++
>>   drivers/gpu/drm/i915/pxp/intel_pxp_irq.c     | 151 +++++++++++++++++++
>>   drivers/gpu/drm/i915/pxp/intel_pxp_irq.h     |  33 ++++
>>   drivers/gpu/drm/i915/pxp/intel_pxp_session.c |   9 +-
>>   drivers/gpu/drm/i915/pxp/intel_pxp_session.h |   1 +
>>   drivers/gpu/drm/i915/pxp/intel_pxp_tee.c     |  10 +-
>>   drivers/gpu/drm/i915/pxp/intel_pxp_types.h   |   8 +
>>   11 files changed, 268 insertions(+), 3 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 8b605f326039..5e9bd34dec38 100644
>> --- a/drivers/gpu/drm/i915/Makefile
>> +++ b/drivers/gpu/drm/i915/Makefile
>> @@ -274,6 +274,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 d29126c458ba..0d3585efe2b8 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);
>>   }
>> @@ -190,6 +194,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 e5dd0203991b..97a6d0c638ec 100644
>> --- a/drivers/gpu/drm/i915/i915_reg.h
>> +++ b/drivers/gpu/drm/i915/i915_reg.h
>> @@ -7958,6 +7958,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 cbec9395bde9..0ca1c2c16972 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_tee.h"
>>   #include "gt/intel_context.h"
>>   #include "i915_drv.h"
>> @@ -67,12 +69,23 @@ void intel_pxp_init(struct intel_pxp *pxp)
>>   
>>          mutex_init(&pxp->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);
>> +
>>          kcr_pxp_enable(gt);
>>   
>>          ret = create_vcs_context(pxp);
>>          if (ret)
>>                  goto out_kcr;
>>   
>> +       intel_pxp_irq_init(pxp);
>> +       intel_pxp_irq_enable(pxp);
>> +
>>          ret = intel_pxp_tee_component_init(pxp);
>>          if (ret)
>>                  goto out_context;
>> @@ -94,10 +107,31 @@ void intel_pxp_fini(struct intel_pxp *pxp)
>>          if (!intel_pxp_is_enabled(pxp))
>>                  return;
>>   
>> +       intel_pxp_irq_disable(pxp);
>> +
>>          intel_pxp_tee_component_fini(pxp);
>>   
>>          destroy_vcs_context(pxp);
>>   
>>          kcr_pxp_disable(gt);
>> +}
>>   
>> +int intel_pxp_wait_for_termination_completion(struct intel_pxp *pxp)
>> +{
>> +       int ret;
>> +
>> +       if (!intel_pxp_is_enabled(pxp))
>> +               return 0;
>> +
>> +       ret = wait_for_completion_timeout(&pxp->termination,
>> +                                         msecs_to_jiffies(100));
>> +
>> +       /* the wait returns 0 on failure */
>> +       if (ret)
>> +               ret = 0;
>> +       else
>> +               ret = -ETIMEDOUT;
>> +
>> +       return ret;
>>   }
>> +
>> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h b/drivers/gpu/drm/i915/pxp/intel_pxp.h
>> index 3bede9306481..89cf66c9bef3 100644
>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
>> @@ -9,6 +9,15 @@
>>   #include "gt/intel_gt_types.h"
>>   #include "intel_pxp_types.h"
>>   
>> +#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)
>> +
>>   static inline struct intel_gt *pxp_to_gt(const struct intel_pxp *pxp)
>>   {
>>          return container_of(pxp, struct intel_gt, pxp);
>> @@ -27,6 +36,8 @@ static inline bool intel_pxp_is_active(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);
>> +
>> +int intel_pxp_wait_for_termination_completion(struct intel_pxp *pxp);
>>   #else
>>   static inline void intel_pxp_init(struct intel_pxp *pxp)
>>   {
>> @@ -35,6 +46,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_termination_completion(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..40115bf0b6bb
>> --- /dev/null
>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
>> @@ -0,0 +1,151 @@
>> +// 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"
>> +
>> +static int pxp_terminate(struct intel_pxp *pxp)
>> +{
>> +       int ret = 0;
>> +
>> +       mutex_lock(&pxp->mutex);
>> +
>> +       pxp->global_state_attacked = true;
>> +
>> +       ret = intel_pxp_arb_terminate_session_with_global_terminate(pxp);
>> +
>> +       mutex_unlock(&pxp->mutex);
>> +
>> +       return ret;
>> +}
>> +
>> +static int pxp_terminate_complete(struct intel_pxp *pxp)
>> +{
>> +       int ret = 0;
>> +
>> +       mutex_lock(&pxp->mutex);
>> +
>> +       if (pxp->global_state_attacked) {
>> +               pxp->global_state_attacked = false;
>> +
>> +               /* Re-create the arb session after teardown handle complete */
>> +               ret = intel_pxp_create_arb_session(pxp);
>> +       }
>> +
>> +       mutex_unlock(&pxp->mutex);
>> +
>> +       complete_all(&pxp->termination);
>> +
>> +       return ret;
>> +}
>> +
>> +static void intel_pxp_irq_work(struct work_struct *work)
>> +{
>> +       struct intel_pxp *pxp = container_of(work, typeof(*pxp), irq_work);
>> +       struct intel_gt *gt = pxp_to_gt(pxp);
>> +       u32 events = 0;
>> +
>> +       spin_lock_irq(&gt->irq_lock);
>> +       events = fetch_and_zero(&pxp->current_events);
>> +       spin_unlock_irq(&gt->irq_lock);
>> +
>> +       if (!events)
>> +               return;
>> +
>> +       if (events & (GEN12_DISPLAY_PXP_STATE_TERMINATED_INTERRUPT |
>> +                     GEN12_DISPLAY_APP_TERMINATED_PER_FW_REQ_INTERRUPT))
>> +               pxp_terminate(pxp);
>> +
>> +       if (events & GEN12_DISPLAY_STATE_RESET_COMPLETE_INTERRUPT)
>> +               pxp_terminate_complete(pxp);
>> +
>> +       /*
>> +        * we expect the terminate complete to arrive quickly after emitting
>> +        * the terminate, so check back on it
>> +        */
>> +       if (pxp->irq_enabled)
>> +               queue_work(system_unbound_wq, &pxp->irq_work);
>> +}
>> +
>> +/**
>> + * 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;
>> +
>> +       /* immediately mark PXP as inactive on termination */
>> +       if (iir & (GEN12_DISPLAY_PXP_STATE_TERMINATED_INTERRUPT |
>> +                  GEN12_DISPLAY_APP_TERMINATED_PER_FW_REQ_INTERRUPT))
>> +               intel_pxp_mark_termination_in_progress(pxp);
>> +
>> +       pxp->current_events |= iir;
>> +       queue_work(system_unbound_wq, &pxp->irq_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_init(struct intel_pxp *pxp)
>> +{
>> +       INIT_WORK(&pxp->irq_work, intel_pxp_irq_work);
>> +}
>> +
>> +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);
>> +
>> +       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->irq_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..7a875831636d
>> --- /dev/null
>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.h
>> @@ -0,0 +1,33 @@
>> +/* 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;
>> +
>> +#ifdef CONFIG_DRM_I915_PXP
>> +void intel_pxp_irq_init(struct intel_pxp *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
>> +void intel_pxp_irq_init(struct intel_pxp *pxp)
>> +{
>> +}
>> +void intel_pxp_irq_enable(struct intel_pxp *pxp)
>> +{
>> +}
>> +void intel_pxp_irq_disable(struct intel_pxp *pxp)
>> +{
>> +}
>> +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 ddbfac75686a..488006a0cf39 100644
>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
>> @@ -99,8 +99,6 @@ int intel_pxp_arb_terminate_session_with_global_terminate(struct intel_pxp *pxp)
>>   
>>          lockdep_assert_held(&pxp->mutex);
>>   
>> -       pxp->arb_is_in_play = false;
>> -
>>          /* terminate the hw sessions */
>>          ret = intel_pxp_submit_session_termination(pxp, ARB_SESSION);
>>          if (ret) {
>> @@ -118,3 +116,10 @@ int intel_pxp_arb_terminate_session_with_global_terminate(struct intel_pxp *pxp)
>>   
>>          return ret;
>>   }
>> +
>> +void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp)
>> +{
>> +       pxp->arb_is_in_play = false;
>> +       reinit_completion(&pxp->termination);
>> +}
>> +
>> diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.h b/drivers/gpu/drm/i915/pxp/intel_pxp_session.h
>> index 07c97df7a509..931169f795ab 100644
>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.h
>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.h
>> @@ -13,5 +13,6 @@ struct intel_pxp;
>>   bool intel_pxp_arb_session_is_in_play(struct intel_pxp *pxp);
>>   int intel_pxp_create_arb_session(struct intel_pxp *pxp);
>>   int intel_pxp_arb_terminate_session_with_global_terminate(struct intel_pxp *pxp);
>> +void intel_pxp_mark_termination_in_progress(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 fd9a69248dd8..b84f675c588e 100644
>> --- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
>> +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
>> @@ -99,9 +99,17 @@ static int i915_pxp_tee_component_bind(struct device *i915_kdev,
>>          mutex_lock(&pxp->mutex);
>>   
>>          /* Create arb session only if tee is ready, during system boot or sleep/resume */
>> -       if (intel_pxp_arb_session_is_in_play(pxp))
>> +       if (intel_pxp_arb_session_is_in_play(pxp)) {
>> +               intel_pxp_mark_termination_in_progress(pxp);
>>                  ret = intel_pxp_arb_terminate_session_with_global_terminate(pxp);
>>   
>> +               if (!ret) {
>> +                       mutex_unlock(&pxp->mutex);
>> +                       ret = intel_pxp_wait_for_termination_completion(pxp);
>> +                       mutex_lock(&pxp->mutex);
> * shivers
>
> This does not give off warm fuzzy feeling about the locking.
> It's clear why you had to drop the lock to avoid blocking the interrupt
> bh (the worker), but it's not actually clear that the locking needs to
> be like that.
>
> Oh well, s/if/while/ to cover the lock dropping.
> -Chris

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

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

end of thread, other threads:[~2021-03-25 21:52 UTC | newest]

Thread overview: 47+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-01 19:31 [Intel-gfx] [PATCH v2 00/16] Introduce Intel PXP Daniele Ceraolo Spurio
2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 01/16] drm/i915/pxp: Define PXP component interface Daniele Ceraolo Spurio
2021-03-03 19:51   ` Rodrigo Vivi
2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 02/16] mei: pxp: export pavp client to me client bus Daniele Ceraolo Spurio
2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 03/16] drm/i915/pxp: define PXP device flag and kconfig Daniele Ceraolo Spurio
2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 04/16] drm/i915/pxp: allocate a vcs context for pxp usage Daniele Ceraolo Spurio
2021-03-03 22:17   ` Chris Wilson
2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 05/16] drm/i915/pxp: set KCR reg init during the boot time Daniele Ceraolo Spurio
2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 06/16] drm/i915/pxp: Implement funcs to create the TEE channel Daniele Ceraolo Spurio
2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 07/16] drm/i915/pxp: Create the arbitrary session after boot Daniele Ceraolo Spurio
2021-03-03 22:08   ` Chris Wilson
2021-03-04  0:18     ` Daniele Ceraolo Spurio
2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 08/16] drm/i915/pxp: Implement arb session teardown Daniele Ceraolo Spurio
2021-03-03 22:04   ` Chris Wilson
2021-03-04  0:29     ` Daniele Ceraolo Spurio
2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 09/16] drm/i915/pxp: Implement PXP irq handler Daniele Ceraolo Spurio
2021-03-03 21:18   ` Chris Wilson
2021-03-08 18:49     ` Daniele Ceraolo Spurio
2021-03-03 22:42   ` Chris Wilson
2021-03-25 21:52     ` Daniele Ceraolo Spurio
2021-03-03 22:45   ` Chris Wilson
2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 10/16] drm/i915/pxp: Enable PXP power management Daniele Ceraolo Spurio
2021-03-03 22:52   ` Chris Wilson
2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 11/16] drm/i915/pxp: interface for creation of protected contexts Daniele Ceraolo Spurio
2021-03-03 23:16   ` Chris Wilson
2021-03-08 18:32     ` Daniele Ceraolo Spurio
2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 12/16] drm/i915/uapi: introduce drm_i915_gem_create_ext Daniele Ceraolo Spurio
2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 13/16] drm/i915/pxp: User interface for Protected buffer Daniele Ceraolo Spurio
2021-03-03 20:39   ` Lionel Landwerlin
2021-03-03 21:59     ` Daniele Ceraolo Spurio
2021-03-03 23:16       ` Lionel Landwerlin
2021-03-03 23:25         ` Daniele Ceraolo Spurio
2021-03-03 23:42           ` Lionel Landwerlin
2021-03-04  0:10             ` Daniele Ceraolo Spurio
2021-03-04  1:24               ` Daniele Ceraolo Spurio
2021-03-08 20:40                 ` Rodrigo Vivi
2021-03-08 21:01                   ` Lionel Landwerlin
2021-03-08 21:54                     ` Daniele Ceraolo Spurio
2021-03-03 23:33   ` Chris Wilson
2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 14/16] drm/i915/pxp: Add plane decryption support Daniele Ceraolo Spurio
2021-03-01 19:31 ` [Intel-gfx] [PATCH v2 15/16] drm/i915/pxp: black pixels on pxp disabled Daniele Ceraolo Spurio
2021-03-01 19:32 ` [Intel-gfx] [PATCH v2 16/16] drm/i915/pxp: enable PXP for integrated Gen12 Daniele Ceraolo Spurio
2021-03-03 19:56   ` Rodrigo Vivi
2021-03-01 20:00 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for Introduce Intel PXP (rev2) Patchwork
2021-03-01 20:01 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2021-03-01 20:28 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2021-03-01 20:35 ` [Intel-gfx] ✓ Fi.CI.IGT: " Patchwork

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).