linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/3] Locality support for tpm_crb
@ 2016-12-03 17:52 Jarkko Sakkinen
  2016-12-03 17:52 ` [PATCH v2 1/3] tpm_crb: map locality registers Jarkko Sakkinen
                   ` (3 more replies)
  0 siblings, 4 replies; 18+ messages in thread
From: Jarkko Sakkinen @ 2016-12-03 17:52 UTC (permalink / raw)
  To: Peter Huewe
  Cc: Jarkko Sakkinen, Jason Gunthorpe, open list,
	moderated list:TPM DEVICE DRIVER

The tpm_crb driver should follow the policy of reserving and
relinquishing the locality it uses when multiple localities are used,
like when TXT is another locality.

Jarkko Sakkinen (3):
  tpm_crb: map locality registers
  tpm_crb: encapsulate crb_wait_for_reg_32
  tpm_crb: request and relinquish locality 0

 drivers/char/tpm/tpm_crb.c | 159 ++++++++++++++++++++++++++++++---------------
 1 file changed, 106 insertions(+), 53 deletions(-)

-- 
v2: added sanity check for start address of the control area
2.9.3

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

* [PATCH v2 1/3] tpm_crb: map locality registers
  2016-12-03 17:52 [PATCH v2 0/3] Locality support for tpm_crb Jarkko Sakkinen
@ 2016-12-03 17:52 ` Jarkko Sakkinen
  2016-12-03 18:41   ` Jarkko Sakkinen
  2016-12-03 17:52 ` [PATCH v2 2/3] tpm_crb: encapsulate crb_wait_for_reg_32 Jarkko Sakkinen
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 18+ messages in thread
From: Jarkko Sakkinen @ 2016-12-03 17:52 UTC (permalink / raw)
  To: Peter Huewe
  Cc: Jarkko Sakkinen, Marcel Selhorst, Jason Gunthorpe,
	moderated list:TPM DEVICE DRIVER, open list

In order to provide access to locality registers, this commits adds
mapping of the head of the CRB registers, which are located right
before the control area.

Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
---
 drivers/char/tpm/tpm_crb.c | 96 ++++++++++++++++++++++++++++++----------------
 1 file changed, 64 insertions(+), 32 deletions(-)

diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
index 717b6b4..8d81b66 100644
--- a/drivers/char/tpm/tpm_crb.c
+++ b/drivers/char/tpm/tpm_crb.c
@@ -52,18 +52,28 @@ enum crb_cancel {
 	CRB_CANCEL_INVOKE	= BIT(0),
 };
 
-struct crb_control_area {
-	u32 req;
-	u32 sts;
-	u32 cancel;
-	u32 start;
-	u32 int_enable;
-	u32 int_sts;
-	u32 cmd_size;
-	u32 cmd_pa_low;
-	u32 cmd_pa_high;
-	u32 rsp_size;
-	u64 rsp_pa;
+struct crb_regs_head {
+	u32 loc_state;
+	u32 reserved1;
+	u32 loc_ctrl;
+	u32 loc_sts;
+	u8 reserved2[32];
+	u64 intf_id;
+	u64 ctrl_ext;
+} __packed;
+
+struct crb_regs_tail {
+	u32 ctrl_req;
+	u32 ctrl_sts;
+	u32 ctrl_cancel;
+	u32 ctrl_start;
+	u32 ctrl_int_enable;
+	u32 ctrl_int_sts;
+	u32 ctrl_cmd_size;
+	u32 ctrl_cmd_pa_low;
+	u32 ctrl_cmd_pa_high;
+	u32 ctrl_rsp_size;
+	u64 ctrl_rsp_pa;
 } __packed;
 
 enum crb_status {
@@ -78,7 +88,8 @@ enum crb_flags {
 struct crb_priv {
 	unsigned int flags;
 	void __iomem *iobase;
-	struct crb_control_area __iomem *cca;
+	struct crb_regs_head __iomem *regs_h;
+	struct crb_regs_tail __iomem *regs_t;
 	u8 __iomem *cmd;
 	u8 __iomem *rsp;
 	u32 cmd_size;
@@ -104,7 +115,7 @@ static int __maybe_unused crb_go_idle(struct device *dev, struct crb_priv *priv)
 	if (priv->flags & CRB_FL_ACPI_START)
 		return 0;
 
-	iowrite32(CRB_CTRL_REQ_GO_IDLE, &priv->cca->req);
+	iowrite32(CRB_CTRL_REQ_GO_IDLE, &priv->regs_t->ctrl_req);
 	/* we don't really care when this settles */
 
 	return 0;
@@ -128,21 +139,23 @@ static int __maybe_unused crb_cmd_ready(struct device *dev,
 					struct crb_priv *priv)
 {
 	ktime_t stop, start;
+	u32 req;
 
 	if (priv->flags & CRB_FL_ACPI_START)
 		return 0;
 
-	iowrite32(CRB_CTRL_REQ_CMD_READY, &priv->cca->req);
+	iowrite32(CRB_CTRL_REQ_CMD_READY, &priv->regs_t->ctrl_req);
 
 	start = ktime_get();
 	stop = ktime_add(start, ms_to_ktime(TPM2_TIMEOUT_C));
 	do {
-		if (!(ioread32(&priv->cca->req) & CRB_CTRL_REQ_CMD_READY))
+		req = ioread32(&priv->regs_t->ctrl_req);
+		if (!(req & CRB_CTRL_REQ_CMD_READY))
 			return 0;
 		usleep_range(50, 100);
 	} while (ktime_before(ktime_get(), stop));
 
-	if (ioread32(&priv->cca->req) & CRB_CTRL_REQ_CMD_READY) {
+	if (ioread32(&priv->regs_t->ctrl_req) & CRB_CTRL_REQ_CMD_READY) {
 		dev_warn(dev, "cmdReady timed out\n");
 		return -ETIME;
 	}
@@ -155,7 +168,7 @@ static u8 crb_status(struct tpm_chip *chip)
 	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
 	u8 sts = 0;
 
-	if ((ioread32(&priv->cca->start) & CRB_START_INVOKE) !=
+	if ((ioread32(&priv->regs_t->ctrl_start) & CRB_START_INVOKE) !=
 	    CRB_START_INVOKE)
 		sts |= CRB_DRV_STS_COMPLETE;
 
@@ -171,7 +184,7 @@ static int crb_recv(struct tpm_chip *chip, u8 *buf, size_t count)
 	if (count < 6)
 		return -EIO;
 
-	if (ioread32(&priv->cca->sts) & CRB_CTRL_STS_ERROR)
+	if (ioread32(&priv->regs_t->ctrl_sts) & CRB_CTRL_STS_ERROR)
 		return -EIO;
 
 	memcpy_fromio(buf, priv->rsp, 6);
@@ -210,7 +223,7 @@ static int crb_send(struct tpm_chip *chip, u8 *buf, size_t len)
 	/* Zero the cancel register so that the next command will not get
 	 * canceled.
 	 */
-	iowrite32(0, &priv->cca->cancel);
+	iowrite32(0, &priv->regs_t->ctrl_cancel);
 
 	if (len > priv->cmd_size) {
 		dev_err(&chip->dev, "invalid command count value %zd %d\n",
@@ -224,7 +237,7 @@ static int crb_send(struct tpm_chip *chip, u8 *buf, size_t len)
 	wmb();
 
 	if (priv->flags & CRB_FL_CRB_START)
-		iowrite32(CRB_START_INVOKE, &priv->cca->start);
+		iowrite32(CRB_START_INVOKE, &priv->regs_t->ctrl_start);
 
 	if (priv->flags & CRB_FL_ACPI_START)
 		rc = crb_do_acpi_start(chip);
@@ -236,7 +249,7 @@ static void crb_cancel(struct tpm_chip *chip)
 {
 	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
 
-	iowrite32(CRB_CANCEL_INVOKE, &priv->cca->cancel);
+	iowrite32(CRB_CANCEL_INVOKE, &priv->regs_t->ctrl_cancel);
 
 	if ((priv->flags & CRB_FL_ACPI_START) && crb_do_acpi_start(chip))
 		dev_err(&chip->dev, "ACPI Start failed\n");
@@ -245,7 +258,7 @@ static void crb_cancel(struct tpm_chip *chip)
 static bool crb_req_canceled(struct tpm_chip *chip, u8 status)
 {
 	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
-	u32 cancel = ioread32(&priv->cca->cancel);
+	u32 cancel = ioread32(&priv->regs_t->ctrl_cancel);
 
 	return (cancel & CRB_CANCEL_INVOKE) == CRB_CANCEL_INVOKE;
 }
@@ -287,6 +300,8 @@ static void __iomem *crb_map_res(struct device *dev, struct crb_priv *priv,
 	if (start != new_res.start)
 		return (void __iomem *) ERR_PTR(-EINVAL);
 
+	dev_dbg(dev, "%pr %pr", io_res, &new_res);
+
 	if (!resource_contains(io_res, &new_res))
 		return devm_ioremap_resource(dev, &new_res);
 
@@ -322,10 +337,27 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv,
 	if (IS_ERR(priv->iobase))
 		return PTR_ERR(priv->iobase);
 
-	priv->cca = crb_map_res(dev, priv, &io_res, buf->control_address,
-				sizeof(struct crb_control_area));
-	if (IS_ERR(priv->cca))
-		return PTR_ERR(priv->cca);
+	/* The ACPI IO region starts at the head area and continues to include
+	 * the control area, as one nice sane region except for some older
+	 * stuff that puts the control area outside the ACPI IO region.
+	 */
+	if (!(priv->flags & CRB_FL_ACPI_START)) {
+		if (buf->control_address == io_res.start +
+		    sizeof(struct crb_regs_head)) {
+			priv->regs_h = crb_map_res(
+				dev, priv, &io_res, io_res.start,
+				sizeof(struct crb_regs_head));
+			if (IS_ERR(priv->regs_h))
+				return PTR_ERR(priv->regs_h);
+		} else {
+			dev_warn(dev, FW_BUG "Bad ACPI memory layout");
+		}
+	}
+
+	priv->regs_t = crb_map_res(dev, priv, &io_res, buf->control_address,
+				   sizeof(struct crb_regs_tail));
+	if (IS_ERR(priv->regs_t))
+		return PTR_ERR(priv->regs_t);
 
 	/*
 	 * PTT HW bug w/a: wake up the device to access
@@ -335,10 +367,10 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv,
 	if (ret)
 		return ret;
 
-	pa_high = ioread32(&priv->cca->cmd_pa_high);
-	pa_low  = ioread32(&priv->cca->cmd_pa_low);
+	pa_high = ioread32(&priv->regs_t->ctrl_cmd_pa_high);
+	pa_low  = ioread32(&priv->regs_t->ctrl_cmd_pa_low);
 	cmd_pa = ((u64)pa_high << 32) | pa_low;
-	cmd_size = ioread32(&priv->cca->cmd_size);
+	cmd_size = ioread32(&priv->regs_t->ctrl_cmd_size);
 
 	dev_dbg(dev, "cmd_hi = %X cmd_low = %X cmd_size %X\n",
 		pa_high, pa_low, cmd_size);
@@ -349,9 +381,9 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv,
 		goto out;
 	}
 
-	memcpy_fromio(&rsp_pa, &priv->cca->rsp_pa, 8);
+	memcpy_fromio(&rsp_pa, &priv->regs_t->ctrl_rsp_pa, 8);
 	rsp_pa = le64_to_cpu(rsp_pa);
-	rsp_size = ioread32(&priv->cca->rsp_size);
+	rsp_size = ioread32(&priv->regs_t->ctrl_rsp_size);
 
 	if (cmd_pa != rsp_pa) {
 		priv->rsp = crb_map_res(dev, priv, &io_res, rsp_pa, rsp_size);
-- 
2.9.3

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

* [PATCH v2 2/3] tpm_crb: encapsulate crb_wait_for_reg_32
  2016-12-03 17:52 [PATCH v2 0/3] Locality support for tpm_crb Jarkko Sakkinen
  2016-12-03 17:52 ` [PATCH v2 1/3] tpm_crb: map locality registers Jarkko Sakkinen
@ 2016-12-03 17:52 ` Jarkko Sakkinen
  2016-12-03 18:41   ` Jarkko Sakkinen
  2016-12-03 17:52 ` [PATCH v2 3/3] tpm_crb: request and relinquish locality 0 Jarkko Sakkinen
  2016-12-03 18:40 ` [PATCH v2 0/3] Locality support for tpm_crb Jarkko Sakkinen
  3 siblings, 1 reply; 18+ messages in thread
From: Jarkko Sakkinen @ 2016-12-03 17:52 UTC (permalink / raw)
  To: Peter Huewe
  Cc: Jarkko Sakkinen, Marcel Selhorst, Jason Gunthorpe,
	moderated list:TPM DEVICE DRIVER, open list

Encapsulated crb_wait_for_reg32() so that state changes in other CRB
registers than TPM_CRB_CTRL_REQ_x can be waited.

Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
---
 drivers/char/tpm/tpm_crb.c | 37 +++++++++++++++++++++++--------------
 1 file changed, 23 insertions(+), 14 deletions(-)

diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
index 8d81b66..f986d02 100644
--- a/drivers/char/tpm/tpm_crb.c
+++ b/drivers/char/tpm/tpm_crb.c
@@ -121,6 +121,25 @@ static int __maybe_unused crb_go_idle(struct device *dev, struct crb_priv *priv)
 	return 0;
 }
 
