]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
platform/x86: dell-smbios-smm: test for WSMT
authorMario Limonciello <mario.limonciello@dell.com>
Wed, 1 Nov 2017 19:25:33 +0000 (14:25 -0500)
committerDarren Hart (VMware) <dvhart@infradead.org>
Fri, 3 Nov 2017 23:33:59 +0000 (16:33 -0700)
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>
Signed-off-by: Darren Hart (VMware) <dvhart@infradead.org>
drivers/platform/x86/dell-smbios-smm.c
drivers/platform/x86/dell-smbios.h

index 53eabb14fb481b258836d913972979e65e47a1dd..89f65c4651a04151aa1002afd65f8a0736f7a776 100644 (file)
@@ -102,6 +102,32 @@ int dell_smbios_smm_call(struct calling_interface_buffer *input)
        return 0;
 }
 
+/* When enabled this indicates that SMM won't work */
+static bool test_wsmt_enabled(void)
+{
+       struct calling_interface_token *wsmt;
+
+       /* if token doesn't exist, SMM will work */
+       wsmt = dell_smbios_find_token(WSMT_EN_TOKEN);
+       if (!wsmt)
+               return false;
+
+       /* If token exists, try to access over SMM but set a dummy return.
+        * - If WSMT disabled it will be overwritten by SMM
+        * - If WSMT enabled then dummy value will remain
+        */
+       buffer->cmd_class = CLASS_TOKEN_READ;
+       buffer->cmd_select = SELECT_TOKEN_STD;
+       memset(buffer, 0, sizeof(struct calling_interface_buffer));
+       buffer->input[0] = wsmt->location;
+       buffer->output[0] = 99;
+       dell_smbios_smm_call(buffer);
+       if (buffer->output[0] == 99)
+               return true;
+
+       return false;
+}
+
 static int __init dell_smbios_smm_init(void)
 {
        int ret;
@@ -115,6 +141,12 @@ static int __init dell_smbios_smm_init(void)
 
        dmi_walk(find_cmd_address, NULL);
 
+       if (test_wsmt_enabled()) {
+               pr_debug("Disabling due to WSMT enabled\n");
+               ret = -ENODEV;
+               goto fail_wsmt;
+       }
+
        platform_device = platform_device_alloc("dell-smbios", 1);
        if (!platform_device) {
                ret = -ENOMEM;
@@ -138,6 +170,7 @@ fail_register:
 fail_platform_device_add:
        platform_device_put(platform_device);
 
+fail_wsmt:
 fail_platform_device_alloc:
        free_page((unsigned long)buffer);
        return ret;
index b3179f5b326b6126bf5f913a4a4bc34b1e15cc66..07effdc7ae8b64d87b536c6ab4572166b2c4b1dc 100644 (file)
@@ -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;