All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC v2 00/14] Add SDEI support for arm64
@ 2019-11-05  9:10 Heyi Guo
  2019-11-05  9:10 ` [RFC v2 01/14] update-linux-headers.sh: import linux/arm_sdei.h to standard-headers Heyi Guo
                   ` (18 more replies)
  0 siblings, 19 replies; 43+ messages in thread
From: Heyi Guo @ 2019-11-05  9:10 UTC (permalink / raw)
  To: qemu-arm, qemu-devel
  Cc: Mark Rutland, Peter Maydell, Michael S. Tsirkin, Marc Zyngier,
	Cornelia Huck, Shannon Zhao, Igor Mammedov, James Morse,
	Paolo Bonzini, Heyi Guo, wanghaibin.wang, Dave Martin

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 <peter.maydell@linaro.org>
Cc: Dave Martin <Dave.Martin@arm.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Cornelia Huck <cohuck@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Shannon Zhao <shannon.zhaosl@gmail.com>
Cc: Igor Mammedov <imammedo@redhat.com>

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



^ permalink raw reply	[flat|nested] 43+ messages in thread

* [RFC v2 01/14] update-linux-headers.sh: import linux/arm_sdei.h to standard-headers
  2019-11-05  9:10 [RFC v2 00/14] Add SDEI support for arm64 Heyi Guo
@ 2019-11-05  9:10 ` Heyi Guo
  2019-11-05  9:10 ` [RFC v2 02/14] standard-headers: import arm_sdei.h Heyi Guo
                   ` (17 subsequent siblings)
  18 siblings, 0 replies; 43+ messages in thread
From: Heyi Guo @ 2019-11-05  9:10 UTC (permalink / raw)
  To: qemu-arm, qemu-devel
  Cc: Mark Rutland, Peter Maydell, Michael S. Tsirkin, Marc Zyngier,
	Cornelia Huck, James Morse, Paolo Bonzini, Heyi Guo,
	wanghaibin.wang, Dave Martin

This is to prepare for qemu SDEI emulation.

Signed-off-by: Heyi Guo <guoheyi@huawei.com>
Cc: Peter Maydell <peter.maydell@linaro.org>
Cc: Dave Martin <Dave.Martin@arm.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Cornelia Huck <cohuck@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
---

Notes:
    v2:
    - Update update-linux-headers.sh first and then import the header file
    - Import arm_sdei.h to include/standard-headers/linux/

 scripts/update-linux-headers.sh | 1 +
 1 file changed, 1 insertion(+)

diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh
index f76d77363b..84d15c18f2 100755
--- a/scripts/update-linux-headers.sh
+++ b/scripts/update-linux-headers.sh
@@ -191,6 +191,7 @@ for i in "$tmpdir"/include/linux/*virtio*.h \
          "$tmpdir/include/linux/pci_regs.h" \
          "$tmpdir/include/linux/ethtool.h" "$tmpdir/include/linux/kernel.h" \
          "$tmpdir/include/linux/vhost_types.h" \
+         "$tmpdir/include/linux/arm_sdei.h" \
          "$tmpdir/include/linux/sysinfo.h"; do
     cp_portable "$i" "$output/include/standard-headers/linux"
 done
-- 
2.19.1



^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [RFC v2 02/14] standard-headers: import arm_sdei.h
  2019-11-05  9:10 [RFC v2 00/14] Add SDEI support for arm64 Heyi Guo
  2019-11-05  9:10 ` [RFC v2 01/14] update-linux-headers.sh: import linux/arm_sdei.h to standard-headers Heyi Guo
@ 2019-11-05  9:10 ` Heyi Guo
  2019-11-06 17:52   ` Cornelia Huck
  2019-11-05  9:10 ` [RFC v2 03/14] arm/sdei: add virtual device framework Heyi Guo
                   ` (16 subsequent siblings)
  18 siblings, 1 reply; 43+ messages in thread
From: Heyi Guo @ 2019-11-05  9:10 UTC (permalink / raw)
  To: qemu-arm, qemu-devel
  Cc: Mark Rutland, Peter Maydell, Michael S. Tsirkin, Marc Zyngier,
	Cornelia Huck, James Morse, Paolo Bonzini, Heyi Guo,
	wanghaibin.wang, Dave Martin

Import Linux header file include/uapi/linux/arm_sdei.h from kernel v5.4-rc5.

This is to prepare for qemu SDEI emulation.

Signed-off-by: Heyi Guo <guoheyi@huawei.com>
Cc: Peter Maydell <peter.maydell@linaro.org>
Cc: Dave Martin <Dave.Martin@arm.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Cornelia Huck <cohuck@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
---

Notes:
    v2:
    - Import arm_sdei.h by running update-linux-headers.sh

 include/standard-headers/linux/arm_sdei.h | 73 +++++++++++++++++++++++
 1 file changed, 73 insertions(+)
 create mode 100644 include/standard-headers/linux/arm_sdei.h

diff --git a/include/standard-headers/linux/arm_sdei.h b/include/standard-headers/linux/arm_sdei.h
new file mode 100644
index 0000000000..568d971915
--- /dev/null
+++ b/include/standard-headers/linux/arm_sdei.h
@@ -0,0 +1,73 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/* Copyright (C) 2017 Arm Ltd. */
+#ifndef _LINUX_ARM_SDEI_H
+#define _LINUX_ARM_SDEI_H
+
+#define SDEI_1_0_FN_BASE			0xC4000020
+#define SDEI_1_0_MASK				0xFFFFFFE0
+#define SDEI_1_0_FN(n)				(SDEI_1_0_FN_BASE + (n))
+
+#define SDEI_1_0_FN_SDEI_VERSION			SDEI_1_0_FN(0x00)
+#define SDEI_1_0_FN_SDEI_EVENT_REGISTER			SDEI_1_0_FN(0x01)
+#define SDEI_1_0_FN_SDEI_EVENT_ENABLE			SDEI_1_0_FN(0x02)
+#define SDEI_1_0_FN_SDEI_EVENT_DISABLE			SDEI_1_0_FN(0x03)
+#define SDEI_1_0_FN_SDEI_EVENT_CONTEXT			SDEI_1_0_FN(0x04)
+#define SDEI_1_0_FN_SDEI_EVENT_COMPLETE			SDEI_1_0_FN(0x05)
+#define SDEI_1_0_FN_SDEI_EVENT_COMPLETE_AND_RESUME	SDEI_1_0_FN(0x06)
+#define SDEI_1_0_FN_SDEI_EVENT_UNREGISTER		SDEI_1_0_FN(0x07)
+#define SDEI_1_0_FN_SDEI_EVENT_STATUS			SDEI_1_0_FN(0x08)
+#define SDEI_1_0_FN_SDEI_EVENT_GET_INFO			SDEI_1_0_FN(0x09)
+#define SDEI_1_0_FN_SDEI_EVENT_ROUTING_SET		SDEI_1_0_FN(0x0A)
+#define SDEI_1_0_FN_SDEI_PE_MASK			SDEI_1_0_FN(0x0B)
+#define SDEI_1_0_FN_SDEI_PE_UNMASK			SDEI_1_0_FN(0x0C)
+#define SDEI_1_0_FN_SDEI_INTERRUPT_BIND			SDEI_1_0_FN(0x0D)
+#define SDEI_1_0_FN_SDEI_INTERRUPT_RELEASE		SDEI_1_0_FN(0x0E)
+#define SDEI_1_0_FN_SDEI_PRIVATE_RESET			SDEI_1_0_FN(0x11)
+#define SDEI_1_0_FN_SDEI_SHARED_RESET			SDEI_1_0_FN(0x12)
+
+#define SDEI_VERSION_MAJOR_SHIFT			48
+#define SDEI_VERSION_MAJOR_MASK				0x7fff
+#define SDEI_VERSION_MINOR_SHIFT			32
+#define SDEI_VERSION_MINOR_MASK				0xffff
+#define SDEI_VERSION_VENDOR_SHIFT			0
+#define SDEI_VERSION_VENDOR_MASK			0xffffffff
+
+#define SDEI_VERSION_MAJOR(x)	(x>>SDEI_VERSION_MAJOR_SHIFT & SDEI_VERSION_MAJOR_MASK)
+#define SDEI_VERSION_MINOR(x)	(x>>SDEI_VERSION_MINOR_SHIFT & SDEI_VERSION_MINOR_MASK)
+#define SDEI_VERSION_VENDOR(x)	(x>>SDEI_VERSION_VENDOR_SHIFT & SDEI_VERSION_VENDOR_MASK)
+
+/* SDEI return values */
+#define SDEI_SUCCESS		0
+#define SDEI_NOT_SUPPORTED	-1
+#define SDEI_INVALID_PARAMETERS	-2
+#define SDEI_DENIED		-3
+#define SDEI_PENDING		-5
+#define SDEI_OUT_OF_RESOURCE	-10
+
+/* EVENT_REGISTER flags */
+#define SDEI_EVENT_REGISTER_RM_ANY	0
+#define SDEI_EVENT_REGISTER_RM_PE	1
+
+/* EVENT_STATUS return value bits */
+#define SDEI_EVENT_STATUS_RUNNING	2
+#define SDEI_EVENT_STATUS_ENABLED	1
+#define SDEI_EVENT_STATUS_REGISTERED	0
+
+/* EVENT_COMPLETE status values */
+#define SDEI_EV_HANDLED	0
+#define SDEI_EV_FAILED	1
+
+/* GET_INFO values */
+#define SDEI_EVENT_INFO_EV_TYPE			0
+#define SDEI_EVENT_INFO_EV_SIGNALED		1
+#define SDEI_EVENT_INFO_EV_PRIORITY		2
+#define SDEI_EVENT_INFO_EV_ROUTING_MODE		3
+#define SDEI_EVENT_INFO_EV_ROUTING_AFF		4
+
+/* and their results */
+#define SDEI_EVENT_TYPE_PRIVATE			0
+#define SDEI_EVENT_TYPE_SHARED			1
+#define SDEI_EVENT_PRIORITY_NORMAL		0
+#define SDEI_EVENT_PRIORITY_CRITICAL		1
+
+#endif /* _LINUX_ARM_SDEI_H */
-- 
2.19.1



^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [RFC v2 03/14] arm/sdei: add virtual device framework
  2019-11-05  9:10 [RFC v2 00/14] Add SDEI support for arm64 Heyi Guo
  2019-11-05  9:10 ` [RFC v2 01/14] update-linux-headers.sh: import linux/arm_sdei.h to standard-headers Heyi Guo
  2019-11-05  9:10 ` [RFC v2 02/14] standard-headers: import arm_sdei.h Heyi Guo
@ 2019-11-05  9:10 ` Heyi Guo
  2019-11-05  9:10 ` [RFC v2 04/14] arm: add CONFIG_SDEI build flag Heyi Guo
                   ` (15 subsequent siblings)
  18 siblings, 0 replies; 43+ messages in thread
From: Heyi Guo @ 2019-11-05  9:10 UTC (permalink / raw)
  To: qemu-arm, qemu-devel
  Cc: Mark Rutland, Peter Maydell, James Morse, Marc Zyngier,
	Jingyi Wang, Heyi Guo, wanghaibin.wang, Dave Martin

SDEI is useful to emulate NMI on arm64 platforms. To support SDEI in
virtual machine with KVM enabled, we choose to implement SDEI
interfaces in qemu. It is targeted for KVM mode only, for the full
user space emulation can also emulate secure world and have ARM
Trusted Firmware to run on emulated EL3.

- We create a logical SDEI device to hold the states of SDEI services,
  to support VM migration.
- Only one SDEI virtual device is allowed in the whole VM to provide
  SDEI services.
- We create struct QemuSDE to hold states of each SDEI event, and
  private events with the same ID on different CPUs have their own
  QemuSDE instance.
- We create struct QemuSDEProp to hold properties of each SDEI event,
  so all private instances with the same ID will pointed to the same
  QemuSDEProp.
- We create struct QemuSDECpu to hold CPU/PE states, including the
  interrupted CPU context.
- Slot numbers for private and shared event are fixed, for guests
  cannot request more interrupt binds than BIND_SLOTS in SDEI_FEATURES
  call.
- The first PRIVATE_SLOT_COUNT slots in property array are for private
  events, and the next SHARED_SLOT_COUNT slots are for shared events.
- We use property slot index as lower bit for each allocated event
  number, so that we can get property easily from valid input event
  number, as well as the QemuSDE instance.

Signed-off-by: Heyi Guo <guoheyi@huawei.com>
Signed-off-by: Jingyi Wang <wangjingyi11@huawei.com>
Cc: Peter Maydell <peter.maydell@linaro.org>
Cc: Dave Martin <Dave.Martin@arm.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: James Morse <james.morse@arm.com>
---
 target/arm/sdei.c     | 344 ++++++++++++++++++++++++++++++++++++++++++
 target/arm/sdei_int.h | 118 +++++++++++++++
 2 files changed, 462 insertions(+)
 create mode 100644 target/arm/sdei.c
 create mode 100644 target/arm/sdei_int.h

diff --git a/target/arm/sdei.c b/target/arm/sdei.c
new file mode 100644
index 0000000000..931e46923a
--- /dev/null
+++ b/target/arm/sdei.c
@@ -0,0 +1,344 @@
+/*
+ * ARM SDEI emulation for ARM64 virtual machine with KVM
+ *
+ * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved.
+ *
+ * Authors:
+ *    Heyi Guo <guoheyi@huawei.com>
+ *    Jingyi Wang <wangjingyi11@huawei.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "arm-powerctl.h"
+#include "qemu/timer.h"
+#include "sysemu/kvm.h"
+#include "sysemu/kvm_int.h"
+#include "sysemu/sysemu.h"
+#include "sysemu/reset.h"
+#include "qemu/error-report.h"
+#include "sdei_int.h"
+#include "internals.h"
+#include "hw/boards.h"
+#include "hw/intc/arm_gicv3.h"
+#include "hw/intc/arm_gic.h"
+#include "hw/irq.h"
+#include "hw/sysbus.h"
+#include "migration/vmstate.h"
+#include "qom/object.h"
+
+#define TYPE_ARM_SDEI "arm_sdei"
+#define QEMU_SDEI(obj) OBJECT_CHECK(QemuSDEState, (obj), TYPE_ARM_SDEI)
+
+static QemuSDEState *sde_state;
+
+static void qemu_sde_prop_init(QemuSDEState *s)
+{
+    QemuSDEProp *sde_props = s->sde_props_state;
+    int i;
+    for (i = 0; i < ARRAY_SIZE(s->sde_props_state); i++) {
+        sde_props[i].event_id = SDEI_INVALID_EVENT_ID;
+        sde_props[i].interrupt = SDEI_INVALID_INTERRUPT;
+        sde_props[i].sde_index = i >= PRIVATE_SLOT_COUNT ?
+                                 i - PRIVATE_SLOT_COUNT : i;
+
+        qemu_mutex_init(&(sde_props[i].lock));
+        sde_props[i].refcount = 0;
+    }
+    sde_props[0].event_id = SDEI_STD_EVT_SOFTWARE_SIGNAL;
+    sde_props[0].interrupt = SDEI_INVALID_INTERRUPT;
+    sde_props[0].is_shared = false;
+    sde_props[0].is_critical = false;
+
+    for (i = 0; i < ARRAY_SIZE(s->irq_map); i++) {
+        s->irq_map[i] = SDEI_INVALID_EVENT_ID;
+    }
+
+    qemu_mutex_init(&s->sdei_interrupt_bind_lock);
+}
+
+static void qemu_sde_cpu_init(QemuSDEState *s)
+{
+    int i;
+    QemuSDECpu *sde_cpus;
+
+    s->sdei_max_cpus = current_machine->smp.max_cpus;
+    s->sde_cpus = g_new0(QemuSDECpu, s->sdei_max_cpus);
+    sde_cpus = s->sde_cpus;
+    for (i = 0; i < s->sdei_max_cpus; i++) {
+        sde_cpus[i].masked = true;
+        sde_cpus[i].critical_running_event = SDEI_INVALID_EVENT_ID;
+        sde_cpus[i].normal_running_event = SDEI_INVALID_EVENT_ID;
+    }
+}
+
+static bool is_valid_event_number(int32_t event)
+{
+    int32_t slot_id;
+
+    if (event < 0 || (event & 0x3F000000)) {
+        return false;
+    }
+
+    slot_id = SDEI_EVENT_TO_SLOT(event);
+    if (slot_id >= PRIVATE_SLOT_COUNT + SHARED_SLOT_COUNT) {
+        return false;
+    }
+
+    return true;
+}
+
+static bool is_valid_event(QemuSDEState *s, int32_t event)
+{
+    if (!is_valid_event_number(event)) {
+        return false;
+    }
+
+    if (s->sde_props_state[SDEI_EVENT_TO_SLOT(event)].event_id != event) {
+        return false;
+    }
+
+    return true;
+}
+
+static QemuSDEProp *get_sde_prop_no_lock(QemuSDEState *s, int32_t event)
+{
+    if (!is_valid_event(s, event)) {
+        return NULL;
+    }
+
+    return &s->sde_props_state[SDEI_EVENT_TO_SLOT(event)];
+}
+
+static void sde_array_init(QemuSDE **array, int count)
+{
+    int i;
+
+    for (i = 0; i < count; i++) {
+        QemuSDE *sde;
+        sde = array[i];
+        if (!sde) {
+            sde = g_new0(QemuSDE, 1);
+        }
+        sde->event_id = SDEI_INVALID_EVENT_ID;
+        sde->enabled = false;
+        sde->running = false;
+        sde->pending = false;
+        sde->unregister_pending = false;
+        qemu_mutex_init(&sde->lock);
+        array[i] = sde;
+    }
+}
+
+static void qemu_shared_sde_init(QemuSDEState *s)
+{
+    sde_array_init(s->shared_sde_array, SHARED_SLOT_COUNT);
+}
+
+static void qemu_private_sde_init(QemuSDEState *s)
+{
+    int i;
+
+    for (i = 0; i < s->sdei_max_cpus; i++) {
+        sde_array_init(s->sde_cpus[i].private_sde_array, PRIVATE_SLOT_COUNT);
+    }
+}
+
+static void qemu_sde_init(QemuSDEState *s)
+{
+    qemu_sde_prop_init(s);
+    qemu_sde_cpu_init(s);
+
+    qemu_shared_sde_init(s);
+    qemu_private_sde_init(s);
+}
+
+static void sde_array_save(QemuSDE **array, int count)
+{
+    int i;
+
+    for (i = 0; i < count; i++) {
+        QemuSDE *sde = array[i];
+        if (sde->event_id != SDEI_INVALID_EVENT_ID) {
+            sde->event_id = sde->prop->event_id;
+            sde->cpu_affinity = ARM_CPU(sde->target_cpu)->mp_affinity;
+        }
+    }
+}
+
+static int qemu_sdei_pre_save(void *opaque)
+{
+    QemuSDEState *s = opaque;
+    int i;
+
+    for (i = 0; i < s->sdei_max_cpus; i++) {
+        sde_array_save(s->sde_cpus[i].private_sde_array, PRIVATE_SLOT_COUNT);
+    }
+
+    sde_array_save(s->shared_sde_array, SHARED_SLOT_COUNT);
+
+    return 0;
+}
+
+
+static int qemu_sdei_post_load(void *opaque, int version_id)
+{
+    QemuSDEState *s = opaque;
+    QemuSDEProp *sde_props = s->sde_props_state;
+    QemuSDE **array;
+    int i, j;
+
+    for (i = 0; i < s->sdei_max_cpus; i++) {
+        array = s->sde_cpus[i].private_sde_array;
+        for (j = 0; j < PRIVATE_SLOT_COUNT; j++) {
+            QemuSDE *sde = array[j];
+            if (sde->event_id != SDEI_INVALID_EVENT_ID) {
+                sde->prop = get_sde_prop_no_lock(s, sde->event_id);
+                sde->target_cpu = arm_get_cpu_by_id(sde->cpu_affinity);
+            }
+        }
+    }
+
+    array = s->shared_sde_array;
+    for (j = 0; j < SHARED_SLOT_COUNT; j++) {
+        QemuSDE *sde = array[j];
+        if (sde->event_id != SDEI_INVALID_EVENT_ID) {
+            sde->prop = get_sde_prop_no_lock(s, sde->event_id);
+            sde->target_cpu = arm_get_cpu_by_id(sde->cpu_affinity);
+        }
+    }
+
+    for (i = 0; i < PRIVATE_SLOT_COUNT + SHARED_SLOT_COUNT; i++) {
+        int intid = sde_props[i].interrupt;
+
+        if (intid != SDEI_INVALID_INTERRUPT) {
+            s->irq_map[intid] = sde_props[i].event_id;
+        }
+    }
+
+    return 0;
+}
+
+static const VMStateDescription vmstate_sdes = {
+    .name = "qemu_sdei/sdes",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_BOOL(enabled, QemuSDE),
+        VMSTATE_BOOL(running, QemuSDE),
+        VMSTATE_BOOL(pending, QemuSDE),
+        VMSTATE_BOOL(unregister_pending, QemuSDE),
+        VMSTATE_UINT64(ep_address, QemuSDE),
+        VMSTATE_UINT64(ep_argument, QemuSDE),
+        VMSTATE_UINT64(routing_mode, QemuSDE),
+        VMSTATE_INT32(event_id, QemuSDE),
+        VMSTATE_UINT64(cpu_affinity, QemuSDE),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static const VMStateDescription vmstate_sde_props = {
+    .name = "qemu_sdei/sde_props",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_INT32(event_id, QemuSDEProp),
+        VMSTATE_INT32(interrupt, QemuSDEProp),
+        VMSTATE_BOOL(is_shared, QemuSDEProp),
+        VMSTATE_BOOL(is_critical, QemuSDEProp),
+        VMSTATE_INT32(sde_index, QemuSDEProp),
+        VMSTATE_INT32(refcount, QemuSDEProp),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static const VMStateDescription vmstate_sde_cpu = {
+    .name = "qemu_sdei/sde_cpu",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_ARRAY_OF_POINTER_TO_STRUCT(private_sde_array, QemuSDECpu,
+                                           PRIVATE_SLOT_COUNT, 1,
+                                           vmstate_sdes, QemuSDE),
+        VMSTATE_UINT64_ARRAY(ctx[0].xregs, QemuSDECpu, SAVED_GP_NUM),
+        VMSTATE_UINT64_ARRAY(ctx[1].xregs, QemuSDECpu, SAVED_GP_NUM),
+        VMSTATE_UINT64(ctx[0].pc, QemuSDECpu),
+        VMSTATE_UINT64(ctx[1].pc, QemuSDECpu),
+        VMSTATE_UINT32(ctx[0].pstate, QemuSDECpu),
+        VMSTATE_UINT32(ctx[1].pstate, QemuSDECpu),
+        VMSTATE_INT32(critical_running_event, QemuSDECpu),
+        VMSTATE_INT32(normal_running_event, QemuSDECpu),
+        VMSTATE_BOOL(masked, QemuSDECpu),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static const VMStateDescription vmstate_sde_state = {
+    .name = "qemu_sdei",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .pre_save = qemu_sdei_pre_save,
+    .post_load = qemu_sdei_post_load,
+    .fields = (VMStateField[]) {
+        VMSTATE_STRUCT_ARRAY(sde_props_state, QemuSDEState,
+                             PRIVATE_SLOT_COUNT + SHARED_SLOT_COUNT, 1,
+                             vmstate_sde_props, QemuSDEProp),
+        VMSTATE_ARRAY_OF_POINTER_TO_STRUCT(shared_sde_array, QemuSDEState,
+                                           SHARED_SLOT_COUNT, 1,
+                                           vmstate_sdes, QemuSDE),
+        VMSTATE_STRUCT_VARRAY_POINTER_INT32(sde_cpus, QemuSDEState,
+                                            sdei_max_cpus,
+                                            vmstate_sde_cpu, QemuSDECpu),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+
+static void sdei_initfn(Object *obj)
+{
+    QemuSDEState *s = QEMU_SDEI(obj);
+
+    if (sde_state) {
+        error_report("Only one SDEI dispatcher is allowed!");
+        abort();
+    }
+    sde_state = s;
+
+    qemu_sde_init(s);
+}
+
+static void qemu_sde_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->desc = "SDEI_QEMU";
+    dc->vmsd = &vmstate_sde_state;
+    dc->user_creatable = true;
+}
+
+static const TypeInfo sde_qemu_info = {
+    .name          = TYPE_ARM_SDEI,
+    .parent        = TYPE_DEVICE,
+    .instance_size = sizeof(QemuSDEState),
+    .instance_init = sdei_initfn,
+    .class_init    = qemu_sde_class_init,
+};
+
+static void register_types(void)
+{
+    type_register_static(&sde_qemu_info);
+}
+
+type_init(register_types);
diff --git a/target/arm/sdei_int.h b/target/arm/sdei_int.h
new file mode 100644
index 0000000000..d3fd7cbc10
--- /dev/null
+++ b/target/arm/sdei_int.h
@@ -0,0 +1,118 @@
+/*
+ * ARM SDEI emulation internal interfaces
+ *
+ * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved.
+ *
+ * Authors:
+ *    Heyi Guo <guoheyi@huawei.com>
+ *    Jingyi Wang <wangjingyi11@huawei.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef QEMU_SDEI_INT_H
+#define QEMU_SDEI_INT_H
+
+#include <linux/kvm.h>
+#include <linux/arm_sdei.h>
+#include <asm-arm64/kvm.h>
+#include "hw/intc/arm_gic_common.h"
+#include "qemu/thread.h"
+
+#define SDEI_STD_EVT_SOFTWARE_SIGNAL        0
+#define SDEI_FEATURE_BIND_SLOTS             0
+#define SDEI_PARAM_MAX                      18
+
+#define PRIVATE_SLOT_COUNT                  16
+#define PLAT_PRIVATE_SLOT_COUNT             8
+#define SHARED_SLOT_COUNT                   32
+#define PLAT_SHARED_SLOT_COUNT              16
+#define SDEI_INVALID_INTERRUPT              -1
+#define SDEI_INVALID_EVENT_ID               -1
+
+#define SDEI_EVENT_TO_SLOT(event)           ((event) & 0xFFFFFF)
+#define SDEI_IS_SHARED_EVENT(event)         \
+    (SDEI_EVENT_TO_SLOT(event) >= PRIVATE_SLOT_COUNT)
+
+typedef enum {
+    SDEI_PRIO_NORMAL        = 0,
+    SDEI_PRIO_CRITICAL      = 1,
+} QemuSDEIPriority;
+
+typedef struct QemuSDEProp {
+    QemuMutex       lock;
+    int32_t         event_id;
+    int             interrupt;
+    bool            is_shared;
+    bool            is_critical;
+    /* This is the internal index for private or shared SDE */
+    int             sde_index;
+    int             refcount;
+} QemuSDEProp;
+
+typedef struct QemuSDE {
+    QemuSDEProp     *prop;
+    CPUState        *target_cpu;
+    QemuMutex       lock;
+    bool            enabled;
+    bool            running;
+    bool            pending;
+    bool            unregister_pending;
+    uint64_t        ep_address;
+    uint64_t        ep_argument;
+    uint64_t        routing_mode;
+    int32_t         event_id;
+    /*
+     * For it is not easy to save the pointer target_cpu during migration, we
+     * add below field to save the corresponding numerical values.
+     */
+    uint64_t        cpu_affinity;
+} QemuSDE;
+
+/*
+ * GP registers x0~x17 may be modified by client, so they must be saved by
+ * dispatcher.
+ */
+#define SAVED_GP_NUM        18
+
+typedef struct QemuSDECpuCtx {
+    uint64_t        xregs[SAVED_GP_NUM];
+    uint64_t        pc;
+    uint32_t        pstate;
+} QemuSDECpuCtx;
+
+typedef enum {
+    SDEI_EVENT_PRIO_NORMAL = 0,
+    SDEI_EVENT_PRIO_CRITICAL,
+    SDEI_EVENT_PRIO_COUNT,
+} SdeiEventPriority;
+
+typedef struct QemuSDECpu {
+    QemuSDE         *private_sde_array[PRIVATE_SLOT_COUNT];
+    QemuSDECpuCtx   ctx[SDEI_EVENT_PRIO_COUNT];
+    bool            masked;
+    int32_t         critical_running_event;
+    int32_t         normal_running_event;
+} QemuSDECpu;
+
+typedef struct QemuSDEState {
+    DeviceState     parent_obj;
+    QemuSDEProp     sde_props_state[PRIVATE_SLOT_COUNT + SHARED_SLOT_COUNT];
+    QemuSDECpu      *sde_cpus;
+    int             sdei_max_cpus;
+    QemuSDE         *shared_sde_array[SHARED_SLOT_COUNT];
+    int32_t         irq_map[GIC_MAXIRQ];
+    QemuMutex       sdei_interrupt_bind_lock;
+} QemuSDEState;
+
+#endif
-- 
2.19.1



^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [RFC v2 04/14] arm: add CONFIG_SDEI build flag
  2019-11-05  9:10 [RFC v2 00/14] Add SDEI support for arm64 Heyi Guo
                   ` (2 preceding siblings ...)
  2019-11-05  9:10 ` [RFC v2 03/14] arm/sdei: add virtual device framework Heyi Guo
@ 2019-11-05  9:10 ` Heyi Guo
  2019-11-05  9:10 ` [RFC v2 05/14] arm/sdei: add support to handle SDEI requests from guest Heyi Guo
                   ` (14 subsequent siblings)
  18 siblings, 0 replies; 43+ messages in thread
