android_kernel_motorola_sm6375/arch
Repository files (latest commit first)
Filename Latest commit message Latest commit date
David Woodhouse 9f89d4ad21 clockevents/drivers/i8253: Fix stop sequence for timer 0
commit 531b2ca0a940ac9db03f246c8b77c4201de72b00 upstream.

According to the data sheet, writing the MODE register should stop the
counter (and thus the interrupts). This appears to work on real hardware,
at least modern Intel and AMD systems. It should also work on Hyper-V.

However, on some buggy virtual machines the mode change doesn't have any
effect until the counter is subsequently loaded (or perhaps when the IRQ
next fires).

So, set MODE 0 and then load the counter, to ensure that those buggy VMs
do the right thing and the interrupts stop. And then write MODE 0 *again*
to stop the counter on compliant implementations too.

Apparently, Hyper-V keeps firing the IRQ *repeatedly* even in mode zero
when it should only happen once, but the second MODE write stops that too.

Userspace test program (mostly written by tglx):
=====
 #include <stdio.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <stdint.h>
 #include <sys/io.h>

static __always_inline void __out##bwl(type value, uint16_t port)	\
{									\
	asm volatile("out" #bwl " %" #bw "0, %w1"			\
		     : : "a"(value), "Nd"(port));			\
}									\
									\
static __always_inline type __in##bwl(uint16_t port)			\
{									\
	type value;							\
	asm volatile("in" #bwl " %w1, %" #bw "0"			\
		     : "=a"(value) : "Nd"(port));			\
	return value;							\
}

BUILDIO(b, b, uint8_t)

 #define inb __inb
 #define outb __outb

 #define PIT_MODE	0x43
 #define PIT_CH0	0x40
 #define PIT_CH2	0x42

static int is8254;

static void dump_pit(void)
{
	if (is8254) {
		// Latch and output counter and status
		outb(0xC2, PIT_MODE);
		printf("%02x %02x %02x\n", inb(PIT_CH0), inb(PIT_CH0), inb(PIT_CH0));
	} else {
		// Latch and output counter
		outb(0x0, PIT_MODE);
		printf("%02x %02x\n", inb(PIT_CH0), inb(PIT_CH0));
	}
}

int main(int argc, char* argv[])
{
	int nr_counts = 2;

	if (argc > 1)
		nr_counts = atoi(argv[1]);

	if (argc > 2)
		is8254 = 1;

	if (ioperm(0x40, 4, 1) != 0)
		return 1;

	dump_pit();

	printf("Set oneshot\n");
	outb(0x38, PIT_MODE);
	outb(0x00, PIT_CH0);
	outb(0x0F, PIT_CH0);

	dump_pit();
	usleep(1000);
	dump_pit();

	printf("Set periodic\n");
	outb(0x34, PIT_MODE);
	outb(0x00, PIT_CH0);
	outb(0x0F, PIT_CH0);

	dump_pit();
	usleep(1000);
	dump_pit();
	dump_pit();
	usleep(100000);
	dump_pit();
	usleep(100000);
	dump_pit();

	printf("Set stop (%d counter writes)\n", nr_counts);
	outb(0x30, PIT_MODE);
	while (nr_counts--)
		outb(0xFF, PIT_CH0);

	dump_pit();
	usleep(100000);
	dump_pit();
	usleep(100000);
	dump_pit();

	printf("Set MODE 0\n");
	outb(0x30, PIT_MODE);

	dump_pit();
	usleep(100000);
	dump_pit();
	usleep(100000);
	dump_pit();

	return 0;
}
=====

Suggested-by: Sean Christopherson <seanjc@google.com>
Co-developed-by: Li RongQing <lirongqing@baidu.com>
Signed-off-by: Li RongQing <lirongqing@baidu.com>
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Michael Kelley <mhkelley@outlook.com>
Link: https://lore.kernel.org/all/20240802135555.564941-2-dwmw2@infradead.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-04-10 14:29:34 +02:00
..
alpha alpha: replace hardcoded stack offsets with autogenerated ones 2025-03-13 12:43:18 +01:00
arc ARC: build: Try to guess GCC variant of cross compiler 2025-01-09 13:23:36 +01:00
arm ARM: dts: mediatek: mt7623: fix IR nodename 2025-03-13 12:42:57 +01:00
arm64 arm64: cacheinfo: Avoid out-of-bounds write to cacheinfo array 2025-03-13 12:43:12 +01:00
c6x
csky
h8300
hexagon hexagon: Fix unbalanced spinlock in die() 2025-03-13 12:43:01 +01:00
ia64
m68k m68k: vga: Fix I/O defines 2025-03-13 12:43:06 +01:00
microblaze microblaze: don't treat zero reserved memory regions as error 2024-11-08 16:20:25 +01:00
mips MIPS: ftrace: Declare ftrace_get_parent_ra_addr() as static 2025-03-13 12:43:11 +01:00
nds32
nios2
openrisc openrisc: Call setup_memory() earlier in the init sequence 2024-09-04 13:14:57 +02:00
parisc parisc: Fix 64-bit userspace syscall path 2024-11-08 16:20:40 +01:00
powerpc powerpc/code-patching: Fix KASAN hit by not flagging text patching area as VM_ALLOC 2025-03-13 12:43:22 +01:00
riscv riscv: Remove unused GENERATING_ASM_OFFSETS 2024-11-08 16:20:54 +01:00
s390 KVM: s390: vsie: fix some corner-cases when grabbing vsie pages 2025-03-13 12:43:07 +01:00
sh sh: cpuinfo: Fix a warning for CONFIG_CPUMASK_OFFSTACK 2024-12-14 19:44:37 +01:00
sparc
um um: Always dump trace for specified task in show_stack 2024-12-14 19:44:40 +01:00
unicore32
x86 clockevents/drivers/i8253: Fix stop sequence for timer 0 2025-04-10 14:29:34 +02:00
xtensa
.gitignore
Kconfig