Project

General

Profile

Actions

Bug #14771

open

apic_shutdown uses illegal NMI delivery mode

Added by Thirteen Oxide about 1 month ago.

Status:
New
Priority:
Normal
Assignee:
-
Category:
-
Start date:
Due date:
% Done:

0%

Estimated time:
Difficulty:
Bite-size
Tags:
Gerrit CR:

Description

There are two places in this function (on i86pc) that we write to the APIC command register to generate IPIs; the first is:

apic_reg_ops->apic_write(APIC_INT_CMD1,
    AV_NMI | AV_LEVEL | AV_SH_ALL_EXCSELF);

which is done unconditionally regardless of the command we've received to cause all other CPUs to shut down their APIC code and stop doing work. Unfortunately this is documented in the AMD64 architecture manual to be invalid; see table 16-4 in volume 2, revision 4.03. When TM = level, Level must be set to asserted as well. In fact, all NMIs are delivered in edge mode and we probably shouldn't be setting AV_LEVEL at all. If we do, however, we should set AV_ASSERT rather than AV_LEVEL. This appears to work regardless, at least on some machines, but it certainly isn't guaranteed given that it directly contradicts the manual.

The second place is in the AD_FASTREBOOT path:

apic_reg_ops->apic_write(APIC_INT_CMD1,
    AV_ASSERT | AV_RESET | AV_SH_ALL_EXCSELF);

Here we're correctly using AV_ASSERT instead of AV_LEVEL to send an INIT message (not reset, which doesn't exist). While some documentation suggests that this message is deprecated on some AMD processors, it is at least architecturally defined and this usage appears correct.

It's not clear whether this bug has any real-world impact, or which processors might misbehave because of it. AMD Milan processors seem to do the right thing regardless of whether we use AV_LEVEL or AV_ASSERT here. But since our clear intent is to assert this IPI, not to deassert it, it seems reasonable to switch to either AV_ASSERT or edge-triggered delivery.

No data to display

Actions

Also available in: Atom PDF