From: Heyi Guo @ 2019-11-05  9:10 UTC (permalink / raw)
  To: qemu-arm, qemu-devel
  Cc: Mark Rutland, Peter Maydell, Marc Zyngier, James Morse, Heyi Guo,
	wanghaibin.wang, Dave Martin

Integrate SDEI support for arm/aarch64 targets by default, if KVM is
enabled.

Signed-off-by: Heyi Guo <guoheyi@huawei.com>
Cc: Peter Maydell <peter.maydell@linaro.org>
Cc: Dave Martin <Dave.Martin@arm.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: James Morse <james.morse@arm.com>
---
 default-configs/arm-softmmu.mak | 1 +
 hw/arm/Kconfig                  | 4 ++++
 target/arm/Makefile.objs        | 2 ++
 3 files changed, 7 insertions(+)

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 1f2e0e7fde..fc1f2b2ead 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -40,3 +40,4 @@ CONFIG_FSL_IMX25=y
 CONFIG_FSL_IMX7=y
 CONFIG_FSL_IMX6UL=y
 CONFIG_SEMIHOSTING=y
+CONFIG_SDEI=y
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index c6e7782580..472bc3a75b 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -469,3 +469,7 @@ config ARMSSE_CPUID
 
 config ARMSSE_MHU
     bool
+
+config SDEI
+    bool
+    depends on KVM
diff --git a/target/arm/Makefile.objs b/target/arm/Makefile.objs
index cf26c16f5f..72e01d08dc 100644
--- a/target/arm/Makefile.objs
+++ b/target/arm/Makefile.objs
@@ -11,6 +11,8 @@ obj-$(call land,$(CONFIG_KVM),$(call lnot,$(TARGET_AARCH64))) += kvm32.o
 obj-$(call land,$(CONFIG_KVM),$(TARGET_AARCH64)) += kvm64.o
 obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
 
+obj-$(CONFIG_SDEI) += sdei.o
+
 DECODETREE = $(SRC_PATH)/scripts/decodetree.py
 
 target/arm/decode-sve.inc.c: $(SRC_PATH)/target/arm/sve.decode $(DECODETREE)
-- 
2.19.1



^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [RFC v2 05/14] arm/sdei: add support to handle SDEI requests from guest
  2019-11-05  9:10 [RFC v2 00/14] Add SDEI support for arm64 Heyi Guo
                   ` (3 preceding siblings ...)
  2019-11-05  9:10 ` [RFC v2 04/14] arm: add CONFIG_SDEI build flag Heyi Guo
