Page MenuHomeFreeBSD

D36946.1792484952.diff
No OneTemporary

Size
2 KB
Referenced Files
None
Subscribers
None

D36946.1792484952.diff

diff --git a/sys/amd64/vmm/io/vlapic.c b/sys/amd64/vmm/io/vlapic.c
--- a/sys/amd64/vmm/io/vlapic.c
+++ b/sys/amd64/vmm/io/vlapic.c
@@ -952,6 +952,63 @@
return (tpr >> 4);
}
+static bool
+vlapic_is_icr_valid(uint64_t icrval)
+{
+ uint32_t mode = icrval & APIC_DELMODE_MASK;
+ uint32_t level = icrval & APIC_LEVEL_MASK;
+ uint32_t trigger = icrval & APIC_TRIGMOD_MASK;
+ uint32_t shorthand = icrval & APIC_DEST_MASK;
+
+ switch (mode) {
+ case APIC_DELMODE_FIXED:
+ if (trigger == APIC_TRIGMOD_EDGE)
+ return (true);
+ /*
+ * AMD allows a level assert IPI and Intel converts a level
+ * assert IPI into an edge IPI.
+ */
+ if (trigger == APIC_TRIGMOD_LEVEL && level == APIC_LEVEL_ASSERT)
+ return (true);
+ break;
+ case APIC_DELMODE_LOWPRIO:
+ case APIC_DELMODE_SMI:
+ case APIC_DELMODE_NMI:
+ case APIC_DELMODE_INIT:
+ if (trigger == APIC_TRIGMOD_EDGE &&
+ (shorthand == APIC_DEST_DESTFLD ||
+ shorthand == APIC_DEST_ALLESELF))
+ return (true);
+ /*
+ * AMD allows a level assert IPI and Intel converts a level
+ * assert IPI into an edge IPI.
+ */
+ if (trigger == APIC_TRIGMOD_LEVEL &&
+ level == APIC_LEVEL_ASSERT &&
+ (shorthand == APIC_DEST_DESTFLD ||
+ shorthand == APIC_DEST_ALLESELF))
+ return (true);
+ break;
+ case APIC_DELMODE_STARTUP:
+ if (shorthand == APIC_DEST_DESTFLD ||
+ shorthand == APIC_DEST_ALLESELF)
+ return (true);
+ break;
+ case APIC_DELMODE_RR:
+ /* Only available on AMD! */
+ if (trigger == APIC_TRIGMOD_EDGE &&
+ shorthand == APIC_DEST_DESTFLD)
+ return (true);
+ break;
+ case APIC_DELMODE_RESV:
+ return (false);
+ default:
+ __assert_unreachable();
+ }
+
+ return (false);
+}
+
int
vlapic_icrlo_write_handler(struct vlapic *vlapic, bool *retu)
{
@@ -984,6 +1041,14 @@
VLAPIC_CTR2(vlapic, "icrlo 0x%016lx triggered ipi %d", icrval, vec);
+ /*
+ * Ignore invalid combinations of the icr.
+ */
+ if (!vlapic_is_icr_valid(icrval)) {
+ VLAPIC_CTR1(vlapic, "Ignoring invalid ICR %016lx", icrval);
+ return (0);
+ }
+
if (mode == APIC_DELMODE_FIXED || mode == APIC_DELMODE_NMI) {
switch (icrval & APIC_DEST_MASK) {
case APIC_DEST_DESTFLD:
@@ -1025,9 +1090,6 @@
maxcpus = vm_get_maxcpus(vlapic->vm);
if (mode == APIC_DELMODE_INIT) {
- if ((icrval & APIC_LEVEL_MASK) == APIC_LEVEL_DEASSERT)
- return (0);
-
if (vlapic->vcpuid == 0 && dest != 0 && dest < maxcpus) {
vlapic2 = vm_lapic(vlapic->vm, dest);

File Metadata

Mime Type
text/plain
Expires
Tue, Oct 20, 8:29 AM (4 h, 31 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30549495
Default Alt Text
D36946.1792484952.diff (2 KB)

Event Timeline