qemu-e2k/qapi/run-state.json
Chenyi Qiang e2e69f6bb9 i386: add notify VM exit support
There are cases that malicious virtual machine can cause CPU stuck (due
to event windows don't open up), e.g., infinite loop in microcode when
nested #AC (CVE-2015-5307). No event window means no event (NMI, SMI and
IRQ) can be delivered. It leads the CPU to be unavailable to host or
other VMs. Notify VM exit is introduced to mitigate such kind of
attacks, which will generate a VM exit if no event window occurs in VM
non-root mode for a specified amount of time (notify window).

A new KVM capability KVM_CAP_X86_NOTIFY_VMEXIT is exposed to user space
so that the user can query the capability and set the expected notify
window when creating VMs. The format of the argument when enabling this
capability is as follows:
  Bit 63:32 - notify window specified in qemu command
  Bit 31:0  - some flags (e.g. KVM_X86_NOTIFY_VMEXIT_ENABLED is set to
              enable the feature.)

Users can configure the feature by a new (x86 only) accel property:
    qemu -accel kvm,notify-vmexit=run|internal-error|disable,notify-window=n

The default option of notify-vmexit is run, which will enable the
capability and do nothing if the exit happens. The internal-error option
raises a KVM internal error if it happens. The disable option does not
enable the capability. The default value of notify-window is 0. It is valid
only when notify-vmexit is not disabled. The valid range of notify-window
is non-negative. It is even safe to set it to zero since there's an
internal hardware threshold to be added to ensure no false positive.

Because a notify VM exit may happen with VM_CONTEXT_INVALID set in exit
qualification (no cases are anticipated that would set this bit), which
means VM context is corrupted. It would be reflected in the flags of
KVM_EXIT_NOTIFY exit. If KVM_NOTIFY_CONTEXT_INVALID bit is set, raise a KVM
internal error unconditionally.

Acked-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Chenyi Qiang <chenyi.qiang@intel.com>
Message-Id: <20220929072014.20705-5-chenyi.qiang@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2022-10-11 09:36:00 +02:00

662 lines
16 KiB
Python

# -*- Mode: Python -*-
# vim: filetype=python
#
##
# = VM run state
##
##
# @RunState:
#
# An enumeration of VM run states.
#
# @debug: QEMU is running on a debugger
#
# @finish-migrate: guest is paused to finish the migration process
#
# @inmigrate: guest is paused waiting for an incoming migration. Note
# that this state does not tell whether the machine will start at the
# end of the migration. This depends on the command-line -S option and
# any invocation of 'stop' or 'cont' that has happened since QEMU was
# started.
#
# @internal-error: An internal error that prevents further guest execution
# has occurred
#
# @io-error: the last IOP has failed and the device is configured to pause
# on I/O errors
#
# @paused: guest has been paused via the 'stop' command
#
# @postmigrate: guest is paused following a successful 'migrate'
#
# @prelaunch: QEMU was started with -S and guest has not started
#
# @restore-vm: guest is paused to restore VM state
#
# @running: guest is actively running
#
# @save-vm: guest is paused to save the VM state
#
# @shutdown: guest is shut down (and -no-shutdown is in use)
#
# @suspended: guest is suspended (ACPI S3)
#
# @watchdog: the watchdog action is configured to pause and has been triggered
#
# @guest-panicked: guest has been panicked as a result of guest OS panic
#
# @colo: guest is paused to save/restore VM state under colo checkpoint,
# VM can not get into this state unless colo capability is enabled
# for migration. (since 2.8)
##
{ 'enum': 'RunState',
'data': [ 'debug', 'inmigrate', 'internal-error', 'io-error', 'paused',
'postmigrate', 'prelaunch', 'finish-migrate', 'restore-vm',
'running', 'save-vm', 'shutdown', 'suspended', 'watchdog',
'guest-panicked', 'colo' ] }
##
# @ShutdownCause:
#
# An enumeration of reasons for a Shutdown.
#
# @none: No shutdown request pending
#
# @host-error: An error prevents further use of guest
#
# @host-qmp-quit: Reaction to the QMP command 'quit'
#
# @host-qmp-system-reset: Reaction to the QMP command 'system_reset'
#
# @host-signal: Reaction to a signal, such as SIGINT
#
# @host-ui: Reaction to a UI event, like window close
#
# @guest-shutdown: Guest shutdown/suspend request, via ACPI or other
# hardware-specific means
#
# @guest-reset: Guest reset request, and command line turns that into
# a shutdown
#
# @guest-panic: Guest panicked, and command line turns that into a shutdown
#
# @subsystem-reset: Partial guest reset that does not trigger QMP events and
# ignores --no-reboot. This is useful for sanitizing
# hypercalls on s390 that are used during kexec/kdump/boot
#
##
{ 'enum': 'ShutdownCause',
# Beware, shutdown_caused_by_guest() depends on enumeration order
'data': [ 'none', 'host-error', 'host-qmp-quit', 'host-qmp-system-reset',
'host-signal', 'host-ui', 'guest-shutdown', 'guest-reset',
'guest-panic', 'subsystem-reset'] }
##
# @StatusInfo:
#
# Information about VCPU run state
#
# @running: true if all VCPUs are runnable, false if not runnable
#
# @singlestep: true if VCPUs are in single-step mode
#
# @status: the virtual machine @RunState
#
# Since: 0.14
#
# Notes: @singlestep is enabled through the GDB stub
##
{ 'struct': 'StatusInfo',
'data': {'running': 'bool', 'singlestep': 'bool', 'status': 'RunState'} }
##
# @query-status:
#
# Query the run status of all VCPUs
#
# Returns: @StatusInfo reflecting all VCPUs
#
# Since: 0.14
#
# Example:
#
# -> { "execute": "query-status" }
# <- { "return": { "running": true,
# "singlestep": false,
# "status": "running" } }
#
##
{ 'command': 'query-status', 'returns': 'StatusInfo',
'allow-preconfig': true }
##
# @SHUTDOWN:
#
# Emitted when the virtual machine has shut down, indicating that qemu is
# about to exit.
#
# @guest: If true, the shutdown was triggered by a guest request (such as
# a guest-initiated ACPI shutdown request or other hardware-specific action)
# rather than a host request (such as sending qemu a SIGINT). (since 2.10)
#
# @reason: The @ShutdownCause which resulted in the SHUTDOWN. (since 4.0)
#
# Note: If the command-line option "-no-shutdown" has been specified, qemu will
# not exit, and a STOP event will eventually follow the SHUTDOWN event
#
# Since: 0.12
#
# Example:
#
# <- { "event": "SHUTDOWN",
# "data": { "guest": true, "reason": "guest-shutdown" },
# "timestamp": { "seconds": 1267040730, "microseconds": 682951 } }
#
##
{ 'event': 'SHUTDOWN', 'data': { 'guest': 'bool', 'reason': 'ShutdownCause' } }
##
# @POWERDOWN:
#
# Emitted when the virtual machine is powered down through the power control
# system, such as via ACPI.
#
# Since: 0.12
#
# Example:
#
# <- { "event": "POWERDOWN",
# "timestamp": { "seconds": 1267040730, "microseconds": 682951 } }
#
##
{ 'event': 'POWERDOWN' }
##
# @RESET:
#
# Emitted when the virtual machine is reset
#
# @guest: If true, the reset was triggered by a guest request (such as
# a guest-initiated ACPI reboot request or other hardware-specific action)
# rather than a host request (such as the QMP command system_reset).
# (since 2.10)
#
# @reason: The @ShutdownCause of the RESET. (since 4.0)
#
# Since: 0.12
#
# Example:
#
# <- { "event": "RESET",
# "data": { "guest": false, "reason": "guest-reset" },
# "timestamp": { "seconds": 1267041653, "microseconds": 9518 } }
#
##
{ 'event': 'RESET', 'data': { 'guest': 'bool', 'reason': 'ShutdownCause' } }
##
# @STOP:
#
# Emitted when the virtual machine is stopped
#
# Since: 0.12
#
# Example:
#
# <- { "event": "STOP",
# "timestamp": { "seconds": 1267041730, "microseconds": 281295 } }
#
##
{ 'event': 'STOP' }
##
# @RESUME:
#
# Emitted when the virtual machine resumes execution
#
# Since: 0.12
#
# Example:
#
# <- { "event": "RESUME",
# "timestamp": { "seconds": 1271770767, "microseconds": 582542 } }
#
##
{ 'event': 'RESUME' }
##
# @SUSPEND:
#
# Emitted when guest enters a hardware suspension state, for example, S3 state,
# which is sometimes called standby state
#
# Since: 1.1
#
# Example:
#
# <- { "event": "SUSPEND",
# "timestamp": { "seconds": 1344456160, "microseconds": 309119 } }
#
##
{ 'event': 'SUSPEND' }
##
# @SUSPEND_DISK:
#
# Emitted when guest enters a hardware suspension state with data saved on
# disk, for example, S4 state, which is sometimes called hibernate state
#
# Note: QEMU shuts down (similar to event @SHUTDOWN) when entering this state
#
# Since: 1.2
#
# Example:
#
# <- { "event": "SUSPEND_DISK",
# "timestamp": { "seconds": 1344456160, "microseconds": 309119 } }
#
##
{ 'event': 'SUSPEND_DISK' }
##
# @WAKEUP:
#
# Emitted when the guest has woken up from suspend state and is running
#
# Since: 1.1
#
# Example:
#
# <- { "event": "WAKEUP",
# "timestamp": { "seconds": 1344522075, "microseconds": 745528 } }
#
##
{ 'event': 'WAKEUP' }
##
# @WATCHDOG:
#
# Emitted when the watchdog device's timer is expired
#
# @action: action that has been taken
#
# Note: If action is "reset", "shutdown", or "pause" the WATCHDOG event is
# followed respectively by the RESET, SHUTDOWN, or STOP events
#
# Note: This event is rate-limited.
#
# Since: 0.13
#
# Example:
#
# <- { "event": "WATCHDOG",
# "data": { "action": "reset" },
# "timestamp": { "seconds": 1267061043, "microseconds": 959568 } }
#
##
{ 'event': 'WATCHDOG',
'data': { 'action': 'WatchdogAction' } }
##
# @WatchdogAction:
#
# An enumeration of the actions taken when the watchdog device's timer is
# expired
#
# @reset: system resets
#
# @shutdown: system shutdown, note that it is similar to @powerdown, which
# tries to set to system status and notify guest
#
# @poweroff: system poweroff, the emulator program exits
#
# @pause: system pauses, similar to @stop
#
# @debug: system enters debug state
#
# @none: nothing is done
#
# @inject-nmi: a non-maskable interrupt is injected into the first VCPU (all
# VCPUS on x86) (since 2.4)
#
# Since: 2.1
##
{ 'enum': 'WatchdogAction',
'data': [ 'reset', 'shutdown', 'poweroff', 'pause', 'debug', 'none',
'inject-nmi' ] }
##
# @RebootAction:
#
# Possible QEMU actions upon guest reboot
#
# @reset: Reset the VM
#
# @shutdown: Shutdown the VM and exit, according to the shutdown action
#
# Since: 6.0
##
{ 'enum': 'RebootAction',
'data': [ 'reset', 'shutdown' ] }
##
# @ShutdownAction:
#
# Possible QEMU actions upon guest shutdown
#
# @poweroff: Shutdown the VM and exit
#
# @pause: pause the VM
#
# Since: 6.0
##
{ 'enum': 'ShutdownAction',
'data': [ 'poweroff', 'pause' ] }
##
# @PanicAction:
#
# @none: Continue VM execution
#
# @pause: Pause the VM
#
# @shutdown: Shutdown the VM and exit, according to the shutdown action
#
# @exit-failure: Shutdown the VM and exit with nonzero status
# (since 7.1)
#
# Since: 6.0
##
{ 'enum': 'PanicAction',
'data': [ 'pause', 'shutdown', 'exit-failure', 'none' ] }
##
# @watchdog-set-action:
#
# Set watchdog action
#
# Since: 2.11
##
{ 'command': 'watchdog-set-action', 'data' : {'action': 'WatchdogAction'} }
##
# @set-action:
#
# Set the actions that will be taken by the emulator in response to guest
# events.
#
# @reboot: @RebootAction action taken on guest reboot.
#
# @shutdown: @ShutdownAction action taken on guest shutdown.
#
# @panic: @PanicAction action taken on guest panic.
#
# @watchdog: @WatchdogAction action taken when watchdog timer expires .
#
# Returns: Nothing on success.
#
# Since: 6.0
#
# Example:
#
# -> { "execute": "set-action",
# "arguments": { "reboot": "shutdown",
# "shutdown" : "pause",
# "panic": "pause",
# "watchdog": "inject-nmi" } }
# <- { "return": {} }
##
{ 'command': 'set-action',
'data': { '*reboot': 'RebootAction',
'*shutdown': 'ShutdownAction',
'*panic': 'PanicAction',
'*watchdog': 'WatchdogAction' },
'allow-preconfig': true }
##
# @GUEST_PANICKED:
#
# Emitted when guest OS panic is detected
#
# @action: action that has been taken, currently always "pause"
#
# @info: information about a panic (since 2.9)
#
# Since: 1.5
#
# Example:
#
# <- { "event": "GUEST_PANICKED",
# "data": { "action": "pause" },
# "timestamp": { "seconds": 1648245231, "microseconds": 900001 } }
#
##
{ 'event': 'GUEST_PANICKED',
'data': { 'action': 'GuestPanicAction', '*info': 'GuestPanicInformation' } }
##
# @GUEST_CRASHLOADED:
#
# Emitted when guest OS crash loaded is detected
#
# @action: action that has been taken, currently always "run"
#
# @info: information about a panic
#
# Since: 5.0
#
# Example:
#
# <- { "event": "GUEST_CRASHLOADED",
# "data": { "action": "run" },
# "timestamp": { "seconds": 1648245259, "microseconds": 893771 } }
#
##
{ 'event': 'GUEST_CRASHLOADED',
'data': { 'action': 'GuestPanicAction', '*info': 'GuestPanicInformation' } }
##
# @GuestPanicAction:
#
# An enumeration of the actions taken when guest OS panic is detected
#
# @pause: system pauses
#
# Since: 2.1 (poweroff since 2.8, run since 5.0)
##
{ 'enum': 'GuestPanicAction',
'data': [ 'pause', 'poweroff', 'run' ] }
##
# @GuestPanicInformationType:
#
# An enumeration of the guest panic information types
#
# @hyper-v: hyper-v guest panic information type
#
# @s390: s390 guest panic information type (Since: 2.12)
#
# Since: 2.9
##
{ 'enum': 'GuestPanicInformationType',
'data': [ 'hyper-v', 's390' ] }
##
# @GuestPanicInformation:
#
# Information about a guest panic
#
# @type: Crash type that defines the hypervisor specific information
#
# Since: 2.9
##
{'union': 'GuestPanicInformation',
'base': {'type': 'GuestPanicInformationType'},
'discriminator': 'type',
'data': { 'hyper-v': 'GuestPanicInformationHyperV',
's390': 'GuestPanicInformationS390' } }
##
# @GuestPanicInformationHyperV:
#
# Hyper-V specific guest panic information (HV crash MSRs)
#
# Since: 2.9
##
{'struct': 'GuestPanicInformationHyperV',
'data': { 'arg1': 'uint64',
'arg2': 'uint64',
'arg3': 'uint64',
'arg4': 'uint64',
'arg5': 'uint64' } }
##
# @S390CrashReason:
#
# Reason why the CPU is in a crashed state.
#
# @unknown: no crash reason was set
#
# @disabled-wait: the CPU has entered a disabled wait state
#
# @extint-loop: clock comparator or cpu timer interrupt with new PSW enabled
# for external interrupts
#
# @pgmint-loop: program interrupt with BAD new PSW
#
# @opint-loop: operation exception interrupt with invalid code at the program
# interrupt new PSW
#
# Since: 2.12
##
{ 'enum': 'S390CrashReason',
'data': [ 'unknown',
'disabled-wait',
'extint-loop',
'pgmint-loop',
'opint-loop' ] }
##
# @GuestPanicInformationS390:
#
# S390 specific guest panic information (PSW)
#
# @core: core id of the CPU that crashed
# @psw-mask: control fields of guest PSW
# @psw-addr: guest instruction address
# @reason: guest crash reason
#
# Since: 2.12
##
{'struct': 'GuestPanicInformationS390',
'data': { 'core': 'uint32',
'psw-mask': 'uint64',
'psw-addr': 'uint64',
'reason': 'S390CrashReason' } }
##
# @MEMORY_FAILURE:
#
# Emitted when a memory failure occurs on host side.
#
# @recipient: recipient is defined as @MemoryFailureRecipient.
#
# @action: action that has been taken. action is defined as @MemoryFailureAction.
#
# @flags: flags for MemoryFailureAction. action is defined as @MemoryFailureFlags.
#
# Since: 5.2
#
# Example:
#
# <- { "event": "MEMORY_FAILURE",
# "data": { "recipient": "hypervisor",
# "action": "fatal",
# "flags": { "action-required": false,
# "recursive": false } },
# "timestamp": { "seconds": 1267061043, "microseconds": 959568 } }
#
##
{ 'event': 'MEMORY_FAILURE',
'data': { 'recipient': 'MemoryFailureRecipient',
'action': 'MemoryFailureAction',
'flags': 'MemoryFailureFlags'} }
##
# @MemoryFailureRecipient:
#
# Hardware memory failure occurs, handled by recipient.
#
# @hypervisor: memory failure at QEMU process address space.
# (none guest memory, but used by QEMU itself).
#
# @guest: memory failure at guest memory,
#
# Since: 5.2
##
{ 'enum': 'MemoryFailureRecipient',
'data': [ 'hypervisor',
'guest' ] }
##
# @MemoryFailureAction:
#
# Actions taken by QEMU in response to a hardware memory failure.
#
# @ignore: the memory failure could be ignored. This will only be the case
# for action-optional failures.
#
# @inject: memory failure occurred in guest memory, the guest enabled MCE
# handling mechanism, and QEMU could inject the MCE into the guest
# successfully.
#
# @fatal: the failure is unrecoverable. This occurs for action-required
# failures if the recipient is the hypervisor; QEMU will exit.
#
# @reset: the failure is unrecoverable but confined to the guest. This
# occurs if the recipient is a guest guest which is not ready
# to handle memory failures.
#
# Since: 5.2
##
{ 'enum': 'MemoryFailureAction',
'data': [ 'ignore',
'inject',
'fatal',
'reset' ] }
##
# @MemoryFailureFlags:
#
# Additional information on memory failures.
#
# @action-required: whether a memory failure event is action-required
# or action-optional (e.g. a failure during memory scrub).
#
# @recursive: whether the failure occurred while the previous
# failure was still in progress.
#
# Since: 5.2
##
{ 'struct': 'MemoryFailureFlags',
'data': { 'action-required': 'bool',
'recursive': 'bool'} }
##
# @NotifyVmexitOption:
#
# An enumeration of the options specified when enabling notify VM exit
#
# @run: enable the feature, do nothing and continue if the notify VM exit happens.
#
# @internal-error: enable the feature, raise a internal error if the notify
# VM exit happens.
#
# @disable: disable the feature.
#
# Since: 7.2
##
{ 'enum': 'NotifyVmexitOption',
'data': [ 'run', 'internal-error', 'disable' ] }