@ 2019-11-05  9:10 ` Heyi Guo
  2019-11-05  9:10 ` [RFC v2 06/14] arm/sdei: add system reset callback Heyi Guo
                   ` (13 subsequent siblings)
  18 siblings, 0 replies; 43+ messages in thread
From: Heyi Guo @ 2019-11-05  9:10 UTC (permalink / raw)
  To: qemu-arm, qemu-devel
  Cc: Mark Rutland, Peter Maydell, James Morse, Marc Zyngier,
	Jingyi Wang, Heyi Guo, wanghaibin.wang, Dave Martin

Add support for all interfaces defined in ARM SDEI 1.0 spec.

http://infocenter.arm.com/help/topic/com.arm.doc.den0054a/ARM_DEN0054A_Software_Delegated_Exception_Interface.pdf

The exit reason KVM_EXIT_HYPERCALL is used to indicate it is an
HVC/SMC forward, and the structure kvm_run->hypercall is used to pass
arguments and return values between KVM and qemu:
Input:
  nr: the immediate value of SMC/HVC calls; not really used today.
  args[6]: x0..x5 (This is not fully conform with SMCCC which requires
           x6 as argument as well, but we can use GET_ONE_REG ioctl
           for such rare case).
Return:
  args[0..3]: x0..x3 as defined in SMCCC. We rely on KVM to extract
              args[0..3] and write them to x0..x3 when hypercall exit
              returns.

Signed-off-by: Heyi Guo <guoheyi@huawei.com>
Signed-off-by: Jingyi Wang <wangjingyi11@huawei.com>
Cc: Peter Maydell <peter.maydell@linaro.org>
Cc: Dave Martin <Dave.Martin@arm.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: James Morse <james.morse@arm.com>
---
 target/arm/sdei.c | 982 ++++++++++++++++++++++++++++++++++++++++++++++
 target/arm/sdei.h |  34 ++
 2 files changed, 1016 insertions(+)
 create mode 100644 target/arm/sdei.h

diff --git a/target/arm/sdei.c b/target/arm/sdei.c
index 931e46923a..0c0212bfa8 100644
--- a/target/arm/sdei.c
+++ b/target/arm/sdei.c
@@ -29,6 +29,7 @@
 #include "sysemu/sysemu.h"
 #include "sysemu/reset.h"
 #include "qemu/error-report.h"
+#include "sdei.h"
 #include "sdei_int.h"
 #include "internals.h"
 #include "hw/boards.h"
@@ -42,6 +43,9 @@
 #define TYPE_ARM_SDEI "arm_sdei"
 #define QEMU_SDEI(obj) OBJECT_CHECK(QemuSDEState, (obj), TYPE_ARM_SDEI)
 
+#define SMCCC_RETURN_REG_COUNT 4
+#define PSTATE_M_EL_SHIFT      2
+
 static QemuSDEState *sde_state;
 
 static void qemu_sde_prop_init(QemuSDEState *s)
@@ -84,6 +88,16 @@ static void qemu_sde_cpu_init(QemuSDEState *s)
     }
 }
 
+static inline QemuSDECpu *get_sde_cpu(QemuSDEState *s, CPUState *cs)
+{
+    if (cs->cpu_index >= s->sdei_max_cpus) {
+        error_report("BUG: cpu index %d >= max_cpus %d",
+                     cs->cpu_index, s->sdei_max_cpus);
+        return NULL;
+    }
+    return &s->sde_cpus[cs->cpu_index];
+}
+
 static bool is_valid_event_number(int32_t event)
 {
     int32_t slot_id;
@@ -122,6 +136,974 @@ static QemuSDEProp *get_sde_prop_no_lock(QemuSDEState *s, int32_t event)
     return &s->sde_props_state[SDEI_EVENT_TO_SLOT(event)];
 }
 
+static QemuSDEProp *get_sde_prop(QemuSDEState *s, int32_t event)
+{
+    QemuSDEProp *sde_props = s->sde_props_state;
+
+    if (!is_valid_event_number(event)) {
+        return NULL;
+    }
+
+    event = SDEI_EVENT_TO_SLOT(event);
+
+    qemu_mutex_lock(&sde_props[event].lock);
+    if (sde_props[event].event_id < 0) {
+        qemu_mutex_unlock(&sde_props[event].lock);
+        return NULL;
+    }
+    return &sde_props[event];
+}
+
+static void put_sde_prop(QemuSDEProp *prop)
+{
+    qemu_mutex_unlock(&prop->lock);
+}
+
+static void sde_slot_lock(QemuSDE *sde, CPUState *cs)
+{
+    qemu_mutex_lock(&sde->lock);
+}
+
+static void sde_slot_unlock(QemuSDE *sde, CPUState *cs)
+{
+    qemu_mutex_unlock(&sde->lock);
+}
+
+/*
+ * It will always return a pointer to a preallocated sde; event number must be
+ * validated before calling this function.
+ */
+static QemuSDE *get_sde_no_check(QemuSDEState *s, int32_t event, CPUState *cs)
+{
+    QemuSDE **array = s->sde_cpus[cs->cpu_index].private_sde_array;
+    int32_t sde_index = SDEI_EVENT_TO_SLOT(event);
+    QemuSDE *sde;
+
+    if (SDEI_IS_SHARED_EVENT(event)) {
+        array = s->shared_sde_array;
+        sde_index -= PRIVATE_SLOT_COUNT;
+    }
+
+    sde = array[sde_index];
+    sde_slot_lock(sde, cs);
+    return sde;
+}
+
+static void put_sde(QemuSDE *sde, CPUState *cs)
+{
+    sde_slot_unlock(sde, cs);
+}
+
+static inline bool is_sde_nested(QemuSDECpu *sde_cpu)
+{
+    return sde_cpu->critical_running_event >= 0 &&
+           sde_cpu->normal_running_event >= 0;
+}
+
+static int32_t get_running_sde(QemuSDEState *s, CPUState *cs)
+{
+    QemuSDECpu *sde_cpu = get_sde_cpu(s, cs);
+
+    if (!sde_cpu) {
+        return SDEI_INVALID_EVENT_ID;
+    }
+
+    if (sde_cpu->critical_running_event >= 0) {
+        return sde_cpu->critical_running_event;
+    }
+    return sde_cpu->normal_running_event;
+}
+
+static void override_return_value(CPUState *cs, uint64_t *args)
+{
+    CPUARMState *env = &ARM_CPU(cs)->env;
+    int i;
+
+    for (i = 0; i < SMCCC_RETURN_REG_COUNT; i++) {
+        args[i] = env->xregs[i];
+    }
+}
+
+static void sde_save_cpu_ctx(CPUState *cs, QemuSDECpu *sde_cpu, bool critical)
+{
+    CPUARMState *env = &ARM_CPU(cs)->env;
+    QemuSDECpuCtx *ctx = &sde_cpu->ctx[critical ? 1 : 0];
+
+    memcpy(ctx->xregs, env->xregs, sizeof(ctx->xregs));
+    ctx->pc = env->pc;
+    ctx->pstate = pstate_read(env);
+}
+
+static void sde_restore_cpu_ctx(QemuSDEState *s, CPUState *cs, bool critical)
+{
+    CPUARMState *env = &ARM_CPU(cs)->env;
+    QemuSDECpu *sde_cpu = get_sde_cpu(s, cs);
+    QemuSDECpuCtx *ctx;
+
+    if (!sde_cpu) {
+        return;
+    }
+
+    ctx = &sde_cpu->ctx[critical ? 1 : 0];
+
+    /*
+     * TODO: we need to optimize to only restore affected registers by calling
+     * ioctl individialy
+     */
+    kvm_arch_get_registers(cs);
+
+    env->aarch64 = ((ctx->pstate & PSTATE_nRW) == 0);
+    memcpy(env->xregs, ctx->xregs, sizeof(ctx->xregs));
+    env->pc = ctx->pc;
+    pstate_write(env, ctx->pstate);
+    aarch64_restore_sp(env, (env->pstate & PSTATE_M) >> PSTATE_M_EL_SHIFT);
+}
+
+static void sde_restore_cpu_ctx_for_resume(QemuSDEState *s,
+                                           CPUState *cs,
+                                           bool critical,
+                                           uint64_t resume_addr)
+{
+    CPUARMState *env = &ARM_CPU(cs)->env;
+    QemuSDECpu *sde_cpu = get_sde_cpu(s, cs);
+    QemuSDECpuCtx *ctx;
+
+    if (!sde_cpu) {
+        return;
+    }
+
+    ctx = &sde_cpu->ctx[critical ? 1 : 0];
+
+    /*
+     * TODO: we need to optimize to only restore affected registers by calling
+     * ioctl individialy
+     */
+    kvm_arch_get_registers(cs);
+
+    memcpy(env->xregs, ctx->xregs, sizeof(ctx->xregs));
+    env->pc = resume_addr;
+    env->aarch64 = 1;
+    /* Constructe pstate in pstate_read() */
+    env->daif = PSTATE_D | PSTATE_A | PSTATE_I | PSTATE_F;
+    /* Clear nRW/M[4] and M[3:0] */
+    env->pstate &= ~(PSTATE_nRW | PSTATE_M);
+    /* Set exception mode to EL1h */
+    env->pstate |= PSTATE_MODE_EL1h;
+    env->elr_el[1] = ctx->pc;
+    env->banked_spsr[KVM_SPSR_EL1 + 1] = ctx->pstate;
+    aarch64_restore_sp(env, 1);
+}
+
+static void sde_build_cpu_ctx(CPUState *cs, QemuSDECpu *sde_cpu, QemuSDE *sde)
+{
+    CPUARMState *env = &ARM_CPU(cs)->env;
+
+    env->xregs[0] = sde->prop->event_id;
+    env->xregs[1] = sde->ep_argument;
+    env->xregs[2] = env->pc;
+    env->xregs[3] = pstate_read(env);
+    env->pc = sde->ep_address;
+    env->aarch64 = 1;
+    /* Constructe pstate in pstate_read() */
+    env->daif = PSTATE_D | PSTATE_A | PSTATE_I | PSTATE_F;
+    /* Clear nRW/M[4] and M[3:0] */
+    env->pstate &= ~(PSTATE_nRW | PSTATE_M);
+    /* Set exception mode to EL1h */
+    env->pstate |= PSTATE_MODE_EL1h;
+    aarch64_restore_sp(env, 1);
+}
+
+static void trigger_sde(CPUState *cs, run_on_cpu_data data)
+{
+    QemuSDEState *s = sde_state;
+    QemuSDECpu *sde_cpu = get_sde_cpu(s, cs);
+    int32_t event = data.host_int;
+    QemuSDE *sde;
+
+    if (!sde_cpu) {
+        return;
+    }
+
+    if (sde_cpu->masked || sde_cpu->critical_running_event >= 0) {
+        return;
+    }
+
+    sde = get_sde_no_check(s, event, cs);
+    if (sde->event_id == SDEI_INVALID_EVENT_ID) {
+        /* Some race condition happens! */
+        put_sde(sde, cs);
+        return;
+    }
+
+    if (sde_cpu->normal_running_event >= 0 && !sde->prop->is_critical) {
+        put_sde(sde, cs);
+        return;
+    }
+
+    if (!sde->enabled || !sde->pending || sde->running) {
+        /* Some race condition happens! */
+        put_sde(sde, cs);
+        return;
+    }
+
+    sde->pending = false;
+    sde->running = true;
+
+    if (sde->prop->is_critical) {
+        sde_cpu->critical_running_event = sde->prop->event_id;
+    } else {
+        sde_cpu->normal_running_event = sde->prop->event_id;
+    }
+
+    kvm_arch_get_registers(cs);
+    sde_save_cpu_ctx(cs, sde_cpu, sde->prop->is_critical);
+    sde_build_cpu_ctx(cs, sde_cpu, sde);
+    kvm_arch_put_registers(cs, 1);
+    put_sde(sde, cs);
+}
+
+static void dispatch_single(QemuSDEState *s, QemuSDE *sde, CPUState *cs)
+{
+    int32_t event = sde->prop->event_id;
+    bool pending = sde->pending;
+    bool enabled = sde->enabled;
+    CPUState *target = sde->target_cpu;
+    put_sde(sde, cs);
+
+    if (pending && enabled) {
+        /*
+         * TODO: we need to find a free-unmasked PE to trigger for shared
+         * unpinned event
+         */
+        async_run_on_cpu(target, trigger_sde,
+                         RUN_ON_CPU_HOST_INT(event));
+    }
+}
+
+static bool sde_ready_to_trigger(QemuSDE *sde, CPUState *cs, bool is_critical)
+{
+    if (sde->event_id == SDEI_INVALID_EVENT_ID) {
+        return false;
+    }
+    if (sde->prop->is_critical != is_critical) {
+        return false;
+    }
+    if (!sde->enabled || !sde->pending || sde->running ||
+        sde->target_cpu != cs) {
+        return false;
+    }
+    return true;
+}
+
+static void dispatch_cpu(QemuSDEState *s, CPUState *cs, bool is_critical)
+{
+    QemuSDE *sde;
+    int i;
+
+    for (i = 0; i < PRIVATE_SLOT_COUNT + SHARED_SLOT_COUNT; i++) {
+        sde = get_sde_no_check(s, i, cs);
+        if (!sde_ready_to_trigger(sde, cs, is_critical)) {
+            put_sde(sde, cs);
+            continue;
+        }
+        dispatch_single(s, sde, cs);
+    }
+}
+
+static int32_t sdei_alloc_event_num(QemuSDEState *s, bool is_critical,
+                                    bool is_shared, int intid)
+{
+    int index;
+    int start = 0;
+    int count = PRIVATE_SLOT_COUNT;
+    int32_t event;
+    QemuSDEProp *sde_props = s->sde_props_state;
+
+    if (is_shared) {
+        start = PRIVATE_SLOT_COUNT;
+        count = PRIVATE_SLOT_COUNT + SHARED_SLOT_COUNT;
+    }
+
+    qemu_mutex_lock(&s->sdei_interrupt_bind_lock);
+    for (index = start; index < count; index++) {
+        qemu_mutex_lock(&sde_props[index].lock);
+        if (sde_props[index].interrupt == intid) {
+            event = sde_props[index].event_id;
+            qemu_mutex_unlock(&sde_props[index].lock);
+            qemu_mutex_unlock(&s->sdei_interrupt_bind_lock);
+            return event;
+        }
+        qemu_mutex_unlock(&sde_props[index].lock);
+    }
+
+    for (index = start; index < count; index++) {
+        qemu_mutex_lock(&sde_props[index].lock);
+        if (sde_props[index].event_id < 0) {
+            event = sde_props[index].event_id = 0x40000000 | index;
+            sde_props[index].interrupt = intid;
+            sde_props[index].is_shared = is_shared;
+            sde_props[index].is_critical = is_critical;
+            s->irq_map[intid] = event;
+            qemu_mutex_unlock(&sde_props[index].lock);
+            qemu_mutex_unlock(&s->sdei_interrupt_bind_lock);
+            return event;
+        }
+        qemu_mutex_unlock(&sde_props[index].lock);
+    }
+    qemu_mutex_unlock(&s->sdei_interrupt_bind_lock);
+    return SDEI_OUT_OF_RESOURCE;
+}
+
+static int32_t sdei_free_event_num_locked(QemuSDEState *s, QemuSDEProp *prop)
+{
+    if (atomic_read(&prop->refcount) > 0) {
+        return SDEI_DENIED;
+    }
+
+    s->irq_map[prop->interrupt] = SDEI_INVALID_EVENT_ID;
+    prop->event_id = SDEI_INVALID_EVENT_ID;
+    prop->interrupt = SDEI_INVALID_INTERRUPT;
+    return SDEI_SUCCESS;
+}
+
+typedef int64_t (*sdei_single_function)(QemuSDEState *s,
+                                        CPUState *cs,
+                                        struct kvm_run *run);
+
+static int64_t sdei_version(QemuSDEState *s, CPUState *cs, struct kvm_run *run)
+{
+    return (1ULL << SDEI_VERSION_MAJOR_SHIFT) |
+           (0ULL << SDEI_VERSION_MINOR_SHIFT);
+}
+
+static int64_t unregister_single_sde(QemuSDEState *s, int32_t event,
+                                     CPUState *cs, bool force)
+{
+    QemuSDE     *sde;
+    QemuSDEProp *prop;
+    int         ret = 0;
+
+    prop = get_sde_prop(s, event);
+    if (!prop) {
+        return SDEI_INVALID_PARAMETERS;
+    }
+
+    sde = get_sde_no_check(s, event, cs);
+    if (sde->event_id == SDEI_INVALID_EVENT_ID) {
+        put_sde(sde, cs);
+        put_sde_prop(prop);
+        return SDEI_DENIED;
+    }
+
+    if (sde->running && !force) {
+        sde->unregister_pending = true;
+        ret = SDEI_PENDING;
+    } else {
+        atomic_dec(&prop->refcount);
+        sde->event_id = SDEI_INVALID_EVENT_ID;
+        sde->enabled = false;
+        sde->running = false;
+        sde->pending = false;
+        sde->unregister_pending = false;
+    }
+    put_sde(sde, cs);
+    put_sde_prop(prop);
+    return ret;
+}
+
+static int64_t sdei_private_reset_common(QemuSDEState *s, CPUState *cs,
+                                         bool force)
+{
+    int64_t ret = SDEI_SUCCESS;
+    int i;
+
+    for (i = 0; i < PRIVATE_SLOT_COUNT; i++) {
+        int64_t ret1;
+        ret1 = unregister_single_sde(s, i, cs, force);
+        /* Ignore other return values in reset interface */
+        if (ret1 == SDEI_PENDING) {
+            ret = SDEI_DENIED;
+        }
+    }
+
+    return ret;
+}
+
+static int64_t sdei_shared_reset_common(QemuSDEState *s, CPUState *cs,
+                                        bool force)
+{
+    int             i;
+    QemuSDEProp     *prop;
+    int32_t         start_event = PRIVATE_SLOT_COUNT;
+    int64_t         ret = SDEI_SUCCESS;
+
+    for (i = start_event; i < PRIVATE_SLOT_COUNT + SHARED_SLOT_COUNT; i++) {
+        int64_t ret1 = unregister_single_sde(s, i, cs, force);
+        /* Ignore other return values in reset interface */
+        if (ret1 == SDEI_PENDING) {
+            ret = SDEI_DENIED;
+        }
+    }
+    if (ret) {
+        return ret;
+    }
+
+    qemu_mutex_lock(&s->sdei_interrupt_bind_lock);
+    for (i = 0; i < PRIVATE_SLOT_COUNT + SHARED_SLOT_COUNT; i++) {
+        prop = get_sde_prop(s, i);
+        if (!prop || prop->interrupt == SDEI_INVALID_INTERRUPT) {
+            if (prop) {
+                put_sde_prop(prop);
+            }
+            continue;
+        }
+        ret |= sdei_free_event_num_locked(s, prop);
+        put_sde_prop(prop);
+    }
+    qemu_mutex_unlock(&s->sdei_interrupt_bind_lock);
+
+    return ret ? SDEI_DENIED : SDEI_SUCCESS;
+}
+
+#define SDEI_EV_REGISTER_RM_MASK 1ULL
+
+static int64_t sdei_event_register(QemuSDEState *s, CPUState *cs,
+                                   struct kvm_run *run)
+{
+    QemuSDE *sde;
+    QemuSDEProp *prop;
+    CPUState *target = cs;
+    uint64_t *args = (uint64_t *)run->hypercall.args;
+    int32_t event = args[1];
+    uint64_t rm_mode = SDEI_EVENT_REGISTER_RM_PE;
+
+    prop = get_sde_prop(s, event);
+    if (!prop) {
+        return SDEI_INVALID_PARAMETERS;
+    }
+
+    sde = get_sde_no_check(s, event, cs);
+    if (sde->event_id != SDEI_INVALID_EVENT_ID) {
+        put_sde(sde, cs);
+        put_sde_prop(prop);
+        return SDEI_DENIED;
+    }
+
+    if (prop->is_shared) {
+        rm_mode = args[4] & SDEI_EV_REGISTER_RM_MASK;
+        if (rm_mode == SDEI_EVENT_REGISTER_RM_PE) {
+            target = arm_get_cpu_by_id(args[5]);
+            if (!target) {
+                put_sde_prop(prop);
+                return SDEI_INVALID_PARAMETERS;
+            }
+        }
+    }
+
+    sde->target_cpu = target;
+    sde->ep_address = args[2];
+    sde->ep_argument = args[3];
+    sde->prop = prop;
+    sde->routing_mode = rm_mode;
+    sde->event_id = prop->event_id;
+
+    put_sde(sde, cs);
+    atomic_inc(&prop->refcount);
+    put_sde_prop(prop);
+
+    return SDEI_SUCCESS;
+}
+
+static int64_t sdei_event_enable(QemuSDEState *s, CPUState *cs,
+                                 struct kvm_run *run)
+{
+    QemuSDE *sde;
+    uint64_t *args = (uint64_t *)(run->hypercall.args);
+    int32_t event = args[1];
+
+    if (!is_valid_event_number(event)) {
+        return SDEI_INVALID_PARAMETERS;
+    }
+    sde = get_sde_no_check(s, event, cs);
+    if (sde->event_id == SDEI_INVALID_EVENT_ID) {
+        put_sde(sde, cs);
+        return SDEI_INVALID_PARAMETERS;
+    }
+
+    sde->enabled = true;
+    dispatch_single(s, sde, cs);
+    return SDEI_SUCCESS;
+}
+
+static int64_t sdei_event_disable(QemuSDEState *s, CPUState *cs,
+                                  struct kvm_run *run)
+{
+    QemuSDE *sde;
+    uint64_t *args = (uint64_t *)run->hypercall.args;
+    int32_t event = args[1];
+
+    if (!is_valid_event_number(event)) {
+        return SDEI_INVALID_PARAMETERS;
+    }
+    sde = get_sde_no_check(s, event, cs);
+    if (sde->event_id == SDEI_INVALID_EVENT_ID) {
+        put_sde(sde, cs);
+        return SDEI_INVALID_PARAMETERS;
+    }
+
+    sde->enabled = false;
+    put_sde(sde, cs);
+    return SDEI_SUCCESS;
+}
+
+static int64_t sdei_event_context(QemuSDEState *s, CPUState *cs,
+                                  struct kvm_run *run)
+{
+    QemuSDECpu *sde_cpu = get_sde_cpu(s, cs);
+    uint64_t *args = (uint64_t *)(run->hypercall.args);
+    uint32_t param_id = args[1];
+    int critical;
+    QemuSDECpuCtx *ctx;
+
+    if (param_id >= SDEI_PARAM_MAX) {
+        return SDEI_INVALID_PARAMETERS;
+    }
+
+    if (!sde_cpu) {
+        return SDEI_DENIED;
+    }
+
+    if (sde_cpu->critical_running_event >= 0) {
+        critical = 1;
+    } else if (sde_cpu->normal_running_event >= 0) {
+        critical = 0;
+    } else {
+        return SDEI_DENIED;
+    }
+
+    ctx = &sde_cpu->ctx[critical];
+    return ctx->xregs[param_id];
+}
+
+static int64_t sdei_event_complete(QemuSDEState *s, CPUState *cs,
+                                   struct kvm_run *run)
+{
+    QemuSDE *sde;
+    QemuSDECpu *cpu = get_sde_cpu(s, cs);
+    int32_t event;
+    uint64_t *args = (uint64_t *)(run->hypercall.args);
+    bool is_critical;
+
+    if (!cpu) {
+        return SDEI_DENIED;
+    }
+
+    event = get_running_sde(s, cs);
+    if (event < 0) {
+        return SDEI_DENIED;
+    }
+
+    if (!is_valid_event_number(event)) {
+        error_report("BUG: running event number 0x%x is invalid!",
+                     event);
+        return SDEI_DENIED;
+    }
+    sde = get_sde_no_check(s, event, cs);
+    if (sde->event_id != event) {
+        error_report("BUG: sde event id 0x%x != running event 0x%x!",
+                     sde->event_id, event);
+        put_sde(sde, cs);
+        return SDEI_DENIED;
+    }
+
+    sde->running = false;
+    is_critical = sde->prop->is_critical;
+    if (sde->unregister_pending) {
+        atomic_dec(&sde->prop->refcount);
+        sde->event_id = SDEI_INVALID_EVENT_ID;
+        sde->unregister_pending = false;
+    }
+    put_sde(sde, cs);
+
+    sde_restore_cpu_ctx(s, cs, is_critical);
+
+    kvm_arch_put_registers(cs, 1);
+    override_return_value(cs, args);
+    if (cpu->critical_running_event >= 0) {
+        cpu->critical_running_event = SDEI_INVALID_EVENT_ID;
+    } else {
+        cpu->normal_running_event = SDEI_INVALID_EVENT_ID;
+    }
+
+    /* TODO: we should not queue more than one sde in work queue */
+    dispatch_cpu(s, cs, true);
+    if (cpu->critical_running_event < 0 && cpu->normal_running_event < 0) {
+        dispatch_cpu(s, cs, false);
+    }
+    return args[0];
+}
+
+static int64_t sdei_event_complete_and_resume(QemuSDEState *s, CPUState *cs,
+                                              struct kvm_run *run)
+{
+    QemuSDE *sde;
+    QemuSDECpu *cpu = get_sde_cpu(s, cs);
+    int32_t event;
+    uint64_t *args = (uint64_t *)(run->hypercall.args);
+    bool is_critical;
+    uint64_t resume_addr = args[1];
+
+    if (!cpu) {
+        return SDEI_DENIED;
+    }
+
+    event = get_running_sde(s, cs);
+    if (event < 0) {
+        return SDEI_DENIED;
+    }
+
+    if (!is_valid_event_number(event)) {
+        error_report("BUG: running event number 0x%x is invalid!",
+                     event);
+        return SDEI_DENIED;
+    }
+
+    sde = get_sde_no_check(s, event, cs);
+    if (sde->event_id != event) {
+        error_report("BUG: sde event id 0x%x != running event 0x%x!",
+                     sde->event_id, event);
+        put_sde(sde, cs);
+        return SDEI_DENIED;
+    }
+
+    sde->running = false;
+    is_critical = sde->prop->is_critical;
+
+    if (sde->unregister_pending) {
+        atomic_dec(&sde->prop->refcount);
+        sde->event_id = SDEI_INVALID_EVENT_ID;
+        sde->unregister_pending = false;
+    }
+    put_sde(sde, cs);
+
+    sde_restore_cpu_ctx_for_resume(s, cs, is_critical, resume_addr);
+    kvm_arch_put_registers(cs, 1);
+
+    override_return_value(cs, args);
+    if (cpu->critical_running_event >= 0) {
+        cpu->critical_running_event = SDEI_INVALID_EVENT_ID;
+    } else {
+        cpu->normal_running_event = SDEI_INVALID_EVENT_ID;
+    }
+
+    dispatch_cpu(s, cs, true);
+    if (cpu->critical_running_event < 0 && cpu->normal_running_event < 0) {
+        dispatch_cpu(s, cs, false);
+    }
+    return args[0];
+}
+
+static int64_t sdei_event_unregister(QemuSDEState *s, CPUState *cs,
+                                     struct kvm_run *run)
+{
+    uint64_t        *args = (uint64_t *)(run->hypercall.args);
+    int32_t         event = args[1];
+
+    return unregister_single_sde(s, event, cs, false);
+}
+
+static int64_t sdei_event_status(QemuSDEState *s, CPUState *cs,
+                                 struct kvm_run *run)
+{
+    QemuSDE *sde;
+    uint64_t *args = (uint64_t *)(run->hypercall.args);
+    int32_t event = args[1];
+    int64_t status = 0;
+
+    if (!is_valid_event(s, event)) {
+        return SDEI_INVALID_PARAMETERS;
+    }
+
+    sde = get_sde_no_check(s, event, cs);
+    if (sde->event_id == SDEI_INVALID_EVENT_ID) {
+        put_sde(sde, cs);
+        return status;
+    }
+
+    status |= SDEI_EVENT_STATUS_REGISTERED;
+    if (sde->enabled) {
+        status |= SDEI_EVENT_STATUS_ENABLED;
+    }
+    if (sde->running) {
+        status |= SDEI_EVENT_STATUS_RUNNING;
+    }
+    put_sde(sde, cs);
+    return status;
+}
+
+static int64_t sdei_event_get_info(QemuSDEState *s, CPUState *cs,
+                                   struct kvm_run *run)
+{
+    QemuSDEProp *prop;
+    QemuSDE *sde;
+    uint64_t *args = (uint64_t *)(run->hypercall.args);
+    int32_t event = args[1];
+    uint32_t info = args[2];
+    int64_t ret = SDEI_INVALID_PARAMETERS;
+
+    if (info > SDEI_EVENT_INFO_EV_ROUTING_AFF) {
+        return SDEI_INVALID_PARAMETERS;
+    }
+
+    prop = get_sde_prop(s, event);
+    if (!prop) {
+        return SDEI_INVALID_PARAMETERS;
+    }
+
+    switch (info) {
+    case SDEI_EVENT_INFO_EV_TYPE:
+        ret = prop->is_shared;
+        break;
+    case SDEI_EVENT_INFO_EV_SIGNALED:
+        ret = (event == SDEI_STD_EVT_SOFTWARE_SIGNAL) ? 1 : 0;
+        break;
+    case SDEI_EVENT_INFO_EV_PRIORITY:
+        ret = prop->is_critical;
+        break;
+    case SDEI_EVENT_INFO_EV_ROUTING_MODE:
+    case SDEI_EVENT_INFO_EV_ROUTING_AFF:
+        if (!prop->is_shared) {
+            break;
+        }
+        sde = get_sde_no_check(s, event, cs);
+        if (sde->event_id == SDEI_INVALID_EVENT_ID) {
+            put_sde(sde, cs);
+            ret = SDEI_DENIED;
+            break;
+        }
+        if (info == SDEI_EVENT_INFO_EV_ROUTING_MODE) {
+            ret = sde->routing_mode;
+        } else if (sde->routing_mode == SDEI_EVENT_REGISTER_RM_PE) {
+            ret = ARM_CPU(sde->target_cpu)->mp_affinity;
+        }
+        put_sde(sde, cs);
+        break;
+    default:
+        ret = SDEI_NOT_SUPPORTED;
+    }
+    put_sde_prop(prop);
+    return ret;
+}
+
+static int64_t sdei_event_routing_set(QemuSDEState *s, CPUState *cs,
+                                      struct kvm_run *run)
+{
+    QemuSDE *sde;
+    CPUState *target = cs;
+    uint64_t *args = (uint64_t *)run->hypercall.args;
+    int32_t event = args[1];
+    uint64_t mode = args[2];
+    uint64_t affinity = args[3];
+
+    if (mode & ~1ULL) {
+        return SDEI_INVALID_PARAMETERS;
+    }
+    if (mode == SDEI_EVENT_REGISTER_RM_PE) {
+        target = arm_get_cpu_by_id(affinity);
+        if (!target) {
+            return SDEI_INVALID_PARAMETERS;
+        }
+    }
+
+    if (!is_valid_event(s, event) || !SDEI_IS_SHARED_EVENT(event)) {
+        return SDEI_INVALID_PARAMETERS;
+    }
+
+    sde = get_sde_no_check(s, event, cs);
+    if (sde->event_id == SDEI_INVALID_EVENT_ID) {
+        put_sde(sde, cs);
+        return SDEI_DENIED;
+    }
+    if (sde->enabled || sde->running ||
+        sde->pending || sde->unregister_pending) {
+        put_sde(sde, cs);
+        return SDEI_DENIED;
+    }
+
+    sde->target_cpu = target;
+    sde->routing_mode = mode;
+    put_sde(sde, cs);
+
+    return SDEI_SUCCESS;
+}
+
+static int64_t sdei_event_pe_mask(QemuSDEState *s, CPUState *cs,
+                                  struct kvm_run *run)
+{
+    QemuSDECpu *sde_cpu;
+
+    sde_cpu = get_sde_cpu(s, cs);
+    if (!sde_cpu) {
+        return SDEI_DENIED;
+    }
+
+    if (sde_cpu->masked) {
+        return 0;
+    }
+    sde_cpu->masked = true;
+    return 1;
+}
+
+static int64_t sdei_event_pe_unmask(QemuSDEState *s, CPUState *cs,
+                                    struct kvm_run *run)
+{
+    QemuSDECpu *sde_cpu;
+
+    sde_cpu = get_sde_cpu(s, cs);
+    if (!sde_cpu) {
+        return SDEI_DENIED;
+    }
+
+    sde_cpu->masked = false;
+    dispatch_cpu(s, cs, true);
+    dispatch_cpu(s, cs, false);
+    return SDEI_SUCCESS;
+}
+
+static int64_t sdei_event_interrupt_bind(QemuSDEState *s, CPUState *cs,
+                                         struct kvm_run *run)
+{
+    uint64_t *args = (uint64_t *)(run->hypercall.args);
+    uint32_t intid = args[1];
+
+    if (intid < GIC_NR_SGIS || intid >= GIC_MAXIRQ) {
+        return SDEI_INVALID_PARAMETERS;
+    }
+    return sdei_alloc_event_num(s, false, intid >= GIC_INTERNAL, intid);
+}
+
+static int64_t sdei_event_interrupt_release(QemuSDEState *s, CPUState *cs,
+                                            struct kvm_run *run)
+{
+    QemuSDEProp *prop;
+    uint64_t *args = (uint64_t *)(run->hypercall.args);
+    int32_t event = args[1];
+    int32_t ret;
+
+    qemu_mutex_lock(&s->sdei_interrupt_bind_lock);
+    prop = get_sde_prop(s, event);
+    if (!prop) {
+        qemu_mutex_unlock(&s->sdei_interrupt_bind_lock);
+        return SDEI_INVALID_PARAMETERS;
+    }
+
+    ret = sdei_free_event_num_locked(s, prop);
+    put_sde_prop(prop);
+    qemu_mutex_unlock(&s->sdei_interrupt_bind_lock);
+    return ret;
+}
+
+static int64_t sdei_event_signal(QemuSDEState *s, CPUState *cs,
+                                 struct kvm_run *run)
+{
+    QemuSDE *sde;
+    CPUState *target_cpu;
+    uint64_t *args = (uint64_t *)(run->hypercall.args);
+    int32_t event = args[1];
+
+    if (event != SDEI_STD_EVT_SOFTWARE_SIGNAL) {
+        return SDEI_INVALID_PARAMETERS;
+    }
+
+    target_cpu = arm_get_cpu_by_id(args[2]);
+    if (!target_cpu) {
+        return SDEI_INVALID_PARAMETERS;
+    }
+
+    sde = get_sde_no_check(s, event, target_cpu);
+    if (sde->event_id == SDEI_INVALID_EVENT_ID) {
+        put_sde(sde, cs);
+        return SDEI_INVALID_PARAMETERS;
+    }
+
+    sde->pending = true;
+    dispatch_single(s, sde, target_cpu);
+    return SDEI_SUCCESS;
+}
+
+#define SDEI_FEATURES_SHARED_SLOTS_SHIFT 16
+static int64_t sdei_features(QemuSDEState *s, CPUState *cs, struct kvm_run *run)
+{
+    uint64_t *args = (uint64_t *)(run->hypercall.args);
+    uint32_t feature = args[1];
+
+    switch (feature) {
+    case SDEI_FEATURE_BIND_SLOTS:
+        return ((SHARED_SLOT_COUNT - PLAT_SHARED_SLOT_COUNT) <<
+                 SDEI_FEATURES_SHARED_SLOTS_SHIFT) |
+               (PRIVATE_SLOT_COUNT - PLAT_PRIVATE_SLOT_COUNT);
+    default:
+        return SDEI_INVALID_PARAMETERS;
+    }
+}
+
+static int64_t sdei_private_reset(QemuSDEState *s, CPUState *cs,
+                                  struct kvm_run *run)
+{
+    return sdei_private_reset_common(s, cs, false);
+}
+
+static int64_t sdei_shared_reset(QemuSDEState *s, CPUState *cs,
+                                 struct kvm_run *run)
+{
+    return sdei_shared_reset_common(s, cs, false);
+}
+
+static sdei_single_function sdei_functions[] = {
+    sdei_version,
+    sdei_event_register,
+    sdei_event_enable,
+    sdei_event_disable,
+    sdei_event_context,
+    sdei_event_complete,
+    sdei_event_complete_and_resume,
+    sdei_event_unregister,
+    sdei_event_status,
+    sdei_event_get_info,
+    sdei_event_routing_set,
+    sdei_event_pe_mask,
+    sdei_event_pe_unmask,
+    sdei_event_interrupt_bind,
+    sdei_event_interrupt_release,
+    sdei_event_signal,
+    sdei_features,
+    sdei_private_reset,
+    sdei_shared_reset,
+};
+
+void sdei_handle_request(CPUState *cs, struct kvm_run *run)
+{
+    uint32_t func_id = run->hypercall.args[0];
+
+    if (!sde_state) {
+        run->hypercall.args[0] = SDEI_NOT_SUPPORTED;
+        return;
+    }
+
+    if (func_id < SDEI_1_0_FN_BASE || func_id > SDEI_MAX_REQ) {
+        error_report("Invalid SDEI function ID: 0x%x", func_id);
+        run->hypercall.args[0] = SDEI_INVALID_PARAMETERS;
+        return;
+    }
+
+    func_id -= SDEI_1_0_FN_BASE;
+    if (func_id < ARRAY_SIZE(sdei_functions) && sdei_functions[func_id]) {
+        run->hypercall.args[0] = sdei_functions[func_id](sde_state, cs, run);
+    } else {
+        run->hypercall.args[0] = SDEI_NOT_SUPPORTED;
+    }
+}
+
 static void sde_array_init(QemuSDE **array, int count)
 {
     int i;
diff --git a/target/arm/sdei.h b/target/arm/sdei.h
new file mode 100644
index 0000000000..828f70bbf1
--- /dev/null
+++ b/target/arm/sdei.h
@@ -0,0 +1,34 @@
+/*
+ * ARM SDEI emulation external interfaces
+ *
+ * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved.
+ *
+ * Authors:
+ *    Heyi Guo <guoheyi@huawei.com>
+ *    Jingyi Wang <wangjingyi11@huawei.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef QEMU_SDEI_H
+#define QEMU_SDEI_H
+
+#include <linux/kvm.h>
+#include <linux/arm_sdei.h>
+#include "hw/core/cpu.h"
+
+#define SDEI_MAX_REQ        SDEI_1_0_FN(0x12)
+
+void sdei_handle_request(CPUState *cs, struct kvm_run *run);
+
+#endif
-- 
2.19.1



^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [RFC v2 06/14] arm/sdei: add system reset callback
  2019-11-05  9:10 [RFC v2 00/14] Add SDEI support for arm64 Heyi Guo
                   ` (4 preceding siblings ...)
  2019-11-05  9:10 ` [RFC v2 05/14] arm/sdei: add support to handle SDEI requests from guest Heyi Guo
@ 2019-11-05  9:10 ` Heyi Guo
  2019-11-05  9:10 ` [RFC v2 07/14] arm/sdei: add support to trigger event by GIC interrupt ID Heyi Guo
                   ` (12 subsequent siblings)
  18 siblings, 0 replies; 43+ messages in thread
From: Heyi Guo @ 2019-11-05  9:10 UTC (permalink / raw)
  To: qemu-arm, qemu-devel
  Cc: Mark Rutland, Peter Maydell, James Morse, Marc Zyngier,
	Jingyi Wang, Heyi Guo, wanghaibin.wang, Dave Martin

For this is a logical device which is not attached to system bus, we
cannot use DeviceClass->reset interface directly. Instead we register
our own reset callback to reset SDEI services when system resets.

Signed-off-by: Heyi Guo <guoheyi@huawei.com>
Signed-off-by: Jingyi Wang <wangjingyi11@huawei.com>
Cc: Peter Maydell <peter.maydell@linaro.org>
Cc: Dave Martin <Dave.Martin@arm.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: James Morse <james.morse@arm.com>
---
 target/arm/sdei.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/target/arm/sdei.c b/target/arm/sdei.c
index 0c0212bfa8..6af4a9044b 100644
--- a/target/arm/sdei.c
+++ b/target/arm/sdei.c
@@ -1147,6 +1147,26 @@ static void qemu_sde_init(QemuSDEState *s)
     qemu_private_sde_init(s);
 }
 
+static void qemu_sde_reset(void *opaque)
+{
+    int64_t         ret = 0;
+    CPUState        *cs;
+    QemuSDEState    *s = opaque;
+
+    CPU_FOREACH(cs) {
+        QemuSDECpu *sde_cpu = get_sde_cpu(s, cs);
+        ret |= sdei_private_reset_common(s, cs, true);
+        sde_cpu->masked = true;
+        sde_cpu->critical_running_event = SDEI_INVALID_EVENT_ID;
+        sde_cpu->normal_running_event = SDEI_INVALID_EVENT_ID;
+    }
+
+    ret |= sdei_shared_reset_common(s, first_cpu, true);
+    if (ret) {
+        error_report("SDEI system reset failed: 0x%lx", ret);
+    }
+}
+
 static void sde_array_save(QemuSDE **array, int count)
 {
     int i;
@@ -1299,6 +1319,7 @@ static void sdei_initfn(Object *obj)
     sde_state = s;
 
     qemu_sde_init(s);
+    qemu_register_reset(qemu_sde_reset, s);
 }
 
 static void qemu_sde_class_init(ObjectClass *klass, void *data)
