Hello everyone,

On 27.02.20 15:46, Ralf Ramsauer wrote:
Hi,

On 27/02/2020 15:24, rayma...@gmail.com wrote:
Hi all,

I'd just like to add that I am experiencing the exact same issue as
described by Ralf on an AMD EPYC 7351P.

aah, 'good' to hear!

The stacktrace is the same as well:

FATAL: Setting invalid LVT delivery mode (reg 35, value 00000700

However, on my side I cannot get past this by just handing over the
xAPIC enabled; I get the same trace..
I added the printk's from Ralf's diff and get the same output:
...
Before disabling: 10000
After disabling: 0
After reenabling: 0

Great. So we definitely have a systematic hardware bug that doesn't only
affect our CPU.

... Did I already post my local hacky workaround?

diff --git a/hypervisor/arch/x86/apic.c b/hypervisor/arch/x86/apic.c
index de691329..7f51b062 100644
--- a/hypervisor/arch/x86/apic.c
+++ b/hypervisor/arch/x86/apic.c
@@ -340,7 +340,7 @@ void apic_clear(void)

         /* Finally, reset the TPR again and disable the APIC */
         apic_ops.write(APIC_REG_TPR, 0);
-       apic_ops.write(APIC_REG_SVR, 0xff);
+       //apic_ops.write(APIC_REG_SVR, 0xff);
  }

  static bool apic_valid_ipi_mode(u32 lo_val)


Maybe we could try to reach out to AMD via some kernel mailing list?

...

I presume that by "hand over the xAPIC enabled" you mean disabling the
write to APIC_REG_SVR? That's what I did but it did not do the trick
unfortunately.

Yep. Andrej, did we have to adjust anything else?

It's been a while that we've been working on that issue, and I don't
have the exact details in mind.

However, Andrej wanted to pick up the topic again soon.

Thanks,

   Ralf


From what I've gathered, Jailhouse works as expected. The inmates may (or may not) require the APIC, so they also are responsible for handling possible hardware bugs.

For this specific case the Linux kernel (inmate) needs a workaround during APIC initialization. However it already has a ancient (pre-git) quirk[1] to delegate interrupts to 8259A in case LVTs are not masked after reset. Nowadays this code seems strange, as the masked state is required per APIC specification (for Intel and AMD).

Jan, do you know more about this?

Interestingly enough this quirk is also the actual trigger of the aforementioned "invalid LVT delivery mode" error in Jailhouse.

For now I've appended a patch with a simple workaround for the kernel.
Hope that helps.

[1]: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/arch/x86/kernel/apic/apic.c?h=v5.4.24#n1716

Thanks,
Andrej Utz

--
You received this message because you are subscribed to the Google Groups 
"Jailhouse" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to jailhouse-dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/jailhouse-dev/bef2d9ff-b6b4-8927-e36a-e9ec41d0ed1a%40st.othr.de.
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 0428ad289899..836436ce05ba 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -1699,6 +1699,14 @@ static void setup_local_APIC(void)
 	value |= SPURIOUS_APIC_VECTOR;
 	apic_write(APIC_SPIV, value);
 
+	// HACK: some CPUs (e.g. the AMD Ryzen family) fail to reset LVT_LINT
+	// registers according to specification, so we help them do that
+	if (((value = apic_read(APIC_LVT0)) & APIC_LVT_MASKED) == 0)
+		apic_write(APIC_LVT0, value | APIC_LVT_MASKED);
+
+	if (((value = apic_read(APIC_LVT1)) & APIC_LVT_MASKED) == 0)
+		apic_write(APIC_LVT1, value | APIC_LVT_MASKED);
+
 	perf_events_lapic_init();
 
 	/*

Reply via email to