diff mbox

[v9,11/17] platform/x86: dell-smbios-smm: test for WSMT

Message ID e552ba67da7281d184936a551501c4040510b372.1508259916.git.mario.limonciello@dell.com (mailing list archive)
State Superseded, archived
Delegated to: Darren Hart
Headers show

Commit Message

Limonciello, Mario Oct. 17, 2017, 6:21 p.m. UTC
WSMT is as an attestation to the OS that the platform won't
modify memory outside of pre-defined areas.

If a platform has WSMT enabled in BIOS setup, SMM calls through
dcdbas will fail.  The only way to access platform data in these
instances is through the WMI SMBIOS calling interface.

Signed-off-by: Mario Limonciello <mario.limonciello@dell.com>
Reviewed-by: Edward O'Callaghan <quasisec@google.com>
---
 drivers/platform/x86/dell-smbios-smm.c | 33 +++++++++++++++++++++++++++++++++
 drivers/platform/x86/dell-smbios.h     |  2 ++
 2 files changed, 35 insertions(+)

Comments

Pali Rohár Oct. 17, 2017, 7:22 p.m. UTC | #1
On Tuesday 17 October 2017 13:21:55 Mario Limonciello wrote:
> +/* When enabled this indicates that SMM won't work */
> +static int test_wsmt_enabled(void)
> +{
> +	struct calling_interface_token *token;
> +
> +	/* if token doesn't exist, SMM will work */
> +	token = dell_smbios_find_token(WSMT_EN_TOKEN);
> +	if (!token)
> +		return 0;
> +
> +	/* if token exists, try to access over SMM */
> +	buffer->class = CLASS_TOKEN_READ;
> +	buffer->select = SELECT_TOKEN_STD;
> +	memset(buffer, 0, sizeof(struct calling_interface_buffer));
> +	buffer->input[0] = token->location;
> +	dell_smbios_smm_call(buffer);
> +
> +	/* if lookup failed, we know WSMT was enabled */
> +	if (buffer->output[0] != 0)
> +		return 1;
> +
> +	/* query token status if it didn't fail */
> +	return (buffer->output[1] == token->value);
> +}

Maybe small suggestion... function returns only zero or one -- what is a
good candidate to have return value boolean and not basic int.
Darren Hart Oct. 18, 2017, 7:09 p.m. UTC | #2
On Tue, Oct 17, 2017 at 09:22:58PM +0200, Pali Rohár wrote:
> On Tuesday 17 October 2017 13:21:55 Mario Limonciello wrote:
> > +/* When enabled this indicates that SMM won't work */
> > +static int test_wsmt_enabled(void)
> > +{
> > +	struct calling_interface_token *token;
> > +
> > +	/* if token doesn't exist, SMM will work */
> > +	token = dell_smbios_find_token(WSMT_EN_TOKEN);
> > +	if (!token)
> > +		return 0;
> > +
> > +	/* if token exists, try to access over SMM */
> > +	buffer->class = CLASS_TOKEN_READ;
> > +	buffer->select = SELECT_TOKEN_STD;
> > +	memset(buffer, 0, sizeof(struct calling_interface_buffer));
> > +	buffer->input[0] = token->location;
> > +	dell_smbios_smm_call(buffer);
> > +
> > +	/* if lookup failed, we know WSMT was enabled */
> > +	if (buffer->output[0] != 0)
> > +		return 1;
> > +
> > +	/* query token status if it didn't fail */
> > +	return (buffer->output[1] == token->value);
> > +}
> 
> Maybe small suggestion... function returns only zero or one -- what is a
> good candidate to have return value boolean and not basic int.