-- 
2.19.1



^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [RFC v2 07/14] arm/sdei: add support to trigger event by GIC interrupt ID
  2019-11-05  9:10 [RFC v2 00/14] Add SDEI support for arm64 Heyi Guo
                   ` (5 preceding siblings ...)
  2019-11-05  9:10 ` [RFC v2 06/14] arm/sdei: add system reset callback Heyi Guo
@ 2019-11-05  9:10 ` Heyi Guo
  2019-11-05  9:10 ` [RFC v2 08/14] core/irq: add qemu_irq_remove_intercept interface Heyi Guo
                   ` (11 subsequent siblings)
  18 siblings, 0 replies; 43+ messages in thread
From: Heyi Guo @ 2019-11-05  9:10 UTC (permalink / raw)
  To: qemu-arm, qemu-devel
  Cc: Mark Rutland, Peter Maydell, Marc Zyngier, James Morse, Heyi Guo,
	wanghaibin.wang, Dave Martin

Add an external interface to trigger an SDEI event bound to an
interrupt by providing GIC interrupt ID.

Signed-off-by: Heyi Guo <guoheyi@huawei.com>
Cc: Peter Maydell <peter.maydell@linaro.org>
Cc: Dave Martin <Dave.Martin@arm.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: James Morse <james.morse@arm.com>
---
 target/arm/sdei.c | 37 +++++++++++++++++++++++++++++++++++++
 target/arm/sdei.h |  7 +++++++
 2 files changed, 44 insertions(+)

diff --git a/target/arm/sdei.c b/target/arm/sdei.c
index 6af4a9044b..713ac97775 100644
--- a/target/arm/sdei.c
+++ b/target/arm/sdei.c
@@ -476,6 +476,28 @@ static int64_t sdei_version(QemuSDEState *s, CPUState *cs, struct kvm_run *run)
            (0ULL << SDEI_VERSION_MINOR_SHIFT);
 }
 
+static bool inject_event(QemuSDEState *s, CPUState *cs, int32_t event, int irq)
+{
+    QemuSDE *sde;
+
+    if (event < 0) {
+        return false;
+    }
+    sde = get_sde_no_check(s, event, cs);
+    if (sde->event_id == SDEI_INVALID_EVENT_ID) {
+        put_sde(sde, cs);
+        return false;
+    }
+    if (irq > 0 && sde->prop->interrupt != irq) {
+        /* Someone unbinds the interrupt! */
+        put_sde(sde, cs);
+        return false;
+    }
+    sde->pending = true;
+    dispatch_single(s, sde, cs);
+    return true;
+}
+
 static int64_t unregister_single_sde(QemuSDEState *s, int32_t event,
                                      CPUState *cs, bool force)
 {
@@ -1104,6 +1126,21 @@ void sdei_handle_request(CPUState *cs, struct kvm_run *run)
     }
 }
 
+bool trigger_sdei_by_irq(int cpu, int irq)
+{
+    QemuSDEState *s = sde_state;
+
+    if (!s || irq >= ARRAY_SIZE(s->irq_map)) {
+        return false;
+    }
+
+    if (s->irq_map[irq] == SDEI_INVALID_EVENT_ID) {
+        return false;
+    }
+
+    return inject_event(s, qemu_get_cpu(cpu), s->irq_map[irq], irq);
+}
+
 static void sde_array_init(QemuSDE **array, int count)
 {
     int i;
diff --git a/target/arm/sdei.h b/target/arm/sdei.h
index 828f70bbf1..5ecc32d667 100644
--- a/target/arm/sdei.h
+++ b/target/arm/sdei.h
@@ -31,4 +31,11 @@
 
 void sdei_handle_request(CPUState *cs, struct kvm_run *run);
 
+/*
+ * Trigger an SDEI event bound to an interrupt.
+ * Return true if event has been triggered successfully.
+ * Return false if event has not been triggered for some reason.
+ */
+bool trigger_sdei_by_irq(int cpu, int irq);
+
 #endif
-- 
2.19.1



^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [RFC v2 08/14] core/irq: add qemu_irq_remove_intercept interface
  2019-11-05  9:10 [RFC v2 00/14] Add SDEI support for arm64 Heyi Guo
                   ` (6 preceding siblings ...)
  2019-11-05  9:10 ` [RFC v2 07/14] arm/sdei: add support to trigger event by GIC interrupt ID Heyi Guo
@ 2019-11-05  9:10 ` Heyi Guo
  2019-11-05  9:10 ` [RFC v2 09/14] arm/sdei: override qemu_irq handler when binding interrupt Heyi Guo
                   ` (10 subsequent siblings)
  18 siblings, 0 replies; 43+ messages in thread
From: Heyi Guo @ 2019-11-05  9:10 UTC (permalink / raw)
  To: qemu-arm, qemu-devel
  Cc: Mark Rutland, Peter Maydell, Marc Zyngier, James Morse, Heyi Guo,
	wanghaibin.wang, Dave Martin

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, so we also need a corresponding
interface to restore the handler to default one (i.e. ARM GIC).

qemu_irq_remove_intercept() is the new interface to do the above
job.

Signed-off-by: Heyi Guo <guoheyi@huawei.com>
Cc: Peter Maydell <peter.maydell@linaro.org>
Cc: Dave Martin <Dave.Martin@arm.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: James Morse <james.morse@arm.com>
---
 hw/core/irq.c    | 11 +++++++++++
 include/hw/irq.h |  8 ++++++--
 2 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/hw/core/irq.c b/hw/core/irq.c
index 7cc0295d0e..114bce6c21 100644
--- a/hw/core/irq.c
+++ b/hw/core/irq.c
@@ -145,6 +145,17 @@ void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n)
     }
 }
 
+void qemu_irq_remove_intercept(qemu_irq *gpio_in, int n)
+{
+    int i;
+    qemu_irq *old_irqs = gpio_in[0]->opaque;
+    for (i = 0; i < n; i++) {
+        gpio_in[i]->handler = old_irqs[i]->handler;
+        gpio_in[i]->opaque = old_irqs[i]->opaque;
+    }
+    qemu_free_irqs(old_irqs, n);
+}
+
 static const TypeInfo irq_type_info = {
    .name = TYPE_IRQ,
    .parent = TYPE_OBJECT,
diff --git a/include/hw/irq.h b/include/hw/irq.h
index fe527f6f51..1af1db93bb 100644
--- a/include/hw/irq.h
+++ b/include/hw/irq.h
@@ -56,8 +56,12 @@ qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2);
  */
 qemu_irq *qemu_irq_proxy(qemu_irq **target, int n);
 
-/* For internal use in qtest.  Similar to qemu_irq_split, but operating
-   on an existing vector of qemu_irq.  */
+/*
+ * Similar to qemu_irq_split, but operating on an existing vector of qemu_irq.
+ */
 void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n);
 
+/* Restore the irq handler intercepted by qemu_irq_intercept_in() */
+void qemu_irq_remove_intercept(qemu_irq *gpio_in, int n);
+
 #endif
-- 
2.19.1



^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [RFC v2 09/14] arm/sdei: override qemu_irq handler when binding interrupt
  2019-11-05  9:10 [RFC v2 00/14] Add SDEI support for arm64 Heyi Guo
                   ` (7 preceding siblings ...)
  2019-11-05  9:10 ` [RFC v2 08/14] core/irq: add qemu_irq_remove_intercept interface Heyi Guo
@ 2019-11-05  9:10 ` Heyi Guo
  2019-11-05  9:10 ` [RFC v2 10/14] arm/sdei: add support to register interrupt bind notifier Heyi Guo
                   ` (9 subsequent siblings)
  18 siblings, 0 replies; 43+ messages in thread
From: Heyi Guo @ 2019-11-05  9:10 UTC (permalink / raw)
  To: qemu-arm, qemu-devel
  Cc: Mark Rutland, Peter Maydell, Marc Zyngier, James Morse, Heyi Guo,
	wanghaibin.wang, Dave Martin

Override qemu_irq handler to support trigger SDEI event transparently
after guest binds interrupt to SDEI event. We don't have good way to
get GIC device and to guarantee SDEI device is initialized after GIC,
so we search GIC in system bus when the first SDEI request happens or
in VMSTATE post_load().

Signed-off-by: Heyi Guo <guoheyi@huawei.com>
Cc: Peter Maydell <peter.maydell@linaro.org>
Cc: Dave Martin <Dave.Martin@arm.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: James Morse <james.morse@arm.com>
---
 target/arm/sdei.c     | 130 +++++++++++++++++++++++++++++++++++++++++-
 target/arm/sdei_int.h |   3 +
 2 files changed, 132 insertions(+), 1 deletion(-)

diff --git a/target/arm/sdei.c b/target/arm/sdei.c
index 713ac97775..529a06c1f6 100644
--- a/target/arm/sdei.c
+++ b/target/arm/sdei.c
@@ -88,6 +88,24 @@ static void qemu_sde_cpu_init(QemuSDEState *s)
     }
 }
 
+static int gic_int_to_irq(int num_irq, int intid, int cpu)
+{
+    if (intid >= GIC_INTERNAL) {
+        return intid - GIC_INTERNAL;
+    }
+    return num_irq - GIC_INTERNAL + cpu * GIC_INTERNAL + intid;
+}
+
+static int irq_to_gic_int(int num_irq, int irq, int *cpu)
+{
+    if (irq < num_irq - GIC_INTERNAL) {
+        return irq + GIC_INTERNAL;
+    }
+    irq -= num_irq - GIC_INTERNAL;
+    *cpu = irq / GIC_INTERNAL;
+    return irq % GIC_INTERNAL;
+}
+
 static inline QemuSDECpu *get_sde_cpu(QemuSDEState *s, CPUState *cs)
 {
     if (cs->cpu_index >= s->sdei_max_cpus) {
@@ -410,6 +428,74 @@ static void dispatch_cpu(QemuSDEState *s, CPUState *cs, bool is_critical)
     }
 }
 
+static void qemu_sdei_irq_handler(void *opaque, int irq, int level)
+{
+    int cpu = 0;
+
+    irq = irq_to_gic_int(sde_state->num_irq, irq, &cpu);
+    trigger_sdei_by_irq(cpu, irq);
+}
+
+static void override_qemu_irq(QemuSDEState *s, int32_t event, uint32_t intid)
+{
+    qemu_irq irq;
+    QemuSDE *sde;
+    CPUState *cs;
+
+    /* SPI */
+    if (intid >= GIC_INTERNAL) {
+        cs = first_cpu;
+        irq = qdev_get_gpio_in(s->gic_dev,
+                               gic_int_to_irq(s->num_irq, intid, 0));
+        if (irq) {
+            qemu_irq_intercept_in(&irq, qemu_sdei_irq_handler, 1);
+        }
+        sde = get_sde_no_check(s, event, cs);
+        sde->irq = irq;
+        put_sde(sde, cs);
+        return;
+    }
+    /* PPI */
+    CPU_FOREACH(cs) {
+        irq = qdev_get_gpio_in(
+            s->gic_dev,
+            gic_int_to_irq(s->num_irq, intid, cs->cpu_index));
+        if (irq) {
+            qemu_irq_intercept_in(&irq, qemu_sdei_irq_handler, 1);
+        }
+        sde = get_sde_no_check(s, event, cs);
+        sde->irq = irq;
+        put_sde(sde, cs);
+    }
+}
+
+static void restore_qemu_irq(QemuSDEState *s, int32_t event, uint32_t intid)
+{
+    QemuSDE *sde;
+    CPUState *cs;
+
+    /* SPI */
+    if (intid >= GIC_INTERNAL) {
+        cs = first_cpu;
+        sde = get_sde_no_check(s, event, cs);
+        if (sde->irq) {
+            qemu_irq_remove_intercept(&sde->irq, 1);
+            sde->irq = NULL;
+        }
+        put_sde(sde, cs);
+        return;
+    }
+    /* PPI */
+    CPU_FOREACH(cs) {
+        sde = get_sde_no_check(s, event, cs);
+        if (sde->irq) {
+            qemu_irq_remove_intercept(&sde->irq, 1);
+            sde->irq = NULL;
+        }
+        put_sde(sde, cs);
+    }
+}
+
 static int32_t sdei_alloc_event_num(QemuSDEState *s, bool is_critical,
                                     bool is_shared, int intid)
 {
@@ -443,6 +529,7 @@ static int32_t sdei_alloc_event_num(QemuSDEState *s, bool is_critical,
             sde_props[index].interrupt = intid;
             sde_props[index].is_shared = is_shared;
             sde_props[index].is_critical = is_critical;
+            override_qemu_irq(s, event, intid);
             s->irq_map[intid] = event;
             qemu_mutex_unlock(&sde_props[index].lock);
             qemu_mutex_unlock(&s->sdei_interrupt_bind_lock);
@@ -460,6 +547,7 @@ static int32_t sdei_free_event_num_locked(QemuSDEState *s, QemuSDEProp *prop)
         return SDEI_DENIED;
     }
 
+    restore_qemu_irq(s, prop->event_id, prop->interrupt);
     s->irq_map[prop->interrupt] = SDEI_INVALID_EVENT_ID;
     prop->event_id = SDEI_INVALID_EVENT_ID;
     prop->interrupt = SDEI_INVALID_INTERRUPT;
@@ -992,13 +1080,33 @@ static int64_t sdei_event_pe_unmask(QemuSDEState *s, CPUState *cs,
     return SDEI_SUCCESS;
 }
 
+static int dev_walkerfn(DeviceState *dev, void *opaque)
+{
+    QemuSDEState *s = opaque;
+
+    if (object_dynamic_cast(OBJECT(dev), TYPE_ARM_GICV3_COMMON)) {
+        GICv3State *gic = ARM_GICV3_COMMON(dev);
+        s->num_irq = gic->num_irq;
+        s->gic_dev = dev;
+        return -1;
+    }
+
+    if (object_dynamic_cast(OBJECT(dev), TYPE_ARM_GIC_COMMON)) {
+        GICState *gic = ARM_GIC_COMMON(dev);
+        s->num_irq = gic->num_irq;
+        s->gic_dev = dev;
+        return -1;
+    }
+    return 0;
+}
+
 static int64_t sdei_event_interrupt_bind(QemuSDEState *s, CPUState *cs,
                                          struct kvm_run *run)
 {
     uint64_t *args = (uint64_t *)(run->hypercall.args);
     uint32_t intid = args[1];
 
-    if (intid < GIC_NR_SGIS || intid >= GIC_MAXIRQ) {
+    if (intid < GIC_NR_SGIS || intid >= s->num_irq) {
         return SDEI_INVALID_PARAMETERS;
     }
     return sdei_alloc_event_num(s, false, intid >= GIC_INTERNAL, intid);
@@ -1112,6 +1220,17 @@ void sdei_handle_request(CPUState *cs, struct kvm_run *run)
         return;
     }
 
+    if (!sde_state->gic_dev) {
+        /* Search for ARM GIC device */
+        qbus_walk_children(sysbus_get_default(), dev_walkerfn,
+                           NULL, NULL, NULL, sde_state);
+        if (!sde_state->gic_dev) {
+            error_report("Cannot find ARM GIC device!");
+            run->hypercall.args[0] = SDEI_NOT_SUPPORTED;
+            return;
+        }
+    }
+
     if (func_id < SDEI_1_0_FN_BASE || func_id > SDEI_MAX_REQ) {
         error_report("Invalid SDEI function ID: 0x%x", func_id);
         run->hypercall.args[0] = SDEI_INVALID_PARAMETERS;
@@ -1259,11 +1378,20 @@ static int qemu_sdei_post_load(void *opaque, int version_id)
         }
     }
 
+    /* Search for ARM GIC device */
+    qbus_walk_children(sysbus_get_default(), dev_walkerfn,
+                       NULL, NULL, NULL, s);
+    if (!s->gic_dev) {
+        error_report("Cannot find ARM GIC device!");
+        return 0;
+    }
+
     for (i = 0; i < PRIVATE_SLOT_COUNT + SHARED_SLOT_COUNT; i++) {
         int intid = sde_props[i].interrupt;
 
         if (intid != SDEI_INVALID_INTERRUPT) {
             s->irq_map[intid] = sde_props[i].event_id;
+            override_qemu_irq(s, sde_props[i].event_id, intid);
         }
     }
 
diff --git a/target/arm/sdei_int.h b/target/arm/sdei_int.h
index d3fd7cbc10..a251b04ab5 100644
--- a/target/arm/sdei_int.h
+++ b/target/arm/sdei_int.h
@@ -63,6 +63,7 @@ typedef struct QemuSDEProp {
 typedef struct QemuSDE {
     QemuSDEProp     *prop;
     CPUState        *target_cpu;
+    qemu_irq        irq;
     QemuMutex       lock;
     bool            enabled;
     bool            running;
@@ -107,9 +108,11 @@ typedef struct QemuSDECpu {
 
 typedef struct QemuSDEState {
     DeviceState     parent_obj;
+    DeviceState     *gic_dev;
     QemuSDEProp     sde_props_state[PRIVATE_SLOT_COUNT + SHARED_SLOT_COUNT];
     QemuSDECpu      *sde_cpus;
     int             sdei_max_cpus;
+    int             num_irq;
     QemuSDE         *shared_sde_array[SHARED_SLOT_COUNT];
     int32_t         irq_map[GIC_MAXIRQ];
     QemuMutex       sdei_interrupt_bind_lock;
-- 
2.19.1



^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [RFC v2 10/14] arm/sdei: add support to register interrupt bind notifier
  2019-11-05  9:10 [RFC v2 00/14] Add SDEI support for arm64 Heyi Guo
                   ` (8 preceding siblings ...)
  2019-11-05  9:10 ` [RFC v2 09/14] arm/sdei: override qemu_irq handler when binding interrupt Heyi Guo
@ 2019-11-05  9:10 ` Heyi Guo
  2019-11-05  9:10 ` [RFC v2 11/14] linux-headers/kvm.h: add capability to forward hypercall Heyi Guo
                   ` (8 subsequent siblings)
  18 siblings, 0 replies; 43+ messages in thread
From: Heyi Guo @ 2019-11-05  9:10 UTC (permalink / raw)
  To: qemu-arm, qemu-devel
  Cc: Mark Rutland, Peter Maydell, Marc Zyngier, James Morse, Heyi Guo,
	wanghaibin.wang, Dave Martin

Other qemu modules related with the interrupt bind operation may want
to be notified when guest requests to bind interrupt to sdei event, so
we add register and unregister interfaces.

Signed-off-by: Heyi Guo <guoheyi@huawei.com>
Cc: Peter Maydell <peter.maydell@linaro.org>
Cc: Dave Martin <Dave.Martin@arm.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: James Morse <james.morse@arm.com>
---
 target/arm/sdei.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++
 target/arm/sdei.h | 17 +++++++++++++++++
 2 files changed, 65 insertions(+)

diff --git a/target/arm/sdei.c b/target/arm/sdei.c
index 529a06c1f6..4cc68e4acf 100644
--- a/target/arm/sdei.c
+++ b/target/arm/sdei.c
@@ -48,6 +48,52 @@
 
 static QemuSDEState *sde_state;
 
