All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stefan Berger <stefanb@linux.vnet.ibm.com>
To: John Hughes <john@calvaedi.com>
Cc: Jonathan Nieder <jrnieder@gmail.com>,
	John Hughes <john@atlantech.com>,
	Jeff Layton <jlayton@poochiereds.net>,
	linux-kernel@vger.kernel.org, tpmdd-devel@lists.sourceforge.net,
	Rajiv Andrade <srajiv@linux.vnet.ibm.com>,
	Eric Paris <eparis@redhat.com>
Subject: Re: [Sony Vaio TX3] TPM chip prevents machine from suspending a second time
Date: Sun, 29 Jan 2012 13:22:04 -0500	[thread overview]
Message-ID: <4F258E4C.8020606@linux.vnet.ibm.com> (raw)
In-Reply-To: <4F252441.3090507@calvaedi.com>

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

On 01/29/2012 05:49 AM, John Hughes wrote:
> On 23/01/12 21:52, Stefan Berger wrote:
>>
>> Can you apply the patch below to your tpm_tis.c (or somewhere else in 
>> the kernel) and let me/us know what it reports in 'dmesg' upon a 
>> 'modprobe tpm_tis'?
>
> [   48.826151] tpm_tis 00:07: dmi: 0: (null)
> [   48.826157] tpm_tis 00:07: dmi: 1: Phoenix Technologies LTD
> [   48.826161] tpm_tis 00:07: dmi: 2: R0021N3
> [   48.826165] tpm_tis 00:07: dmi: 3: 05/09/2006
> [   48.826169] tpm_tis 00:07: dmi: 4: Sony Corporation
> [   48.826173] tpm_tis 00:07: dmi: 5: VGN-TX3XP_B
> [   48.826177] tpm_tis 00:07: dmi: 6: J001QHZL
> [   48.826181] tpm_tis 00:07: dmi: 7: 28244651-5000176
> [   48.826186] tpm_tis 00:07: dmi: 8: 
> DC744BA0-5B3C-11D9-8822-0013A93CCD4D
> [   48.826190] tpm_tis 00:07: dmi: 9: Sony Corporation
> [   48.826195] tpm_tis 00:07: dmi: 10: VAIO
> [   48.826199] tpm_tis 00:07: dmi: 11: N/A
> [   48.826204] tpm_tis 00:07: dmi: 12: N/A
> [   48.826208] tpm_tis 00:07: dmi: 13: N/A
> [   48.826213] tpm_tis 00:07: dmi: 14: Sony Corporation
> [   48.826217] tpm_tis 00:07: dmi: 15: 10
> [   48.826221] tpm_tis 00:07: dmi: 16: N/A
> [   48.826225] tpm_tis 00:07: dmi: 17: J001QHZL
> [   48.826229] tpm_tis 00:07: dmi: 18:
> [   48.826235] tpm_tis 00:07: 1.2 TPM (device-id 0xB, rev-id 16)
>
Thanks. Please try the attached patch.

I am not sure whether this is the right way to go, though: Is it a 
problem particular to this BIOS + Board or a general problem of this 
BIOS? Is it specific to the TX3 or to all VAIOs?

   Stefan