+static bool crb_wait_for_reg_32(u32 __iomem *reg, u32 mask, u32 value,
+				unsigned long timeout)
+{
+	ktime_t start;
+	ktime_t stop;
+
+	start = ktime_get();
+	stop = ktime_add(start, ms_to_ktime(timeout));
+
+	do {
+		if ((ioread32(reg) & mask) == value)
+			return true;
+
+		usleep_range(50, 100);
+	} while (ktime_before(ktime_get(), stop));
+
+	return false;
+}
+
 /**
  * crb_cmd_ready - request tpm crb device to enter ready state
  *
@@ -138,24 +157,14 @@ static int __maybe_unused crb_go_idle(struct device *dev, struct crb_priv *priv)
 static int __maybe_unused crb_cmd_ready(struct device *dev,
 					struct crb_priv *priv)
 {
-	ktime_t stop, start;
-	u32 req;
-
 	if (priv->flags & CRB_FL_ACPI_START)
 		return 0;
 
 	iowrite32(CRB_CTRL_REQ_CMD_READY, &priv->regs_t->ctrl_req);
-
-	start = ktime_get();
-	stop = ktime_add(start, ms_to_ktime(TPM2_TIMEOUT_C));
-	do {
-		req = ioread32(&priv->regs_t->ctrl_req);
-		if (!(req & CRB_CTRL_REQ_CMD_READY))
-			return 0;
-		usleep_range(50, 100);
-	} while (ktime_before(ktime_get(), stop));
-
-	if (ioread32(&priv->regs_t->ctrl_req) & CRB_CTRL_REQ_CMD_READY) {
+	if (!crb_wait_for_reg_32(&priv->regs_t->ctrl_req,
+				 CRB_CTRL_REQ_CMD_READY /* mask */,
+				 0, /* value */
+				 TPM2_TIMEOUT_C)) {
 		dev_warn(dev, "cmdReady timed out\n");
 		return -ETIME;
 	}
-- 
2.9.3

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

* [PATCH v2 3/3] tpm_crb: request and relinquish locality 0
  2016-12-03 17:52 [PATCH v2 0/3] Locality support for tpm_crb Jarkko Sakkinen
  2016-12-03 17:52 ` [PATCH v2 1/3] tpm_crb: map locality registers Jarkko Sakkinen
  2016-12-03 17:52 ` [PATCH v2 2/3] tpm_crb: encapsulate crb_wait_for_reg_32 Jarkko Sakkinen
@ 2016-12-03 17:52 ` Jarkko Sakkinen
  2016-12-03 18:42   ` Jarkko Sakkinen
  2016-12-05 16:32   ` Jason Gunthorpe
  2016-12-03 18:40 ` [PATCH v2 0/3] Locality support for tpm_crb Jarkko Sakkinen
  3 siblings, 2 replies; 18+ messages in thread
From: Jarkko Sakkinen @ 2016-12-03 17:52 UTC (permalink / raw)
  To: Peter Huewe
  Cc: Jarkko Sakkinen, Marcel Selhorst, Jason Gunthorpe,
	moderated list:TPM DEVICE DRIVER, open list

Request and relinquish locality for the driver use in order to be
a better citizen in a multi locality environment like TXT. The
locality is requested and relinquished as part of going into and
waking up from idle.

Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
---
 drivers/char/tpm/tpm_crb.c | 36 ++++++++++++++++++++++++------------
 1 file changed, 24 insertions(+), 12 deletions(-)

diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
index f986d02..f6e0beb 100644
--- a/drivers/char/tpm/tpm_crb.c
+++ b/drivers/char/tpm/tpm_crb.c
@@ -34,6 +34,15 @@ enum crb_defaults {
 	CRB_ACPI_START_INDEX = 1,
 };
 