+typedef struct QemuSDEIBindNotifyEntry {
+    QTAILQ_ENTRY(QemuSDEIBindNotifyEntry) entry;
+    QemuSDEIBindNotify *func;
+    void *opaque;
+    int irq;
+} QemuSDEIBindNotifyEntry;
+
+static QTAILQ_HEAD(, QemuSDEIBindNotifyEntry) bind_notifiers =
+    QTAILQ_HEAD_INITIALIZER(bind_notifiers);
+
+void qemu_register_sdei_bind_notifier(QemuSDEIBindNotify *func,
+                                      void *opaque, int irq)
+{
+    QemuSDEIBindNotifyEntry *be = g_new0(QemuSDEIBindNotifyEntry, 1);
+
+    be->func = func;
+    be->opaque = opaque;
+    be->irq = irq;
+    QTAILQ_INSERT_TAIL(&bind_notifiers, be, entry);
+}
+
+void qemu_unregister_sdei_bind_notifier(QemuSDEIBindNotify *func,
+                                        void *opaque, int irq)
+{
+    QemuSDEIBindNotifyEntry *be;
+
+    QTAILQ_FOREACH(be, &bind_notifiers, entry) {
+        if (be->func == func && be->opaque == opaque && be->irq == irq) {
+            QTAILQ_REMOVE(&bind_notifiers, be, entry);
+            g_free(be);
+            return;
+        }
+    }
+}
+
+static void sdei_notify_bind(int irq, int32_t event, bool bind)
+{
+    QemuSDEIBindNotifyEntry *be, *nbe;
+
+    QTAILQ_FOREACH_SAFE(be, &bind_notifiers, entry, nbe) {
+        if (be->irq == irq) {
+            be->func(be->opaque, irq, event, bind);
+        }
+    }
+}
+
 static void qemu_sde_prop_init(QemuSDEState *s)
 {
     QemuSDEProp *sde_props = s->sde_props_state;
@@ -529,6 +575,7 @@ static int32_t sdei_alloc_event_num(QemuSDEState *s, bool is_critical,
             sde_props[index].interrupt = intid;
             sde_props[index].is_shared = is_shared;
             sde_props[index].is_critical = is_critical;
+            sdei_notify_bind(intid, event, true);
             override_qemu_irq(s, event, intid);
             s->irq_map[intid] = event;
             qemu_mutex_unlock(&sde_props[index].lock);
@@ -547,6 +594,7 @@ static int32_t sdei_free_event_num_locked(QemuSDEState *s, QemuSDEProp *prop)
         return SDEI_DENIED;
     }
 
+    sdei_notify_bind(prop->interrupt, prop->event_id, false);
     restore_qemu_irq(s, prop->event_id, prop->interrupt);
     s->irq_map[prop->interrupt] = SDEI_INVALID_EVENT_ID;
     prop->event_id = SDEI_INVALID_EVENT_ID;
diff --git a/target/arm/sdei.h b/target/arm/sdei.h
index 5ecc32d667..9c15cf3186 100644
--- a/target/arm/sdei.h
+++ b/target/arm/sdei.h
@@ -38,4 +38,21 @@ void sdei_handle_request(CPUState *cs, struct kvm_run *run);
  */
 bool trigger_sdei_by_irq(int cpu, int irq);
 
+/*
+ * Notify callback prototype; the argument "bind" tells whether it is a bind
+ * operation or unbind one.
+ */
+typedef void QemuSDEIBindNotify(void *opaque, int irq,
+                                int32_t event, bool bind);
+/*
+ * Register a notify callback for a specific interrupt bind operation; the
+ * client will be both notified by bind and unbind operation.
+ */
+void qemu_register_sdei_bind_notifier(QemuSDEIBindNotify *func,
+                                      void *opaque, int irq);
+/*
+ * Unregister a notify callback for a specific interrupt bind operation.
+ */
+void qemu_unregister_sdei_bind_notifier(QemuSDEIBindNotify *func,
+                                        void *opaque, int irq);
 #endif
-- 
2.19.1



^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [RFC v2 11/14] linux-headers/kvm.h: add capability to forward hypercall
  2019-11-05  9:10 [RFC v2 00/14] Add SDEI support for arm64 Heyi Guo
                   ` (9 preceding siblings ...)
  2019-11-05  9:10 ` [RFC v2 10/14] arm/sdei: add support to register interrupt bind notifier Heyi Guo
@ 2019-11-05  9:10 ` Heyi Guo
  2019-11-06 17:55   ` Cornelia Huck
  2019-11-05  9:10 ` [RFC v2 12/14] arm/sdei: add stub to fix build failure when SDEI is not enabled Heyi Guo
                   ` (7 subsequent siblings)
  18 siblings, 1 reply; 43+ messages in thread
From: Heyi Guo @ 2019-11-05  9:10 UTC (permalink / raw)
  To: qemu-arm, qemu-devel
  Cc: Mark Rutland, Peter Maydell, Michael S. Tsirkin, Marc Zyngier,
	Cornelia Huck, James Morse, Paolo Bonzini, Heyi Guo,
	wanghaibin.wang, Dave Martin

To keep backward compatibility, we add new KVM capability
"KVM_CAP_FORWARD_HYPERCALL" to probe whether KVM supports forwarding
hypercall to userspace.

The capability should be enabled explicitly, for we don't want user
space application to deal with unexpected hypercall exits. After
enabling this cap, all HVC calls unhandled by kvm will be forwarded to
user space.

Signed-off-by: Heyi Guo <guoheyi@huawei.com>
Cc: Peter Maydell <peter.maydell@linaro.org>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Cornelia Huck <cohuck@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Dave Martin <Dave.Martin@arm.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: James Morse <james.morse@arm.com>
---
 linux-headers/linux/kvm.h |  1 +
 target/arm/sdei.c         | 16 ++++++++++++++++
 target/arm/sdei.h         |  2 ++
 3 files changed, 19 insertions(+)

diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index 3d9b18f7f8..36c9b3859f 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -1000,6 +1000,7 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_PMU_EVENT_FILTER 173
 #define KVM_CAP_ARM_IRQ_LINE_LAYOUT_2 174
 #define KVM_CAP_HYPERV_DIRECT_TLBFLUSH 175
+#define KVM_CAP_FORWARD_HYPERCALL 176
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
diff --git a/target/arm/sdei.c b/target/arm/sdei.c
index 4cc68e4acf..56e6874f6f 100644
--- a/target/arm/sdei.c
+++ b/target/arm/sdei.c
@@ -46,6 +46,7 @@
 #define SMCCC_RETURN_REG_COUNT 4
 #define PSTATE_M_EL_SHIFT      2
 
+bool sdei_enabled;
 static QemuSDEState *sde_state;
 
 typedef struct QemuSDEIBindNotifyEntry {
@@ -1524,6 +1525,7 @@ static const VMStateDescription vmstate_sde_state = {
 static void sdei_initfn(Object *obj)
 {
     QemuSDEState *s = QEMU_SDEI(obj);
+    KVMState *kvm = KVM_STATE(current_machine->accelerator);
 
     if (sde_state) {
         error_report("Only one SDEI dispatcher is allowed!");
@@ -1533,6 +1535,20 @@ static void sdei_initfn(Object *obj)
 
     qemu_sde_init(s);
     qemu_register_reset(qemu_sde_reset, s);
+
+    if (kvm_check_extension(kvm, KVM_CAP_FORWARD_HYPERCALL)) {
+        int ret;
+        ret = kvm_vm_enable_cap(kvm, KVM_CAP_FORWARD_HYPERCALL, 0, 0);
+        if (ret < 0) {
+            error_report("Enable hypercall forwarding failed: %s",
+                         strerror(-ret));
+            abort();
+        }
+        sdei_enabled = true;
+        info_report("qemu sdei enabled");
+    } else {
+        info_report("KVM does not support forwarding hypercall.");
+    }
 }
 
 static void qemu_sde_class_init(ObjectClass *klass, void *data)
diff --git a/target/arm/sdei.h b/target/arm/sdei.h
index 9c15cf3186..9f683ca2a0 100644
--- a/target/arm/sdei.h
+++ b/target/arm/sdei.h
@@ -29,6 +29,8 @@
 
 #define SDEI_MAX_REQ        SDEI_1_0_FN(0x12)
 
+extern bool sdei_enabled;
+
 void sdei_handle_request(CPUState *cs, struct kvm_run *run);
 
 /*
-- 
2.19.1



^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [RFC v2 12/14] arm/sdei: add stub to fix build failure when SDEI is not enabled
  2019-11-05  9:10 [RFC v2 00/14] Add SDEI support for arm64 Heyi Guo
                   ` (10 preceding siblings ...)
  2019-11-05  9:10 ` [RFC v2 11/14] linux-headers/kvm.h: add capability to forward hypercall Heyi Guo
@ 2019-11-05  9:10 ` Heyi Guo
  2019-11-05  9:10 ` [RFC v2 13/14] arm/kvm: handle guest exit of hypercall Heyi Guo
                   ` (6 subsequent siblings)
  18 siblings, 0 replies; 43+ messages in thread
From: Heyi Guo @ 2019-11-05  9:10 UTC (permalink / raw)
  To: qemu-arm, qemu-devel
  Cc: Mark Rutland, Peter Maydell, Marc Zyngier, James Morse, Heyi Guo,
	wanghaibin.wang, Dave Martin

Signed-off-by: Heyi Guo <guoheyi@huawei.com>
Cc: Peter Maydell <peter.maydell@linaro.org>
Cc: Dave Martin <Dave.Martin@arm.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: James Morse <james.morse@arm.com>
---
 target/arm/Makefile.objs |  2 ++
 target/arm/sdei-stub.c   | 49 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 51 insertions(+)
 create mode 100644 target/arm/sdei-stub.c

diff --git a/target/arm/Makefile.objs b/target/arm/Makefile.objs
index 72e01d08dc..90235af8ec 100644
--- a/target/arm/Makefile.objs
+++ b/target/arm/Makefile.objs
@@ -12,6 +12,8 @@ obj-$(call land,$(CONFIG_KVM),$(TARGET_AARCH64)) += kvm64.o
 obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
 
 obj-$(CONFIG_SDEI) += sdei.o
+obj-$(call lnot,$(CONFIG_SDEI)) += sdei-stub.o
+
 
 DECODETREE = $(SRC_PATH)/scripts/decodetree.py
 
diff --git a/target/arm/sdei-stub.c b/target/arm/sdei-stub.c
new file mode 100644
index 0000000000..4eaf365de7
--- /dev/null
+++ b/target/arm/sdei-stub.c
@@ -0,0 +1,49 @@
+/*
+ * QEMU ARM SDEI specific function stubs
+ *
+ * Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved.
+ *
+ * Author: Heyi Guo <guoheyi@huawei.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "sdei.h"
+
+bool sdei_enabled;
+
+void sdei_handle_request(CPUState *cs, struct kvm_run *run)
+{
+    run->hypercall.args[0] = SDEI_NOT_SUPPORTED;
+    return;
+}
+
+/*
+ * Trigger an SDEI event bound to an interrupt.
+ * Return true if event has been triggered successfully.
+ * Return false if event has not been triggered for some reason.
+ */
+bool trigger_sdei_by_irq(int cpu, int irq)
+{
+    return false;
+}
+
+/*
+ * Register a notify callback for a specific interrupt bind operation; the
+ * client will be both notified by bind and unbind operation.
+ */
+void qemu_register_sdei_bind_notifier(QemuSDEIBindNotify *func,
+                                      void *opaque, int irq)
+{
+}
+
+/*
+ * Unregister a notify callback for a specific interrupt bind operation.
+ */
+void qemu_unregister_sdei_bind_notifier(QemuSDEIBindNotify *func,
+                                        void *opaque, int irq)
+{
+}
-- 
2.19.1



^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [RFC v2 13/14] arm/kvm: handle guest exit of hypercall
  2019-11-05  9:10 [RFC v2 00/14] Add SDEI support for arm64 Heyi Guo
                   ` (11 preceding siblings ...)
  2019-11-05  9:10 ` [RFC v2 12/14] arm/sdei: add stub to fix build failure when SDEI is not enabled Heyi Guo
@ 2019-11-05  9:10 ` Heyi Guo
  2019-11-05  9:10 ` [RFC v2 14/14] virt/acpi: add SDEI table if SDEI is enabled Heyi Guo
                   ` (5 subsequent siblings)
  18 siblings, 0 replies; 43+ messages in thread
From: Heyi Guo @ 2019-11-05  9:10 UTC (permalink / raw)
  To: qemu-arm, qemu-devel
  Cc: Mark Rutland, Peter Maydell, Marc Zyngier, James Morse, Heyi Guo,
	wanghaibin.wang, Dave Martin

Add support to handle guest exit of hypercall, and forward to SDEI
dispatcher if SDEI is enabled and it is an SDEI request.

Signed-off-by: Heyi Guo <guoheyi@huawei.com>
Cc: Peter Maydell <peter.maydell@linaro.org>
Cc: Dave Martin <Dave.Martin@arm.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: James Morse <james.morse@arm.com>
---
 target/arm/kvm.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index b473c63edb..035a39e49f 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -30,6 +30,7 @@
 #include "hw/boards.h"
 #include "hw/irq.h"
 #include "qemu/log.h"
+#include "sdei.h"
 
 const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
     KVM_CAP_LAST_INFO
@@ -676,6 +677,19 @@ MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run)
 }
 
 
+static void kvm_arm_handle_hypercall(CPUState *cs, struct kvm_run *run)
+{
+    uint32_t func_id = run->hypercall.args[0];
+
+    if (sdei_enabled &&
+        func_id >= SDEI_1_0_FN_BASE && func_id <= SDEI_MAX_REQ) {
+        sdei_handle_request(cs, run);
+        return;
+    }
+
+    run->hypercall.args[0] = -1;
+}
+
 int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
 {
     int ret = 0;
@@ -686,6 +700,9 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
             ret = EXCP_DEBUG;
         } /* otherwise return to guest */
         break;
+    case KVM_EXIT_HYPERCALL:
+        kvm_arm_handle_hypercall(cs, run);
+        break;
     default:
         qemu_log_mask(LOG_UNIMP, "%s: un-handled exit reason %d\n",
                       __func__, run->exit_reason);
-- 
2.19.1



^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [RFC v2 14/14] virt/acpi: add SDEI table if SDEI is enabled
  2019-11-05  9:10 [RFC v2 00/14] Add SDEI support for arm64 Heyi Guo
                   ` (12 preceding siblings ...)
  2019-11-05  9:10 ` [RFC v2 13/14] arm/kvm: handle guest exit of hypercall Heyi Guo
@ 2019-11-05  9:10 ` Heyi Guo
  2019-11-12 14:52   ` Igor Mammedov
  2019-11-05  9:15 ` [RFC v2 00/14] Add SDEI support for arm64 Guoheyi
                   ` (4 subsequent siblings)
  18 siblings, 1 reply; 43+ messages in thread
From: Heyi Guo @ 2019-11-05  9:10 UTC (permalink / raw)
  To: qemu-arm, qemu-devel
  Cc: Mark Rutland, Peter Maydell, Michael S. Tsirkin, Marc Zyngier,
	Shannon Zhao, James Morse, Igor Mammedov, Heyi Guo,
	wanghaibin.wang, Dave Martin

Add SDEI table if SDEI is enabled, so that guest OS can get aware and
utilize the interfaces.

Signed-off-by: Heyi Guo <guoheyi@huawei.com>
Cc: Peter Maydell <peter.maydell@linaro.org>
Cc: Dave Martin <Dave.Martin@arm.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Shannon Zhao <shannon.zhaosl@gmail.com>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Igor Mammedov <imammedo@redhat.com>
---

Notes:
    v2:
    - Drop SDEI table definition and add comments

 hw/arm/virt-acpi-build.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 4cd50175e0..73d3f8cd15 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -32,6 +32,7 @@
 #include "trace.h"
 #include "hw/core/cpu.h"
 #include "target/arm/cpu.h"
+#include "target/arm/sdei.h"
 #include "hw/acpi/acpi-defs.h"
 #include "hw/acpi/acpi.h"
 #include "hw/nvram/fw_cfg.h"
@@ -475,6 +476,26 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
                  "IORT", table_data->len - iort_start, 0, NULL, NULL);
 }
 
+/*
+ * ACPI spec 6.2 Software Delegated Exception Interface (SDEI).
+ * (Revision 1.0)
+ * "SDEI" was reserved in ACPI 6.2. See "Links to ACPI-Related Documents"
+ * (http://uefi.org/acpi) under the heading "Software
+ * Delegated Exceptions Interface." The definition is under
+ * "10 Appendix C: ACPI table definitions for SDEI" in the linked document.
+ *
+ * This is a dummy table to expose platform SDEI capbility to OS.
+ */
+static void
+build_sdei(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
+{
+    int sdei_start = table_data->len;
+
+    (void)acpi_data_push(table_data, sizeof(AcpiTableHeader));
+    build_header(linker, table_data, (void *)(table_data->data + sdei_start),
+                 "SDEI", table_data->len - sdei_start, 1, NULL, NULL);
+}
+
 static void
 build_spcr(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
 {
@@ -825,6 +846,11 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables)
     acpi_add_table(table_offsets, tables_blob);
     build_spcr(tables_blob, tables->linker, vms);
 
+    if (sdei_enabled) {
+        acpi_add_table(table_offsets, tables_blob);
+        build_sdei(tables_blob, tables->linker, vms);
+    }
+
     if (ms->numa_state->num_nodes > 0) {
         acpi_add_table(table_offsets, tables_blob);
         build_srat(tables_blob, tables->linker, vms);
-- 
2.19.1



^ permalink raw reply related	[flat|nested] 43+ messages in thread

* Re: [RFC v2 00/14] Add SDEI support for arm64
  2019-11-05  9:10 [RFC v2 00/14] Add SDEI support for arm64 Heyi Guo
                   ` (13 preceding siblings ...)
  2019-11-05  9:10 ` [RFC v2 14/14] virt/acpi: add SDEI table if SDEI is enabled Heyi Guo
@ 2019-11-05  9:15 ` Guoheyi
  2019-11-05  9:36 ` no-reply
                   ` (3 subsequent siblings)
  18 siblings, 0 replies; 43+ messages in thread
From: Guoheyi @ 2019-11-05  9:15 UTC (permalink / raw)
  To: qemu-arm, qemu-devel
  Cc: Mark Rutland, Peter Maydell, Michael S. Tsirkin, Marc Zyngier,
	Cornelia Huck, Shannon Zhao, Igor Mammedov, James Morse,
	Paolo Bonzini, wanghaibin.wang, Dave Martin



On 2019/11/5 17:10, Heyi Guo wrote:
> 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.
Sorry I forgot to attach the link of SDEI specification v1.0:

http://infocenter.arm.com/help/topic/com.arm.doc.den0054a/ARM_DEN0054A_Software_Delegated_Exception_Interface.pdf

>
> 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 <peter.maydell@linaro.org>
> Cc: Dave Martin <Dave.Martin@arm.com>
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: James Morse <james.morse@arm.com>
> Cc: "Michael S. Tsirkin" <mst@redhat.com>
> Cc: Cornelia Huck <cohuck@redhat.com>
> Cc: Paolo Bonzini <pbonzini@redhat.com>
> Cc: Shannon Zhao <shannon.zhaosl@gmail.com>
> Cc: Igor Mammedov <imammedo@redhat.com>
>
> 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
>




^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [RFC v2 00/14] Add SDEI support for arm64
  2019-11-05  9:10 [RFC v2 00/14] Add SDEI support for arm64 Heyi Guo
                   ` (14 preceding siblings ...)
  2019-11-05  9:15 ` [RFC v2 00/14] Add SDEI support for arm64 Guoheyi
@ 2019-11-05  9:36 ` no-reply
  2019-11-05  9:38 ` no-reply
                   ` (2 subsequent siblings)
  18 siblings, 0 replies; 43+ messages in thread
From: no-reply @ 2019-11-05  9:36 UTC (permalink / raw)
  To: guoheyi
  Cc: mark.rutland, peter.maydell, mst, marc.zyngier, wanghaibin.wang,
	cohuck, qemu-devel, shannon.zhaosl, qemu-arm, james.morse,
	pbonzini, guoheyi, imammedo, Dave.Martin

Patchew URL: https://patchew.org/QEMU/20191105091056.9541-1-guoheyi@huawei.com/



Hi,

This series failed the docker-quick@centos7 build test. Please find the testing commands and
their output below. If you have Docker installed, you can probably reproduce it
locally.

=== TEST SCRIPT BEGIN ===
#!/bin/bash
make docker-image-centos7 V=1 NETWORK=1
time make docker-test-quick@centos7 SHOW_ENV=1 J=14 NETWORK=1
=== TEST SCRIPT END ===

    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['sudo', '-n', 'docker', 'run', '--label', 'com.qemu.instance.uuid=eed29e87c1cd46b29d4327f6effafd5b', '-u', '1003', '--security-opt', 'seccomp=unconfined', '--rm', '-e', 'TARGET_LIST=', '-e', 'EXTRA_CONFIGURE_OPTS=', '-e', 'V=', '-e', 'J=14', '-e', 'DEBUG=', '-e', 'SHOW_ENV=1', '-e', 'CCACHE_DIR=/var/tmp/ccache', '-v', '/home/patchew2/.cache/qemu-docker-ccache:/var/tmp/ccache:z', '-v', '/var/tmp/patchew-tester-tmp-nkpfmo47/src/docker-src.2019-11-05-04.33.58.25415:/var/tmp/qemu:z,ro', 'qemu:centos7', '/var/tmp/qemu/run', 'test-quick']' returned non-zero exit status 2.
filter=--filter=label=com.qemu.instance.uuid=eed29e87c1cd46b29d4327f6effafd5b
make[1]: *** [docker-run] Error 1
make[1]: Leaving directory `/var/tmp/patchew-tester-tmp-nkpfmo47/src'
make: *** [docker-run-test-quick@centos7] Error 2

real    2m10.919s
user    0m8.019s


The full log is available at
http://patchew.org/logs/20191105091056.9541-1-guoheyi@huawei.com/testing.docker-quick@centos7/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-devel@redhat.com

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [RFC v2 00/14] Add SDEI support for arm64
  2019-11-05  9:10 [RFC v2 00/14] Add SDEI support for arm64 Heyi Guo
                   ` (15 preceding siblings ...)
  2019-11-05  9:36 ` no-reply
@ 2019-11-05  9:38 ` no-reply
  2019-11-18  6:55 ` Guoheyi
  2019-12-20 13:44 ` Peter Maydell
  18 siblings, 0 replies; 43+ messages in thread
From: no-reply @ 2019-11-05  9:38 UTC (permalink / raw)
  To: guoheyi
  Cc: mark.rutland, peter.maydell, mst, marc.zyngier, wanghaibin.wang,
	cohuck, qemu-devel, shannon.zhaosl, qemu-arm, james.morse,
	pbonzini, guoheyi, imammedo, Dave.Martin

Patchew URL: https://patchew.org/QEMU/20191105091056.9541-1-guoheyi@huawei.com/



Hi,

This series failed the docker-mingw@fedora build test. Please find the testing commands and
their output below. If you have Docker installed, you can probably reproduce it
locally.

=== TEST SCRIPT BEGIN ===
#! /bin/bash
export ARCH=x86_64
make docker-image-fedora V=1 NETWORK=1
time make docker-test-mingw@fedora J=14 NETWORK=1
=== TEST SCRIPT END ===

    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['sudo', '-n', 'docker', 'run', '--label', 'com.qemu.instance.uuid=3708b2e272fa453aaa2f6dd31f5c4bff', '-u', '1003', '--security-opt', 'seccomp=unconfined', '--rm', '-e', 'TARGET_LIST=', '-e', 'EXTRA_CONFIGURE_OPTS=', '-e', 'V=', '-e', 'J=14', '-e', 'DEBUG=', '-e', 'SHOW_ENV=', '-e', 'CCACHE_DIR=/var/tmp/ccache', '-v', '/home/patchew2/.cache/qemu-docker-ccache:/var/tmp/ccache:z', '-v', '/var/tmp/patchew-tester-tmp-aclbx6j2/src/docker-src.2019-11-05-04.36.51.1877:/var/tmp/qemu:z,ro', 'qemu:fedora', '/var/tmp/qemu/run', 'test-mingw']' returned non-zero exit status 2.
filter=--filter=label=com.qemu.instance.uuid=3708b2e272fa453aaa2f6dd31f5c4bff
make[1]: *** [docker-run] Error 1
make[1]: Leaving directory `/var/tmp/patchew-tester-tmp-aclbx6j2/src'
make: *** [docker-run-test-mingw@fedora] Error 2

real    1m57.553s
user    0m7.728s


The full log is available at
http://patchew.org/logs/20191105091056.9541-1-guoheyi@huawei.com/testing.docker-mingw@fedora/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-devel@redhat.com

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [RFC v2 02/14] standard-headers: import arm_sdei.h
  2019-11-05  9:10 ` [RFC v2 02/14] standard-headers: import arm_sdei.h Heyi Guo
@ 2019-11-06 17:52   ` Cornelia Huck
  2019-11-07  1:40     ` Guoheyi
  0 siblings, 1 reply; 43+ messages in thread
From: Cornelia Huck @ 2019-11-06 17:52 UTC (permalink / raw)
  To: Heyi Guo
  Cc: Mark Rutland, Peter Maydell, Michael S. Tsirkin, Marc Zyngier,
	qemu-devel, qemu-arm, James Morse, Paolo Bonzini,
	wanghaibin.wang, Dave Martin

On Tue, 5 Nov 2019 17:10:44 +0800
Heyi Guo <guoheyi@huawei.com> wrote:

> Import Linux header file include/uapi/linux/arm_sdei.h from kernel v5.4-rc5.
> 
> This is to prepare for qemu SDEI emulation.
> 
> Signed-off-by: Heyi Guo <guoheyi@huawei.com>
> Cc: Peter Maydell <peter.maydell@linaro.org>
> Cc: Dave Martin <Dave.Martin@arm.com>
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: James Morse <james.morse@arm.com>
> Cc: "Michael S. Tsirkin" <mst@redhat.com>
> Cc: Cornelia Huck <cohuck@redhat.com>
> Cc: Paolo Bonzini <pbonzini@redhat.com>
> ---
> 
> Notes:
>     v2:
>     - Import arm_sdei.h by running update-linux-headers.sh
> 
>  include/standard-headers/linux/arm_sdei.h | 73 +++++++++++++++++++++++
>  1 file changed, 73 insertions(+)
>  create mode 100644 include/standard-headers/linux/arm_sdei.h

Just a remark that I find it a bit odd that that a header that looks
arm-specific is in the generic linux/ directory (already in the kernel,
I know.) Is this for sharing between arm and arm64, maybe?



^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [RFC v2 11/14] linux-headers/kvm.h: add capability to forward hypercall
  2019-11-05  9:10 ` [RFC v2 11/14] linux-headers/kvm.h: add capability to forward hypercall Heyi Guo
@ 2019-11-06 17:55   ` Cornelia Huck
  2019-11-07  1:44     ` Guoheyi
  0 siblings, 1 reply; 43+ messages in thread
From: Cornelia Huck @ 2019-11-06 17:55 UTC (permalink / raw)
  To: Heyi Guo
  Cc: Mark Rutland, Peter Maydell, Michael S. Tsirkin, Marc Zyngier,
	qemu-devel, qemu-arm, James Morse, Paolo Bonzini,
	wanghaibin.wang, Dave Martin

On Tue, 5 Nov 2019 17:10:53 +0800
Heyi Guo <guoheyi@huawei.com> wrote:

> To keep backward compatibility, we add new KVM capability
> "KVM_CAP_FORWARD_HYPERCALL" to probe whether KVM supports forwarding
> hypercall to userspace.
> 
> The capability should be enabled explicitly, for we don't want user
> space application to deal with unexpected hypercall exits. After
> enabling this cap, all HVC calls unhandled by kvm will be forwarded to
> user space.
> 
> Signed-off-by: Heyi Guo <guoheyi@huawei.com>
> Cc: Peter Maydell <peter.maydell@linaro.org>
> Cc: "Michael S. Tsirkin" <mst@redhat.com>
> Cc: Cornelia Huck <cohuck@redhat.com>
> Cc: Paolo Bonzini <pbonzini@redhat.com>
> Cc: Dave Martin <Dave.Martin@arm.com>
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: James Morse <james.morse@arm.com>
> ---
>  linux-headers/linux/kvm.h |  1 +
>  target/arm/sdei.c         | 16 ++++++++++++++++
>  target/arm/sdei.h         |  2 ++
>  3 files changed, 19 insertions(+)
> 
> diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
> index 3d9b18f7f8..36c9b3859f 100644
> --- a/linux-headers/linux/kvm.h
> +++ b/linux-headers/linux/kvm.h
> @@ -1000,6 +1000,7 @@ struct kvm_ppc_resize_hpt {
>  #define KVM_CAP_PMU_EVENT_FILTER 173
>  #define KVM_CAP_ARM_IRQ_LINE_LAYOUT_2 174
>  #define KVM_CAP_HYPERV_DIRECT_TLBFLUSH 175
> +#define KVM_CAP_FORWARD_HYPERCALL 176
>  
>  #ifdef KVM_CAP_IRQ_ROUTING

Is this cap upstream already? I would have thought your header sync
would have brought it in, then. (Saying this, that header sync looks
awfully small.)

If it is not upstream yet, please split off this hunk into a separate
patch -- it's a bit annoying, but makes life easier for merging.



^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [RFC v2 02/14] standard-headers: import arm_sdei.h
  2019-11-06 17:52   ` Cornelia Huck
@ 2019-11-07  1:40     ` Guoheyi
  2019-11-07  8:50       ` Cornelia Huck
  2019-11-07  8:55       ` Michael S. Tsirkin
  0 siblings, 2 replies; 43+ messages in thread
From: Guoheyi @ 2019-11-07  1:40 UTC (permalink / raw)
  To: Cornelia Huck
  Cc: Mark Rutland, Peter Maydell, Michael S. Tsirkin, Marc Zyngier,
	qemu-devel, qemu-arm, James Morse, Paolo Bonzini,
	wanghaibin.wang, Dave Martin



On 2019/11/7 1:52, Cornelia Huck wrote:
> On Tue, 5 Nov 2019 17:10:44 +0800
> Heyi Guo <guoheyi@huawei.com> wrote:
>
>> Import Linux header file include/uapi/linux/arm_sdei.h from kernel v5.4-rc5.
>>
>> This is to prepare for qemu SDEI emulation.
>>
>> Signed-off-by: Heyi Guo <guoheyi@huawei.com>
>> Cc: Peter Maydell <peter.maydell@linaro.org>
>> Cc: Dave Martin <Dave.Martin@arm.com>
>> Cc: Marc Zyngier <marc.zyngier@arm.com>
>> Cc: Mark Rutland <mark.rutland@arm.com>
>> Cc: James Morse <james.morse@arm.com>
>> Cc: "Michael S. Tsirkin" <mst@redhat.com>
>> Cc: Cornelia Huck <cohuck@redhat.com>
>> Cc: Paolo Bonzini <pbonzini@redhat.com>
>> ---
>>
>> Notes:
>>      v2:
>>      - Import arm_sdei.h by running update-linux-headers.sh
>>
>>   include/standard-headers/linux/arm_sdei.h | 73 +++++++++++++++++++++++
>>   1 file changed, 73 insertions(+)
>>   create mode 100644 include/standard-headers/linux/arm_sdei.h
> Just a remark that I find it a bit odd that that a header that looks
> arm-specific is in the generic linux/ directory (already in the kernel,
> I know.) Is this for sharing between arm and arm64, maybe?
I don't think arm platforms will use this header. In section 4.1 of SDEI 
spec, it says " Both the client and dispatcher of SDEI must execute in 
AArch64 state."
So shall we move it to include/standard-headers/asm-arm64/?

Thanks,
HG

>
>
> .
>




^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [RFC v2 11/14] linux-headers/kvm.h: add capability to forward hypercall
  2019-11-06 17:55   ` Cornelia Huck
@ 2019-11-07  1:44     ` Guoheyi
  2019-11-07  8:57       ` Michael S. Tsirkin
  0 siblings, 1 reply; 43+ messages in thread
From: Guoheyi @ 2019-11-07  1:44 UTC (permalink / raw)
  To: Cornelia Huck
  Cc: Mark Rutland, Peter Maydell, Michael S. Tsirkin, Marc Zyngier,
	qemu-devel, qemu-arm, James Morse, Paolo Bonzini,
	wanghaibin.wang, Dave Martin



On 2019/11/7 1:55, Cornelia Huck wrote:
> On Tue, 5 Nov 2019 17:10:53 +0800
> Heyi Guo <guoheyi@huawei.com> wrote:
>
>> To keep backward compatibility, we add new KVM capability
>> "KVM_CAP_FORWARD_HYPERCALL" to probe whether KVM supports forwarding
>> hypercall to userspace.
>>
>> The capability should be enabled explicitly, for we don't want user
>> space application to deal with unexpected hypercall exits. After
>> enabling this cap, all HVC calls unhandled by kvm will be forwarded to
>> user space.
>>
>> Signed-off-by: Heyi Guo <guoheyi@huawei.com>
>> Cc: Peter Maydell <peter.maydell@linaro.org>
>> Cc: "Michael S. Tsirkin" <mst@redhat.com>
>> Cc: Cornelia Huck <cohuck@redhat.com>
>> Cc: Paolo Bonzini <pbonzini@redhat.com>
>> Cc: Dave Martin <Dave.Martin@arm.com>
>> Cc: Marc Zyngier <marc.zyngier@arm.com>
>> Cc: Mark Rutland <mark.rutland@arm.com>
>> Cc: James Morse <james.morse@arm.com>
>> ---
>>   linux-headers/linux/kvm.h |  1 +
>>   target/arm/sdei.c         | 16 ++++++++++++++++
>>   target/arm/sdei.h         |  2 ++
>>   3 files changed, 19 insertions(+)
>>
>> diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
>> index 3d9b18f7f8..36c9b3859f 100644
>> --- a/linux-headers/linux/kvm.h
>> +++ b/linux-headers/linux/kvm.h
>> @@ -1000,6 +1000,7 @@ struct kvm_ppc_resize_hpt {
>>   #define KVM_CAP_PMU_EVENT_FILTER 173
>>   #define KVM_CAP_ARM_IRQ_LINE_LAYOUT_2 174
>>   #define KVM_CAP_HYPERV_DIRECT_TLBFLUSH 175
>> +#define KVM_CAP_FORWARD_HYPERCALL 176
>>   
>>   #ifdef KVM_CAP_IRQ_ROUTING
> Is this cap upstream already? I would have thought your header sync
> would have brought it in, then. (Saying this, that header sync looks
> awfully small.)
>
> If it is not upstream yet, please split off this hunk into a separate
> patch -- it's a bit annoying, but makes life easier for merging.
No, it is not upstream yet. The whole framework and interfaces between 
KVM and qemu are still under discussion. I'll keep in mind of this when 
moving forward to next steps...

Thanks,
HG
>
>
> .
>




^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [RFC v2 02/14] standard-headers: import arm_sdei.h
  2019-11-07  1:40     ` Guoheyi
@ 2019-11-07  8:50       ` Cornelia Huck
  2019-11-07  8:55       ` Michael S. Tsirkin
  1 sibling, 0 replies; 43+ messages in thread
From: Cornelia Huck @ 2019-11-07  8:50 UTC (permalink / raw)
  To: Guoheyi
  Cc: Mark Rutland, Peter Maydell, Michael S. Tsirkin, Marc Zyngier,
	qemu-devel, qemu-arm, James Morse, Paolo Bonzini,
	wanghaibin.wang, Dave Martin

On Thu, 7 Nov 2019 09:40:49 +0800
Guoheyi <guoheyi@huawei.com> wrote:

> On 2019/11/7 1:52, Cornelia Huck wrote:
> > On Tue, 5 Nov 2019 17:10:44 +0800
> > Heyi Guo <guoheyi@huawei.com> wrote:
> >  
> >> Import Linux header file include/uapi/linux/arm_sdei.h from kernel v5.4-rc5.
> >>
> >> This is to prepare for qemu SDEI emulation.
> >>
> >> Signed-off-by: Heyi Guo <guoheyi@huawei.com>
> >> Cc: Peter Maydell <peter.maydell@linaro.org>
> >> Cc: Dave Martin <Dave.Martin@arm.com>
> >> Cc: Marc Zyngier <marc.zyngier@arm.com>
> >> Cc: Mark Rutland <mark.rutland@arm.com>
> >> Cc: James Morse <james.morse@arm.com>
> >> Cc: "Michael S. Tsirkin" <mst@redhat.com>
> >> Cc: Cornelia Huck <cohuck@redhat.com>
> >> Cc: Paolo Bonzini <pbonzini@redhat.com>
> >> ---
> >>
> >> Notes:
> >>      v2:
> >>      - Import arm_sdei.h by running update-linux-headers.sh
> >>
> >>   include/standard-headers/linux/arm_sdei.h | 73 +++++++++++++++++++++++
> >>   1 file changed, 73 insertions(+)
> >>   create mode 100644 include/standard-headers/linux/arm_sdei.h  
> > Just a remark that I find it a bit odd that that a header that looks
> > arm-specific is in the generic linux/ directory (already in the kernel,
> > I know.) Is this for sharing between arm and arm64, maybe?  
> I don't think arm platforms will use this header. In section 4.1 of SDEI 
> spec, it says " Both the client and dispatcher of SDEI must execute in 
> AArch64 state."
> So shall we move it to include/standard-headers/asm-arm64/?

Well, the kernel already put it into the generic directory... I'd just
leave it like that, then; moving it in the kernel is probably too much
churn.



^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [RFC v2 02/14] standard-headers: import arm_sdei.h
  2019-11-07  1:40     ` Guoheyi
  2019-11-07  8:50       ` Cornelia Huck
@ 2019-11-07  8:55       ` Michael S. Tsirkin
  1 sibling, 0 replies; 43+ messages in thread
From: Michael S. Tsirkin @ 2019-11-07  8:55 UTC (permalink / raw)
  To: Guoheyi
  Cc: Mark Rutland, Peter Maydell, Marc Zyngier, Cornelia Huck,
	qemu-devel, qemu-arm, James Morse, Paolo Bonzini,
	wanghaibin.wang, Dave Martin

On Thu, Nov 07, 2019 at 09:40:49AM +0800, Guoheyi wrote:
> 
> 
> On 2019/11/7 1:52, Cornelia Huck wrote:
> > On Tue, 5 Nov 2019 17:10:44 +0800
> > Heyi Guo <guoheyi@huawei.com> wrote:
> > 
> > > Import Linux header file include/uapi/linux/arm_sdei.h from kernel v5.4-rc5.
> > > 
> > > This is to prepare for qemu SDEI emulation.
> > > 
> > > Signed-off-by: Heyi Guo <guoheyi@huawei.com>
> > > Cc: Peter Maydell <peter.maydell@linaro.org>
> > > Cc: Dave Martin <Dave.Martin@arm.com>
> > > Cc: Marc Zyngier <marc.zyngier@arm.com>
> > > Cc: Mark Rutland <mark.rutland@arm.com>
> > > Cc: James Morse <james.morse@arm.com>
> > > Cc: "Michael S. Tsirkin" <mst@redhat.com>
> > > Cc: Cornelia Huck <cohuck@redhat.com>
> > > Cc: Paolo Bonzini <pbonzini@redhat.com>
> > > ---
> > > 
> > > Notes:
> > >      v2:
> > >      - Import arm_sdei.h by running update-linux-headers.sh
> > > 
> > >   include/standard-headers/linux/arm_sdei.h | 73 +++++++++++++++++++++++
> > >   1 file changed, 73 insertions(+)
> > >   create mode 100644 include/standard-headers/linux/arm_sdei.h
> > Just a remark that I find it a bit odd that that a header that looks
> > arm-specific is in the generic linux/ directory (already in the kernel,
> > I know.) Is this for sharing between arm and arm64, maybe?
> I don't think arm platforms will use this header. In section 4.1 of SDEI
> spec, it says " Both the client and dispatcher of SDEI must execute in
> AArch64 state."
> So shall we move it to include/standard-headers/asm-arm64/?
> 
> Thanks,
> HG


Yea, that's because it's used by drivers/firmware/arm_sdei.c, also flat
in the top level hierarchy. It's been like this historically.
If you want to do a small kernel project and reorganize
drivers/firmware/ according to the architecture,
then arm_sdei.h can move too.

Until that happens upstream let's just mirror what kernel does.

> > 
> > 
> > .
> > 
> 


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [RFC v2 11/14] linux-headers/kvm.h: add capability to forward hypercall
  2019-11-07  1:44     ` Guoheyi
@ 2019-11-07  8:57       ` Michael S. Tsirkin
  2019-11-07 11:57         ` Guoheyi
  0 siblings, 1 reply; 43+ messages in thread
From: Michael S. Tsirkin @ 2019-11-07  8:57 UTC (permalink / raw)
  To: Guoheyi
  Cc: Mark Rutland, Peter Maydell, Marc Zyngier, Cornelia Huck,
	qemu-devel, qemu-arm, James Morse, Paolo Bonzini,
	wanghaibin.wang, Dave Martin

On Thu, Nov 07, 2019 at 09:44:36AM +0800, Guoheyi wrote:
> 
> 
> On 2019/11/7 1:55, Cornelia Huck wrote:
> > On Tue, 5 Nov 2019 17:10:53 +0800
> > Heyi Guo <guoheyi@huawei.com> wrote:
> > 
> > > To keep backward compatibility, we add new KVM capability
> > > "KVM_CAP_FORWARD_HYPERCALL" to probe whether KVM supports forwarding
> > > hypercall to userspace.
> > > 
> > > The capability should be enabled explicitly, for we don't want user
> > > space application to deal with unexpected hypercall exits. After
> > > enabling this cap, all HVC calls unhandled by kvm will be forwarded to
> > > user space.
> > > 
> > > Signed-off-by: Heyi Guo <guoheyi@huawei.com>
> > > Cc: Peter Maydell <peter.maydell@linaro.org>
> > > Cc: "Michael S. Tsirkin" <mst@redhat.com>
> > > Cc: Cornelia Huck <cohuck@redhat.com>
> > > Cc: Paolo Bonzini <pbonzini@redhat.com>
> > > Cc: Dave Martin <Dave.Martin@arm.com>
> > > Cc: Marc Zyngier <marc.zyngier@arm.com>
> > > Cc: Mark Rutland <mark.rutland@arm.com>
> > > Cc: James Morse <james.morse@arm.com>
> > > ---
> > >   linux-headers/linux/kvm.h |  1 +
> > >   target/arm/sdei.c         | 16 ++++++++++++++++
> > >   target/arm/sdei.h         |  2 ++
> > >   3 files changed, 19 insertions(+)
> > > 
> > > diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
> > > index 3d9b18f7f8..36c9b3859f 100644
> > > --- a/linux-headers/linux/kvm.h
> > > +++ b/linux-headers/linux/kvm.h
> > > @@ -1000,6 +1000,7 @@ struct kvm_ppc_resize_hpt {
> > >   #define KVM_CAP_PMU_EVENT_FILTER 173
> > >   #define KVM_CAP_ARM_IRQ_LINE_LAYOUT_2 174
> > >   #define KVM_CAP_HYPERV_DIRECT_TLBFLUSH 175
> > > +#define KVM_CAP_FORWARD_HYPERCALL 176
> > >   #ifdef KVM_CAP_IRQ_ROUTING
> > Is this cap upstream already? I would have thought your header sync
> > would have brought it in, then. (Saying this, that header sync looks
> > awfully small.)
> > 
> > If it is not upstream yet, please split off this hunk into a separate
> > patch -- it's a bit annoying, but makes life easier for merging.
> No, it is not upstream yet. The whole framework and interfaces between KVM
> and qemu are still under discussion. I'll keep in mind of this when moving
> forward to next steps...
> 
> Thanks,
> HG

It's best to add it in some other place meanwhile.
Then we can drop it when it's in an upstream header.


> > 
> > 
> > .
> > 
> 


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [RFC v2 11/14] linux-headers/kvm.h: add capability to forward hypercall
  2019-11-07  8:57       ` Michael S. Tsirkin
@ 2019-11-07 11:57         ` Guoheyi
  2019-11-07 12:12           ` Cornelia Huck
  0 siblings, 1 reply; 43+ messages in thread
From: Guoheyi @ 2019-11-07 11:57 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Mark Rutland, Peter Maydell, Marc Zyngier, Cornelia Huck,
	qemu-devel, qemu-arm, James Morse, Paolo Bonzini,
	wanghaibin.wang, Dave Martin



On 2019/11/7 16:57, Michael S. Tsirkin wrote:
> On Thu, Nov 07, 2019 at 09:44:36AM +0800, Guoheyi wrote:
>>
>> On 2019/11/7 1:55, Cornelia Huck wrote:
>>> On Tue, 5 Nov 2019 17:10:53 +0800
>>> Heyi Guo <guoheyi@huawei.com> wrote:
>>>
>>>> To keep backward compatibility, we add new KVM capability
>>>> "KVM_CAP_FORWARD_HYPERCALL" to probe whether KVM supports forwarding
>>>> hypercall to userspace.
>>>>
>>>> The capability should be enabled explicitly, for we don't want user
>>>> space application to deal with unexpected hypercall exits. After
>>>> enabling this cap, all HVC calls unhandled by kvm will be forwarded to
>>>> user space.
>>>>
>>>> Signed-off-by: Heyi Guo <guoheyi@huawei.com>
>>>> Cc: Peter Maydell <peter.maydell@linaro.org>
>>>> Cc: "Michael S. Tsirkin" <mst@redhat.com>
>>>> Cc: Cornelia Huck <cohuck@redhat.com>
>>>> Cc: Paolo Bonzini <pbonzini@redhat.com>
>>>> Cc: Dave Martin <Dave.Martin@arm.com>
>>>> Cc: Marc Zyngier <marc.zyngier@arm.com>
>>>> Cc: Mark Rutland <mark.rutland@arm.com>
>>>> Cc: James Morse <james.morse@arm.com>
>>>> ---
>>>>    linux-headers/linux/kvm.h |  1 +
>>>>    target/arm/sdei.c         | 16 ++++++++++++++++
>>>>    target/arm/sdei.h         |  2 ++
>>>>    3 files changed, 19 insertions(+)
>>>>
>>>> diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
>>>> index 3d9b18f7f8..36c9b3859f 100644
>>>> --- a/linux-headers/linux/kvm.h
>>>> +++ b/linux-headers/linux/kvm.h
>>>> @@ -1000,6 +1000,7 @@ struct kvm_ppc_resize_hpt {
>>>>    #define KVM_CAP_PMU_EVENT_FILTER 173
>>>>    #define KVM_CAP_ARM_IRQ_LINE_LAYOUT_2 174
>>>>    #define KVM_CAP_HYPERV_DIRECT_TLBFLUSH 175
>>>> +#define KVM_CAP_FORWARD_HYPERCALL 176
>>>>    #ifdef KVM_CAP_IRQ_ROUTING
>>> Is this cap upstream already? I would have thought your header sync
>>> would have brought it in, then. (Saying this, that header sync looks
>>> awfully small.)
>>>
>>> If it is not upstream yet, please split off this hunk into a separate
>>> patch -- it's a bit annoying, but makes life easier for merging.
>> No, it is not upstream yet. The whole framework and interfaces between KVM
>> and qemu are still under discussion. I'll keep in mind of this when moving
>> forward to next steps...
>>
>> Thanks,
>> HG
> It's best to add it in some other place meanwhile.
Do you mean to split this patch from the whole patch set and send it 
separately? Sorry I'm not clear about maintainers' work and may bring 
you some trouble...

Thanks,
HG

> Then we can drop it when it's in an upstream header.
>
>
>>>
>>> .
>>>
> .
>




^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [RFC v2 11/14] linux-headers/kvm.h: add capability to forward hypercall
  2019-11-07 11:57         ` Guoheyi
@ 2019-11-07 12:12           ` Cornelia Huck
  2019-11-08  1:54             ` Guoheyi
  0 siblings, 1 reply; 43+ messages in thread
From: Cornelia Huck @ 2019-11-07 12:12 UTC (permalink / raw)
  To: Guoheyi
  Cc: Mark Rutland, Peter Maydell, Michael S. Tsirkin, Marc Zyngier,
	qemu-devel, qemu-arm, James Morse, Paolo Bonzini,
	wanghaibin.wang, Dave Martin

On Thu, 7 Nov 2019 19:57:22 +0800
Guoheyi <guoheyi@huawei.com> wrote:

> On 2019/11/7 16:57, Michael S. Tsirkin wrote:
> > On Thu, Nov 07, 2019 at 09:44:36AM +0800, Guoheyi wrote:  
> >>
> >> On 2019/11/7 1:55, Cornelia Huck wrote:  
> >>> On Tue, 5 Nov 2019 17:10:53 +0800
> >>> Heyi Guo <guoheyi@huawei.com> wrote:
> >>>  
> >>>> To keep backward compatibility, we add new KVM capability
> >>>> "KVM_CAP_FORWARD_HYPERCALL" to probe whether KVM supports forwarding
> >>>> hypercall to userspace.
> >>>>
> >>>> The capability should be enabled explicitly, for we don't want user
> >>>> space application to deal with unexpected hypercall exits. After
> >>>> enabling this cap, all HVC calls unhandled by kvm will be forwarded to
> >>>> user space.
> >>>>
> >>>> Signed-off-by: Heyi Guo <guoheyi@huawei.com>
> >>>> Cc: Peter Maydell <peter.maydell@linaro.org>
> >>>> Cc: "Michael S. Tsirkin" <mst@redhat.com>
> >>>> Cc: Cornelia Huck <cohuck@redhat.com>
> >>>> Cc: Paolo Bonzini <pbonzini@redhat.com>
> >>>> Cc: Dave Martin <Dave.Martin@arm.com>
> >>>> Cc: Marc Zyngier <marc.zyngier@arm.com>
> >>>> Cc: Mark Rutland <mark.rutland@arm.com>
> >>>> Cc: James Morse <james.morse@arm.com>
> >>>> ---
> >>>>    linux-headers/linux/kvm.h |  1 +
> >>>>    target/arm/sdei.c         | 16 ++++++++++++++++
> >>>>    target/arm/sdei.h         |  2 ++
> >>>>    3 files changed, 19 insertions(+)
> >>>>
> >>>> diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
> >>>> index 3d9b18f7f8..36c9b3859f 100644
> >>>> --- a/linux-headers/linux/kvm.h
> >>>> +++ b/linux-headers/linux/kvm.h
> >>>> @@ -1000,6 +1000,7 @@ struct kvm_ppc_resize_hpt {
> >>>>    #define KVM_CAP_PMU_EVENT_FILTER 173
> >>>>    #define KVM_CAP_ARM_IRQ_LINE_LAYOUT_2 174
> >>>>    #define KVM_CAP_HYPERV_DIRECT_TLBFLUSH 175
> >>>> +#define KVM_CAP_FORWARD_HYPERCALL 176
> >>>>    #ifdef KVM_CAP_IRQ_ROUTING  
> >>> Is this cap upstream already? I would have thought your header sync
> >>> would have brought it in, then. (Saying this, that header sync looks
> >>> awfully small.)
> >>>
> >>> If it is not upstream yet, please split off this hunk into a separate
> >>> patch -- it's a bit annoying, but makes life easier for merging.  
> >> No, it is not upstream yet. The whole framework and interfaces between KVM
> >> and qemu are still under discussion. I'll keep in mind of this when moving
> >> forward to next steps...
> >>
> >> Thanks,
> >> HG  
> > It's best to add it in some other place meanwhile.  
> Do you mean to split this patch from the whole patch set and send it 
> separately? Sorry I'm not clear about maintainers' work and may bring 
> you some trouble...

My preferred approach:

- add a commit entitled "placeholder for headers update" that contains
  the not-yet-upstream changes in the header files you need
- base the rest of your work on that
...
<review happens, series looks good>
...
- if kernel changes are upstream: replace the placeholder patch with a
  real update (may include separate patches, if you need an additional
  header); maintainer merges
- if kernel changes are not yet upstream: maintainer merges with
  placeholder to a feature branch, replaces with real update and merges
  once kernel patches hit upstream
(not every maintainer does the second approach; they may ask you
instead to resend with a proper headers update once the kernel changes
are upstream)



^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [RFC v2 11/14] linux-headers/kvm.h: add capability to forward hypercall
  2019-11-07 12:12           ` Cornelia Huck
@ 2019-11-08  1:54             ` Guoheyi
  0 siblings, 0 replies; 43+ messages in thread
From: Guoheyi @ 2019-11-08  1:54 UTC (permalink / raw)
  To: Cornelia Huck
  Cc: Mark Rutland, Peter Maydell, Michael S. Tsirkin, Marc Zyngier,
	qemu-devel, qemu-arm, James Morse, Paolo Bonzini,
	wanghaibin.wang, Dave Martin



On 2019/11/7 20:12, Cornelia Huck wrote:
> On Thu, 7 Nov 2019 19:57:22 +0800
> Guoheyi <guoheyi@huawei.com> wrote:
>
>> On 2019/11/7 16:57, Michael S. Tsirkin wrote:
>>> On Thu, Nov 07, 2019 at 09:44:36AM +0800, Guoheyi wrote:
>>>> On 2019/11/7 1:55, Cornelia Huck wrote:
>>>>> On Tue, 5 Nov 2019 17:10:53 +0800
>>>>> Heyi Guo <guoheyi@huawei.com> wrote:
>>>>>   
>>>>>> To keep backward compatibility, we add new KVM capability
>>>>>> "KVM_CAP_FORWARD_HYPERCALL" to probe whether KVM supports forwarding
>>>>>> hypercall to userspace.
>>>>>>
>>>>>> The capability should be enabled explicitly, for we don't want user
>>>>>> space application to deal with unexpected hypercall exits. After
>>>>>> enabling this cap, all HVC calls unhandled by kvm will be forwarded to
>>>>>> user space.
>>>>>>
>>>>>> Signed-off-by: Heyi Guo <guoheyi@huawei.com>
>>>>>> Cc: Peter Maydell <peter.maydell@linaro.org>
>>>>>> Cc: "Michael S. Tsirkin" <mst@redhat.com>
>>>>>> Cc: Cornelia Huck <cohuck@redhat.com>
>>>>>> Cc: Paolo Bonzini <pbonzini@redhat.com>
>>>>>> Cc: Dave Martin <Dave.Martin@arm.com>
>>>>>> Cc: Marc Zyngier <marc.zyngier@arm.com>
>>>>>> Cc: Mark Rutland <mark.rutland@arm.com>
>>>>>> Cc: James Morse <james.morse@arm.com>
>>>>>> ---
>>>>>>     linux-headers/linux/kvm.h |  1 +
>>>>>>     target/arm/sdei.c         | 16 ++++++++++++++++
>>>>>>     target/arm/sdei.h         |  2 ++
>>>>>>     3 files changed, 19 insertions(+)
>>>>>>
>>>>>> diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
>>>>>> index 3d9b18f7f8..36c9b3859f 100644
>>>>>> --- a/linux-headers/linux/kvm.h
>>>>>> +++ b/linux-headers/linux/kvm.h
>>>>>> @@ -1000,6 +1000,7 @@ struct kvm_ppc_resize_hpt {
>>>>>>     #define KVM_CAP_PMU_EVENT_FILTER 173
>>>>>>     #define KVM_CAP_ARM_IRQ_LINE_LAYOUT_2 174
>>>>>>     #define KVM_CAP_HYPERV_DIRECT_TLBFLUSH 175
>>>>>> +#define KVM_CAP_FORWARD_HYPERCALL 176
>>>>>>     #ifdef KVM_CAP_IRQ_ROUTING
>>>>> Is this cap upstream already? I would have thought your header sync
>>>>> would have brought it in, then. (Saying this, that header sync looks
>>>>> awfully small.)
>>>>>
>>>>> If it is not upstream yet, please split off this hunk into a separate
>>>>> patch -- it's a bit annoying, but makes life easier for merging.
>>>> No, it is not upstream yet. The whole framework and interfaces between KVM
>>>> and qemu are still under discussion. I'll keep in mind of this when moving
>>>> forward to next steps...
>>>>
>>>> Thanks,
>>>> HG
>>> It's best to add it in some other place meanwhile.
>> Do you mean to split this patch from the whole patch set and send it
>> separately? Sorry I'm not clear about maintainers' work and may bring
>> you some trouble...
> My preferred approach:
>
> - add a commit entitled "placeholder for headers update" that contains
>    the not-yet-upstream changes in the header files you need
> - base the rest of your work on that
> ...
> <review happens, series looks good>
> ...
> - if kernel changes are upstream: replace the placeholder patch with a
>    real update (may include separate patches, if you need an additional
>    header); maintainer merges
> - if kernel changes are not yet upstream: maintainer merges with
>    placeholder to a feature branch, replaces with real update and merges
>    once kernel patches hit upstream
> (not every maintainer does the second approach; they may ask you
> instead to resend with a proper headers update once the kernel changes
> are upstream)

Thanks a lot. I'll do that in the next version.
HG

>
> .
>




^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [RFC v2 14/14] virt/acpi: add SDEI table if SDEI is enabled
  2019-11-05  9:10 ` [RFC v2 14/14] virt/acpi: add SDEI table if SDEI is enabled Heyi Guo
@ 2019-11-12 14:52   ` Igor Mammedov
  2019-11-18  6:44     ` Guoheyi
  0 siblings, 1 reply; 43+ messages in thread
From: Igor Mammedov @ 2019-11-12 14:52 UTC (permalink / raw)
  To: Heyi Guo
  Cc: Mark Rutland, Peter Maydell, Michael S. Tsirkin, Marc Zyngier,
	qemu-devel, Shannon Zhao, qemu-arm, James Morse, wanghaibin.wang,
	Dave Martin

On Tue, 5 Nov 2019 17:10:56 +0800
Heyi Guo <guoheyi@huawei.com> wrote:

> Add SDEI table if SDEI is enabled, so that guest OS can get aware and
> utilize the interfaces.
> 
> Signed-off-by: Heyi Guo <guoheyi@huawei.com>
> Cc: Peter Maydell <peter.maydell@linaro.org>
> Cc: Dave Martin <Dave.Martin@arm.com>
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: James Morse <james.morse@arm.com>
> Cc: Shannon Zhao <shannon.zhaosl@gmail.com>
> Cc: "Michael S. Tsirkin" <mst@redhat.com>
> Cc: Igor Mammedov <imammedo@redhat.com>
> ---
> 
> Notes:
>     v2:
>     - Drop SDEI table definition and add comments
> 
>  hw/arm/virt-acpi-build.c | 26 ++++++++++++++++++++++++++
>  1 file changed, 26 insertions(+)
> 
> diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
> index 4cd50175e0..73d3f8cd15 100644
> --- a/hw/arm/virt-acpi-build.c
> +++ b/hw/arm/virt-acpi-build.c
> @@ -32,6 +32,7 @@
>  #include "trace.h"
>  #include "hw/core/cpu.h"
>  #include "target/arm/cpu.h"
> +#include "target/arm/sdei.h"
>  #include "hw/acpi/acpi-defs.h"
>  #include "hw/acpi/acpi.h"
>  #include "hw/nvram/fw_cfg.h"
> @@ -475,6 +476,26 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
>                   "IORT", table_data->len - iort_start, 0, NULL, NULL);
>  }
>  
> +/*
> + * ACPI spec 6.2 Software Delegated Exception Interface (SDEI).
> + * (Revision 1.0)
> + * "SDEI" was reserved in ACPI 6.2. See "Links to ACPI-Related Documents"
> + * (http://uefi.org/acpi) under the heading "Software
> + * Delegated Exceptions Interface." The definition is under
> + * "10 Appendix C: ACPI table definitions for SDEI" in the linked document.
> + *
> + * This is a dummy table to expose platform SDEI capbility to OS.
> + */
> +static void
> +build_sdei(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
> +{
> +    int sdei_start = table_data->len;
> +
> +    (void)acpi_data_push(table_data, sizeof(AcpiTableHeader));
> +    build_header(linker, table_data, (void *)(table_data->data + sdei_start),
> +                 "SDEI", table_data->len - sdei_start, 1, NULL, NULL);
> +}
> +
>  static void
>  build_spcr(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
>  {
> @@ -825,6 +846,11 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables)
>      acpi_add_table(table_offsets, tables_blob);
>      build_spcr(tables_blob, tables->linker, vms);
>  
> +    if (sdei_enabled) {
globals shouldn't be introduced in new code

> +        acpi_add_table(table_offsets, tables_blob);
> +        build_sdei(tables_blob, tables->linker, vms);
> +    }
> +
>      if (ms->numa_state->num_nodes > 0) {
>          acpi_add_table(table_offsets, tables_blob);
>          build_srat(tables_blob, tables->linker, vms);



^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [RFC v2 14/14] virt/acpi: add SDEI table if SDEI is enabled
  2019-11-12 14:52   ` Igor Mammedov
@ 2019-11-18  6:44     ` Guoheyi
  0 siblings, 0 replies; 43+ messages in thread
From: Guoheyi @ 2019-11-18  6:44 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: Mark Rutland, Peter Maydell, Michael S. Tsirkin, Marc Zyngier,
	qemu-devel, Shannon Zhao, qemu-arm, James Morse, wanghaibin.wang,
	Dave Martin



On 2019/11/12 22:52, Igor Mammedov wrote:
> On Tue, 5 Nov 2019 17:10:56 +0800
> Heyi Guo <guoheyi@huawei.com> wrote:
>
>> Add SDEI table if SDEI is enabled, so that guest OS can get aware and
>> utilize the interfaces.
>>
>> Signed-off-by: Heyi Guo <guoheyi@huawei.com>
>> Cc: Peter Maydell <peter.maydell@linaro.org>
>> Cc: Dave Martin <Dave.Martin@arm.com>
>> Cc: Marc Zyngier <marc.zyngier@arm.com>
>> Cc: Mark Rutland <mark.rutland@arm.com>
>> Cc: James Morse <james.morse@arm.com>
>> Cc: Shannon Zhao <shannon.zhaosl@gmail.com>
>> Cc: "Michael S. Tsirkin" <mst@redhat.com>
>> Cc: Igor Mammedov <imammedo@redhat.com>
>> ---
>>
>> Notes:
>>      v2:
>>      - Drop SDEI table definition and add comments
>>
>>   hw/arm/virt-acpi-build.c | 26 ++++++++++++++++++++++++++
>>   1 file changed, 26 insertions(+)
>>
>> diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
>> index 4cd50175e0..73d3f8cd15 100644
>> --- a/hw/arm/virt-acpi-build.c
>> +++ b/hw/arm/virt-acpi-build.c
>> @@ -32,6 +32,7 @@
>>   #include "trace.h"
>>   #include "hw/core/cpu.h"
>>   #include "target/arm/cpu.h"
>> +#include "target/arm/sdei.h"
>>   #include "hw/acpi/acpi-defs.h"
>>   #include "hw/acpi/acpi.h"
>>   #include "hw/nvram/fw_cfg.h"
>> @@ -475,6 +476,26 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
>>                    "IORT", table_data->len - iort_start, 0, NULL, NULL);
>>   }
>>   
>> +/*
>> + * ACPI spec 6.2 Software Delegated Exception Interface (SDEI).
>> + * (Revision 1.0)
>> + * "SDEI" was reserved in ACPI 6.2. See "Links to ACPI-Related Documents"
>> + * (http://uefi.org/acpi) under the heading "Software
>> + * Delegated Exceptions Interface." The definition is under
>> + * "10 Appendix C: ACPI table definitions for SDEI" in the linked document.
>> + *
>> + * This is a dummy table to expose platform SDEI capbility to OS.
>> + */
>> +static void
>> +build_sdei(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
>> +{
>> +    int sdei_start = table_data->len;
>> +
>> +    (void)acpi_data_push(table_data, sizeof(AcpiTableHeader));
>> +    build_header(linker, table_data, (void *)(table_data->data + sdei_start),
>> +                 "SDEI", table_data->len - sdei_start, 1, NULL, NULL);
>> +}
>> +
>>   static void
>>   build_spcr(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
>>   {
>> @@ -825,6 +846,11 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables)
>>       acpi_add_table(table_offsets, tables_blob);
>>       build_spcr(tables_blob, tables->linker, vms);
>>   
>> +    if (sdei_enabled) {
> globals shouldn't be introduced in new code
OK. For this feature depends on KVM, does it make sense to add a flag to 
struct VirtMachineState?

Thanks,
HG
>
>> +        acpi_add_table(table_offsets, tables_blob);
>> +        build_sdei(tables_blob, tables->linker, vms);
>> +    }
>> +
>>       if (ms->numa_state->num_nodes > 0) {
>>           acpi_add_table(table_offsets, tables_blob);
>>           build_srat(tables_blob, tables->linker, vms);
>
> .
>




^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [RFC v2 00/14] Add SDEI support for arm64
  2019-11-05  9:10 [RFC v2 00/14] Add SDEI support for arm64 Heyi Guo
                   ` (16 preceding siblings ...)
  2019-11-05  9:38 ` no-reply
@ 2019-11-18  6:55 ` Guoheyi
  2019-11-18 13:35   ` Peter Maydell
  2019-12-20 13:44 ` Peter Maydell
  18 siblings, 1 reply; 43+ messages in thread
From: Guoheyi @ 2019-11-18  6:55 UTC (permalink / raw)
  To: qemu-arm, qemu-devel, Peter Maydell
  Cc: Mark Rutland, Michael S. Tsirkin, Marc Zyngier, Cornelia Huck,
	Shannon Zhao, Igor Mammedov, James Morse, Paolo Bonzini,
	wanghaibin.wang, Dave Martin

Hi Peter,

Could you spare some time to review the framework and provide comments 
and advice?

Thanks,

HG


On 2019/11/5 17:10, Heyi Guo wrote:
> 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 <peter.maydell@linaro.org>
> Cc: Dave Martin <Dave.Martin@arm.com>
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: James Morse <james.morse@arm.com>
> Cc: "Michael S. Tsirkin" <mst@redhat.com>
> Cc: Cornelia Huck <cohuck@redhat.com>
> Cc: Paolo Bonzini <pbonzini@redhat.com>
> Cc: Shannon Zhao <shannon.zhaosl@gmail.com>
> Cc: Igor Mammedov <imammedo@redhat.com>
>
> 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
>




^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [RFC v2 00/14] Add SDEI support for arm64
  2019-11-18  6:55 ` Guoheyi
@ 2019-11-18 13:35   ` Peter Maydell
  2019-11-18 14:04     ` Guoheyi
  0 siblings, 1 reply; 43+ messages in thread
From: Peter Maydell @ 2019-11-18 13:35 UTC (permalink / raw)
  To: Guoheyi
  Cc: Mark Rutland, Michael S. Tsirkin, Marc Zyngier, Cornelia Huck,
	QEMU Developers, Shannon Zhao, Igor Mammedov, qemu-arm,
	James Morse, Paolo Bonzini, wanghaibin.wang, Dave Martin

On Mon, 18 Nov 2019 at 06:55, Guoheyi <guoheyi@huawei.com> wrote:
>
> Hi Peter,
>
> Could you spare some time to review the framework and provide comments
> and advice?

This patchset is on my to-review list but there are also
a lot of others on that list...

thanks
-- PMM


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [RFC v2 00/14] Add SDEI support for arm64
  2019-11-18 13:35   ` Peter Maydell
@ 2019-11-18 14:04     ` Guoheyi
  0 siblings, 0 replies; 43+ messages in thread
From: Guoheyi @ 2019-11-18 14:04 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Mark Rutland, Michael S. Tsirkin, Marc Zyngier, Cornelia Huck,
	QEMU Developers, Shannon Zhao, Igor Mammedov, qemu-arm,
	James Morse, Paolo Bonzini, wanghaibin.wang, Dave Martin

Thanks a lot. Please take your time.

HG


On 2019/11/18 21:35, Peter Maydell wrote:
> On Mon, 18 Nov 2019 at 06:55, Guoheyi <guoheyi@huawei.com> wrote:
>> Hi Peter,
>>
>> Could you spare some time to review the framework and provide comments
>> and advice?
> This patchset is on my to-review list but there are also
> a lot of others on that list...
>
> thanks
> -- PMM
>
> .
>




^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [RFC v2 00/14] Add SDEI support for arm64
  2019-11-05  9:10 [RFC v2 00/14] Add SDEI support for arm64 Heyi Guo
                   ` (17 preceding siblings ...)
  2019-11-18  6:55 ` Guoheyi
@ 2019-12-20 13:44 ` Peter Maydell
  2019-12-23  8:20   ` Guoheyi
  18 siblings, 1 reply; 43+ messages in thread
From: Peter Maydell @ 2019-12-20 13:44 UTC (permalink / raw)
  To: Heyi Guo
  Cc: Mark Rutland, Michael S. Tsirkin, Marc Zyngier, Cornelia Huck,
	QEMU Developers, Shannon Zhao, Igor Mammedov, qemu-arm,
	James Morse, Paolo Bonzini, wanghaibin.wang, Dave Martin

On Tue, 5 Nov 2019 at 09:12, Heyi Guo <guoheyi@huawei.com> wrote:
> 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.

Hi; I read through these patches last week, but I didn't reply
then because although there are some aspects to the design that
I don't like, I don't have a clear idea of what a better approach
to the problems it's trying to solve would be. However I didn't
want to go home for the end of the year without providing at
least some response. So I'm going to lay out the parts I have
issues with and perhaps somebody else will have a good idea.

The first part that I dislike here is that this is implementing
an entire ABI which in real hardware is provided by firmware. I
think that QEMU's design works best when QEMU provides emulation of
hardware or hardware-like facilities, which guest code (either
in the kernel, or firmware/bios running in the guest) can then
make use of. Once we start getting into implementing firmware
interfaces directly in QEMU this rapidly becomes a large amount
of work and code, and it's unclear where it should stop. Should
we implement also the equivalent of firmware for omap boards?
For imx* boards? For the raspberry pi? For xilinx boards?
Are we going to end up reimplementing more of ARM Trusted Firmware
functionality inside QEMU? The code to implement firmware-equivalent
ABIs in all these boards would I think quickly become a large part
of the codebase.

My second concern is that to do the things it wants to do,
the implementation here does some pretty invasive things:
 * intercepting interrupt lines which ought to just be
   emulated hardware signals between devices and the GIC
 * capturing register values of other CPUs, and arbitrarily
   stopping those other CPUs and making them run other code
   at a later point in time
I'm really uncomfortable with what's just an 'emulated firmware'
interface for one specific board model doing this kind of thing.

Finally, the stated rationale for the patchset ("we'd like an
emulated NMI equivalent") doesn't really feel to me like it's
strong enough to counterbalance the amount of code here and
the degree to which it's moving us into a swamp I'd prefer
it if we could stay out of.

I'd be much happier with a design where QEMU provides simple
facilities to the guest and the guest firmware and kernel
deal with making use of them. I appreciate that it's not
clear how that would work though, given that in real hardware
this works by the firmware running at EL3 and KVM not
providing a mechanism that allows guest code that runs at
a higher (effective or emulated) privilege level than the
guest kernel...

thanks
-- PMM


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [RFC v2 00/14] Add SDEI support for arm64
  2019-12-20 13:44 ` Peter Maydell
@ 2019-12-23  8:20   ` Guoheyi
  2020-02-04  8:26     ` Heyi Guo
  0 siblings, 1 reply; 43+ messages in thread
From: Guoheyi @ 2019-12-23  8:20 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Mark Rutland, Michael S. Tsirkin, Marc Zyngier, Cornelia Huck,
	QEMU Developers, Shannon Zhao, Igor Mammedov, qemu-arm,
	James Morse, Paolo Bonzini, wanghaibin.wang, Dave Martin

Hi Peter,

Really appreciate your comments.

For other platforms/boards emulated in qemu, like omap, imx*, etc, are 
they just TCG platforms? Can we just enable security and EL3 emulation 
for these platforms instead of implementing copies of firmware 
interfaces in qemu? Also I think it is possible to optimize the code to 
support all KVM enabled virtual boards with one single copy of SDEI 
code, so at least the duplication of code inside qemu might be avoided.

I can understand your concerns; the exsiting SDEI code in ARM Trusted 
Firmware also tempted me when I started to writing the code in qemu. I 
agree the ideal way is to use the existing firmware directly, but how 
can we achieve that? Either I don't think it is good to modify the 
firmware code too much, for firmware should be kept simple and reliable.

Does James or Marc have any idea?

Thanks,

Heyi

在 2019/12/20 21:44, Peter Maydell 写道:
> On Tue, 5 Nov 2019 at 09:12, Heyi Guo <guoheyi@huawei.com> wrote:
>> 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.
> Hi; I read through these patches last week, but I didn't reply
> then because although there are some aspects to the design that
> I don't like, I don't have a clear idea of what a better approach
> to the problems it's trying to solve would be. However I didn't
> want to go home for the end of the year without providing at
> least some response. So I'm going to lay out the parts I have
> issues with and perhaps somebody else will have a good idea.
>
> The first part that I dislike here is that this is implementing
> an entire ABI which in real hardware is provided by firmware. I
> think that QEMU's design works best when QEMU provides emulation of
> hardware or hardware-like facilities, which guest code (either
> in the kernel, or firmware/bios running in the guest) can then
> make use of. Once we start getting into implementing firmware
> interfaces directly in QEMU this rapidly becomes a large amount
> of work and code, and it's unclear where it should stop. Should
> we implement also the equivalent of firmware for omap boards?
> For imx* boards? For the raspberry pi? For xilinx boards?
> Are we going to end up reimplementing more of ARM Trusted Firmware
> functionality inside QEMU? The code to implement firmware-equivalent
> ABIs in all these boards would I think quickly become a large part
> of the codebase.
>
> My second concern is that to do the things it wants to do,
> the implementation here does some pretty invasive things:
>   * intercepting interrupt lines which ought to just be
>     emulated hardware signals between devices and the GIC
>   * capturing register values of other CPUs, and arbitrarily
>     stopping those other CPUs and making them run other code
>     at a later point in time
> I'm really uncomfortable with what's just an 'emulated firmware'
> interface for one specific board model doing this kind of thing.
>
> Finally, the stated rationale for the patchset ("we'd like an
> emulated NMI equivalent") doesn't really feel to me like it's
> strong enough to counterbalance the amount of code here and
> the degree to which it's moving us into a swamp I'd prefer
> it if we could stay out of.
>
> I'd be much happier with a design where QEMU provides simple
> facilities to the guest and the guest firmware and kernel
> deal with making use of them. I appreciate that it's not
> clear how that would work though, given that in real hardware
> this works by the firmware running at EL3 and KVM not
> providing a mechanism that allows guest code that runs at
> a higher (effective or emulated) privilege level than the
> guest kernel...
>
> thanks
> -- PMM
>
> .



^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [RFC v2 00/14] Add SDEI support for arm64
  2019-12-23  8:20   ` Guoheyi
@ 2020-02-04  8:26     ` Heyi Guo
  2020-02-05 13:15       ` Marc Zyngier
  0 siblings, 1 reply; 43+ messages in thread
From: Heyi Guo @ 2020-02-04  8:26 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Mark Rutland, Gavin Shan, Michael S. Tsirkin, Marc Zyngier,
	Cornelia Huck, QEMU Developers, Shannon Zhao, Igor Mammedov,
	qemu-arm, James Morse, Paolo Bonzini, wanghaibin.wang,
	Dave Martin

Update Marc's email address.

+cc Gavin as he is posting a RFC for ARM NMI.

Hi Marc,

Really sorry for missing to update your email address, for the initial 
topic was raised long time ago and I forgot to update the Cc list in the 
commit message of the patches.

Thanks Gavin for forwarding current discussion on ARM NMI to me.

For you said SDEI is "horrible", does it mean we'd better never 
implement SDEI in virtual world? Or do you have any advice on how to 
implement it?

Thanks,

Heyi

On 2019/12/23 16:20, Guoheyi wrote:
> Hi Peter,
>
> Really appreciate your comments.
>
> For other platforms/boards emulated in qemu, like omap, imx*, etc, are 
> they just TCG platforms? Can we just enable security and EL3 emulation 
> for these platforms instead of implementing copies of firmware 
> interfaces in qemu? Also I think it is possible to optimize the code 
> to support all KVM enabled virtual boards with one single copy of SDEI 
> code, so at least the duplication of code inside qemu might be avoided.
>
> I can understand your concerns; the exsiting SDEI code in ARM Trusted 
> Firmware also tempted me when I started to writing the code in qemu. I 
> agree the ideal way is to use the existing firmware directly, but how 
> can we achieve that? Either I don't think it is good to modify the 
> firmware code too much, for firmware should be kept simple and reliable.
>
> Does James or Marc have any idea?
>
> Thanks,
>
> Heyi
>
> 在 2019/12/20 21:44, Peter Maydell 写道:
>> On Tue, 5 Nov 2019 at 09:12, Heyi Guo <guoheyi@huawei.com> wrote:
>>> 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.
>> Hi; I read through these patches last week, but I didn't reply
>> then because although there are some aspects to the design that
>> I don't like, I don't have a clear idea of what a better approach
>> to the problems it's trying to solve would be. However I didn't
>> want to go home for the end of the year without providing at
>> least some response. So I'm going to lay out the parts I have
>> issues with and perhaps somebody else will have a good idea.
>>
>> The first part that I dislike here is that this is implementing
>> an entire ABI which in real hardware is provided by firmware. I
>> think that QEMU's design works best when QEMU provides emulation of
>> hardware or hardware-like facilities, which guest code (either
>> in the kernel, or firmware/bios running in the guest) can then
>> make use of. Once we start getting into implementing firmware
>> interfaces directly in QEMU this rapidly becomes a large amount
>> of work and code, and it's unclear where it should stop. Should
>> we implement also the equivalent of firmware for omap boards?
>> For imx* boards? For the raspberry pi? For xilinx boards?
>> Are we going to end up reimplementing more of ARM Trusted Firmware
>> functionality inside QEMU? The code to implement firmware-equivalent
>> ABIs in all these boards would I think quickly become a large part
>> of the codebase.
>>
>> My second concern is that to do the things it wants to do,
>> the implementation here does some pretty invasive things:
>>   * intercepting interrupt lines which ought to just be
>>     emulated hardware signals between devices and the GIC
>>   * capturing register values of other CPUs, and arbitrarily
>>     stopping those other CPUs and making them run other code
>>     at a later point in time
>> I'm really uncomfortable with what's just an 'emulated firmware'
>> interface for one specific board model doing this kind of thing.
>>
>> Finally, the stated rationale for the patchset ("we'd like an
>> emulated NMI equivalent") doesn't really feel to me like it's
>> strong enough to counterbalance the amount of code here and
>> the degree to which it's moving us into a swamp I'd prefer
>> it if we could stay out of.
>>
>> I'd be much happier with a design where QEMU provides simple
>> facilities to the guest and the guest firmware and kernel
>> deal with making use of them. I appreciate that it's not
>> clear how that would work though, given that in real hardware
>> this works by the firmware running at EL3 and KVM not
>> providing a mechanism that allows guest code that runs at
>> a higher (effective or emulated) privilege level than the
>> guest kernel...
>>
>> thanks
>> -- PMM
>>
>> .



^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [RFC v2 00/14] Add SDEI support for arm64
  2020-02-04  8:26     ` Heyi Guo
@ 2020-02-05 13:15       ` Marc Zyngier
  2020-02-06  1:20         ` Heyi Guo
  0 siblings, 1 reply; 43+ messages in thread
From: Marc Zyngier @ 2020-02-05 13:15 UTC (permalink / raw)
  To: Heyi Guo
  Cc: Mark Rutland, Peter Maydell, Gavin Shan, Michael S. Tsirkin,
	Cornelia Huck, QEMU Developers, Shannon Zhao, Igor Mammedov,
	qemu-arm, James Morse, Paolo Bonzini, wanghaibin.wang,
	Dave Martin

Hi Heyi,

On 2020-02-04 08:26, Heyi Guo wrote:
> Update Marc's email address.
> 
> +cc Gavin as he is posting a RFC for ARM NMI.
> 
> Hi Marc,
> 
> Really sorry for missing to update your email address, for the initial
> topic was raised long time ago and I forgot to update the Cc list in
> the commit message of the patches.
> 
> Thanks Gavin for forwarding current discussion on ARM NMI to me.
> 
> For you said SDEI is "horrible", does it mean we'd better never
> implement SDEI in virtual world? Or do you have any advice on how to
> implement it?

My concern is that SDEI implies having EL3. EL3 not being virtualizable
with KVM, you end-up baking SDEI in *hardware*. Of course, this hardware
is actually software (it is QEMU), but this isn't the way it was 
intended.

It's not the first time we've done that (PSCI is another example), but 
the
logic behind SDEI looks much more invasive.

         M.
-- 
Jazz is not dead. It just smells funny...


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [RFC v2 00/14] Add SDEI support for arm64
  2020-02-05 13:15       ` Marc Zyngier
@ 2020-02-06  1:20         ` Heyi Guo
  2020-02-06 17:30           ` Marc Zyngier
  0 siblings, 1 reply; 43+ messages in thread
From: Heyi Guo @ 2020-02-06  1:20 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Mark Rutland, Peter Maydell, Gavin Shan, Michael S. Tsirkin,
	Cornelia Huck, QEMU Developers, Shannon Zhao, Igor Mammedov,
	qemu-arm, James Morse, Paolo Bonzini, wanghaibin.wang,
	Dave Martin

Hi Marc,

On 2020/2/5 21:15, Marc Zyngier wrote:
> Hi Heyi,
>
> On 2020-02-04 08:26, Heyi Guo wrote:
>> Update Marc's email address.
>>
>> +cc Gavin as he is posting a RFC for ARM NMI.
>>
>> Hi Marc,
>>
>> Really sorry for missing to update your email address, for the initial
>> topic was raised long time ago and I forgot to update the Cc list in
>> the commit message of the patches.
>>
>> Thanks Gavin for forwarding current discussion on ARM NMI to me.
>>
>> For you said SDEI is "horrible", does it mean we'd better never
>> implement SDEI in virtual world? Or do you have any advice on how to
>> implement it?
>
> My concern is that SDEI implies having EL3. EL3 not being virtualizable
> with KVM, you end-up baking SDEI in *hardware*. Of course, this hardware
> is actually software (it is QEMU), but this isn't the way it was 
> intended.

>
> It's not the first time we've done that (PSCI is another example), but 
> the
> logic behind SDEI looks much more invasive.

Thanks for your comments.

Thinking about them for quite a while, below is my understanding, please 
correct me if I'm wrong:

So should the KVM based virtual machine be treated as one with CPUs only 
having NS-EL1 and NS-EL0, ideally? And SDEI messes up this model, isn't it?

PSCI only contains some one-shot operations, so it is much less invasive 
than SDEI.


I've another question. The origin of "virtual" SDEI requirement comes 
from the lack of hard lockup detector in VM. We can have some kind of 
watchdog, but how can the watchdog trigger the VM OS to panic and run 
kdump, even in irq-off state?

Thanks,

Heyi

>
>         M.



^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [RFC v2 00/14] Add SDEI support for arm64
  2020-02-06  1:20         ` Heyi Guo
@ 2020-02-06 17:30           ` Marc Zyngier
  2020-02-07 10:52             ` James Morse
  2020-02-07 13:17             ` Heyi Guo
  0 siblings, 2 replies; 43+ messages in thread
From: Marc Zyngier @ 2020-02-06 17:30 UTC (permalink / raw)
  To: Heyi Guo
  Cc: Mark Rutland, Peter Maydell, Gavin Shan, Michael S. Tsirkin,
	Cornelia Huck, QEMU Developers, Shannon Zhao, Igor Mammedov,
	qemu-arm, James Morse, Paolo Bonzini, wanghaibin.wang,
	Dave Martin

On 2020-02-06 01:20, Heyi Guo wrote:
> Hi Marc,
> 
> On 2020/2/5 21:15, Marc Zyngier wrote:
>> Hi Heyi,
>> 
>> On 2020-02-04 08:26, Heyi Guo wrote:
>>> Update Marc's email address.
>>> 
>>> +cc Gavin as he is posting a RFC for ARM NMI.
>>> 
>>> Hi Marc,
>>> 
>>> Really sorry for missing to update your email address, for the 
>>> initial
>>> topic was raised long time ago and I forgot to update the Cc list in
>>> the commit message of the patches.
>>> 
>>> Thanks Gavin for forwarding current discussion on ARM NMI to me.
>>> 
>>> For you said SDEI is "horrible", does it mean we'd better never
>>> implement SDEI in virtual world? Or do you have any advice on how to
>>> implement it?
>> 
>> My concern is that SDEI implies having EL3. EL3 not being 
>> virtualizable
>> with KVM, you end-up baking SDEI in *hardware*. Of course, this 
>> hardware
>> is actually software (it is QEMU), but this isn't the way it was 
>> intended.
> 
>> 
>> It's not the first time we've done that (PSCI is another example), but 
>> the
>> logic behind SDEI looks much more invasive.
> 
> Thanks for your comments.
> 
> Thinking about them for quite a while, below is my understanding,
> please correct me if I'm wrong:
> 
> So should the KVM based virtual machine be treated as one with CPUs
> only having NS-EL1 and NS-EL0, ideally? And SDEI messes up this model,
> isn't it?

Well, that's exactly what it is (until we have nested virt, in which 
case
you will be able to add NS-EL2 to the mix).

> PSCI only contains some one-shot operations, so it is much less
> invasive than SDEI.
> 
> 
> I've another question. The origin of "virtual" SDEI requirement comes
> from the lack of hard lockup detector in VM.

Sure. But nothing guarantees that the guest is going to register a SDEI
entry point anyway.

> We can have some kind of
> watchdog, but how can the watchdog trigger the VM OS to panic and run
> kdump, even in irq-off state?

Nothing. All the events, including SDEI, are maskable, one way or 
another.

Gavin's approach to inject a SError is probably OK for Linux, given that
it tends to run with PSTATE.A==0. But that's not a guarantee either (if
you take a recursive exception, SError won't be delivered).

The long and the short of it is that there is no way to do what you want
with absolute guarantees on the ARM architecture. It just doesn't exist.

         M.
-- 
Jazz is not dead. It just smells funny...


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [RFC v2 00/14] Add SDEI support for arm64
  2020-02-06 17:30           ` Marc Zyngier
@ 2020-02-07 10:52             ` James Morse
  2020-02-07 11:08               ` Peter Maydell
  2020-02-07 13:45               ` Heyi Guo
  2020-02-07 13:17             ` Heyi Guo
  1 sibling, 2 replies; 43+ messages in thread
From: James Morse @ 2020-02-07 10:52 UTC (permalink / raw)
  To: Marc Zyngier, Heyi Guo
  Cc: Mark Rutland, Peter Maydell, Gavin Shan, Michael S. Tsirkin,
	Cornelia Huck, QEMU Developers, Shannon Zhao, Igor Mammedov,
	qemu-arm, Paolo Bonzini, wanghaibin.wang, Dave Martin

Hi guys,

On 06/02/2020 17:30, Marc Zyngier wrote:
> On 2020-02-06 01:20, Heyi Guo wrote:
>> On 2020/2/5 21:15, Marc Zyngier wrote:
>>> My concern is that SDEI implies having EL3. EL3 not being virtualizable
>>> with KVM, you end-up baking SDEI in *hardware*. Of course, this hardware
>>> is actually software (it is QEMU), but this isn't the way it was intended.
>>
>>>
>>> It's not the first time we've done that (PSCI is another example), but the
>>> logic behind SDEI looks much more invasive.
>>
>> Thanks for your comments.
>>
>> Thinking about them for quite a while, below is my understanding,
>> please correct me if I'm wrong:
>>
>> So should the KVM based virtual machine be treated as one with CPUs
>> only having NS-EL1 and NS-EL0, ideally? And SDEI messes up this model,
>> isn't it?
> 
> Well, that's exactly what it is (until we have nested virt, in which case
> you will be able to add NS-EL2 to the mix).
> 
>> PSCI only contains some one-shot operations, so it is much less
>> invasive than SDEI.

Is there an established pattern for how Qemu 'gets' things that are done in secure-world?
For PSCI the kernel does it, but this obviously doesn't scale to something like OP-TEE.

Ideally we'd get the reference implementation (from ATF) in some form that is easy to use...


>> I've another question. The origin of "virtual" SDEI requirement comes
>> from the lack of hard lockup detector in VM.

(this is your use case. Its origin was just symmetry with EL3<->EL2)


> Sure. But nothing guarantees that the guest is going to register a SDEI
> entry point anyway.

>> We can have some kind of
>> watchdog, but how can the watchdog trigger the VM OS to panic and run
>> kdump, even in irq-off state?
> 
> Nothing. All the events, including SDEI, are maskable, one way or another.
> 
> Gavin's approach to inject a SError is probably OK for Linux, given that
> it tends to run with PSTATE.A==0. But that's not a guarantee either (if
> you take a recursive exception, SError won't be delivered).

Or get stuck in debug-state (for which we mask SError), power-management, the vectors or
somewhere weird, like KVM's world-switch.


If you just want to kill the OS if its sort-of-alive, there is another trick:

Synchronous exceptions can't be masked because they are caused by the instruction pointed
to by the ELR. You can't inject an emulated data-abort unless the ELR points to an
instruction that accesses memory, but...

synchronous external abort for instruction fetch is something that  could happen at any
time. If you have v8.2 you can make the severity uncontainable for extra points.

On real hardware, this would be as if this instruction missed in the i-cache, then got an
abort from the PoU-cache. The PoU-cache must have suffered some metadata corruption to
report an uncontained error. On real hardware its very likely the next instruction would
suffer the same fate, but linux should put up a good show of trying to panic().


> The long and the short of it is that there is no way to do what you want
> with absolute guarantees on the ARM architecture. It just doesn't exist.

Yes. By sort-of-alive it needs to be making some kind of progress. If the CPU is spinning
through the vectors (because some joker unmapped them), all bets are off.


Thanks,

James


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [RFC v2 00/14] Add SDEI support for arm64
  2020-02-07 10:52             ` James Morse
@ 2020-02-07 11:08               ` Peter Maydell
  2020-02-07 13:45               ` Heyi Guo
  1 sibling, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2020-02-07 11:08 UTC (permalink / raw)
  To: James Morse
  Cc: Mark Rutland, Gavin Shan, Michael S. Tsirkin, Marc Zyngier,
	Cornelia Huck, QEMU Developers, Shannon Zhao, Igor Mammedov,
	qemu-arm, Paolo Bonzini, Heyi Guo, wanghaibin.wang, Dave Martin

On Fri, 7 Feb 2020 at 10:52, James Morse <james.morse@arm.com> wrote:
> Is there an established pattern for how Qemu 'gets' things that are done in secure-world?
> For PSCI the kernel does it, but this obviously doesn't scale to something like OP-TEE.

The answer broadly is "it doesn't get them", the same way
that a real hardware implementation that provides only EL1
and EL0 has no way to get them. Ideally there would be an
architecturally provided way to run a virtualized EL3 in the
guest so it could run (a QEMU-aware flavour of) firmware...

thanks
-- PMM


^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [RFC v2 00/14] Add SDEI support for arm64
  2020-02-06 17:30           ` Marc Zyngier
  2020-02-07 10:52             ` James Morse
@ 2020-02-07 13:17             ` Heyi Guo
  1 sibling, 0 replies; 43+ messages in thread
From: Heyi Guo @ 2020-02-07 13:17 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Mark Rutland, Peter Maydell, Gavin Shan, Michael S. Tsirkin,
	Cornelia Huck, QEMU Developers, Shannon Zhao, Igor Mammedov,
	qemu-arm, James Morse, Paolo Bonzini, wanghaibin.wang,
	Dave Martin


On 2020/2/7 1:30, Marc Zyngier wrote:
> On 2020-02-06 01:20, Heyi Guo wrote:
>> Hi Marc,
>>
>> On 2020/2/5 21:15, Marc Zyngier wrote:
>>> Hi Heyi,
>>>
>>> On 2020-02-04 08:26, Heyi Guo wrote:
>>>> Update Marc's email address.
>>>>
>>>> +cc Gavin as he is posting a RFC for ARM NMI.
>>>>
>>>> Hi Marc,
>>>>
>>>> Really sorry for missing to update your email address, for the initial
>>>> topic was raised long time ago and I forgot to update the Cc list in
>>>> the commit message of the patches.
>>>>
>>>> Thanks Gavin for forwarding current discussion on ARM NMI to me.
>>>>
>>>> For you said SDEI is "horrible", does it mean we'd better never
>>>> implement SDEI in virtual world? Or do you have any advice on how to
>>>> implement it?
>>>
>>> My concern is that SDEI implies having EL3. EL3 not being virtualizable
>>> with KVM, you end-up baking SDEI in *hardware*. Of course, this 
>>> hardware
>>> is actually software (it is QEMU), but this isn't the way it was 
>>> intended.
>>
>>>
>>> It's not the first time we've done that (PSCI is another example), 
>>> but the
>>> logic behind SDEI looks much more invasive.
>>
>> Thanks for your comments.
>>
>> Thinking about them for quite a while, below is my understanding,
>> please correct me if I'm wrong:
>>
>> So should the KVM based virtual machine be treated as one with CPUs
>> only having NS-EL1 and NS-EL0, ideally? And SDEI messes up this model,
>> isn't it?
>
> Well, that's exactly what it is (until we have nested virt, in which case
> you will be able to add NS-EL2 to the mix).
>
>> PSCI only contains some one-shot operations, so it is much less
>> invasive than SDEI.
>>
>>
>> I've another question. The origin of "virtual" SDEI requirement comes
>> from the lack of hard lockup detector in VM.
>
> Sure. But nothing guarantees that the guest is going to register a SDEI
> entry point anyway.
>
>> We can have some kind of
>> watchdog, but how can the watchdog trigger the VM OS to panic and run
>> kdump, even in irq-off state?
>
> Nothing. All the events, including SDEI, are maskable, one way or 
> another.

Indeed...

>
> Gavin's approach to inject a SError is probably OK for Linux, given that
> it tends to run with PSTATE.A==0. But that's not a guarantee either (if
> you take a recursive exception, SError won't be delivered).
>
> The long and the short of it is that there is no way to do what you want
> with absolute guarantees on the ARM architecture. It just doesn't exist.

Much appreciate your explanation and advice.

Thanks,

Heyi

>
>         M.



^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [RFC v2 00/14] Add SDEI support for arm64
  2020-02-07 10:52             ` James Morse
  2020-02-07 11:08               ` Peter Maydell
@ 2020-02-07 13:45               ` Heyi Guo
  1 sibling, 0 replies; 43+ messages in thread
From: Heyi Guo @ 2020-02-07 13:45 UTC (permalink / raw)
  To: James Morse, Marc Zyngier
  Cc: Mark Rutland, Peter Maydell, Gavin Shan, Michael S. Tsirkin,
	Cornelia Huck, QEMU Developers, Shannon Zhao, Igor Mammedov,
	qemu-arm, Paolo Bonzini, wanghaibin.wang, Dave Martin


On 2020/2/7 18:52, James Morse wrote:
> Hi guys,
>
> On 06/02/2020 17:30, Marc Zyngier wrote:
>> On 2020-02-06 01:20, Heyi Guo wrote:
>>> On 2020/2/5 21:15, Marc Zyngier wrote:
>>>> My concern is that SDEI implies having EL3. EL3 not being virtualizable
>>>> with KVM, you end-up baking SDEI in *hardware*. Of course, this hardware
>>>> is actually software (it is QEMU), but this isn't the way it was intended.
>>>> It's not the first time we've done that (PSCI is another example), but the
>>>> logic behind SDEI looks much more invasive.
>>> Thanks for your comments.
>>>
>>> Thinking about them for quite a while, below is my understanding,
>>> please correct me if I'm wrong:
>>>
>>> So should the KVM based virtual machine be treated as one with CPUs
>>> only having NS-EL1 and NS-EL0, ideally? And SDEI messes up this model,
>>> isn't it?
>> Well, that's exactly what it is (until we have nested virt, in which case
>> you will be able to add NS-EL2 to the mix).
>>
>>> PSCI only contains some one-shot operations, so it is much less
>>> invasive than SDEI.
> Is there an established pattern for how Qemu 'gets' things that are done in secure-world?
> For PSCI the kernel does it, but this obviously doesn't scale to something like OP-TEE.
>
> Ideally we'd get the reference implementation (from ATF) in some form that is easy to use...
>
>
>>> I've another question. The origin of "virtual" SDEI requirement comes
>>> from the lack of hard lockup detector in VM.
> (this is your use case. Its origin was just symmetry with EL3<->EL2)
>
>
>> Sure. But nothing guarantees that the guest is going to register a SDEI
>> entry point anyway.
>>> We can have some kind of
>>> watchdog, but how can the watchdog trigger the VM OS to panic and run
>>> kdump, even in irq-off state?
>> Nothing. All the events, including SDEI, are maskable, one way or another.
>>
>> Gavin's approach to inject a SError is probably OK for Linux, given that
>> it tends to run with PSTATE.A==0. But that's not a guarantee either (if
>> you take a recursive exception, SError won't be delivered).
> Or get stuck in debug-state (for which we mask SError), power-management, the vectors or
> somewhere weird, like KVM's world-switch.
>
>
> If you just want to kill the OS if its sort-of-alive, there is another trick:
>
> Synchronous exceptions can't be masked because they are caused by the instruction pointed
> to by the ELR. You can't inject an emulated data-abort unless the ELR points to an
> instruction that accesses memory, but...
>
> synchronous external abort for instruction fetch is something that  could happen at any
> time. If you have v8.2 you can make the severity uncontainable for extra points.
>
> On real hardware, this would be as if this instruction missed in the i-cache, then got an
> abort from the PoU-cache. The PoU-cache must have suffered some metadata corruption to
> report an uncontained error. On real hardware its very likely the next instruction would
> suffer the same fate, but linux should put up a good show of trying to panic().

Good idea. It seems to be able to cover all the possible the cases, 
while we only need to highlight this exception in the user document :)

Thanks,

Heyi

>
>
>> The long and the short of it is that there is no way to do what you want
>> with absolute guarantees on the ARM architecture. It just doesn't exist.
> Yes. By sort-of-alive it needs to be making some kind of progress. If the CPU is spinning
> through the vectors (because some joker unmapped them), all bets are off.
>
>
> Thanks,
>
> James
>
> .



^ permalink raw reply	[flat|nested] 43+ messages in thread

end of thread, other threads:[~2020-02-07 13:46 UTC | newest]

Thread overview: 43+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-11-05  9:10 [RFC v2 00/14] Add SDEI support for arm64 Heyi Guo
2019-11-05  9:10 ` [RFC v2 01/14] update-linux-headers.sh: import linux/arm_sdei.h to standard-headers Heyi Guo
2019-11-05  9:10 ` [RFC v2 02/14] standard-headers: import arm_sdei.h Heyi Guo
2019-11-06 17:52   ` Cornelia Huck
2019-11-07  1:40     ` Guoheyi
2019-11-07  8:50       ` Cornelia Huck
2019-11-07  8:55       ` Michael S. Tsirkin
2019-11-05  9:10 ` [RFC v2 03/14] arm/sdei: add virtual device framework Heyi Guo
2019-11-05  9:10 ` [RFC v2 04/14] arm: add CONFIG_SDEI build flag Heyi Guo
2019-11-05  9:10 ` [RFC v2 05/14] arm/sdei: add support to handle SDEI requests from guest Heyi Guo
2019-11-05  9:10 ` [RFC v2 06/14] arm/sdei: add system reset callback Heyi Guo
2019-11-05  9:10 ` [RFC v2 07/14] arm/sdei: add support to trigger event by GIC interrupt ID Heyi Guo
2019-11-05  9:10 ` [RFC v2 08/14] core/irq: add qemu_irq_remove_intercept interface Heyi Guo
2019-11-05  9:10 ` [RFC v2 09/14] arm/sdei: override qemu_irq handler when binding interrupt Heyi Guo
2019-11-05  9:10 ` [RFC v2 10/14] arm/sdei: add support to register interrupt bind notifier Heyi Guo
2019-11-05  9:10 ` [RFC v2 11/14] linux-headers/kvm.h: add capability to forward hypercall Heyi Guo
2019-11-06 17:55   ` Cornelia Huck
2019-11-07  1:44     ` Guoheyi
2019-11-07  8:57       ` Michael S. Tsirkin
2019-11-07 11:57         ` Guoheyi
2019-11-07 12:12           ` Cornelia Huck
2019-11-08  1:54             ` Guoheyi
2019-11-05  9:10 ` [RFC v2 12/14] arm/sdei: add stub to fix build failure when SDEI is not enabled Heyi Guo
2019-11-05  9:10 ` [RFC v2 13/14] arm/kvm: handle guest exit of hypercall Heyi Guo
2019-11-05  9:10 ` [RFC v2 14/14] virt/acpi: add SDEI table if SDEI is enabled Heyi Guo
2019-11-12 14:52   ` Igor Mammedov
2019-11-18  6:44     ` Guoheyi
2019-11-05  9:15 ` [RFC v2 00/14] Add SDEI support for arm64 Guoheyi
2019-11-05  9:36 ` no-reply
2019-11-05  9:38 ` no-reply
2019-11-18  6:55 ` Guoheyi
2019-11-18 13:35   ` Peter Maydell
2019-11-18 14:04     ` Guoheyi
2019-12-20 13:44 ` Peter Maydell
2019-12-23  8:20   ` Guoheyi
2020-02-04  8:26     ` Heyi Guo
2020-02-05 13:15       ` Marc Zyngier
2020-02-06  1:20         ` Heyi Guo
2020-02-06 17:30           ` Marc Zyngier
2020-02-07 10:52             ` James Morse
2020-02-07 11:08               ` Peter Maydell
2020-02-07 13:45               ` Heyi Guo
2020-02-07 13:17             ` Heyi Guo

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.