hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/firmware/google/gsmi.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright 2010 Google Inc. All Rights Reserved.
34 * Author: dlaurie@google.com (Duncan Laurie)
....@@ -29,6 +30,7 @@
2930 #include <linux/efi.h>
3031 #include <linux/module.h>
3132 #include <linux/ucs2_string.h>
33
+#include <linux/suspend.h>
3234
3335 #define GSMI_SHUTDOWN_CLEAN 0 /* Clean Shutdown */
3436 /* TODO(mikew@google.com): Tie in HARDLOCKUP_DETECTOR with NMIWDT */
....@@ -70,8 +72,11 @@
7072 #define GSMI_CMD_SET_NVRAM_VAR 0x03
7173 #define GSMI_CMD_SET_EVENT_LOG 0x08
7274 #define GSMI_CMD_CLEAR_EVENT_LOG 0x09
75
+#define GSMI_CMD_LOG_S0IX_SUSPEND 0x0a
76
+#define GSMI_CMD_LOG_S0IX_RESUME 0x0b
7377 #define GSMI_CMD_CLEAR_CONFIG 0x20
7478 #define GSMI_CMD_HANDSHAKE_TYPE 0xC1
79
+#define GSMI_CMD_RESERVED 0xff
7580
7681 /* Magic entry type for kernel events */
7782 #define GSMI_LOG_ENTRY_TYPE_KERNEL 0xDEAD
....@@ -84,7 +89,7 @@
8489 u32 address; /* physical address of buffer */
8590 };
8691
87
-struct gsmi_device {
92
+static struct gsmi_device {
8893 struct platform_device *pdev; /* platform device */
8994 struct gsmi_buf *name_buf; /* variable name buffer */
9095 struct gsmi_buf *data_buf; /* generic data buffer */
....@@ -122,7 +127,6 @@
122127 u32 instance;
123128 } __packed;
124129
125
-
126130 /*
127131 * Some platforms don't have explicit SMI handshake
128132 * and need to wait for SMI to complete.
....@@ -132,6 +136,15 @@
132136 module_param(spincount, uint, 0600);
133137 MODULE_PARM_DESC(spincount,
134138 "The number of loop iterations to use when using the spin handshake.");
139
+
140
+/*
141
+ * Platforms might not support S0ix logging in their GSMI handlers. In order to
142
+ * avoid any side-effects of generating an SMI for S0ix logging, use the S0ix
143
+ * related GSMI commands only for those platforms that explicitly enable this
144
+ * option.
145
+ */
146
+static bool s0ix_logging_enable;
147
+module_param(s0ix_logging_enable, bool, 0600);
135148
136149 static struct gsmi_buf *gsmi_buf_alloc(void)
137150 {
....@@ -288,6 +301,10 @@
288301
289302 return rc;
290303 }
304
+
305
+#ifdef CONFIG_EFI
306
+
307
+static struct efivars efivars;
291308
292309 static efi_status_t gsmi_get_variable(efi_char16_t *name,
293310 efi_guid_t *vendor, u32 *attr,
....@@ -465,6 +482,8 @@
465482 .set_variable = gsmi_set_variable,
466483 .get_next_variable = gsmi_get_next_variable,
467484 };
485
+
486
+#endif /* CONFIG_EFI */
468487
469488 static ssize_t eventlog_write(struct file *filp, struct kobject *kobj,
470489 struct bin_attribute *bin_attr,
....@@ -661,6 +680,15 @@
661680 static int gsmi_panic_callback(struct notifier_block *nb,
662681 unsigned long reason, void *arg)
663682 {
683
+
684
+ /*
685
+ * Panic callbacks are executed with all other CPUs stopped,
686
+ * so we must not attempt to spin waiting for gsmi_dev.lock
687
+ * to be released.
688
+ */
689
+ if (spin_is_locked(&gsmi_dev.lock))
690
+ return NOTIFY_DONE;
691
+
664692 gsmi_shutdown_reason(GSMI_SHUTDOWN_PANIC);
665693 return NOTIFY_DONE;
666694 }
....@@ -715,6 +743,12 @@
715743 DMI_MATCH(DMI_BOARD_VENDOR, "Google, Inc."),
716744 },
717745 },
746
+ {
747
+ .ident = "Coreboot Firmware",
748
+ .matches = {
749
+ DMI_MATCH(DMI_BIOS_VENDOR, "coreboot"),
750
+ },
751
+ },
718752 {}
719753 };
720754 MODULE_DEVICE_TABLE(dmi, gsmi_dmi_table);
....@@ -722,6 +756,7 @@
722756 static __init int gsmi_system_valid(void)
723757 {
724758 u32 hash;
759
+ u16 cmd, result;
725760
726761 if (!dmi_check_system(gsmi_dmi_table))
727762 return -ENODEV;
....@@ -756,12 +791,28 @@
756791 return -ENODEV;
757792 }
758793
794
+ /* Test the smihandler with a bogus command. If it leaves the
795
+ * calling argument in %ax untouched, there is no handler for
796
+ * GSMI commands.
797
+ */
798
+ cmd = GSMI_CALLBACK | GSMI_CMD_RESERVED << 8;
799
+ asm volatile (
800
+ "outb %%al, %%dx\n\t"
801
+ : "=a" (result)
802
+ : "0" (cmd),
803
+ "d" (acpi_gbl_FADT.smi_command)
804
+ : "memory", "cc"
805
+ );
806
+ if (cmd == result) {
807
+ pr_info("gsmi: no gsmi handler in firmware\n");
808
+ return -ENODEV;
809
+ }
810
+
759811 /* Found */
760812 return 0;
761813 }
762814
763815 static struct kobject *gsmi_kobj;
764
-static struct efivars efivars;
765816
766817 static const struct platform_device_info gsmi_dev_info = {
767818 .name = "gsmi",
....@@ -769,6 +820,78 @@
769820 /* SMI callbacks require 32bit addresses */
770821 .dma_mask = DMA_BIT_MASK(32),
771822 };
823
+
824
+#ifdef CONFIG_PM
825
+static void gsmi_log_s0ix_info(u8 cmd)
826
+{
827
+ unsigned long flags;
828
+
829
+ /*
830
+ * If platform has not enabled S0ix logging, then no action is
831
+ * necessary.
832
+ */
833
+ if (!s0ix_logging_enable)
834
+ return;
835
+
836
+ spin_lock_irqsave(&gsmi_dev.lock, flags);
837
+
838
+ memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
839
+
840
+ gsmi_exec(GSMI_CALLBACK, cmd);
841
+
842
+ spin_unlock_irqrestore(&gsmi_dev.lock, flags);
843
+}
844
+
845
+static int gsmi_log_s0ix_suspend(struct device *dev)
846
+{
847
+ /*
848
+ * If system is not suspending via firmware using the standard ACPI Sx
849
+ * types, then make a GSMI call to log the suspend info.
850
+ */
851
+ if (!pm_suspend_via_firmware())
852
+ gsmi_log_s0ix_info(GSMI_CMD_LOG_S0IX_SUSPEND);
853
+
854
+ /*
855
+ * Always return success, since we do not want suspend
856
+ * to fail just because of logging failure.
857
+ */
858
+ return 0;
859
+}
860
+
861
+static int gsmi_log_s0ix_resume(struct device *dev)
862
+{
863
+ /*
864
+ * If system did not resume via firmware, then make a GSMI call to log
865
+ * the resume info and wake source.
866
+ */
867
+ if (!pm_resume_via_firmware())
868
+ gsmi_log_s0ix_info(GSMI_CMD_LOG_S0IX_RESUME);
869
+
870
+ /*
871
+ * Always return success, since we do not want resume
872
+ * to fail just because of logging failure.
873
+ */
874
+ return 0;
875
+}
876
+
877
+static const struct dev_pm_ops gsmi_pm_ops = {
878
+ .suspend_noirq = gsmi_log_s0ix_suspend,
879
+ .resume_noirq = gsmi_log_s0ix_resume,
880
+};
881
+
882
+static int gsmi_platform_driver_probe(struct platform_device *dev)
883
+{
884
+ return 0;
885
+}
886
+
887
+static struct platform_driver gsmi_driver_info = {
888
+ .driver = {
889
+ .name = "gsmi",
890
+ .pm = &gsmi_pm_ops,
891
+ },
892
+ .probe = gsmi_platform_driver_probe,
893
+};
894
+#endif
772895
773896 static __init int gsmi_init(void)
774897 {
....@@ -780,6 +903,14 @@
780903 return ret;
781904
782905 gsmi_dev.smi_cmd = acpi_gbl_FADT.smi_command;
906
+
907
+#ifdef CONFIG_PM
908
+ ret = platform_driver_register(&gsmi_driver_info);
909
+ if (unlikely(ret)) {
910
+ printk(KERN_ERR "gsmi: unable to register platform driver\n");
911
+ return ret;
912
+ }
913
+#endif
783914
784915 /* register device */
785916 gsmi_dev.pdev = platform_device_register_full(&gsmi_dev_info);
....@@ -885,11 +1016,14 @@
8851016 goto out_remove_bin_file;
8861017 }
8871018
1019
+#ifdef CONFIG_EFI
8881020 ret = efivars_register(&efivars, &efivar_ops, gsmi_kobj);
8891021 if (ret) {
8901022 printk(KERN_INFO "gsmi: Failed to register efivars\n");
891
- goto out_remove_sysfs_files;
1023
+ sysfs_remove_files(gsmi_kobj, gsmi_attrs);
1024
+ goto out_remove_bin_file;
8921025 }
1026
+#endif
8931027
8941028 register_reboot_notifier(&gsmi_reboot_notifier);
8951029 register_die_notifier(&gsmi_die_notifier);
....@@ -900,8 +1034,6 @@
9001034
9011035 return 0;
9021036
903
-out_remove_sysfs_files:
904
- sysfs_remove_files(gsmi_kobj, gsmi_attrs);
9051037 out_remove_bin_file:
9061038 sysfs_remove_bin_file(gsmi_kobj, &eventlog_bin_attr);
9071039 out_err:
....@@ -912,6 +1044,9 @@
9121044 dma_pool_destroy(gsmi_dev.dma_pool);
9131045 platform_device_unregister(gsmi_dev.pdev);
9141046 pr_info("gsmi: failed to load: %d\n", ret);
1047
+#ifdef CONFIG_PM
1048
+ platform_driver_unregister(&gsmi_driver_info);
1049
+#endif
9151050 return ret;
9161051 }
9171052
....@@ -921,7 +1056,9 @@
9211056 unregister_die_notifier(&gsmi_die_notifier);
9221057 atomic_notifier_chain_unregister(&panic_notifier_list,
9231058 &gsmi_panic_notifier);
1059
+#ifdef CONFIG_EFI
9241060 efivars_unregister(&efivars);
1061
+#endif
9251062
9261063 sysfs_remove_files(gsmi_kobj, gsmi_attrs);
9271064 sysfs_remove_bin_file(gsmi_kobj, &eventlog_bin_attr);
....@@ -931,6 +1068,9 @@
9311068 gsmi_buf_free(gsmi_dev.name_buf);
9321069 dma_pool_destroy(gsmi_dev.dma_pool);
9331070 platform_device_unregister(gsmi_dev.pdev);
1071
+#ifdef CONFIG_PM
1072
+ platform_driver_unregister(&gsmi_driver_info);
1073
+#endif
9341074 }
9351075
9361076 module_init(gsmi_init);