@@ -323,6 +323,26 @@ static void __init hv_smp_prepare_cpus(unsigned int max_cpus)
323
323
}
324
324
#endif
325
325
326
+ /*
327
+ * When a fully enlightened TDX VM runs on Hyper-V, the firmware sets the
328
+ * HW_REDUCED flag: refer to acpi_tb_create_local_fadt(). Consequently ttyS0
329
+ * interrupts can't work because request_irq() -> ... -> irq_to_desc() returns
330
+ * NULL for ttyS0. This happens because mp_config_acpi_legacy_irqs() sees a
331
+ * nr_legacy_irqs() of 0, so it doesn't initialize the array 'mp_irqs[]', and
332
+ * later setup_IO_APIC_irqs() -> find_irq_entry() fails to find the legacy irqs
333
+ * from the array and hence doesn't create the necessary irq description info.
334
+ *
335
+ * Clone arch/x86/kernel/acpi/boot.c: acpi_generic_reduced_hw_init() here,
336
+ * except don't change 'legacy_pic', which keeps its default value
337
+ * 'default_legacy_pic'. This way, mp_config_acpi_legacy_irqs() sees a non-zero
338
+ * nr_legacy_irqs() and eventually serial console interrupts works properly.
339
+ */
340
+ static void __init reduced_hw_init (void )
341
+ {
342
+ x86_init .timers .timer_init = x86_init_noop ;
343
+ x86_init .irqs .pre_vector_init = x86_init_noop ;
344
+ }
345
+
326
346
static void __init ms_hyperv_init_platform (void )
327
347
{
328
348
int hv_max_functions_eax ;
@@ -433,6 +453,8 @@ static void __init ms_hyperv_init_platform(void)
433
453
434
454
/* Don't trust Hyper-V's TLB-flushing hypercalls. */
435
455
ms_hyperv .hints &= ~HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED ;
456
+
457
+ x86_init .acpi .reduced_hw_early_init = reduced_hw_init ;
436
458
}
437
459
}
438
460
}
0 commit comments