linux-kernel.vger.kernel.org archive mirror
 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 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).