Yes please.
Limonciello, Mario Oct. 18, 2017, 7:10 p.m. UTC | #3
> -----Original Message-----
> From: Darren Hart [mailto:dvhart@infradead.org]
> Sent: Wednesday, October 18, 2017 2:09 PM
> To: Pali Rohár <pali.rohar@gmail.com>
> Cc: Limonciello, Mario <Mario_Limonciello@Dell.com>; Andy Shevchenko
> <andy.shevchenko@gmail.com>; LKML <linux-kernel@vger.kernel.org>; platform-
> driver-x86@vger.kernel.org; Andy Lutomirski <luto@kernel.org>;
> quasisec@google.com; rjw@rjwysocki.net; mjg59@google.com; hch@lst.de; Greg
> KH <greg@kroah.com>; Alan Cox <gnomes@lxorguk.ukuu.org.uk>
> Subject: Re: [PATCH v9 11/17] platform/x86: dell-smbios-smm: test for WSMT
> 
> On Tue, Oct 17, 2017 at 09:22:58PM +0200, Pali Rohár wrote:
> > On Tuesday 17 October 2017 13:21:55 Mario Limonciello wrote:
> > > +/* When enabled this indicates that SMM won't work */
> > > +static int test_wsmt_enabled(void)
> > > +{
> > > +	struct calling_interface_token *token;
> > > +
> > > +	/* if token doesn't exist, SMM will work */
> > > +	token = dell_smbios_find_token(WSMT_EN_TOKEN);
> > > +	if (!token)
> > > +		return 0;
> > > +
> > > +	/* if token exists, try to access over SMM */
> > > +	buffer->class = CLASS_TOKEN_READ;
> > > +	buffer->select = SELECT_TOKEN_STD;
> > > +	memset(buffer, 0, sizeof(struct calling_interface_buffer));
> > > +	buffer->input[0] = token->location;
> > > +	dell_smbios_smm_call(buffer);
> > > +
> > > +	/* if lookup failed, we know WSMT was enabled */
> > > +	if (buffer->output[0] != 0)
> > > +		return 1;
> > > +
> > > +	/* query token status if it didn't fail */
> > > +	return (buffer->output[1] == token->value);
> > > +}
> >
> > Maybe small suggestion... function returns only zero or one -- what is a
> > good candidate to have return value boolean and not basic int.
> 
> Yes please.
> 

OK I'll adjust this (and the other things Pali sent recently) in the next submission.

Just waiting on feedback for some of the other areas before sending off again.
diff mbox

Patch

diff --git a/drivers/platform/x86/dell-smbios-smm.c b/drivers/platform/x86/dell-smbios-smm.c
index 53eabb14fb48..c2dfe4c5908c 100644
--- a/drivers/platform/x86/dell-smbios-smm.c
+++ b/drivers/platform/x86/dell-smbios-smm.c
@@ -102,6 +102,31 @@  int dell_smbios_smm_call(struct calling_interface_buffer *input)
 	return 0;
 }
 
+/* When enabled this indicates that SMM won't work */
+static int test_wsmt_enabled(void)
+{
+	struct calling_interface_token *token;
+
+	/* if token doesn't exist, SMM will work */
+	token = dell_smbios_find_token(WSMT_EN_TOKEN);
+	if (!token)
+		return 0;
+
+	/* if token exists, try to access over SMM */
+	buffer->class = CLASS_TOKEN_READ;
+	buffer->select = SELECT_TOKEN_STD;
+	memset(buffer, 0, sizeof(struct calling_interface_buffer));
+	buffer->input[0] = token->location;
+	dell_smbios_smm_call(buffer);
+
+	/* if lookup failed, we know WSMT was enabled */
+	if (buffer->output[0] != 0)
+		return 1;
+
+	/* query token status if it didn't fail */
+	return (buffer->output[1] == token->value);
+}
+
 static int __init dell_smbios_smm_init(void)
 {
 	int ret;
@@ -115,6 +140,13 @@  static int __init dell_smbios_smm_init(void)
 
 	dmi_walk(find_cmd_address, NULL);
 
+	ret = test_wsmt_enabled();
+	pr_debug("WSMT enable test: %d\n", ret);
+	if (ret) {
+		ret = -ENODEV;
+		goto fail_wsmt;
+	}
+
 	platform_device = platform_device_alloc("dell-smbios", 1);
 	if (!platform_device) {
 		ret = -ENOMEM;
@@ -138,6 +170,7 @@  static int __init dell_smbios_smm_init(void)
 fail_platform_device_add:
 	platform_device_put(platform_device);
 
+fail_wsmt:
 fail_platform_device_alloc:
 	free_page((unsigned long)buffer);
 	return ret;
diff --git a/drivers/platform/x86/dell-smbios.h b/drivers/platform/x86/dell-smbios.h
index 8df330abeb5d..db6a16e5f87c 100644
--- a/drivers/platform/x86/dell-smbios.h
+++ b/drivers/platform/x86/dell-smbios.h
@@ -44,6 +44,8 @@ 
 #define KBD_LED_AUTO_100_TOKEN	0x02F6
 #define GLOBAL_MIC_MUTE_ENABLE	0x0364
 #define GLOBAL_MIC_MUTE_DISABLE	0x0365
+#define WSMT_EN_TOKEN		0x04EC
+#define WSMT_DIS_TOKEN		0x04ED
 
 struct notifier_block;