+enum crb_loc_ctrl {
+	CRB_LOC_CTRL_REQUEST_ACCESS	= BIT(0),
+	CRB_LOC_CTRL_RELINQUISH		= BIT(1),
+};
+
+enum crb_loc_state {
+	CRB_LOC_STATE_LOC_ASSIGNED	= BIT(1),
+};
+
 enum crb_ctrl_req {
 	CRB_CTRL_REQ_CMD_READY	= BIT(0),
 	CRB_CTRL_REQ_GO_IDLE	= BIT(1),
@@ -101,12 +110,8 @@ struct crb_priv {
  * @dev:  crb device
  * @priv: crb private data
  *
- * Write CRB_CTRL_REQ_GO_IDLE to TPM_CRB_CTRL_REQ
- * The device should respond within TIMEOUT_C by clearing the bit.
- * Anyhow, we do not wait here as a consequent CMD_READY request
- * will be handled correctly even if idle was not completed.
- *
- * The function does nothing for devices with ACPI-start method.
+ * Put device to the idle state and relinquish locality. The function does
+ * nothing for devices with the ACPI-start method.
  *
  * Return: 0 always
  */
@@ -115,6 +120,7 @@ static int __maybe_unused crb_go_idle(struct device *dev, struct crb_priv *priv)
 	if (priv->flags & CRB_FL_ACPI_START)
 		return 0;
 
+	iowrite32(CRB_LOC_CTRL_RELINQUISH, &priv->regs_h->loc_ctrl);
 	iowrite32(CRB_CTRL_REQ_GO_IDLE, &priv->regs_t->ctrl_req);
 	/* we don't really care when this settles */
 
@@ -146,11 +152,8 @@ static bool crb_wait_for_reg_32(u32 __iomem *reg, u32 mask, u32 value,
  * @dev:  crb device
  * @priv: crb private data
  *
- * Write CRB_CTRL_REQ_CMD_READY to TPM_CRB_CTRL_REQ
- * and poll till the device acknowledge it by clearing the bit.
- * The device should respond within TIMEOUT_C.
- *
- * The function does nothing for devices with ACPI-start method
+ * Try to wake up the device and request locality. The function does nothing
+ * for devices with the ACPI-start method.
  *
  * Return: 0 on success -ETIME on timeout;
  */
@@ -165,7 +168,16 @@ static int __maybe_unused crb_cmd_ready(struct device *dev,
 				 CRB_CTRL_REQ_CMD_READY /* mask */,
 				 0, /* value */
 				 TPM2_TIMEOUT_C)) {
-		dev_warn(dev, "cmdReady timed out\n");
+		dev_warn(dev, "TPM_CRB_CTRL_REQ_x.cmdReady timed out\n");
+		return -ETIME;
+	}
+
+	iowrite32(CRB_LOC_CTRL_REQUEST_ACCESS, &priv->regs_h->loc_ctrl);
+	if (!crb_wait_for_reg_32(&priv->regs_h->loc_state,
+				 CRB_LOC_STATE_LOC_ASSIGNED, /* mask */
+				 CRB_LOC_STATE_LOC_ASSIGNED, /* value */
+				 TPM2_TIMEOUT_C)) {
+		dev_warn(dev, "TPM_LOC_STATE_x.requestAccess timed out\n");
 		return -ETIME;
 	}
 
-- 
2.9.3

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

* Re: [PATCH v2 0/3] Locality support for tpm_crb
  2016-12-03 17:52 [PATCH v2 0/3] Locality support for tpm_crb Jarkko Sakkinen
                   ` (2 preceding siblings ...)
  2016-12-03 17:52 ` [PATCH v2 3/3] tpm_crb: request and relinquish locality 0 Jarkko Sakkinen
@ 2016-12-03 18:40 ` Jarkko Sakkinen
  3 siblings, 0 replies; 18+ messages in thread
From: Jarkko Sakkinen @ 2016-12-03 18:40 UTC (permalink / raw)
  To: Peter Huewe
  Cc: Jason Gunthorpe, open list, moderated list:TPM DEVICE DRIVER,
	linux-security-module

CC linux-security-module

On Sat, Dec 03, 2016 at 07:52:10PM +0200, Jarkko Sakkinen wrote:
> The tpm_crb driver should follow the policy of reserving and
> relinquishing the locality it uses when multiple localities are used,
> like when TXT is another locality.
> 
> Jarkko Sakkinen (3):
>   tpm_crb: map locality registers
>   tpm_crb: encapsulate crb_wait_for_reg_32
>   tpm_crb: request and relinquish locality 0
> 
>  drivers/char/tpm/tpm_crb.c | 159 ++++++++++++++++++++++++++++++---------------
>  1 file changed, 106 insertions(+), 53 deletions(-)
> 
> -- 
> v2: added sanity check for start address of the control area
> 2.9.3
> 

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

* Re: [PATCH v2 1/3] tpm_crb: map locality registers
  2016-12-03 17:52 ` [PATCH v2 1/3] tpm_crb: map locality registers Jarkko Sakkinen
@ 2016-12-03 18:41   ` Jarkko Sakkinen
  2016-12-05 12:07     ` [tpmdd-devel] " Winkler, Tomas
  0 siblings, 1 reply; 18+ messages in thread
From: Jarkko Sakkinen @ 2016-12-03 18:41 UTC (permalink / raw)
  To: Peter Huewe
  Cc: Marcel Selhorst, Jason Gunthorpe,
	moderated list:TPM DEVICE DRIVER, open list,
	linux-security-module

CC linux-security-module

On Sat, Dec 03, 2016 at 07:52:11PM +0200, Jarkko Sakkinen wrote:
> In order to provide access to locality registers, this commits adds
> mapping of the head of the CRB registers, which are located right
> before the control area.
> 
> Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
> ---
>  drivers/char/tpm/tpm_crb.c | 96 ++++++++++++++++++++++++++++++----------------
>  1 file changed, 64 insertions(+), 32 deletions(-)
> 
> diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
> index 717b6b4..8d81b66 100644
> --- a/drivers/char/tpm/tpm_crb.c
> +++ b/drivers/char/tpm/tpm_crb.c
> @@ -52,18 +52,28 @@ enum crb_cancel {
>  	CRB_CANCEL_INVOKE	= BIT(0),
>  };
>  
> -struct crb_control_area {
> -	u32 req;
> -	u32 sts;
> -	u32 cancel;
> -	u32 start;
> -	u32 int_enable;
> -	u32 int_sts;
> -	u32 cmd_size;
> -	u32 cmd_pa_low;
> -	u32 cmd_pa_high;
> -	u32 rsp_size;
> -	u64 rsp_pa;
> +struct crb_regs_head {
> +	u32 loc_state;
> +	u32 reserved1;
> +	u32 loc_ctrl;
> +	u32 loc_sts;
> +	u8 reserved2[32];
> +	u64 intf_id;
> +	u64 ctrl_ext;
> +} __packed;
> +
> +struct crb_regs_tail {
> +	u32 ctrl_req;
> +	u32 ctrl_sts;
> +	u32 ctrl_cancel;
> +	u32 ctrl_start;
> +	u32 ctrl_int_enable;
> +	u32 ctrl_int_sts;
> +	u32 ctrl_cmd_size;
> +	u32 ctrl_cmd_pa_low;
> +	u32 ctrl_cmd_pa_high;
> +	u32 ctrl_rsp_size;
> +	u64 ctrl_rsp_pa;
>  } __packed;
>  
>  enum crb_status {
> @@ -78,7 +88,8 @@ enum crb_flags {
>  struct crb_priv {
>  	unsigned int flags;
>  	void __iomem *iobase;
> -	struct crb_control_area __iomem *cca;
> +	struct crb_regs_head __iomem *regs_h;
> +	struct crb_regs_tail __iomem *regs_t;
>  	u8 __iomem *cmd;
>  	u8 __iomem *rsp;
>  	u32 cmd_size;
> @@ -104,7 +115,7 @@ static int __maybe_unused crb_go_idle(struct device *dev, struct crb_priv *priv)
>  	if (priv->flags & CRB_FL_ACPI_START)
>  		return 0;
>  
> -	iowrite32(CRB_CTRL_REQ_GO_IDLE, &priv->cca->req);
> +	iowrite32(CRB_CTRL_REQ_GO_IDLE, &priv->regs_t->ctrl_req);
>  	/* we don't really care when this settles */
>  
>  	return 0;
> @@ -128,21 +139,23 @@ static int __maybe_unused crb_cmd_ready(struct device *dev,
>  					struct crb_priv *priv)
>  {
>  	ktime_t stop, start;
> +	u32 req;
>  
>  	if (priv->flags & CRB_FL_ACPI_START)
>  		return 0;
>  
> -	iowrite32(CRB_CTRL_REQ_CMD_READY, &priv->cca->req);
> +	iowrite32(CRB_CTRL_REQ_CMD_READY, &priv->regs_t->ctrl_req);
>  
>  	start = ktime_get();
>  	stop = ktime_add(start, ms_to_ktime(TPM2_TIMEOUT_C));
>  	do {
> -		if (!(ioread32(&priv->cca->req) & CRB_CTRL_REQ_CMD_READY))
> +		req = ioread32(&priv->regs_t->ctrl_req);
> +		if (!(req & CRB_CTRL_REQ_CMD_READY))
>  			return 0;
>  		usleep_range(50, 100);
>  	} while (ktime_before(ktime_get(), stop));
>  
> -	if (ioread32(&priv->cca->req) & CRB_CTRL_REQ_CMD_READY) {
> +	if (ioread32(&priv->regs_t->ctrl_req) & CRB_CTRL_REQ_CMD_READY) {
>  		dev_warn(dev, "cmdReady timed out\n");
>  		return -ETIME;
>  	}
> @@ -155,7 +168,7 @@ static u8 crb_status(struct tpm_chip *chip)
>  	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
>  	u8 sts = 0;
>  
> -	if ((ioread32(&priv->cca->start) & CRB_START_INVOKE) !=
> +	if ((ioread32(&priv->regs_t->ctrl_start) & CRB_START_INVOKE) !=
>  	    CRB_START_INVOKE)
>  		sts |= CRB_DRV_STS_COMPLETE;
>  
> @@ -171,7 +184,7 @@ static int crb_recv(struct tpm_chip *chip, u8 *buf, size_t count)
>  	if (count < 6)
>  		return -EIO;
>  
> -	if (ioread32(&priv->cca->sts) & CRB_CTRL_STS_ERROR)
> +	if (ioread32(&priv->regs_t->ctrl_sts) & CRB_CTRL_STS_ERROR)
>  		return -EIO;
>  
>  	memcpy_fromio(buf, priv->rsp, 6);
> @@ -210,7 +223,7 @@ static int crb_send(struct tpm_chip *chip, u8 *buf, size_t len)
>  	/* Zero the cancel register so that the next command will not get
>  	 * canceled.
>  	 */
> -	iowrite32(0, &priv->cca->cancel);
> +	iowrite32(0, &priv->regs_t->ctrl_cancel);
>  
>  	if (len > priv->cmd_size) {
>  		dev_err(&chip->dev, "invalid command count value %zd %d\n",
> @@ -224,7 +237,7 @@ static int crb_send(struct tpm_chip *chip, u8 *buf, size_t len)
>  	wmb();
>  
>  	if (priv->flags & CRB_FL_CRB_START)
> -		iowrite32(CRB_START_INVOKE, &priv->cca->start);
> +		iowrite32(CRB_START_INVOKE, &priv->regs_t->ctrl_start);
>  
>  	if (priv->flags & CRB_FL_ACPI_START)
>  		rc = crb_do_acpi_start(chip);
> @@ -236,7 +249,7 @@ static void crb_cancel(struct tpm_chip *chip)
>  {
>  	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
>  
> -	iowrite32(CRB_CANCEL_INVOKE, &priv->cca->cancel);
> +	iowrite32(CRB_CANCEL_INVOKE, &priv->regs_t->ctrl_cancel);
>  
>  	if ((priv->flags & CRB_FL_ACPI_START) && crb_do_acpi_start(chip))
>  		dev_err(&chip->dev, "ACPI Start failed\n");
> @@ -245,7 +258,7 @@ static void crb_cancel(struct tpm_chip *chip)
>  static bool crb_req_canceled(struct tpm_chip *chip, u8 status)
>  {
>  	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
> -	u32 cancel = ioread32(&priv->cca->cancel);
> +	u32 cancel = ioread32(&priv->regs_t->ctrl_cancel);
>  
>  	return (cancel & CRB_CANCEL_INVOKE) == CRB_CANCEL_INVOKE;
>  }
> @@ -287,6 +300,8 @@ static void __iomem *crb_map_res(struct device *dev, struct crb_priv *priv,
>  	if (start != new_res.start)
>  		return (void __iomem *) ERR_PTR(-EINVAL);
>  
> +	dev_dbg(dev, "%pr %pr", io_res, &new_res);
> +
>  	if (!resource_contains(io_res, &new_res))
>  		return devm_ioremap_resource(dev, &new_res);
>  
> @@ -322,10 +337,27 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv,
>  	if (IS_ERR(priv->iobase))
>  		return PTR_ERR(priv->iobase);
>  
> -	priv->cca = crb_map_res(dev, priv, &io_res, buf->control_address,
> -				sizeof(struct crb_control_area));
> -	if (IS_ERR(priv->cca))
> -		return PTR_ERR(priv->cca);
> +	/* The ACPI IO region starts at the head area and continues to include
> +	 * the control area, as one nice sane region except for some older
> +	 * stuff that puts the control area outside the ACPI IO region.
> +	 */
> +	if (!(priv->flags & CRB_FL_ACPI_START)) {
> +		if (buf->control_address == io_res.start +
> +		    sizeof(struct crb_regs_head)) {
> +			priv->regs_h = crb_map_res(
> +				dev, priv, &io_res, io_res.start,
> +				sizeof(struct crb_regs_head));
> +			if (IS_ERR(priv->regs_h))
> +				return PTR_ERR(priv->regs_h);
> +		} else {
> +			dev_warn(dev, FW_BUG "Bad ACPI memory layout");
> +		}
> +	}
> +
> +	priv->regs_t = crb_map_res(dev, priv, &io_res, buf->control_address,
> +				   sizeof(struct crb_regs_tail));
> +	if (IS_ERR(priv->regs_t))
> +		return PTR_ERR(priv->regs_t);
>  
>  	/*
>  	 * PTT HW bug w/a: wake up the device to access
> @@ -335,10 +367,10 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv,
>  	if (ret)
>  		return ret;
>  
> -	pa_high = ioread32(&priv->cca->cmd_pa_high);
> -	pa_low  = ioread32(&priv->cca->cmd_pa_low);
> +	pa_high = ioread32(&priv->regs_t->ctrl_cmd_pa_high);
> +	pa_low  = ioread32(&priv->regs_t->ctrl_cmd_pa_low);
>  	cmd_pa = ((u64)pa_high << 32) | pa_low;
> -	cmd_size = ioread32(&priv->cca->cmd_size);
> +	cmd_size = ioread32(&priv->regs_t->ctrl_cmd_size);
>  
>  	dev_dbg(dev, "cmd_hi = %X cmd_low = %X cmd_size %X\n",
>  		pa_high, pa_low, cmd_size);
> @@ -349,9 +381,9 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv,
>  		goto out;
>  	}
>  
> -	memcpy_fromio(&rsp_pa, &priv->cca->rsp_pa, 8);
> +	memcpy_fromio(&rsp_pa, &priv->regs_t->ctrl_rsp_pa, 8);
>  	rsp_pa = le64_to_cpu(rsp_pa);
> -	rsp_size = ioread32(&priv->cca->rsp_size);
> +	rsp_size = ioread32(&priv->regs_t->ctrl_rsp_size);
>  
>  	if (cmd_pa != rsp_pa) {
>  		priv->rsp = crb_map_res(dev, priv, &io_res, rsp_pa, rsp_size);
> -- 
> 2.9.3
> 

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

* Re: [PATCH v2 2/3] tpm_crb: encapsulate crb_wait_for_reg_32
  2016-12-03 17:52 ` [PATCH v2 2/3] tpm_crb: encapsulate crb_wait_for_reg_32 Jarkko Sakkinen
@ 2016-12-03 18:41   ` Jarkko Sakkinen
  2016-12-05 21:34     ` [tpmdd-devel] " Winkler, Tomas
  0 siblings, 1 reply; 18+ messages in thread
From: Jarkko Sakkinen @ 2016-12-03 18:41 UTC (permalink / raw)
  To: Peter Huewe
  Cc: Marcel Selhorst, Jason Gunthorpe,
	moderated list:TPM DEVICE DRIVER, open list,
	linux-security-module

CC linux-security-module

On Sat, Dec 03, 2016 at 07:52:12PM +0200, Jarkko Sakkinen wrote:
> Encapsulated crb_wait_for_reg32() so that state changes in other CRB
> registers than TPM_CRB_CTRL_REQ_x can be waited.
> 
> Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
> ---
>  drivers/char/tpm/tpm_crb.c | 37 +++++++++++++++++++++++--------------
>  1 file changed, 23 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
> index 8d81b66..f986d02 100644
> --- a/drivers/char/tpm/tpm_crb.c
> +++ b/drivers/char/tpm/tpm_crb.c
> @@ -121,6 +121,25 @@ static int __maybe_unused crb_go_idle(struct device *dev, struct crb_priv *priv)
>  	return 0;
>  }
>  
> +static bool crb_wait_for_reg_32(u32 __iomem *reg, u32 mask, u32 value,
> +				unsigned long timeout)
> +{
> +	ktime_t start;
> +	ktime_t stop;
> +
> +	start = ktime_get();
> +	stop = ktime_add(start, ms_to_ktime(timeout));
> +
> +	do {
> +		if ((ioread32(reg) & mask) == value)
> +			return true;
> +
> +		usleep_range(50, 100);
> +	} while (ktime_before(ktime_get(), stop));
> +
> +	return false;
> +}
> +
>  /**
>   * crb_cmd_ready - request tpm crb device to enter ready state
>   *
> @@ -138,24 +157,14 @@ static int __maybe_unused crb_go_idle(struct device *dev, struct crb_priv *priv)
>  static int __maybe_unused crb_cmd_ready(struct device *dev,
>  					struct crb_priv *priv)
>  {
> -	ktime_t stop, start;
> -	u32 req;
> -
>  	if (priv->flags & CRB_FL_ACPI_START)
>  		return 0;
>  
>  	iowrite32(CRB_CTRL_REQ_CMD_READY, &priv->regs_t->ctrl_req);
> -
> -	start = ktime_get();
> -	stop = ktime_add(start, ms_to_ktime(TPM2_TIMEOUT_C));
> -	do {
> -		req = ioread32(&priv->regs_t->ctrl_req);
> -		if (!(req & CRB_CTRL_REQ_CMD_READY))
> -			return 0;
> -		usleep_range(50, 100);
> -	} while (ktime_before(ktime_get(), stop));
> -
> -	if (ioread32(&priv->regs_t->ctrl_req) & CRB_CTRL_REQ_CMD_READY) {
> +	if (!crb_wait_for_reg_32(&priv->regs_t->ctrl_req,
> +				 CRB_CTRL_REQ_CMD_READY /* mask */,
> +				 0, /* value */
> +				 TPM2_TIMEOUT_C)) {
>  		dev_warn(dev, "cmdReady timed out\n");
>  		return -ETIME;
>  	}
> -- 
> 2.9.3
> 

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

* Re: [PATCH v2 3/3] tpm_crb: request and relinquish locality 0
  2016-12-03 17:52 ` [PATCH v2 3/3] tpm_crb: request and relinquish locality 0 Jarkko Sakkinen
@ 2016-12-03 18:42   ` Jarkko Sakkinen
  2016-12-05 21:51     ` [tpmdd-devel] " Winkler, Tomas
  2016-12-05 16:32   ` Jason Gunthorpe
  1 sibling, 1 reply; 18+ messages in thread
From: Jarkko Sakkinen @ 2016-12-03 18:42 UTC (permalink / raw)
  To: Peter Huewe
  Cc: Marcel Selhorst, Jason Gunthorpe,
	moderated list:TPM DEVICE DRIVER, open list,
	linux-security-module

CC linux-security-module

On Sat, Dec 03, 2016 at 07:52:13PM +0200, Jarkko Sakkinen wrote:
> Request and relinquish locality for the driver use in order to be
> a better citizen in a multi locality environment like TXT. The
> locality is requested and relinquished as part of going into and
> waking up from idle.
> 
> Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
> ---
>  drivers/char/tpm/tpm_crb.c | 36 ++++++++++++++++++++++++------------
>  1 file changed, 24 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
> index f986d02..f6e0beb 100644
> --- a/drivers/char/tpm/tpm_crb.c
> +++ b/drivers/char/tpm/tpm_crb.c
> @@ -34,6 +34,15 @@ enum crb_defaults {
>  	CRB_ACPI_START_INDEX = 1,
>  };
>  
> +enum crb_loc_ctrl {
> +	CRB_LOC_CTRL_REQUEST_ACCESS	= BIT(0),
> +	CRB_LOC_CTRL_RELINQUISH		= BIT(1),
> +};
> +
> +enum crb_loc_state {
> +	CRB_LOC_STATE_LOC_ASSIGNED	= BIT(1),
> +};
> +
>  enum crb_ctrl_req {
>  	CRB_CTRL_REQ_CMD_READY	= BIT(0),
>  	CRB_CTRL_REQ_GO_IDLE	= BIT(1),
> @@ -101,12 +110,8 @@ struct crb_priv {
>   * @dev:  crb device
>   * @priv: crb private data
>   *
> - * Write CRB_CTRL_REQ_GO_IDLE to TPM_CRB_CTRL_REQ
> - * The device should respond within TIMEOUT_C by clearing the bit.
> - * Anyhow, we do not wait here as a consequent CMD_READY request
> - * will be handled correctly even if idle was not completed.
> - *
> - * The function does nothing for devices with ACPI-start method.
> + * Put device to the idle state and relinquish locality. The function does
> + * nothing for devices with the ACPI-start method.
>   *
>   * Return: 0 always
>   */
> @@ -115,6 +120,7 @@ static int __maybe_unused crb_go_idle(struct device *dev, struct crb_priv *priv)
>  	if (priv->flags & CRB_FL_ACPI_START)
>  		return 0;
>  
> +	iowrite32(CRB_LOC_CTRL_RELINQUISH, &priv->regs_h->loc_ctrl);
>  	iowrite32(CRB_CTRL_REQ_GO_IDLE, &priv->regs_t->ctrl_req);
>  	/* we don't really care when this settles */
>  
> @@ -146,11 +152,8 @@ static bool crb_wait_for_reg_32(u32 __iomem *reg, u32 mask, u32 value,
>   * @dev:  crb device
>   * @priv: crb private data
>   *
> - * Write CRB_CTRL_REQ_CMD_READY to TPM_CRB_CTRL_REQ
> - * and poll till the device acknowledge it by clearing the bit.
> - * The device should respond within TIMEOUT_C.
> - *
> - * The function does nothing for devices with ACPI-start method
> + * Try to wake up the device and request locality. The function does nothing
> + * for devices with the ACPI-start method.
>   *
>   * Return: 0 on success -ETIME on timeout;
>   */
> @@ -165,7 +168,16 @@ static int __maybe_unused crb_cmd_ready(struct device *dev,
>  				 CRB_CTRL_REQ_CMD_READY /* mask */,
>  				 0, /* value */
>  				 TPM2_TIMEOUT_C)) {
> -		dev_warn(dev, "cmdReady timed out\n");
> +		dev_warn(dev, "TPM_CRB_CTRL_REQ_x.cmdReady timed out\n");
> +		return -ETIME;
> +	}
> +
> +	iowrite32(CRB_LOC_CTRL_REQUEST_ACCESS, &priv->regs_h->loc_ctrl);
> +	if (!crb_wait_for_reg_32(&priv->regs_h->loc_state,
> +				 CRB_LOC_STATE_LOC_ASSIGNED, /* mask */
> +				 CRB_LOC_STATE_LOC_ASSIGNED, /* value */
> +				 TPM2_TIMEOUT_C)) {
> +		dev_warn(dev, "TPM_LOC_STATE_x.requestAccess timed out\n");
>  		return -ETIME;
>  	}
>  
> -- 
> 2.9.3
> 

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

* RE: [tpmdd-devel] [PATCH v2 1/3] tpm_crb: map locality registers
  2016-12-03 18:41   ` Jarkko Sakkinen
@ 2016-12-05 12:07     ` Winkler, Tomas
  2016-12-05 12:21       ` Jarkko Sakkinen
  0 siblings, 1 reply; 18+ messages in thread
From: Winkler, Tomas @ 2016-12-05 12:07 UTC (permalink / raw)
  To: Jarkko Sakkinen, Peter Huewe
  Cc: linux-security-module, moderated list:TPM DEVICE DRIVER, open list

> > ---
> >  drivers/char/tpm/tpm_crb.c | 96
> > ++++++++++++++++++++++++++++++----------------
> >  1 file changed, 64 insertions(+), 32 deletions(-)
> >
> > diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
> > index 717b6b4..8d81b66 100644
> > --- a/drivers/char/tpm/tpm_crb.c
> > +++ b/drivers/char/tpm/tpm_crb.c
> > @@ -52,18 +52,28 @@ enum crb_cancel {
> >  	CRB_CANCEL_INVOKE	= BIT(0),
> >  };
> >
> > -struct crb_control_area {
> > -	u32 req;
> > -	u32 sts;
> > -	u32 cancel;
> > -	u32 start;
> > -	u32 int_enable;
> > -	u32 int_sts;
> > -	u32 cmd_size;
> > -	u32 cmd_pa_low;
> > -	u32 cmd_pa_high;
> > -	u32 rsp_size;
> > -	u64 rsp_pa;
> > +struct crb_regs_head {
> > +	u32 loc_state;
> > +	u32 reserved1;
> > +	u32 loc_ctrl;
> > +	u32 loc_sts;
> > +	u8 reserved2[32];
> > +	u64 intf_id;
> > +	u64 ctrl_ext;
> > +} __packed;
> > +
> > +struct crb_regs_tail {
> > +	u32 ctrl_req;
> > +	u32 ctrl_sts;
> > +	u32 ctrl_cancel;
> > +	u32 ctrl_start;
> > +	u32 ctrl_int_enable;
> > +	u32 ctrl_int_sts;
> > +	u32 ctrl_cmd_size;
> > +	u32 ctrl_cmd_pa_low;
> > +	u32 ctrl_cmd_pa_high;
> > +	u32 ctrl_rsp_size;
> > +	u64 ctrl_rsp_pa;
> >  } __packed;


Now I wonder if using  traditional offsets wouldn't be cleaner solution.

> >  enum crb_status {
> > @@ -78,7 +88,8 @@ enum crb_flags {
> >  struct crb_priv {
> >  	unsigned int flags;
> >  	void __iomem *iobase;
> > -	struct crb_control_area __iomem *cca;
> > +	struct crb_regs_head __iomem *regs_h;
> > +	struct crb_regs_tail __iomem *regs_t;
Why just not leaving it cca, it's descriptive enough. 
> >  	u8 __iomem *cmd;
> >  	u8 __iomem *rsp;
> >  	u32 cmd_size;
> > @@ -104,7 +115,7 @@ static int __maybe_unused crb_go_idle(struct device
> *dev, struct crb_priv *priv)
> >  	if (priv->flags & CRB_FL_ACPI_START)
> >  		return 0;
> >
> > -	iowrite32(CRB_CTRL_REQ_GO_IDLE, &priv->cca->req);
> > +	iowrite32(CRB_CTRL_REQ_GO_IDLE, &priv->regs_t->ctrl_req);
> >  	/* we don't really care when this settles */
> >
> >  	return 0;
> > @@ -128,21 +139,23 @@ static int __maybe_unused crb_cmd_ready(struct
> device *dev,
> >  					struct crb_priv *priv)
> >  {
> >  	ktime_t stop, start;
> > +	u32 req;
> >
> >  	if (priv->flags & CRB_FL_ACPI_START)
> >  		return 0;
> >
> > -	iowrite32(CRB_CTRL_REQ_CMD_READY, &priv->cca->req);
> > +	iowrite32(CRB_CTRL_REQ_CMD_READY, &priv->regs_t->ctrl_req);
> >
> >  	start = ktime_get();
> >  	stop = ktime_add(start, ms_to_ktime(TPM2_TIMEOUT_C));
> >  	do {
> > -		if (!(ioread32(&priv->cca->req) &
> CRB_CTRL_REQ_CMD_READY))
> > +		req = ioread32(&priv->regs_t->ctrl_req);
> > +		if (!(req & CRB_CTRL_REQ_CMD_READY))
> >  			return 0;
> >  		usleep_range(50, 100);
> >  	} while (ktime_before(ktime_get(), stop));
> >
> > -	if (ioread32(&priv->cca->req) & CRB_CTRL_REQ_CMD_READY) {
> > +	if (ioread32(&priv->regs_t->ctrl_req) & CRB_CTRL_REQ_CMD_READY)
> {
> >  		dev_warn(dev, "cmdReady timed out\n");
> >  		return -ETIME;
> >  	}
> > @@ -155,7 +168,7 @@ static u8 crb_status(struct tpm_chip *chip)
> >  	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
> >  	u8 sts = 0;
> >
> > -	if ((ioread32(&priv->cca->start) & CRB_START_INVOKE) !=
> > +	if ((ioread32(&priv->regs_t->ctrl_start) & CRB_START_INVOKE) !=
> >  	    CRB_START_INVOKE)
> >  		sts |= CRB_DRV_STS_COMPLETE;
> >
> > @@ -171,7 +184,7 @@ static int crb_recv(struct tpm_chip *chip, u8 *buf,
> size_t count)
> >  	if (count < 6)
> >  		return -EIO;
> >
> > -	if (ioread32(&priv->cca->sts) & CRB_CTRL_STS_ERROR)
> > +	if (ioread32(&priv->regs_t->ctrl_sts) & CRB_CTRL_STS_ERROR)
> >  		return -EIO;
> >
> >  	memcpy_fromio(buf, priv->rsp, 6);
> > @@ -210,7 +223,7 @@ static int crb_send(struct tpm_chip *chip, u8 *buf,
> size_t len)
> >  	/* Zero the cancel register so that the next command will not get
> >  	 * canceled.
> >  	 */
> > -	iowrite32(0, &priv->cca->cancel);
> > +	iowrite32(0, &priv->regs_t->ctrl_cancel);
> >
> >  	if (len > priv->cmd_size) {
> >  		dev_err(&chip->dev, "invalid command count value %zd %d\n",
> @@
> > -224,7 +237,7 @@ static int crb_send(struct tpm_chip *chip, u8 *buf, size_t
> len)
> >  	wmb();
> >
> >  	if (priv->flags & CRB_FL_CRB_START)
> > -		iowrite32(CRB_START_INVOKE, &priv->cca->start);
> > +		iowrite32(CRB_START_INVOKE, &priv->regs_t->ctrl_start);
> >
> >  	if (priv->flags & CRB_FL_ACPI_START)
> >  		rc = crb_do_acpi_start(chip);
> > @@ -236,7 +249,7 @@ static void crb_cancel(struct tpm_chip *chip)  {
> >  	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
> >
> > -	iowrite32(CRB_CANCEL_INVOKE, &priv->cca->cancel);
> > +	iowrite32(CRB_CANCEL_INVOKE, &priv->regs_t->ctrl_cancel);
> >
> >  	if ((priv->flags & CRB_FL_ACPI_START) && crb_do_acpi_start(chip))
> >  		dev_err(&chip->dev, "ACPI Start failed\n"); @@ -245,7 +258,7
> @@
> > static void crb_cancel(struct tpm_chip *chip)  static bool
> > crb_req_canceled(struct tpm_chip *chip, u8 status)  {
> >  	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
> > -	u32 cancel = ioread32(&priv->cca->cancel);
> > +	u32 cancel = ioread32(&priv->regs_t->ctrl_cancel);
> >
> >  	return (cancel & CRB_CANCEL_INVOKE) == CRB_CANCEL_INVOKE;  }
> @@
> > -287,6 +300,8 @@ static void __iomem *crb_map_res(struct device *dev,
> struct crb_priv *priv,
> >  	if (start != new_res.start)
> >  		return (void __iomem *) ERR_PTR(-EINVAL);
> >
> > +	dev_dbg(dev, "%pr %pr", io_res, &new_res);
> > +
> >  	if (!resource_contains(io_res, &new_res))
> >  		return devm_ioremap_resource(dev, &new_res);
> >
> > @@ -322,10 +337,27 @@ static int crb_map_io(struct acpi_device *device,
> struct crb_priv *priv,
> >  	if (IS_ERR(priv->iobase))
> >  		return PTR_ERR(priv->iobase);
> >
> > -	priv->cca = crb_map_res(dev, priv, &io_res, buf->control_address,
> > -				sizeof(struct crb_control_area));
> > -	if (IS_ERR(priv->cca))
> > -		return PTR_ERR(priv->cca);
> > +	/* The ACPI IO region starts at the head area and continues to include
> > +	 * the control area, as one nice sane region except for some older
> > +	 * stuff that puts the control area outside the ACPI IO region.
> > +	 */

This is not by the spec, can you be more specific, what platforms has that behavior?

> > +	if (!(priv->flags & CRB_FL_ACPI_START)) {
> > +		if (buf->control_address == io_res.start +
> > +		    sizeof(struct crb_regs_head)) {
> > +			priv->regs_h = crb_map_res(
Why do you need to map this again it just same as iobase ? 
> > +				dev, priv, &io_res, io_res.start,
> > +				sizeof(struct crb_regs_head));
> > +			if (IS_ERR(priv->regs_h))
> > +				return PTR_ERR(priv->regs_h);
> > +		} else {
> > +			dev_warn(dev, FW_BUG "Bad ACPI memory layout");
> > +		}
> > +	}
> > +
> > +	priv->regs_t = crb_map_res(dev, priv, &io_res, buf->control_address,
> > +				   sizeof(struct crb_regs_tail));

> > +	if (IS_ERR(priv->regs_t))
> > +		return PTR_ERR(priv->regs_t);
> >
> >  	/*
> >  	 * PTT HW bug w/a: wake up the device to access @@ -335,10 +367,10
> > @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv,
> >  	if (ret)
> >  		return ret;
> >
> > -	pa_high = ioread32(&priv->cca->cmd_pa_high);
> > -	pa_low  = ioread32(&priv->cca->cmd_pa_low);
> > +	pa_high = ioread32(&priv->regs_t->ctrl_cmd_pa_high);
> > +	pa_low  = ioread32(&priv->regs_t->ctrl_cmd_pa_low);
> >  	cmd_pa = ((u64)pa_high << 32) | pa_low;
> > -	cmd_size = ioread32(&priv->cca->cmd_size);
> > +	cmd_size = ioread32(&priv->regs_t->ctrl_cmd_size);
> >
> >  	dev_dbg(dev, "cmd_hi = %X cmd_low = %X cmd_size %X\n",
> >  		pa_high, pa_low, cmd_size);
> > @@ -349,9 +381,9 @@ static int crb_map_io(struct acpi_device *device,
> struct crb_priv *priv,
> >  		goto out;
> >  	}
> >
> > -	memcpy_fromio(&rsp_pa, &priv->cca->rsp_pa, 8);
> > +	memcpy_fromio(&rsp_pa, &priv->regs_t->ctrl_rsp_pa, 8);
> >  	rsp_pa = le64_to_cpu(rsp_pa);
> > -	rsp_size = ioread32(&priv->cca->rsp_size);
> > +	rsp_size = ioread32(&priv->regs_t->ctrl_rsp_size);
> >
> >  	if (cmd_pa != rsp_pa) {
> >  		priv->rsp = crb_map_res(dev, priv, &io_res, rsp_pa, rsp_size);
> > --
> > 2.9.3
> >
> 

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

* Re: [tpmdd-devel] [PATCH v2 1/3] tpm_crb: map locality registers
  2016-12-05 12:07     ` [tpmdd-devel] " Winkler, Tomas
@ 2016-12-05 12:21       ` Jarkko Sakkinen
  2016-12-05 21:31         ` Winkler, Tomas
  0 siblings, 1 reply; 18+ messages in thread
From: Jarkko Sakkinen @ 2016-12-05 12:21 UTC (permalink / raw)
  To: Winkler, Tomas
  Cc: Peter Huewe, linux-security-module,
	moderated list:TPM DEVICE DRIVER, open list

On Mon, Dec 05, 2016 at 12:07:51PM +0000, Winkler, Tomas wrote:
> > > ---
> > >  drivers/char/tpm/tpm_crb.c | 96
> > > ++++++++++++++++++++++++++++++----------------
> > >  1 file changed, 64 insertions(+), 32 deletions(-)
> > >
> > > diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
> > > index 717b6b4..8d81b66 100644
> > > --- a/drivers/char/tpm/tpm_crb.c
> > > +++ b/drivers/char/tpm/tpm_crb.c
> > > @@ -52,18 +52,28 @@ enum crb_cancel {
> > >  	CRB_CANCEL_INVOKE	= BIT(0),
> > >  };
> > >
> > > -struct crb_control_area {
> > > -	u32 req;
> > > -	u32 sts;
> > > -	u32 cancel;
> > > -	u32 start;
> > > -	u32 int_enable;
> > > -	u32 int_sts;
> > > -	u32 cmd_size;
> > > -	u32 cmd_pa_low;
> > > -	u32 cmd_pa_high;
> > > -	u32 rsp_size;
> > > -	u64 rsp_pa;
> > > +struct crb_regs_head {
> > > +	u32 loc_state;
> > > +	u32 reserved1;
> > > +	u32 loc_ctrl;
> > > +	u32 loc_sts;
> > > +	u8 reserved2[32];
> > > +	u64 intf_id;
> > > +	u64 ctrl_ext;
> > > +} __packed;
> > > +
> > > +struct crb_regs_tail {
> > > +	u32 ctrl_req;
> > > +	u32 ctrl_sts;
> > > +	u32 ctrl_cancel;
> > > +	u32 ctrl_start;
> > > +	u32 ctrl_int_enable;
> > > +	u32 ctrl_int_sts;
> > > +	u32 ctrl_cmd_size;
> > > +	u32 ctrl_cmd_pa_low;
> > > +	u32 ctrl_cmd_pa_high;
> > > +	u32 ctrl_rsp_size;
> > > +	u64 ctrl_rsp_pa;
> > >  } __packed;
> 
> 
> Now I wonder if using  traditional offsets wouldn't be cleaner solution.

I'm not sure what you are trying to say.

> > >  enum crb_status {
> > > @@ -78,7 +88,8 @@ enum crb_flags {
> > >  struct crb_priv {
> > >  	unsigned int flags;
> > >  	void __iomem *iobase;
> > > -	struct crb_control_area __iomem *cca;
> > > +	struct crb_regs_head __iomem *regs_h;
> > > +	struct crb_regs_tail __iomem *regs_t;
> Why just not leaving it cca, it's descriptive enough. 
> > >  	u8 __iomem *cmd;
> > >  	u8 __iomem *rsp;
> > >  	u32 cmd_size;
> > > @@ -104,7 +115,7 @@ static int __maybe_unused crb_go_idle(struct device
> > *dev, struct crb_priv *priv)
> > >  	if (priv->flags & CRB_FL_ACPI_START)
> > >  		return 0;
> > >
> > > -	iowrite32(CRB_CTRL_REQ_GO_IDLE, &priv->cca->req);
> > > +	iowrite32(CRB_CTRL_REQ_GO_IDLE, &priv->regs_t->ctrl_req);
> > >  	/* we don't really care when this settles */
> > >
> > >  	return 0;
> > > @@ -128,21 +139,23 @@ static int __maybe_unused crb_cmd_ready(struct
> > device *dev,
> > >  					struct crb_priv *priv)
> > >  {
> > >  	ktime_t stop, start;
> > > +	u32 req;
> > >
> > >  	if (priv->flags & CRB_FL_ACPI_START)
> > >  		return 0;
> > >
> > > -	iowrite32(CRB_CTRL_REQ_CMD_READY, &priv->cca->req);
> > > +	iowrite32(CRB_CTRL_REQ_CMD_READY, &priv->regs_t->ctrl_req);
> > >
> > >  	start = ktime_get();
> > >  	stop = ktime_add(start, ms_to_ktime(TPM2_TIMEOUT_C));
> > >  	do {
> > > -		if (!(ioread32(&priv->cca->req) &
> > CRB_CTRL_REQ_CMD_READY))
> > > +		req = ioread32(&priv->regs_t->ctrl_req);
> > > +		if (!(req & CRB_CTRL_REQ_CMD_READY))
> > >  			return 0;
> > >  		usleep_range(50, 100);
> > >  	} while (ktime_before(ktime_get(), stop));
> > >
> > > -	if (ioread32(&priv->cca->req) & CRB_CTRL_REQ_CMD_READY) {
> > > +	if (ioread32(&priv->regs_t->ctrl_req) & CRB_CTRL_REQ_CMD_READY)
> > {
> > >  		dev_warn(dev, "cmdReady timed out\n");
> > >  		return -ETIME;
> > >  	}
> > > @@ -155,7 +168,7 @@ static u8 crb_status(struct tpm_chip *chip)
> > >  	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
> > >  	u8 sts = 0;
> > >
> > > -	if ((ioread32(&priv->cca->start) & CRB_START_INVOKE) !=
> > > +	if ((ioread32(&priv->regs_t->ctrl_start) & CRB_START_INVOKE) !=
> > >  	    CRB_START_INVOKE)
> > >  		sts |= CRB_DRV_STS_COMPLETE;
> > >
> > > @@ -171,7 +184,7 @@ static int crb_recv(struct tpm_chip *chip, u8 *buf,
> > size_t count)
> > >  	if (count < 6)
> > >  		return -EIO;
> > >
> > > -	if (ioread32(&priv->cca->sts) & CRB_CTRL_STS_ERROR)
> > > +	if (ioread32(&priv->regs_t->ctrl_sts) & CRB_CTRL_STS_ERROR)
> > >  		return -EIO;
> > >
> > >  	memcpy_fromio(buf, priv->rsp, 6);
> > > @@ -210,7 +223,7 @@ static int crb_send(struct tpm_chip *chip, u8 *buf,
> > size_t len)
> > >  	/* Zero the cancel register so that the next command will not get
> > >  	 * canceled.
> > >  	 */
> > > -	iowrite32(0, &priv->cca->cancel);
> > > +	iowrite32(0, &priv->regs_t->ctrl_cancel);
> > >
> > >  	if (len > priv->cmd_size) {
> > >  		dev_err(&chip->dev, "invalid command count value %zd %d\n",
> > @@
> > > -224,7 +237,7 @@ static int crb_send(struct tpm_chip *chip, u8 *buf, size_t
> > len)
> > >  	wmb();
> > >
> > >  	if (priv->flags & CRB_FL_CRB_START)
> > > -		iowrite32(CRB_START_INVOKE, &priv->cca->start);
> > > +		iowrite32(CRB_START_INVOKE, &priv->regs_t->ctrl_start);
> > >
> > >  	if (priv->flags & CRB_FL_ACPI_START)
> > >  		rc = crb_do_acpi_start(chip);
> > > @@ -236,7 +249,7 @@ static void crb_cancel(struct tpm_chip *chip)  {
> > >  	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
> > >
> > > -	iowrite32(CRB_CANCEL_INVOKE, &priv->cca->cancel);
> > > +	iowrite32(CRB_CANCEL_INVOKE, &priv->regs_t->ctrl_cancel);
> > >
> > >  	if ((priv->flags & CRB_FL_ACPI_START) && crb_do_acpi_start(chip))
> > >  		dev_err(&chip->dev, "ACPI Start failed\n"); @@ -245,7 +258,7
> > @@
> > > static void crb_cancel(struct tpm_chip *chip)  static bool
> > > crb_req_canceled(struct tpm_chip *chip, u8 status)  {
> > >  	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
> > > -	u32 cancel = ioread32(&priv->cca->cancel);
> > > +	u32 cancel = ioread32(&priv->regs_t->ctrl_cancel);
> > >
> > >  	return (cancel & CRB_CANCEL_INVOKE) == CRB_CANCEL_INVOKE;  }
> > @@
> > > -287,6 +300,8 @@ static void __iomem *crb_map_res(struct device *dev,
> > struct crb_priv *priv,
> > >  	if (start != new_res.start)
> > >  		return (void __iomem *) ERR_PTR(-EINVAL);
> > >
> > > +	dev_dbg(dev, "%pr %pr", io_res, &new_res);
> > > +
> > >  	if (!resource_contains(io_res, &new_res))
> > >  		return devm_ioremap_resource(dev, &new_res);
> > >
> > > @@ -322,10 +337,27 @@ static int crb_map_io(struct acpi_device *device,
> > struct crb_priv *priv,
> > >  	if (IS_ERR(priv->iobase))
> > >  		return PTR_ERR(priv->iobase);
> > >
> > > -	priv->cca = crb_map_res(dev, priv, &io_res, buf->control_address,
> > > -				sizeof(struct crb_control_area));
> > > -	if (IS_ERR(priv->cca))
> > > -		return PTR_ERR(priv->cca);
> > > +	/* The ACPI IO region starts at the head area and continues to include
> > > +	 * the control area, as one nice sane region except for some older
> > > +	 * stuff that puts the control area outside the ACPI IO region.
> > > +	 */
> 
> This is not by the spec, can you be more specific, what platforms has that behavior?

Pre-Skylake (Haswell, Broadwell) does not follow the spec.

> > > +	if (!(priv->flags & CRB_FL_ACPI_START)) {
> > > +		if (buf->control_address == io_res.start +
> > > +		    sizeof(struct crb_regs_head)) {
> > > +			priv->regs_h = crb_map_res(
> Why do you need to map this again it just same as iobase ? 

crb_map_res() works in a way that it does ioremap only when the range
is not included to iomem.


/Jarkko

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

* Re: [PATCH v2 3/3] tpm_crb: request and relinquish locality 0
  2016-12-03 17:52 ` [PATCH v2 3/3] tpm_crb: request and relinquish locality 0 Jarkko Sakkinen
  2016-12-03 18:42   ` Jarkko Sakkinen
@ 2016-12-05 16:32   ` Jason Gunthorpe
  2016-12-06 18:40     ` Jarkko Sakkinen
  1 sibling, 1 reply; 18+ messages in thread
From: Jason Gunthorpe @ 2016-12-05 16:32 UTC (permalink / raw)
  To: Jarkko Sakkinen
  Cc: Peter Huewe, Marcel Selhorst, moderated list:TPM DEVICE DRIVER,
	open list

On Sat, Dec 03, 2016 at 07:52:13PM +0200, Jarkko Sakkinen wrote:
> +	iowrite32(CRB_LOC_CTRL_RELINQUISH, &priv->regs_h->loc_ctrl);

Since regs_h can be null shouldn't there be some guards ?

Jason

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

* RE: [tpmdd-devel] [PATCH v2 1/3] tpm_crb: map locality registers
  2016-12-05 12:21       ` Jarkko Sakkinen
@ 2016-12-05 21:31         ` Winkler, Tomas
  2016-12-06 18:35           ` Jarkko Sakkinen
  0 siblings, 1 reply; 18+ messages in thread
From: Winkler, Tomas @ 2016-12-05 21:31 UTC (permalink / raw)
  To: Jarkko Sakkinen
  Cc: Peter Huewe, linux-security-module,
	moderated list:TPM DEVICE DRIVER, open list

> 
> On Mon, Dec 05, 2016 at 12:07:51PM +0000, Winkler, Tomas wrote:
> > > > ---
> > > >  drivers/char/tpm/tpm_crb.c | 96
> > > > ++++++++++++++++++++++++++++++----------------
> > > >  1 file changed, 64 insertions(+), 32 deletions(-)
> > > >
> > > > diff --git a/drivers/char/tpm/tpm_crb.c
> > > > b/drivers/char/tpm/tpm_crb.c index 717b6b4..8d81b66 100644
> > > > --- a/drivers/char/tpm/tpm_crb.c
> > > > +++ b/drivers/char/tpm/tpm_crb.c
> > > > @@ -52,18 +52,28 @@ enum crb_cancel {
> > > >  	CRB_CANCEL_INVOKE	= BIT(0),
> > > >  };
> > > >
> > > > -struct crb_control_area {
> > > > -	u32 req;
> > > > -	u32 sts;
> > > > -	u32 cancel;
> > > > -	u32 start;
> > > > -	u32 int_enable;
> > > > -	u32 int_sts;
> > > > -	u32 cmd_size;
> > > > -	u32 cmd_pa_low;
> > > > -	u32 cmd_pa_high;
> > > > -	u32 rsp_size;
> > > > -	u64 rsp_pa;
> > > > +struct crb_regs_head {
> > > > +	u32 loc_state;
> > > > +	u32 reserved1;
> > > > +	u32 loc_ctrl;
> > > > +	u32 loc_sts;
> > > > +	u8 reserved2[32];
> > > > +	u64 intf_id;
> > > > +	u64 ctrl_ext;
> > > > +} __packed;
> > > > +
> > > > +struct crb_regs_tail {
> > > > +	u32 ctrl_req;
> > > > +	u32 ctrl_sts;
> > > > +	u32 ctrl_cancel;
> > > > +	u32 ctrl_start;
> > > > +	u32 ctrl_int_enable;
> > > > +	u32 ctrl_int_sts;
> > > > +	u32 ctrl_cmd_size;
> > > > +	u32 ctrl_cmd_pa_low;
> > > > +	u32 ctrl_cmd_pa_high;
> > > > +	u32 ctrl_rsp_size;
> > > > +	u64 ctrl_rsp_pa;
> > > >  } __packed;
> >
> >
> > Now I wonder if using  traditional offsets wouldn't be cleaner solution.
> 
> I'm not sure what you are trying to say.

Such as iowrite32(val, base + offset)

> 
> > > >  enum crb_status {
> > > > @@ -78,7 +88,8 @@ enum crb_flags {  struct crb_priv {
> > > >  	unsigned int flags;
> > > >  	void __iomem *iobase;
> > > > -	struct crb_control_area __iomem *cca;
> > > > +	struct crb_regs_head __iomem *regs_h;
> > > > +	struct crb_regs_tail __iomem *regs_t;
> > Why just not leaving it cca, it's descriptive enough.
> > > >  	u8 __iomem *cmd;
> > > >  	u8 __iomem *rsp;
> > > >  	u32 cmd_size;
> > > > @@ -104,7 +115,7 @@ static int __maybe_unused crb_go_idle(struct
> > > > device
> > > *dev, struct crb_priv *priv)
> > > >  	if (priv->flags & CRB_FL_ACPI_START)
> > > >  		return 0;
> > > >
> > > > -	iowrite32(CRB_CTRL_REQ_GO_IDLE, &priv->cca->req);
> > > > +	iowrite32(CRB_CTRL_REQ_GO_IDLE, &priv->regs_t->ctrl_req);
> > > >  	/* we don't really care when this settles */
> > > >
> > > >  	return 0;
> > > > @@ -128,21 +139,23 @@ static int __maybe_unused
> > > > crb_cmd_ready(struct
> > > device *dev,
> > > >  					struct crb_priv *priv)
> > > >  {
> > > >  	ktime_t stop, start;
> > > > +	u32 req;
> > > >
> > > >  	if (priv->flags & CRB_FL_ACPI_START)
> > > >  		return 0;
> > > >
> > > > -	iowrite32(CRB_CTRL_REQ_CMD_READY, &priv->cca->req);
> > > > +	iowrite32(CRB_CTRL_REQ_CMD_READY, &priv->regs_t->ctrl_req);
> > > >
> > > >  	start = ktime_get();
> > > >  	stop = ktime_add(start, ms_to_ktime(TPM2_TIMEOUT_C));
> > > >  	do {
> > > > -		if (!(ioread32(&priv->cca->req) &
> > > CRB_CTRL_REQ_CMD_READY))
> > > > +		req = ioread32(&priv->regs_t->ctrl_req);
> > > > +		if (!(req & CRB_CTRL_REQ_CMD_READY))
> > > >  			return 0;
> > > >  		usleep_range(50, 100);
> > > >  	} while (ktime_before(ktime_get(), stop));
> > > >
> > > > -	if (ioread32(&priv->cca->req) & CRB_CTRL_REQ_CMD_READY) {
> > > > +	if (ioread32(&priv->regs_t->ctrl_req) & CRB_CTRL_REQ_CMD_READY)
> > > {
> > > >  		dev_warn(dev, "cmdReady timed out\n");
> > > >  		return -ETIME;
> > > >  	}
> > > > @@ -155,7 +168,7 @@ static u8 crb_status(struct tpm_chip *chip)
> > > >  	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
> > > >  	u8 sts = 0;
> > > >
> > > > -	if ((ioread32(&priv->cca->start) & CRB_START_INVOKE) !=
> > > > +	if ((ioread32(&priv->regs_t->ctrl_start) & CRB_START_INVOKE) !=
> > > >  	    CRB_START_INVOKE)
> > > >  		sts |= CRB_DRV_STS_COMPLETE;
> > > >
> > > > @@ -171,7 +184,7 @@ static int crb_recv(struct tpm_chip *chip, u8
> > > > *buf,
> > > size_t count)
> > > >  	if (count < 6)
> > > >  		return -EIO;
> > > >
> > > > -	if (ioread32(&priv->cca->sts) & CRB_CTRL_STS_ERROR)
> > > > +	if (ioread32(&priv->regs_t->ctrl_sts) & CRB_CTRL_STS_ERROR)
> > > >  		return -EIO;
> > > >
> > > >  	memcpy_fromio(buf, priv->rsp, 6); @@ -210,7 +223,7 @@ static int
> > > > crb_send(struct tpm_chip *chip, u8 *buf,
> > > size_t len)
> > > >  	/* Zero the cancel register so that the next command will not get
> > > >  	 * canceled.
> > > >  	 */
> > > > -	iowrite32(0, &priv->cca->cancel);
> > > > +	iowrite32(0, &priv->regs_t->ctrl_cancel);
> > > >
> > > >  	if (len > priv->cmd_size) {
> > > >  		dev_err(&chip->dev, "invalid command count value %zd %d\n",
> > > @@
> > > > -224,7 +237,7 @@ static int crb_send(struct tpm_chip *chip, u8
> > > > *buf, size_t
> > > len)
> > > >  	wmb();
> > > >
> > > >  	if (priv->flags & CRB_FL_CRB_START)
> > > > -		iowrite32(CRB_START_INVOKE, &priv->cca->start);
> > > > +		iowrite32(CRB_START_INVOKE, &priv->regs_t->ctrl_start);
> > > >
> > > >  	if (priv->flags & CRB_FL_ACPI_START)
> > > >  		rc = crb_do_acpi_start(chip);
> > > > @@ -236,7 +249,7 @@ static void crb_cancel(struct tpm_chip *chip)  {
> > > >  	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
> > > >
> > > > -	iowrite32(CRB_CANCEL_INVOKE, &priv->cca->cancel);
> > > > +	iowrite32(CRB_CANCEL_INVOKE, &priv->regs_t->ctrl_cancel);
> > > >
> > > >  	if ((priv->flags & CRB_FL_ACPI_START) && crb_do_acpi_start(chip))
> > > >  		dev_err(&chip->dev, "ACPI Start failed\n"); @@ -245,7 +258,7
> > > @@
> > > > static void crb_cancel(struct tpm_chip *chip)  static bool
> > > > crb_req_canceled(struct tpm_chip *chip, u8 status)  {
> > > >  	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
> > > > -	u32 cancel = ioread32(&priv->cca->cancel);
> > > > +	u32 cancel = ioread32(&priv->regs_t->ctrl_cancel);
> > > >
> > > >  	return (cancel & CRB_CANCEL_INVOKE) == CRB_CANCEL_INVOKE;  }
> > > @@
> > > > -287,6 +300,8 @@ static void __iomem *crb_map_res(struct device
> > > > *dev,
> > > struct crb_priv *priv,
> > > >  	if (start != new_res.start)
> > > >  		return (void __iomem *) ERR_PTR(-EINVAL);
> > > >
> > > > +	dev_dbg(dev, "%pr %pr", io_res, &new_res);
> > > > +
> > > >  	if (!resource_contains(io_res, &new_res))
> > > >  		return devm_ioremap_resource(dev, &new_res);
> > > >
> > > > @@ -322,10 +337,27 @@ static int crb_map_io(struct acpi_device
> > > > *device,
> > > struct crb_priv *priv,
> > > >  	if (IS_ERR(priv->iobase))
> > > >  		return PTR_ERR(priv->iobase);
> > > >
> > > > -	priv->cca = crb_map_res(dev, priv, &io_res, buf->control_address,
> > > > -				sizeof(struct crb_control_area));
> > > > -	if (IS_ERR(priv->cca))
> > > > -		return PTR_ERR(priv->cca);
> > > > +	/* The ACPI IO region starts at the head area and continues to include
> > > > +	 * the control area, as one nice sane region except for some older
> > > > +	 * stuff that puts the control area outside the ACPI IO region.
> > > > +	 */
> >
> > This is not by the spec, can you be more specific, what platforms has that
> behavior?
> 
> Pre-Skylake (Haswell, Broadwell) does not follow the spec.

Okay, will check what is the issue heere
> > > > +	if (!(priv->flags & CRB_FL_ACPI_START)) {
> > > > +		if (buf->control_address == io_res.start +
> > > > +		    sizeof(struct crb_regs_head)) {
> > > > +			priv->regs_h = crb_map_res(
> > Why do you need to map this again it just same as iobase ?
> 
> crb_map_res() works in a way that it does ioremap only when the range is not
> included to iomem.

Right it does nothing, so why to do so, or I'm missing something?
Tomas

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

* RE: [tpmdd-devel] [PATCH v2 2/3] tpm_crb: encapsulate crb_wait_for_reg_32
  2016-12-03 18:41   ` Jarkko Sakkinen
@ 2016-12-05 21:34     ` Winkler, Tomas
  2016-12-06 18:38       ` Jarkko Sakkinen
  0 siblings, 1 reply; 18+ messages in thread
From: Winkler, Tomas @ 2016-12-05 21:34 UTC (permalink / raw)
  To: Jarkko Sakkinen, Peter Huewe
  Cc: linux-security-module, moderated list:TPM DEVICE DRIVER, open list

> CC linux-security-module
> 
> On Sat, Dec 03, 2016 at 07:52:12PM +0200, Jarkko Sakkinen wrote:
> > Encapsulated crb_wait_for_reg32() so that state changes in other CRB
> > registers than TPM_CRB_CTRL_REQ_x can be waited.
> >
> > Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
> > ---
> >  drivers/char/tpm/tpm_crb.c | 37 +++++++++++++++++++++++--------------
> >  1 file changed, 23 insertions(+), 14 deletions(-)
> >
> > diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
> > index 8d81b66..f986d02 100644
> > --- a/drivers/char/tpm/tpm_crb.c
> > +++ b/drivers/char/tpm/tpm_crb.c
> > @@ -121,6 +121,25 @@ static int __maybe_unused crb_go_idle(struct
> device *dev, struct crb_priv *priv)
> >  	return 0;
> >  }
> >
> > +static bool crb_wait_for_reg_32(u32 __iomem *reg, u32 mask, u32 value,
> > +				unsigned long timeout)
> > +{
> > +	ktime_t start;
> > +	ktime_t stop;
> > +
> > +	start = ktime_get();
> > +	stop = ktime_add(start, ms_to_ktime(timeout));
> > +
> > +	do {
> > +		if ((ioread32(reg) & mask) == value)
> > +			return true;
> > +
> > +		usleep_range(50, 100);
This was tuned for power management, have you tuned it for locality? 

> > +	} while (ktime_before(ktime_get(), stop));
> > +
> > +	return false;
> > +}
> > +
> >  /**
> >   * crb_cmd_ready - request tpm crb device to enter ready state
> >   *
> > @@ -138,24 +157,14 @@ static int __maybe_unused crb_go_idle(struct
> > device *dev, struct crb_priv *priv)  static int __maybe_unused
> crb_cmd_ready(struct device *dev,
> >  					struct crb_priv *priv)
> >  {
> > -	ktime_t stop, start;
> > -	u32 req;
> > -
> >  	if (priv->flags & CRB_FL_ACPI_START)
> >  		return 0;
> >
> >  	iowrite32(CRB_CTRL_REQ_CMD_READY, &priv->regs_t->ctrl_req);
> > -
> > -	start = ktime_get();
> > -	stop = ktime_add(start, ms_to_ktime(TPM2_TIMEOUT_C));
> > -	do {
> > -		req = ioread32(&priv->regs_t->ctrl_req);
> > -		if (!(req & CRB_CTRL_REQ_CMD_READY))
> > -			return 0;
> > -		usleep_range(50, 100);
> > -	} while (ktime_before(ktime_get(), stop));
> > -
> > -	if (ioread32(&priv->regs_t->ctrl_req) & CRB_CTRL_REQ_CMD_READY)
> {
> > +	if (!crb_wait_for_reg_32(&priv->regs_t->ctrl_req,
> > +				 CRB_CTRL_REQ_CMD_READY /* mask */,
> > +				 0, /* value */
> > +				 TPM2_TIMEOUT_C)) {
> >  		dev_warn(dev, "cmdReady timed out\n");
> >  		return -ETIME;
> >  	}
> > --
> > 2.9.3
> >
> 
> ------------------------------------------------------------------------------
> Check out the vibrant tech community on one of the world's most
> engaging tech sites, SlashDot.org! http://sdm.link/slashdot
> _______________________________________________
> tpmdd-devel mailing list
> tpmdd-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/tpmdd-devel

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

* RE: [tpmdd-devel] [PATCH v2 3/3] tpm_crb: request and relinquish locality 0
  2016-12-03 18:42   ` Jarkko Sakkinen
@ 2016-12-05 21:51     ` Winkler, Tomas
  2016-12-06 18:41       ` Jarkko Sakkinen
  0 siblings, 1 reply; 18+ messages in thread
From: Winkler, Tomas @ 2016-12-05 21:51 UTC (permalink / raw)
  To: Jarkko Sakkinen, Peter Huewe
  Cc: linux-security-module, moderated list:TPM DEVICE DRIVER, open list

> 
> CC linux-security-module
> 
> On Sat, Dec 03, 2016 at 07:52:13PM +0200, Jarkko Sakkinen wrote:
> > Request and relinquish locality for the driver use in order to be a
> > better citizen in a multi locality environment like TXT. The locality
> > is requested and relinquished as part of going into and waking up from
> > idle.
> 
This has nothing to do with power management, please note, that this is run via runtime_pm handlers, 
which can be disabled  via sysfs and actually on server platforms runtime pm is not relevant, 
while you cannot disable locality acquire/relinquish flow.

NACK
> > Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
> > ---
> >  drivers/char/tpm/tpm_crb.c | 36 ++++++++++++++++++++++++------------
> >  1 file changed, 24 insertions(+), 12 deletions(-)
> >
> > diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
> > index f986d02..f6e0beb 100644
> > --- a/drivers/char/tpm/tpm_crb.c
> > +++ b/drivers/char/tpm/tpm_crb.c
> > @@ -34,6 +34,15 @@ enum crb_defaults {
> >  	CRB_ACPI_START_INDEX = 1,
> >  };
> >
> > +enum crb_loc_ctrl {
> > +	CRB_LOC_CTRL_REQUEST_ACCESS	= BIT(0),
> > +	CRB_LOC_CTRL_RELINQUISH		= BIT(1),
> > +};
> > +
> > +enum crb_loc_state {
> > +	CRB_LOC_STATE_LOC_ASSIGNED	= BIT(1),
> > +};
> > +
> >  enum crb_ctrl_req {
> >  	CRB_CTRL_REQ_CMD_READY	= BIT(0),
> >  	CRB_CTRL_REQ_GO_IDLE	= BIT(1),
> > @@ -101,12 +110,8 @@ struct crb_priv {
> >   * @dev:  crb device
> >   * @priv: crb private data
> >   *
> > - * Write CRB_CTRL_REQ_GO_IDLE to TPM_CRB_CTRL_REQ
> > - * The device should respond within TIMEOUT_C by clearing the bit.
> > - * Anyhow, we do not wait here as a consequent CMD_READY request
> > - * will be handled correctly even if idle was not completed.
> > - *
> > - * The function does nothing for devices with ACPI-start method.
> > + * Put device to the idle state and relinquish locality. The function
> > + does
> > + * nothing for devices with the ACPI-start method.
> >   *
> >   * Return: 0 always
> >   */
> > @@ -115,6 +120,7 @@ static int __maybe_unused crb_go_idle(struct device
> *dev, struct crb_priv *priv)
> >  	if (priv->flags & CRB_FL_ACPI_START)
> >  		return 0;
> >
> > +	iowrite32(CRB_LOC_CTRL_RELINQUISH, &priv->regs_h->loc_ctrl);	
This is misleading this has nothing to do with go idle,  what is the 
> >  	iowrite32(CRB_CTRL_REQ_GO_IDLE, &priv->regs_t->ctrl_req);
> >  	/* we don't really care when this settles */
> >
> > @@ -146,11 +152,8 @@ static bool crb_wait_for_reg_32(u32 __iomem *reg,
> u32 mask, u32 value,
> >   * @dev:  crb device
> >   * @priv: crb private data
> >   *
> > - * Write CRB_CTRL_REQ_CMD_READY to TPM_CRB_CTRL_REQ
> > - * and poll till the device acknowledge it by clearing the bit.
> > - * The device should respond within TIMEOUT_C.
> > - *
> > - * The function does nothing for devices with ACPI-start method
> > + * Try to wake up the device and request locality. The function does
> > + nothing
> > + * for devices with the ACPI-start method.
> >   *
> >   * Return: 0 on success -ETIME on timeout;
> >   */
> > @@ -165,7 +168,16 @@ static int __maybe_unused crb_cmd_ready(struct
> device *dev,
> >  				 CRB_CTRL_REQ_CMD_READY /* mask */,
> >  				 0, /* value */
> >  				 TPM2_TIMEOUT_C)) {
> > -		dev_warn(dev, "cmdReady timed out\n");
> > +		dev_warn(dev, "TPM_CRB_CTRL_REQ_x.cmdReady timed
> out\n");
We are always in locality 0 here, right?

> > +		return -ETIME;
> > +	}
> > +
> > +	iowrite32(CRB_LOC_CTRL_REQUEST_ACCESS, &priv->regs_h-
> >loc_ctrl);
> > +	if (!crb_wait_for_reg_32(&priv->regs_h->loc_state,
> > +				 CRB_LOC_STATE_LOC_ASSIGNED, /* mask */
> > +				 CRB_LOC_STATE_LOC_ASSIGNED, /* value */
> > +				 TPM2_TIMEOUT_C)) {
> > +		dev_warn(dev, "TPM_LOC_STATE_x.requestAccess timed
> out\n");


> >  		return -ETIME;
> >  	}
 

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

* Re: [tpmdd-devel] [PATCH v2 1/3] tpm_crb: map locality registers
  2016-12-05 21:31         ` Winkler, Tomas
@ 2016-12-06 18:35           ` Jarkko Sakkinen
  0 siblings, 0 replies; 18+ messages in thread
From: Jarkko Sakkinen @ 2016-12-06 18:35 UTC (permalink / raw)
  To: Winkler, Tomas
  Cc: Peter Huewe, linux-security-module,
	moderated list:TPM DEVICE DRIVER, open list

On Mon, Dec 05, 2016 at 09:31:57PM +0000, Winkler, Tomas wrote:
> > 
> > On Mon, Dec 05, 2016 at 12:07:51PM +0000, Winkler, Tomas wrote:
> > > > > ---
> > > > >  drivers/char/tpm/tpm_crb.c | 96
> > > > > ++++++++++++++++++++++++++++++----------------
> > > > >  1 file changed, 64 insertions(+), 32 deletions(-)
> > > > >
> > > > > diff --git a/drivers/char/tpm/tpm_crb.c
> > > > > b/drivers/char/tpm/tpm_crb.c index 717b6b4..8d81b66 100644
> > > > > --- a/drivers/char/tpm/tpm_crb.c
> > > > > +++ b/drivers/char/tpm/tpm_crb.c
> > > > > @@ -52,18 +52,28 @@ enum crb_cancel {
> > > > >  	CRB_CANCEL_INVOKE	= BIT(0),
> > > > >  };
> > > > >
> > > > > -struct crb_control_area {
> > > > > -	u32 req;
> > > > > -	u32 sts;
> > > > > -	u32 cancel;
> > > > > -	u32 start;
> > > > > -	u32 int_enable;
> > > > > -	u32 int_sts;
> > > > > -	u32 cmd_size;
> > > > > -	u32 cmd_pa_low;
> > > > > -	u32 cmd_pa_high;
> > > > > -	u32 rsp_size;
> > > > > -	u64 rsp_pa;
> > > > > +struct crb_regs_head {
> > > > > +	u32 loc_state;
> > > > > +	u32 reserved1;
> > > > > +	u32 loc_ctrl;
> > > > > +	u32 loc_sts;
> > > > > +	u8 reserved2[32];
> > > > > +	u64 intf_id;
> > > > > +	u64 ctrl_ext;
> > > > > +} __packed;
> > > > > +
> > > > > +struct crb_regs_tail {
> > > > > +	u32 ctrl_req;
> > > > > +	u32 ctrl_sts;
> > > > > +	u32 ctrl_cancel;
> > > > > +	u32 ctrl_start;
> > > > > +	u32 ctrl_int_enable;
> > > > > +	u32 ctrl_int_sts;
> > > > > +	u32 ctrl_cmd_size;
> > > > > +	u32 ctrl_cmd_pa_low;
> > > > > +	u32 ctrl_cmd_pa_high;
> > > > > +	u32 ctrl_rsp_size;
> > > > > +	u64 ctrl_rsp_pa;
> > > > >  } __packed;
> > >
> > >
> > > Now I wonder if using  traditional offsets wouldn't be cleaner solution.
> > 
> > I'm not sure what you are trying to say.
> 
> Such as iowrite32(val, base + offset)

I rather stick using structures. I do not see the point to turn things
around.

> 
> > 
> > > > >  enum crb_status {
> > > > > @@ -78,7 +88,8 @@ enum crb_flags {  struct crb_priv {
> > > > >  	unsigned int flags;
> > > > >  	void __iomem *iobase;
> > > > > -	struct crb_control_area __iomem *cca;
> > > > > +	struct crb_regs_head __iomem *regs_h;
> > > > > +	struct crb_regs_tail __iomem *regs_t;
> > > Why just not leaving it cca, it's descriptive enough.
> > > > >  	u8 __iomem *cmd;
> > > > >  	u8 __iomem *rsp;
> > > > >  	u32 cmd_size;
> > > > > @@ -104,7 +115,7 @@ static int __maybe_unused crb_go_idle(struct
> > > > > device
> > > > *dev, struct crb_priv *priv)
> > > > >  	if (priv->flags & CRB_FL_ACPI_START)
> > > > >  		return 0;
> > > > >
> > > > > -	iowrite32(CRB_CTRL_REQ_GO_IDLE, &priv->cca->req);
> > > > > +	iowrite32(CRB_CTRL_REQ_GO_IDLE, &priv->regs_t->ctrl_req);
> > > > >  	/* we don't really care when this settles */
> > > > >
> > > > >  	return 0;
> > > > > @@ -128,21 +139,23 @@ static int __maybe_unused
> > > > > crb_cmd_ready(struct
> > > > device *dev,
> > > > >  					struct crb_priv *priv)
> > > > >  {
> > > > >  	ktime_t stop, start;
> > > > > +	u32 req;
> > > > >
> > > > >  	if (priv->flags & CRB_FL_ACPI_START)
> > > > >  		return 0;
> > > > >
> > > > > -	iowrite32(CRB_CTRL_REQ_CMD_READY, &priv->cca->req);
> > > > > +	iowrite32(CRB_CTRL_REQ_CMD_READY, &priv->regs_t->ctrl_req);
> > > > >
> > > > >  	start = ktime_get();
> > > > >  	stop = ktime_add(start, ms_to_ktime(TPM2_TIMEOUT_C));
> > > > >  	do {
> > > > > -		if (!(ioread32(&priv->cca->req) &
> > > > CRB_CTRL_REQ_CMD_READY))
> > > > > +		req = ioread32(&priv->regs_t->ctrl_req);
> > > > > +		if (!(req & CRB_CTRL_REQ_CMD_READY))
> > > > >  			return 0;
> > > > >  		usleep_range(50, 100);
> > > > >  	} while (ktime_before(ktime_get(), stop));
> > > > >
> > > > > -	if (ioread32(&priv->cca->req) & CRB_CTRL_REQ_CMD_READY) {
> > > > > +	if (ioread32(&priv->regs_t->ctrl_req) & CRB_CTRL_REQ_CMD_READY)
> > > > {
> > > > >  		dev_warn(dev, "cmdReady timed out\n");
> > > > >  		return -ETIME;
> > > > >  	}
> > > > > @@ -155,7 +168,7 @@ static u8 crb_status(struct tpm_chip *chip)
> > > > >  	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
> > > > >  	u8 sts = 0;
> > > > >
> > > > > -	if ((ioread32(&priv->cca->start) & CRB_START_INVOKE) !=
> > > > > +	if ((ioread32(&priv->regs_t->ctrl_start) & CRB_START_INVOKE) !=
> > > > >  	    CRB_START_INVOKE)
> > > > >  		sts |= CRB_DRV_STS_COMPLETE;
> > > > >
> > > > > @@ -171,7 +184,7 @@ static int crb_recv(struct tpm_chip *chip, u8
> > > > > *buf,
> > > > size_t count)
> > > > >  	if (count < 6)
> > > > >  		return -EIO;
> > > > >
> > > > > -	if (ioread32(&priv->cca->sts) & CRB_CTRL_STS_ERROR)
> > > > > +	if (ioread32(&priv->regs_t->ctrl_sts) & CRB_CTRL_STS_ERROR)
> > > > >  		return -EIO;
> > > > >
> > > > >  	memcpy_fromio(buf, priv->rsp, 6); @@ -210,7 +223,7 @@ static int
> > > > > crb_send(struct tpm_chip *chip, u8 *buf,
> > > > size_t len)
> > > > >  	/* Zero the cancel register so that the next command will not get
> > > > >  	 * canceled.
> > > > >  	 */
> > > > > -	iowrite32(0, &priv->cca->cancel);
> > > > > +	iowrite32(0, &priv->regs_t->ctrl_cancel);
> > > > >
> > > > >  	if (len > priv->cmd_size) {
> > > > >  		dev_err(&chip->dev, "invalid command count value %zd %d\n",
> > > > @@
> > > > > -224,7 +237,7 @@ static int crb_send(struct tpm_chip *chip, u8
> > > > > *buf, size_t
> > > > len)
> > > > >  	wmb();
> > > > >
> > > > >  	if (priv->flags & CRB_FL_CRB_START)
> > > > > -		iowrite32(CRB_START_INVOKE, &priv->cca->start);
> > > > > +		iowrite32(CRB_START_INVOKE, &priv->regs_t->ctrl_start);
> > > > >
> > > > >  	if (priv->flags & CRB_FL_ACPI_START)
> > > > >  		rc = crb_do_acpi_start(chip);
> > > > > @@ -236,7 +249,7 @@ static void crb_cancel(struct tpm_chip *chip)  {
> > > > >  	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
> > > > >
> > > > > -	iowrite32(CRB_CANCEL_INVOKE, &priv->cca->cancel);
> > > > > +	iowrite32(CRB_CANCEL_INVOKE, &priv->regs_t->ctrl_cancel);
> > > > >
> > > > >  	if ((priv->flags & CRB_FL_ACPI_START) && crb_do_acpi_start(chip))
> > > > >  		dev_err(&chip->dev, "ACPI Start failed\n"); @@ -245,7 +258,7
> > > > @@
> > > > > static void crb_cancel(struct tpm_chip *chip)  static bool
> > > > > crb_req_canceled(struct tpm_chip *chip, u8 status)  {
> > > > >  	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
> > > > > -	u32 cancel = ioread32(&priv->cca->cancel);
> > > > > +	u32 cancel = ioread32(&priv->regs_t->ctrl_cancel);
> > > > >
> > > > >  	return (cancel & CRB_CANCEL_INVOKE) == CRB_CANCEL_INVOKE;  }
> > > > @@
> > > > > -287,6 +300,8 @@ static void __iomem *crb_map_res(struct device
> > > > > *dev,
> > > > struct crb_priv *priv,
> > > > >  	if (start != new_res.start)
> > > > >  		return (void __iomem *) ERR_PTR(-EINVAL);
> > > > >
> > > > > +	dev_dbg(dev, "%pr %pr", io_res, &new_res);
> > > > > +
> > > > >  	if (!resource_contains(io_res, &new_res))
> > > > >  		return devm_ioremap_resource(dev, &new_res);
> > > > >
> > > > > @@ -322,10 +337,27 @@ static int crb_map_io(struct acpi_device
> > > > > *device,
> > > > struct crb_priv *priv,
> > > > >  	if (IS_ERR(priv->iobase))
> > > > >  		return PTR_ERR(priv->iobase);
> > > > >
> > > > > -	priv->cca = crb_map_res(dev, priv, &io_res, buf->control_address,
> > > > > -				sizeof(struct crb_control_area));
> > > > > -	if (IS_ERR(priv->cca))
> > > > > -		return PTR_ERR(priv->cca);
> > > > > +	/* The ACPI IO region starts at the head area and continues to include
> > > > > +	 * the control area, as one nice sane region except for some older
> > > > > +	 * stuff that puts the control area outside the ACPI IO region.
> > > > > +	 */
> > >
> > > This is not by the spec, can you be more specific, what platforms has that
> > behavior?
> > 
> > Pre-Skylake (Haswell, Broadwell) does not follow the spec.
> 
> Okay, will check what is the issue heere
> > > > > +	if (!(priv->flags & CRB_FL_ACPI_START)) {
> > > > > +		if (buf->control_address == io_res.start +
> > > > > +		    sizeof(struct crb_regs_head)) {
> > > > > +			priv->regs_h = crb_map_res(
> > > Why do you need to map this again it just same as iobase ?
> > 
> > crb_map_res() works in a way that it does ioremap only when the range is not
> > included to iomem.
> 
> Right it does nothing, so why to do so, or I'm missing something?
> Tomas

Yes, in this case using the wrapper is not necessity. I can change that
to assignment.

/Jarkko

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

* Re: [tpmdd-devel] [PATCH v2 2/3] tpm_crb: encapsulate crb_wait_for_reg_32
  2016-12-05 21:34     ` [tpmdd-devel] " Winkler, Tomas
@ 2016-12-06 18:38       ` Jarkko Sakkinen
  0 siblings, 0 replies; 18+ messages in thread
From: Jarkko Sakkinen @ 2016-12-06 18:38 UTC (permalink / raw)
  To: Winkler, Tomas
  Cc: Peter Huewe, linux-security-module,
	moderated list:TPM DEVICE DRIVER, open list

On Mon, Dec 05, 2016 at 09:34:50PM +0000, Winkler, Tomas wrote:
> > CC linux-security-module
> > 
> > On Sat, Dec 03, 2016 at 07:52:12PM +0200, Jarkko Sakkinen wrote:
> > > Encapsulated crb_wait_for_reg32() so that state changes in other CRB
> > > registers than TPM_CRB_CTRL_REQ_x can be waited.
> > >
> > > Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
> > > ---
> > >  drivers/char/tpm/tpm_crb.c | 37 +++++++++++++++++++++++--------------
> > >  1 file changed, 23 insertions(+), 14 deletions(-)
> > >
> > > diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
> > > index 8d81b66..f986d02 100644
> > > --- a/drivers/char/tpm/tpm_crb.c
> > > +++ b/drivers/char/tpm/tpm_crb.c
> > > @@ -121,6 +121,25 @@ static int __maybe_unused crb_go_idle(struct
> > device *dev, struct crb_priv *priv)
> > >  	return 0;
> > >  }
> > >
> > > +static bool crb_wait_for_reg_32(u32 __iomem *reg, u32 mask, u32 value,
> > > +				unsigned long timeout)
> > > +{
> > > +	ktime_t start;
> > > +	ktime_t stop;
> > > +
> > > +	start = ktime_get();
> > > +	stop = ktime_add(start, ms_to_ktime(timeout));
> > > +
> > > +	do {
> > > +		if ((ioread32(reg) & mask) == value)
> > > +			return true;
> > > +
> > > +		usleep_range(50, 100);
> This was tuned for power management, have you tuned it for locality? 

We don't want million different wait functions and the current values
work without issues for locale.

/Jarkko

> > > +	} while (ktime_before(ktime_get(), stop));
> > > +
> > > +	return false;
> > > +}
> > > +
> > >  /**
> > >   * crb_cmd_ready - request tpm crb device to enter ready state
> > >   *
> > > @@ -138,24 +157,14 @@ static int __maybe_unused crb_go_idle(struct
> > > device *dev, struct crb_priv *priv)  static int __maybe_unused
> > crb_cmd_ready(struct device *dev,
> > >  					struct crb_priv *priv)
> > >  {
> > > -	ktime_t stop, start;
> > > -	u32 req;
> > > -
> > >  	if (priv->flags & CRB_FL_ACPI_START)
> > >  		return 0;
> > >
> > >  	iowrite32(CRB_CTRL_REQ_CMD_READY, &priv->regs_t->ctrl_req);
> > > -
> > > -	start = ktime_get();
> > > -	stop = ktime_add(start, ms_to_ktime(TPM2_TIMEOUT_C));
> > > -	do {
> > > -		req = ioread32(&priv->regs_t->ctrl_req);
> > > -		if (!(req & CRB_CTRL_REQ_CMD_READY))
> > > -			return 0;
> > > -		usleep_range(50, 100);
> > > -	} while (ktime_before(ktime_get(), stop));
> > > -
> > > -	if (ioread32(&priv->regs_t->ctrl_req) & CRB_CTRL_REQ_CMD_READY)
> > {
> > > +	if (!crb_wait_for_reg_32(&priv->regs_t->ctrl_req,
> > > +				 CRB_CTRL_REQ_CMD_READY /* mask */,
> > > +				 0, /* value */
> > > +				 TPM2_TIMEOUT_C)) {
> > >  		dev_warn(dev, "cmdReady timed out\n");
> > >  		return -ETIME;
> > >  	}
> > > --
> > > 2.9.3
> > >
> > 
> > ------------------------------------------------------------------------------
> > Check out the vibrant tech community on one of the world's most
> > engaging tech sites, SlashDot.org! http://sdm.link/slashdot
> > _______________________________________________
> > tpmdd-devel mailing list
> > tpmdd-devel@lists.sourceforge.net
> > https://lists.sourceforge.net/lists/listinfo/tpmdd-devel

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

* Re: [PATCH v2 3/3] tpm_crb: request and relinquish locality 0
  2016-12-05 16:32   ` Jason Gunthorpe
@ 2016-12-06 18:40     ` Jarkko Sakkinen
  0 siblings, 0 replies; 18+ messages in thread
From: Jarkko Sakkinen @ 2016-12-06 18:40 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Peter Huewe, Marcel Selhorst, moderated list:TPM DEVICE DRIVER,
	open list

On Mon, Dec 05, 2016 at 09:32:35AM -0700, Jason Gunthorpe wrote:
> On Sat, Dec 03, 2016 at 07:52:13PM +0200, Jarkko Sakkinen wrote:
> > +	iowrite32(CRB_LOC_CTRL_RELINQUISH, &priv->regs_h->loc_ctrl);
> 
> Since regs_h can be null shouldn't there be some guards ?

Yes, there should. Thanks for pointing this out!

/Jarkko

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

* Re: [tpmdd-devel] [PATCH v2 3/3] tpm_crb: request and relinquish locality 0
  2016-12-05 21:51     ` [tpmdd-devel] " Winkler, Tomas
@ 2016-12-06 18:41       ` Jarkko Sakkinen
  0 siblings, 0 replies; 18+ messages in thread
From: Jarkko Sakkinen @ 2016-12-06 18:41 UTC (permalink / raw)
  To: Winkler, Tomas
  Cc: Peter Huewe, linux-security-module,
	moderated list:TPM DEVICE DRIVER, open list

On Mon, Dec 05, 2016 at 09:51:42PM +0000, Winkler, Tomas wrote:
> > 
> > CC linux-security-module
> > 
> > On Sat, Dec 03, 2016 at 07:52:13PM +0200, Jarkko Sakkinen wrote:
> > > Request and relinquish locality for the driver use in order to be a
> > > better citizen in a multi locality environment like TXT. The locality
> > > is requested and relinquished as part of going into and waking up from
> > > idle.
> > 
> This has nothing to do with power management, please note, that this is run via runtime_pm handlers, 
> which can be disabled  via sysfs and actually on server platforms runtime pm is not relevant, 
> while you cannot disable locality acquire/relinquish flow.
> 
> NACK

Good point. I'll move it as part of tpm_transmit()

/Jarkko

> > > Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
> > > ---
> > >  drivers/char/tpm/tpm_crb.c | 36 ++++++++++++++++++++++++------------
> > >  1 file changed, 24 insertions(+), 12 deletions(-)
> > >
> > > diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
> > > index f986d02..f6e0beb 100644
> > > --- a/drivers/char/tpm/tpm_crb.c
> > > +++ b/drivers/char/tpm/tpm_crb.c
> > > @@ -34,6 +34,15 @@ enum crb_defaults {
> > >  	CRB_ACPI_START_INDEX = 1,
> > >  };
> > >
> > > +enum crb_loc_ctrl {
> > > +	CRB_LOC_CTRL_REQUEST_ACCESS	= BIT(0),
> > > +	CRB_LOC_CTRL_RELINQUISH		= BIT(1),
> > > +};
> > > +
> > > +enum crb_loc_state {
> > > +	CRB_LOC_STATE_LOC_ASSIGNED	= BIT(1),
> > > +};
> > > +
> > >  enum crb_ctrl_req {
> > >  	CRB_CTRL_REQ_CMD_READY	= BIT(0),
> > >  	CRB_CTRL_REQ_GO_IDLE	= BIT(1),
> > > @@ -101,12 +110,8 @@ struct crb_priv {
> > >   * @dev:  crb device
> > >   * @priv: crb private data
> > >   *
> > > - * Write CRB_CTRL_REQ_GO_IDLE to TPM_CRB_CTRL_REQ
> > > - * The device should respond within TIMEOUT_C by clearing the bit.
> > > - * Anyhow, we do not wait here as a consequent CMD_READY request
> > > - * will be handled correctly even if idle was not completed.
> > > - *
> > > - * The function does nothing for devices with ACPI-start method.
> > > + * Put device to the idle state and relinquish locality. The function
> > > + does
> > > + * nothing for devices with the ACPI-start method.
> > >   *
> > >   * Return: 0 always
> > >   */
> > > @@ -115,6 +120,7 @@ static int __maybe_unused crb_go_idle(struct device
> > *dev, struct crb_priv *priv)
> > >  	if (priv->flags & CRB_FL_ACPI_START)
> > >  		return 0;
> > >
> > > +	iowrite32(CRB_LOC_CTRL_RELINQUISH, &priv->regs_h->loc_ctrl);	
> This is misleading this has nothing to do with go idle,  what is the 
> > >  	iowrite32(CRB_CTRL_REQ_GO_IDLE, &priv->regs_t->ctrl_req);
> > >  	/* we don't really care when this settles */
> > >
> > > @@ -146,11 +152,8 @@ static bool crb_wait_for_reg_32(u32 __iomem *reg,
> > u32 mask, u32 value,
> > >   * @dev:  crb device
> > >   * @priv: crb private data
> > >   *
> > > - * Write CRB_CTRL_REQ_CMD_READY to TPM_CRB_CTRL_REQ
> > > - * and poll till the device acknowledge it by clearing the bit.
> > > - * The device should respond within TIMEOUT_C.
> > > - *
> > > - * The function does nothing for devices with ACPI-start method
> > > + * Try to wake up the device and request locality. The function does
> > > + nothing
> > > + * for devices with the ACPI-start method.
> > >   *
> > >   * Return: 0 on success -ETIME on timeout;
> > >   */
> > > @@ -165,7 +168,16 @@ static int __maybe_unused crb_cmd_ready(struct
> > device *dev,
> > >  				 CRB_CTRL_REQ_CMD_READY /* mask */,
> > >  				 0, /* value */
> > >  				 TPM2_TIMEOUT_C)) {
> > > -		dev_warn(dev, "cmdReady timed out\n");
> > > +		dev_warn(dev, "TPM_CRB_CTRL_REQ_x.cmdReady timed
> > out\n");
> We are always in locality 0 here, right?
> 
> > > +		return -ETIME;
> > > +	}
> > > +
> > > +	iowrite32(CRB_LOC_CTRL_REQUEST_ACCESS, &priv->regs_h-
> > >loc_ctrl);
> > > +	if (!crb_wait_for_reg_32(&priv->regs_h->loc_state,
> > > +				 CRB_LOC_STATE_LOC_ASSIGNED, /* mask */
> > > +				 CRB_LOC_STATE_LOC_ASSIGNED, /* value */
> > > +				 TPM2_TIMEOUT_C)) {
> > > +		dev_warn(dev, "TPM_LOC_STATE_x.requestAccess timed
> > out\n");
> 
> 
> > >  		return -ETIME;
> > >  	}
>  
> 

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

end of thread, other threads:[~2016-12-06 18:43 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-12-03 17:52 [PATCH v2 0/3] Locality support for tpm_crb Jarkko Sakkinen
2016-12-03 17:52 ` [PATCH v2 1/3] tpm_crb: map locality registers Jarkko Sakkinen
2016-12-03 18:41   ` Jarkko Sakkinen
2016-12-05 12:07     ` [tpmdd-devel] " Winkler, Tomas
2016-12-05 12:21       ` Jarkko Sakkinen
2016-12-05 21:31         ` Winkler, Tomas
2016-12-06 18:35           ` Jarkko Sakkinen
2016-12-03 17:52 ` [PATCH v2 2/3] tpm_crb: encapsulate crb_wait_for_reg_32 Jarkko Sakkinen
2016-12-03 18:41   ` Jarkko Sakkinen
2016-12-05 21:34     ` [tpmdd-devel] " Winkler, Tomas
2016-12-06 18:38       ` Jarkko Sakkinen
2016-12-03 17:52 ` [PATCH v2 3/3] tpm_crb: request and relinquish locality 0 Jarkko Sakkinen
2016-12-03 18:42   ` Jarkko Sakkinen
2016-12-05 21:51     ` [tpmdd-devel] " Winkler, Tomas
2016-12-06 18:41       ` Jarkko Sakkinen
2016-12-05 16:32   ` Jason Gunthorpe
2016-12-06 18:40     ` Jarkko Sakkinen
2016-12-03 18:40 ` [PATCH v2 0/3] Locality support for tpm_crb Jarkko Sakkinen

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