[-- Attachment #2: tpm_resume_quirks.diff --]
[-- Type: text/plain, Size: 5699 bytes --]

Add a TPM resume quirk for machines where the BIOS doesn't send the
TPM_Startup(ST_STATE) to the TPM and subsequent suspends fail due
to this. Identify machines by their SMBIOS data and only apply the quirk
on those known to need it.

Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>

---
 drivers/char/tpm/tpm.c |  153 +++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/char/tpm/tpm.h |    8 ++
 2 files changed, 161 insertions(+)

Index: linux-2.6/drivers/char/tpm/tpm.c
===================================================================
--- linux-2.6.orig/drivers/char/tpm/tpm.c
+++ linux-2.6/drivers/char/tpm/tpm.c
@@ -28,6 +28,7 @@
 #include <linux/mutex.h>
 #include <linux/spinlock.h>
 #include <linux/freezer.h>
+#include <linux/dmi.h>
 
 #include "tpm.h"
 
@@ -62,6 +63,131 @@ static LIST_HEAD(tpm_chip_list);
 static DEFINE_SPINLOCK(driver_lock);
 static DECLARE_BITMAP(dev_mask, TPM_NUM_DEVICES);
 
+/***** tpm quirks *****/
+
+#ifdef CONFIG_DMI
+
+struct tpm_dmi_entry {
+	enum dmi_field id;
+	const char **value;
+};
+
+struct tpm_resume_quirks {
+	const char *quirk_name;
+	const struct tpm_dmi_entry *dmi_entry;
+};
+
+#define TPM_DMI_ENTRY_LAST \
+	{ .id = DMI_NONE, .value = (const char*[]) { NULL }, }
+
+static const struct tpm_resume_quirks tpm_resume_quirks[] = {
+	{
+		.quirk_name = "Sony Vaio TX3",
+		.dmi_entry = (struct tpm_dmi_entry[]) {
+			{
+				.id = DMI_BIOS_VENDOR,
+				.value = (const char*[]) {
+					"Phoenix Technologies LTD",
+					NULL,
+				},
+			},
+			{
+				.id = DMI_SYS_VENDOR,
+				.value = (const char*[]) {
+					"Sony Corporation",
+					NULL,
+				},
+			},
+			{
+				.id = DMI_PRODUCT_NAME,
+				.value = (const char*[]) {
+					"VGN-TX3XP_B",
+					NULL,
+				},
+			},
+			{
+				.id = DMI_BOARD_NAME,
+				.value = (const char*[]) {
+					"VAIO",
+					NULL,
+				},
+			},
+			TPM_DMI_ENTRY_LAST
+		}
+	}
+};
+
+bool find_str_in_array(const char **array, const char *val)
+{
+	int i = 0;
+
+	while (array[i]) {
+		if (!strcmp(array[i++], val))
+			return true;
+	}
+
+	return false;
+}
+
+static bool tpm_resume_quirk_dmi(struct tpm_chip *chip)
+{
+	int i, j, rc;
+	bool found = false, handled = false;
+	const char *val;
+	const struct tpm_dmi_entry *dmi_entry;
+
+	for (i = 0; i < ARRAY_SIZE(tpm_resume_quirks) && !handled; i++) {
+		j = 0;
+		found = true;
+
+		while (true) {
+			dmi_entry = &tpm_resume_quirks[i].dmi_entry[j];
+
+			if (dmi_entry->id == DMI_NONE)
+				break;
+
+			val = dmi_get_system_info(dmi_entry->id);
+			if (!val) {
+				found = false;
+				break;
+			}
+
+			found = find_str_in_array(dmi_entry->value, val);
+			if (!found)
+				break;
+			j++;
+		}
+
+		if (found) {
+			dev_info(chip->dev,
+				 "Using tpm resume quirk '%s'.\n",
+				 tpm_resume_quirks[i].quirk_name);
+			rc = tpm_startup_ststate(chip);
+			if (rc < 0)
+				dev_err(chip->dev,
+					"quirk: TPM startup(ST_STATE) "
+					"failed.\n");
+			handled = true;
+			break;
+		}
+	}
+	return handled;
+}
+
+#else
+
+static bool tpm_resume_quirk_dmi(struct tpm_chip *tpm_chip)
+{
+	return false;
+}
+
+#endif
+
+static void tpm_resume_quirk(struct tpm_chip *tpm_chip)
+{
+	tpm_resume_quirk_dmi(tpm_chip);
+}
+
 /*
  * Array with one entry per ordinal defining the maximum amount
  * of time the chip could take to return the result.  The ordinal
@@ -864,6 +990,31 @@ int tpm_do_selftest(struct tpm_chip *chi
 }
 EXPORT_SYMBOL_GPL(tpm_do_selftest);
 
+/**
+ * tpm_startup_ststate - send a ststartup to the TPM
+ */
+#define TPM_ORD_STARTUP 153
+#define STARTUP_RESULT_SIZE 10
+
+static struct tpm_input_header startup_ststate_header = {
+	.tag = TPM_TAG_RQU_COMMAND,
+	.length = cpu_to_be32(10),
+	.ordinal = cpu_to_be32(TPM_ORD_STARTUP),
+};
+
+int tpm_startup_ststate(struct tpm_chip *chip)
+{
+	int rc;
+	struct tpm_cmd_t cmd;
+
+	cmd.header.in = startup_ststate_header;
+	cmd.params.startup_in.state = cpu_to_be16(TPM_ST_STATE);
+	rc = transmit_cmd(chip, &cmd, STARTUP_RESULT_SIZE,
+			  "startup(st_state)");
+	return rc;
+}
+EXPORT_SYMBOL_GPL(tpm_startup_ststate);
+
 int tpm_send(u32 chip_num, void *cmd, size_t buflen)
 {
 	struct tpm_chip *chip;
@@ -1313,6 +1464,8 @@ int tpm_pm_resume(struct device *dev)
 	if (chip == NULL)
 		return -ENODEV;
 
+	tpm_resume_quirk(chip);
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(tpm_pm_resume);
Index: linux-2.6/drivers/char/tpm/tpm.h
===================================================================
--- linux-2.6.orig/drivers/char/tpm/tpm.h
+++ linux-2.6/drivers/char/tpm/tpm.h
@@ -42,6 +42,8 @@ enum tpm_addr {
 #define TPM_ERR_DEACTIVATED     0x6
 #define TPM_ERR_DISABLED        0x7
 
+#define TPM_ST_STATE            0x2
+
 #define TPM_HEADER_SIZE		10
 extern ssize_t tpm_show_pubek(struct device *, struct device_attribute *attr,
 				char *);
@@ -269,6 +271,10 @@ struct tpm_pcrextend_in {
 	u8	hash[TPM_DIGEST_SIZE];
 }__attribute__((packed));
 
+struct tpm_startup_in {
+	__be16 state;
+} __packed;
+
 typedef union {
 	struct	tpm_getcap_params_out getcap_out;
 	struct	tpm_readpubek_params_out readpubek_out;
@@ -277,6 +283,7 @@ typedef union {
 	struct	tpm_pcrread_in	pcrread_in;
 	struct	tpm_pcrread_out	pcrread_out;
 	struct	tpm_pcrextend_in pcrextend_in;
+	struct  tpm_startup_in startup_in;
 } tpm_cmd_params;
 
 struct tpm_cmd_t {
@@ -289,6 +296,7 @@ ssize_t	tpm_getcap(struct device *, __be
 extern int tpm_get_timeouts(struct tpm_chip *);
 extern void tpm_gen_interrupt(struct tpm_chip *);
 extern int tpm_do_selftest(struct tpm_chip *);
+extern int tpm_startup_ststate(struct tpm_chip *);
 extern unsigned long tpm_calc_ordinal_duration(struct tpm_chip *, u32);
 extern struct tpm_chip* tpm_register_hardware(struct device *,
 				 const struct tpm_vendor_specific *);

  reply	other threads:[~2012-01-29 18:22 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-03-28 14:08 TPM chip prevents machine from suspending Jeff Layton
2011-03-28 17:25 ` Stefan Berger
2011-03-28 18:12   ` Jeff Layton
2011-03-28 19:45     ` Jeff Layton
2011-03-28 19:57       ` Sisir Koppaka
2011-03-28 20:16         ` Jeff Layton
2011-03-28 20:32           ` Sisir Koppaka
2011-03-28 23:10       ` Stefan Berger
2011-03-29  0:19         ` Stefan Berger
2011-03-29 12:08         ` Jeff Layton
2011-03-29 12:25           ` Stefan Berger
2011-03-29 12:30             ` Jeff Layton
2011-03-29 14:30             ` Rajiv Andrade
2011-03-29 15:03               ` Stefan Berger
2011-03-30 19:43                 ` [tpmdd-devel] " Eric Paris
2012-01-21 17:01         ` [Sony Vaio TX3] TPM chip prevents machine from suspending a second time Jonathan Nieder
2012-01-23 20:52           ` Stefan Berger
2012-01-29 10:49             ` John Hughes
2012-01-29 18:22               ` Stefan Berger [this message]
2012-01-30  9:10                 ` John Hughes
2012-02-26 15:44                   ` Jonathan Nieder
2012-05-03 15:34                     ` John Hughes

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4F258E4C.8020606@linux.vnet.ibm.com \
    --to=stefanb@linux.vnet.ibm.com \
    --cc=eparis@redhat.com \
    --cc=jlayton@poochiereds.net \
    --cc=john@atlantech.com \
    --cc=john@calvaedi.com \
    --cc=jrnieder@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=srajiv@linux.vnet.ibm.com \
    --cc=tpmdd-devel@lists.sourceforge.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.