Skip to content

openvmm: KVM snapshot restore collapses two pending NMIs into one #1161

Open

Description

@tangruize

When KVM reports two queued NMIs, snapshot capture stores only whether any NMI is pending. Restore writes one pending NMI, losing a notification.

KvmVpStateAccess::activity in vmm_core/virt_kvm/src/arch/x86_64/vp_state.rs converts the KVM event fields into Activity:

        Ok(vp::Activity {
            mp_state,
            nmi_pending: events.nmi.pending != 0,
            nmi_masked: events.nmi.masked != 0,
            interrupt_shadow: events.interrupt.shadow != 0,
            pending_event: event,
            pending_interruption: interruption,
        })

For events.nmi.pending == 2, nmi_pending becomes true. Activity::nmi_pending is Boolean, and set_activity converts it back into the KVM pending field as one. The separately saved injected-NMI slot does not carry the missing queued count.

Trigger

Stop a KVM vCPU while KVM_GET_VCPU_EVENTS reports two pending NMIs, save its activity, and restore into a fresh vCPU. Reading the destination events shows only one queued NMI. Allow guest delivery after unmasking NMIs to observe the lost notification.

Proposed Fix

Represent the pending count on backends that support it without changing the existing Boolean field's wire meaning. An additional optional count could use the Boolean as a fallback for old snapshots and backends.

Decide whether an older reader may collapse two pending NMIs when it ignores the new count, or whether preserving both requires a compatible reader. Keep this count-preservation change separate from the reset path's event-validity flags.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions