qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[RFC v2 00/14] Add SDEI support for arm64


From: Heyi Guo
Subject: [RFC v2 00/14] Add SDEI support for arm64
Date: Tue, 5 Nov 2019 17:10:42 +0800

SDEI is for ARM "Software Delegated Exception Interface". AS ARM64 doesn't have
native non-maskable interrupt (NMI), we rely on higher privileged (larger
exception level) software to change the execution flow of lower privileged
(smaller exception level) software when certain events occur, to emulate NMI
mechanism, and SDEI is the standard interfaces between the two levels of
privileged software. It is based on SMC/HVC calls.

The higher privileged software implements an SDEI dispatcher to handle SDEI
related SMC/HVC calls and trigger SDEI events; the lower privileged software
implements an SDEI client to request SDEI services and handle SDEI events.

Core interfaces provided by SDEI include:

1. interrupt bind: client can request to bind an interrupt to an SDEI event, so
the interrupt will be a non-maskable event and the event number will be returned
to the caller. Only PPI and SPI can be bound to SDEI events.

2. register: client can request to register a handler to an SDEI event, so
dispatcher will change PC of lower privileged software to this handler when
certain event occurs.

3. complete: client notifies dispatcher that it has completed the event
handling, so dispatcher will restore the context of guest when it is
interrupted. 

In virtualization situation, guest OS is the lower privileged software and
hypervisor is the higher one.

KVM is supposed to pass SMC/HVC calls to qemu, and qemu will emulate an SDEI
dispatcher to serve the SDEI requests and trigger the events. If an interrupt is
requested to be bound to an event, qemu should not inject the interrupt to guest
any more; instead, it should save the context of VCPU and change the PC to event
handler which is registered by guest, and then return to guest.

To make the conversion of interrupt to SDEI event transparent to other modules
in qemu, we used qemu_irq and qemu_irq_intercept_in() to override the default
irq handler with SDEI event trigger. I saw qemu_irq_intercept_in() should be
only used in qemu MST, but it seemed fit to override interrupt injection with
event trigger after guest requests to bind interrupt to SDEI event. 

This patchset is trying to implement the whole SDEI framework in qemu with KVM
enabled, including all SDEI v1.0 interfaces, as well as event trigger conduit
from other qemu devices after interrupt binding. 

Key points:
- We propose to only support kvm enabled arm64 virtual machines, for
  non-kvm VMs can emulate EL3 and have Trusted Firmware run on it,
  which has a builtin SDEI dispatcher.
- New kvm capability KVM_CAP_FORWARD_HYPERCALL is added to probe if
  kvm supports forwarding hypercalls, and the capability should be
  enabled explicitly.
- We make the dispatcher as a logical device, to save the states
  during migration or save/restore operation; only one instance is
  allowed in one VM.
- We use qemu_irq as the bridge for other qemu modules to switch from
  irq injection to SDEI event trigger after VM binds the interrupt to
  SDEI event. We use qemu_irq_intercept_in() to override qemu_irq
  handler with SDEI event trigger, and a new interface
  qemu_irq_remove_intercept() is added to restore the handler to
  default one (i.e. ARM GIC).

More details are in the commit message of each patch.

Basic tests are done by emulating a watchdog timer and triggering SDEI
event in every 10s.

Please focus on the interfaces and framework first. We can refine the code for
several rounds after the big things have been determined.

Any comment or suggestion is welcome.

Thanks,

HG

Cc: Peter Maydell <address@hidden>
Cc: Dave Martin <address@hidden>
Cc: Marc Zyngier <address@hidden>
Cc: Mark Rutland <address@hidden>
Cc: James Morse <address@hidden>
Cc: "Michael S. Tsirkin" <address@hidden>
Cc: Cornelia Huck <address@hidden>
Cc: Paolo Bonzini <address@hidden>
Cc: Shannon Zhao <address@hidden>
Cc: Igor Mammedov <address@hidden>

v2:
- Import import linux/arm_sdei.h to standard-headers
- Drop SDEI table definition and add comments
- Some bugfix and code refinement

Heyi Guo (14):
  update-linux-headers.sh: import linux/arm_sdei.h to standard-headers
  standard-headers: import arm_sdei.h
  arm/sdei: add virtual device framework
  arm: add CONFIG_SDEI build flag
  arm/sdei: add support to handle SDEI requests from guest
  arm/sdei: add system reset callback
  arm/sdei: add support to trigger event by GIC interrupt ID
  core/irq: add qemu_irq_remove_intercept interface
  arm/sdei: override qemu_irq handler when binding interrupt
  arm/sdei: add support to register interrupt bind notifier
  linux-headers/kvm.h: add capability to forward hypercall
  arm/sdei: add stub to fix build failure when SDEI is not enabled
  arm/kvm: handle guest exit of hypercall
  virt/acpi: add SDEI table if SDEI is enabled

 default-configs/arm-softmmu.mak           |    1 +
 hw/arm/Kconfig                            |    4 +
 hw/arm/virt-acpi-build.c                  |   26 +
 hw/core/irq.c                             |   11 +
 include/hw/irq.h                          |    8 +-
 include/standard-headers/linux/arm_sdei.h |   73 +
 linux-headers/linux/kvm.h                 |    1 +
 scripts/update-linux-headers.sh           |    1 +
 target/arm/Makefile.objs                  |    4 +
 target/arm/kvm.c                          |   17 +
 target/arm/sdei-stub.c                    |   49 +
 target/arm/sdei.c                         | 1576 +++++++++++++++++++++
 target/arm/sdei.h                         |   60 +
 target/arm/sdei_int.h                     |  121 ++
 14 files changed, 1950 insertions(+), 2 deletions(-)
 create mode 100644 include/standard-headers/linux/arm_sdei.h
 create mode 100644 target/arm/sdei-stub.c
 create mode 100644 target/arm/sdei.c
 create mode 100644 target/arm/sdei.h
 create mode 100644 target/arm/sdei_int.h

-- 
2.19.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]