diff mbox series

[v3] watchdog: it87_wdt: add PWRGD enable quirk for Qotom QCML04

Message ID 20241020232410.2576778-1-james.hilliard1@gmail.com
State Superseded
Headers show
Series [v3] watchdog: it87_wdt: add PWRGD enable quirk for Qotom QCML04 | expand

Commit Message

James Hilliard Oct. 20, 2024, 11:24 p.m. UTC
For the watchdog timer to work properly on the QCML04 board we need to
set PWRGD enable in the Environment Controller Configuration Registers
Special Configuration Register 1 when it is not already set, this may
be the case when the watchdog is not enabled from within the BIOS.

Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
---
Changes v2 -> v3:
  - add linux/bits.h header
  - check for quirks on all it87 chips
Changes v1 -> v2:
  - remove QGLK02/IT87_WDT_BROKEN
---
 drivers/watchdog/it87_wdt.c | 38 +++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

Comments

Guenter Roeck Oct. 21, 2024, 12:13 a.m. UTC | #1
On 10/20/24 16:24, James Hilliard wrote:
> For the watchdog timer to work properly on the QCML04 board we need to
> set PWRGD enable in the Environment Controller Configuration Registers
> Special Configuration Register 1 when it is not already set, this may
> be the case when the watchdog is not enabled from within the BIOS.
> 
> Signed-off-by: James Hilliard <james.hilliard1@gmail.com>

Reviewed-by: Guenter Roeck <linux@roeck-us.net>

Thanks,
Guenter
kernel test robot Oct. 25, 2024, 6:12 a.m. UTC | #2
Hello,

kernel test robot noticed "BUG:KASAN:global-out-of-bounds_in_dmi_first_match" on:

commit: 4a192c0d3e47d9be2fef576b882165a3b459861d ("[PATCH v3] watchdog: it87_wdt: add PWRGD enable quirk for Qotom QCML04")
url: https://github.com/intel-lab-lkp/linux/commits/James-Hilliard/watchdog-it87_wdt-add-PWRGD-enable-quirk-for-Qotom-QCML04/20241021-072541
base: https://git.kernel.org/cgit/linux/kernel/git/groeck/linux-staging.git hwmon-next
patch link: https://lore.kernel.org/all/20241020232410.2576778-1-james.hilliard1@gmail.com/
patch subject: [PATCH v3] watchdog: it87_wdt: add PWRGD enable quirk for Qotom QCML04

in testcase: boot

config: x86_64-randconfig-161-20241021
compiler: gcc-12
test machine: qemu-system-x86_64 -enable-kvm -cpu SandyBridge -smp 2 -m 16G

(please refer to attached dmesg/kmsg for entire log/backtrace)


+---------------------------------------------------+------------+------------+
|                                                   | 516ddbfef7 | 4a192c0d3e |
+---------------------------------------------------+------------+------------+
| BUG:KASAN:global-out-of-bounds_in_dmi_first_match | 0          | 12         |
+---------------------------------------------------+------------+------------+


If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <oliver.sang@intel.com>
| Closes: https://lore.kernel.org/oe-lkp/202410251317.64508d45-lkp@intel.com


[ 55.288289][ T1] BUG: KASAN: global-out-of-bounds in dmi_first_match (drivers/firmware/dmi_scan.c:935 (discriminator 1)) 
[   55.289377][    T1] Read of size 1 at addr ffffffff84934b48 by task swapper/0/1
[   55.289377][    T1]
[   55.289377][    T1] CPU: 1 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.12.0-rc1-00023-g4a192c0d3e47 #1
[   55.289377][    T1] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.2-debian-1.16.2-1 04/01/2014
[   55.289377][    T1] Call Trace:
[   55.289377][    T1]  <TASK>
[ 55.289377][ T1] dump_stack_lvl (lib/dump_stack.c:123) 
[ 55.289377][ T1] print_address_description+0x52/0x2d1 
[ 55.289377][ T1] print_report (mm/kasan/report.c:489) 
[ 55.289377][ T1] ? rcu_read_unlock_sched (arch/x86/include/asm/preempt.h:103 (discriminator 9) include/linux/rcupdate.h:964 (discriminator 9)) 
[ 55.289377][ T1] ? __virt_addr_valid (arch/x86/mm/physaddr.c:65) 
[ 55.289377][ T1] ? dmi_first_match (drivers/firmware/dmi_scan.c:935 (discriminator 1)) 
[ 55.289377][ T1] kasan_report (mm/kasan/report.c:603) 
[ 55.289377][ T1] ? dmi_first_match (drivers/firmware/dmi_scan.c:935 (discriminator 1)) 
[ 55.289377][ T1] dmi_first_match (drivers/firmware/dmi_scan.c:935 (discriminator 1)) 
[ 55.289377][ T1] it87_wdt_init (drivers/watchdog/it87_wdt.c:302) 
[ 55.289377][ T1] ? it8712f_wdt_init (drivers/watchdog/it87_wdt.c:286) 
[ 55.289377][ T1] do_one_initcall (init/main.c:1270) 
[ 55.289377][ T1] ? rcu_lock_acquire (include/linux/rcupdate.h:849 include/linux/rcupdate.h:1161) 
[ 55.289377][ T1] ? parse_one (kernel/params.c:143) 
[ 55.289377][ T1] ? kasan_unpoison (mm/kasan/shadow.c:182) 
[ 55.289377][ T1] ? poison_kmalloc_redzone (mm/kasan/common.c:376) 
[ 55.289377][ T1] ? rcu_is_watching (include/linux/context_tracking.h:128 kernel/rcu/tree.c:737) 
[ 55.289377][ T1] do_initcalls (init/main.c:1330 init/main.c:1347) 
[ 55.289377][ T1] kernel_init_freeable (init/main.c:1584) 
[ 55.289377][ T1] ? rest_init (init/main.c:1461) 
[ 55.289377][ T1] kernel_init (init/main.c:1471) 
[ 55.289377][ T1] ? rest_init (init/main.c:1461) 
[ 55.289377][ T1] ret_from_fork (arch/x86/kernel/process.c:153) 
[ 55.289377][ T1] ? rest_init (init/main.c:1461) 
[ 55.289377][ T1] ret_from_fork_asm (arch/x86/entry/entry_64.S:257) 
[   55.289377][    T1]  </TASK>
[   55.289377][    T1]
[   55.289377][    T1] The buggy address belongs to the variable:
[ 55.289377][ T1] it87_quirks+0x168/0x180 
[   55.289377][    T1]
[   55.289377][    T1] The buggy address belongs to the physical page:
[   55.289377][    T1] page: refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x4934
[   55.289377][    T1] flags: 0x4000000000002000(reserved|zone=1)
[   55.289377][    T1] raw: 4000000000002000 ffffea0000124d08 ffffea0000124d08 0000000000000000
[   55.289377][    T1] raw: 0000000000000000 0000000000000000 00000001ffffffff 0000000000000000
[   55.289377][    T1] page dumped because: kasan: bad access detected
[   55.289377][    T1] page_owner info is not present (never set?)
[   55.289377][    T1]
[   55.289377][    T1] Memory state around the buggy address:
[   55.289377][    T1]  ffffffff84934a00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[   55.289377][    T1]  ffffffff84934a80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[   55.289377][    T1] >ffffffff84934b00: 00 00 00 00 00 00 00 f9 f9 f9 f9 f9 00 00 02 f9
[   55.289377][    T1]                                               ^
[   55.289377][    T1]  ffffffff84934b80: f9 f9 f9 f9 00 00 02 f9 f9 f9 f9 f9 00 00 01 f9
[   55.289377][    T1]  ffffffff84934c00: f9 f9 f9 f9 00 00 00 06 f9 f9 f9 f9 00 00 00 00
[   55.289377][    T1] ==================================================================
[   55.337178][    T1] Disabling lock debugging due to kernel taint
[   55.338122][    T1] it87_wdt: no device



The kernel config and materials to reproduce are available at:
https://download.01.org/0day-ci/archive/20241025/202410251317.64508d45-lkp@intel.com
diff mbox series

Patch

diff --git a/drivers/watchdog/it87_wdt.c b/drivers/watchdog/it87_wdt.c
index 3e8c15138edd..03274e48e834 100644
--- a/drivers/watchdog/it87_wdt.c
+++ b/drivers/watchdog/it87_wdt.c
@@ -20,6 +20,8 @@ 
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+#include <linux/bits.h>
+#include <linux/dmi.h>
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
@@ -40,6 +42,7 @@ 
 #define VAL		0x2f
 
 /* Logical device Numbers LDN */
+#define EC		0x04
 #define GPIO		0x07
 
 /* Configuration Registers and Functions */
@@ -73,6 +76,12 @@ 
 #define IT8784_ID	0x8784
 #define IT8786_ID	0x8786
 
+/* Environment Controller Configuration Registers LDN=0x04 */
+#define SCR1		0xfa
+
+/* Environment Controller Bits SCR1 */
+#define WDT_PWRGD	0x20
+
 /* GPIO Configuration Registers LDN=0x07 */
 #define WDTCTRL		0x71
 #define WDTCFG		0x72
@@ -240,6 +249,20 @@  static int wdt_set_timeout(struct watchdog_device *wdd, unsigned int t)
 	return ret;
 }
 
+enum {
+	IT87_WDT_OUTPUT_THROUGH_PWRGD	= BIT(0),
+};
+
+static const struct dmi_system_id it87_quirks[] = {
+	{
+		/* Qotom Q30900P (IT8786) */
+		.matches = {
+			DMI_EXACT_MATCH(DMI_BOARD_NAME, "QCML04"),
+		},
+		.driver_data = (void *)IT87_WDT_OUTPUT_THROUGH_PWRGD,
+	}
+};
+
 static const struct watchdog_info ident = {
 	.options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
 	.firmware_version = 1,
@@ -261,8 +284,10 @@  static struct watchdog_device wdt_dev = {
 
 static int __init it87_wdt_init(void)
 {
+	const struct dmi_system_id *dmi_id;
 	u8  chip_rev;
 	u8 ctrl;
+	int quirks = 0;
 	int rc;
 
 	rc = superio_enter();
@@ -273,6 +298,10 @@  static int __init it87_wdt_init(void)
 	chip_rev  = superio_inb(CHIPREV) & 0x0f;
 	superio_exit();
 
+	dmi_id = dmi_first_match(it87_quirks);
+	if (dmi_id)
+		quirks = (long)dmi_id->driver_data;
+
 	switch (chip_type) {
 	case IT8702_ID:
 		max_units = 255;
@@ -333,6 +362,15 @@  static int __init it87_wdt_init(void)
 		superio_outb(0x00, WDTCTRL);
 	}
 
+	if (quirks & IT87_WDT_OUTPUT_THROUGH_PWRGD) {
+		superio_select(EC);
+		ctrl = superio_inb(SCR1);
+		if (!(ctrl & WDT_PWRGD)) {
+			ctrl |= WDT_PWRGD;
+			superio_outb(ctrl, SCR1);
+		}
+	}
+
 	superio_exit();
 
 	if (timeout < 1 || timeout > max_units * 60) {