From nobody Tue May 7 06:18:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1569338796; cv=none; d=zoho.com; s=zohoarc; b=H3CJyNDzd+q+ve/7Tioi2dVvVeVUio2OG+RRA3x2+xtZoW1IczpetCLyJU07kZDSDkECUiIxVJ/swiEq/m7MP03Umh2+L+jsReKT6BAHHI73qKPUX3jn5TuEuAZcjyyKYjd9oUKoob3LQh0wemTdwI2+t0E7IuCbSZ7rtsG1O+Q= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1569338796; h=Content-Type:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=EyPBar7D4EjHbJsVUSOw/D0cMid/8Wvpjd1NOj3X76A=; b=fXm1pfRmzCY6C74TFc/4bWc204bNtiKbP/6VzxHUo5MmmfMumgLDuoriMpAepds2X3835SXpzaYm1rPuTC4V3KskuatyqnqlIIGvPyBJj8eJYeiajdFluwFEYwfb95eoDea0t8A57dPxxcPYiAUkgxzNI4rXTGQ5VAU1aLvtqSA= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 15693387963395.2167319522477555; Tue, 24 Sep 2019 08:26:36 -0700 (PDT) Received: from localhost ([::1]:47114 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iCmi2-0003KM-Qf for importer@patchew.org; Tue, 24 Sep 2019 11:26:34 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48189) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iCmf6-0001EB-84 for qemu-devel@nongnu.org; Tue, 24 Sep 2019 11:23:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iCmf4-0006iT-7e for qemu-devel@nongnu.org; Tue, 24 Sep 2019 11:23:31 -0400 Received: from szxga05-in.huawei.com ([45.249.212.191]:2242 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iCmf0-0006fs-PO; Tue, 24 Sep 2019 11:23:27 -0400 Received: from DGGEMS409-HUB.china.huawei.com (unknown [172.30.72.59]) by Forcepoint Email with ESMTP id 532B4BCC54BC3747BF23; Tue, 24 Sep 2019 23:23:22 +0800 (CST) Received: from linux-Bxxcye.huawei.com (10.175.104.222) by DGGEMS409-HUB.china.huawei.com (10.3.19.209) with Microsoft SMTP Server id 14.3.439.0; Tue, 24 Sep 2019 23:23:14 +0800 From: Heyi Guo To: , , , Subject: [RFC PATCH 01/12] linux-headers: import arm_sdei.h Date: Tue, 24 Sep 2019 23:21:40 +0800 Message-ID: <1569338511-3572-2-git-send-email-guoheyi@huawei.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1569338511-3572-1-git-send-email-guoheyi@huawei.com> References: <1569338511-3572-1-git-send-email-guoheyi@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.104.222] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 45.249.212.191 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Mark Rutland , Peter Maydell , "Michael S. Tsirkin" , Marc Zyngier , Cornelia Huck , James Morse , Paolo Bonzini , Heyi Guo , wanghaibin.wang@huawei.com, Dave Martin Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Import Linux header file include/uapi/linux/arm_sdei.h from kernel v5.3 release. This is to prepare for qemu SDEI emulation. Signed-off-by: Heyi Guo Cc: Peter Maydell Cc: Dave Martin Cc: Marc Zyngier Cc: Mark Rutland Cc: James Morse Cc: "Michael S. Tsirkin" Cc: Cornelia Huck Cc: Paolo Bonzini --- linux-headers/linux/arm_sdei.h | 73 ++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 73 insertions(+) create mode 100644 linux-headers/linux/arm_sdei.h diff --git a/linux-headers/linux/arm_sdei.h b/linux-headers/linux/arm_sdei.h new file mode 100644 index 0000000..af0630b --- /dev/null +++ b/linux-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 _UAPI_LINUX_ARM_SDEI_H +#define _UAPI_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_VERSIO= N_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 /* _UAPI_LINUX_ARM_SDEI_H */ --=20 1.8.3.1 From nobody Tue May 7 06:18:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1569340212; cv=none; d=zoho.com; s=zohoarc; b=WzL9nv7y6kyuJmZ2ta5y1iPP3NMU68EbrxndtDaveECMJ9dTzPCtnJnt/1/CrDYCIS9Oo14DlfOlPBBesNk4E03sszlgWXd3VNvzDJSgEF+9eZgRYr09vjI26/mNp8gJ+/kBfR+jUdlnn6tKR9dI033O8cRYMo6tmukMFh480Ww= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1569340212; h=Content-Type:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=ekJm9Ukkbv9SOaegiOG879s0Iwad3kCmTQjCjFaniKw=; b=MUsg/z+KWfIuQGb+P1QZ+JMJRvo073+i3GiHhcBAutmmKVvRu0CXMp0bfbrhDXVhiCmok37pcV4QV3VzpXC3QDiSLA3GuC/5sjIOovX7NvSGt+BaJmYGKL61V9/Z8HwUW0XAW7mcQdBNzpDVykHDvqrcRupwVzVkD6Snx7N1bhQ= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1569340212173319.5481072109035; Tue, 24 Sep 2019 08:50:12 -0700 (PDT) Received: from localhost ([::1]:47438 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iCn4p-0000jq-Vl for importer@patchew.org; Tue, 24 Sep 2019 11:50:08 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48372) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iCmfD-0001Pg-Iz for qemu-devel@nongnu.org; Tue, 24 Sep 2019 11:23:42 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iCmf9-0006m1-Dd for qemu-devel@nongnu.org; Tue, 24 Sep 2019 11:23:39 -0400 Received: from szxga05-in.huawei.com ([45.249.212.191]:2241 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iCmf0-0006fu-KG; Tue, 24 Sep 2019 11:23:27 -0400 Received: from DGGEMS409-HUB.china.huawei.com (unknown [172.30.72.59]) by Forcepoint Email with ESMTP id 5AF7A2C1E6C1AC4F4F26; Tue, 24 Sep 2019 23:23:22 +0800 (CST) Received: from linux-Bxxcye.huawei.com (10.175.104.222) by DGGEMS409-HUB.china.huawei.com (10.3.19.209) with Microsoft SMTP Server id 14.3.439.0; Tue, 24 Sep 2019 23:23:15 +0800 From: Heyi Guo To: , , , Subject: [RFC PATCH 02/12] arm/sdei: add virtual device framework Date: Tue, 24 Sep 2019 23:21:41 +0800 Message-ID: <1569338511-3572-3-git-send-email-guoheyi@huawei.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1569338511-3572-1-git-send-email-guoheyi@huawei.com> References: <1569338511-3572-1-git-send-email-guoheyi@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.104.222] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 45.249.212.191 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Mark Rutland , Peter Maydell , James Morse , Marc Zyngier , Jingyi Wang , Heyi Guo , wanghaibin.wang@huawei.com, Dave Martin Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 Signed-off-by: Jingyi Wang Cc: Peter Maydell Cc: Dave Martin Cc: Marc Zyngier Cc: Mark Rutland Cc: James Morse --- target/arm/Makefile.objs | 1 + target/arm/sdei.c | 351 +++++++++++++++++++++++++++++++++++++++++++= ++++ target/arm/sdei_int.h | 106 ++++++++++++++ 3 files changed, 458 insertions(+) create mode 100644 target/arm/sdei.c create mode 100644 target/arm/sdei_int.h diff --git a/target/arm/Makefile.objs b/target/arm/Makefile.objs index cf26c16..674109d 100644 --- a/target/arm/Makefile.objs +++ b/target/arm/Makefile.objs @@ -7,6 +7,7 @@ obj-$(CONFIG_SOFTMMU) +=3D machine.o arch_dump.o monitor.o obj-$(CONFIG_SOFTMMU) +=3D arm-powerctl.o =20 obj-$(CONFIG_KVM) +=3D kvm.o +obj-$(CONFIG_KVM) +=3D sdei.o obj-$(call land,$(CONFIG_KVM),$(call lnot,$(TARGET_AARCH64))) +=3D kvm32.o obj-$(call land,$(CONFIG_KVM),$(TARGET_AARCH64)) +=3D kvm64.o obj-$(call lnot,$(CONFIG_KVM)) +=3D kvm-stub.o diff --git a/target/arm/sdei.c b/target/arm/sdei.c new file mode 100644 index 0000000..7f12d69 --- /dev/null +++ b/target/arm/sdei.c @@ -0,0 +1,351 @@ +/* + * ARM SDEI emulation for ARM64 virtual machine with KVM + * + * Copyright (c) 2019 HUAWEI TECHNOLOGIES CO., LTD. + * + * Authors: + * Heyi Guo + * Jingyi Wang + * + * 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 f= or + * more details. + * + * You should have received a copy of the GNU General Public License along= with + * this program. If not, see . + */ + +#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_QEMU_SDEI "qemu_sdei" +#define QEMU_SDEI(obj) OBJECT_CHECK(QemuSDEState, (obj), TYPE_QEMU_SDEI) + +static QemuSDEState *sde_state; + +static void qemu_sde_prop_init(QemuSDEState *s) +{ + QemuSDEProp *sde_props =3D s->sde_props_state; + int i; + for (i =3D 0; i < ARRAY_SIZE(s->sde_props_state); i++) { + sde_props[i].event_id =3D SDEI_INVALID_EVENT_ID; + sde_props[i].interrupt =3D SDEI_INVALID_INTERRUPT; + sde_props[i].sde_index =3D i >=3D PRIVATE_SLOT_COUNT ? + i - PRIVATE_SLOT_COUNT : i; + + qemu_mutex_init(&(sde_props[i].lock)); + sde_props[i].refcount =3D 0; + } + sde_props[0].event_id =3D SDEI_STD_EVT_SOFTWARE_SIGNAL; + sde_props[0].interrupt =3D SDEI_INVALID_INTERRUPT; + sde_props[0].is_shared =3D false; + sde_props[0].is_critical =3D false; + + for (i =3D 0; i < ARRAY_SIZE(s->irq_map); i++) { + s->irq_map[i] =3D 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 =3D current_machine->smp.max_cpus; + s->sde_cpus =3D g_new0(QemuSDECpu, s->sdei_max_cpus); + sde_cpus =3D s->sde_cpus; + for (i =3D 0; i < s->sdei_max_cpus; i++) { + sde_cpus[i].masked =3D true; + sde_cpus[i].critical_running_event =3D SDEI_INVALID_EVENT_ID; + sde_cpus[i].normal_running_event =3D 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 =3D SDEI_EVENT_TO_SLOT(event); + if (slot_id >=3D 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 !=3D 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 qemu_shared_sde_init(QemuSDEState *s) +{ + int i; + for (i =3D 0; i < SHARED_SLOT_COUNT; i++) { + QemuSDE *sde; + sde =3D s->shared_sde_array[i]; + if (!sde) { + sde =3D g_new0(QemuSDE, 1); + } + sde->event_id =3D SDEI_INVALID_EVENT_ID; + sde->enabled =3D false; + sde->running =3D false; + sde->pending =3D false; + sde->unregister_pending =3D false; + qemu_mutex_init(&sde->lock); + s->shared_sde_array[i] =3D sde; + } +} + +static void qemu_private_sde_init(QemuSDEState *s) +{ + int i, j; + for (i =3D 0; i < s->sdei_max_cpus; i++) { + QemuSDE **array =3D s->sde_cpus[i].private_sde_array; + for (j =3D 0; j < PRIVATE_SLOT_COUNT; j++) { + QemuSDE *sde; + sde =3D array[j]; + if (!sde) { + sde =3D g_new0(QemuSDE, 1); + } + sde->event_id =3D SDEI_INVALID_EVENT_ID; + sde->enabled =3D false; + sde->running =3D false; + sde->pending =3D false; + sde->unregister_pending =3D false; + qemu_mutex_init(&sde->lock); + array[j] =3D sde; + } + } +} + +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 int qemu_sdei_pre_save(void *opaque) +{ + QemuSDEState *s =3D opaque; + QemuSDE **array; + int i, j; + + for (i =3D 0; i < s->sdei_max_cpus; i++) { + array =3D s->sde_cpus[i].private_sde_array; + for (j =3D 0; j < PRIVATE_SLOT_COUNT; j++) { + QemuSDE *sde =3D array[j]; + if (sde->event_id !=3D SDEI_INVALID_EVENT_ID) { + sde->event_id =3D sde->prop->event_id; + sde->cpu_affinity =3D ARM_CPU(sde->target_cpu)->mp_affinit= y; + } + } + } + + array =3D s->shared_sde_array; + for (j =3D 0; j < SHARED_SLOT_COUNT; j++) { + QemuSDE *sde =3D array[j]; + if (sde->event_id !=3D SDEI_INVALID_EVENT_ID) { + sde->event_id =3D sde->prop->event_id; + sde->cpu_affinity =3D ARM_CPU(sde->target_cpu)->mp_affinity; + } + } + + return 0; +} + + +static int qemu_sdei_post_load(void *opaque, int version_id) +{ + QemuSDEState *s =3D opaque; + QemuSDEProp *sde_props =3D s->sde_props_state; + QemuSDE **array; + int i, j; + + for (i =3D 0; i < s->sdei_max_cpus; i++) { + array =3D s->sde_cpus[i].private_sde_array; + for (j =3D 0; j < PRIVATE_SLOT_COUNT; j++) { + QemuSDE *sde =3D array[j]; + if (sde->event_id !=3D SDEI_INVALID_EVENT_ID) { + sde->prop =3D get_sde_prop_no_lock(s, sde->event_id); + sde->target_cpu =3D arm_get_cpu_by_id(sde->cpu_affinity); + } + } + } + + array =3D s->shared_sde_array; + for (j =3D 0; j < SHARED_SLOT_COUNT; j++) { + QemuSDE *sde =3D array[j]; + if (sde->event_id !=3D SDEI_INVALID_EVENT_ID) { + sde->prop =3D get_sde_prop_no_lock(s, sde->event_id); + sde->target_cpu =3D arm_get_cpu_by_id(sde->cpu_affinity); + } + } + + for (i =3D 0; i < PRIVATE_SLOT_COUNT + SHARED_SLOT_COUNT; i++) { + if (sde_props[i].interrupt !=3D SDEI_INVALID_INTERRUPT) { + s->irq_map[sde_props[i].interrupt] =3D sde_props[i].event_id; + } + } + + return 0; +} + +static const VMStateDescription vmstate_sdes =3D { + .name =3D "qemu_sdei/sdes", + .version_id =3D 1, + .minimum_version_id =3D 1, + .fields =3D (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 =3D { + .name =3D "qemu_sdei/sde_props", + .version_id =3D 1, + .minimum_version_id =3D 1, + .fields =3D (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 =3D { + .name =3D "qemu_sdei/sde_cpu", + .version_id =3D 1, + .minimum_version_id =3D 1, + .fields =3D (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, 18), + VMSTATE_UINT64_ARRAY(ctx[1].xregs, QemuSDECpu, 18), + 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 =3D { + .name =3D "qemu_sdei", + .version_id =3D 1, + .minimum_version_id =3D 1, + .pre_save =3D qemu_sdei_pre_save, + .post_load =3D qemu_sdei_post_load, + .fields =3D (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 =3D QEMU_SDEI(obj); + + if (sde_state) { + error_report("Only one SDEI dispatcher is allowed!"); + abort(); + } + sde_state =3D s; + + qemu_sde_init(s); +} + +static void qemu_sde_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + + dc->desc =3D "SDEI_QEMU"; + dc->vmsd =3D &vmstate_sde_state; + dc->user_creatable =3D true; +} + +static const TypeInfo sde_qemu_info =3D { + .name =3D TYPE_QEMU_SDEI, + .parent =3D TYPE_DEVICE, + .instance_size =3D sizeof(QemuSDEState), + .instance_init =3D sdei_initfn, + .class_init =3D 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 0000000..7f69507 --- /dev/null +++ b/target/arm/sdei_int.h @@ -0,0 +1,106 @@ +/* + * ARM SDEI emulation internal interfaces + * + * Copyright (c) 2019 HUAWEI TECHNOLOGIES CO., LTD. + * + * Authors: + * Heyi Guo + * Jingyi Wang + * + * 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 f= or + * more details. + * + * You should have received a copy of the GNU General Public License along= with + * this program. If not, see . + */ + +#ifndef QEMU_SDEI_INT_H +#define QEMU_SDEI_INT_H + +#include +#include +#include +#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) >=3D PRIVATE_SLOT_COUNT) + +typedef enum { + SDEI_PRIO_NORMAL =3D 0, + SDEI_PRIO_CRITICAL =3D 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; + +typedef struct QemuSDECpuCtx { + uint64_t xregs[18]; + uint64_t pc; + uint32_t pstate; +} QemuSDECpuCtx; + +typedef struct QemuSDECpu { + QemuSDE *private_sde_array[PRIVATE_SLOT_COUNT]; + QemuSDECpuCtx ctx[2]; + 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 --=20 1.8.3.1 From nobody Tue May 7 06:18:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1569342608; cv=none; d=zoho.com; s=zohoarc; b=QxlKjZufC89nYiumjLp78D6YVWPveZg2zmY3rGPUTo0qEQ7fUTG49NEuIYsYmYoiDlHZJAQbhJO7CWXZqDmlXGd0LeAQ6oI8DHZW+/4E57gE1arWC0bRAVNrT5e65Zz3/sDQMJbzOYLIig0/Yr69u5P6mfNiR03/Rb+bZSM9+pg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1569342608; h=Content-Type:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=oedf95RUqBxnm1EqTDvR/GvPvDxfKYIwuFyBryfY9pw=; b=b3+D7/6kP5d8VZHJFmycsYiucnO32g0UyNB7ImWrqf21+JH2LhqahxCluXAHVlwu/1072VbeQzOVzMCExQ9JDLDqefeypmiDlcTFL+12Rvk3zu7Tuwi/mzvmHUeDZR1UgNP1IlT5xVO6XN24CWZqqt2Wc5HaRIDlpKhh4u7HHys= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1569342608024285.35585741472437; Tue, 24 Sep 2019 09:30:08 -0700 (PDT) Received: from localhost ([::1]:48080 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iCnhP-0001Dw-Us for importer@patchew.org; Tue, 24 Sep 2019 12:29:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48439) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iCmfH-0001Tw-1c for qemu-devel@nongnu.org; Tue, 24 Sep 2019 11:23:46 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iCmfB-0006nU-Mm for qemu-devel@nongnu.org; Tue, 24 Sep 2019 11:23:42 -0400 Received: from szxga05-in.huawei.com ([45.249.212.191]:2240 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iCmez-0006ft-T2; Tue, 24 Sep 2019 11:23:26 -0400 Received: from DGGEMS409-HUB.china.huawei.com (unknown [172.30.72.59]) by Forcepoint Email with ESMTP id 62FD0D73C3932A7CBA5E; Tue, 24 Sep 2019 23:23:22 +0800 (CST) Received: from linux-Bxxcye.huawei.com (10.175.104.222) by DGGEMS409-HUB.china.huawei.com (10.3.19.209) with Microsoft SMTP Server id 14.3.439.0; Tue, 24 Sep 2019 23:23:15 +0800 From: Heyi Guo To: , , , Subject: [RFC PATCH 03/12] arm/sdei: add support to handle SDEI requests from guest Date: Tue, 24 Sep 2019 23:21:42 +0800 Message-ID: <1569338511-3572-4-git-send-email-guoheyi@huawei.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1569338511-3572-1-git-send-email-guoheyi@huawei.com> References: <1569338511-3572-1-git-send-email-guoheyi@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.104.222] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 45.249.212.191 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Mark Rutland , Peter Maydell , James Morse , Marc Zyngier , Jingyi Wang , Heyi Guo , wanghaibin.wang@huawei.com, Dave Martin Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add support for all interfaces defined in ARM SDEI 1.0 spec. http://infocenter.arm.com/help/topic/com.arm.doc.den0054a/ARM_DEN0054A_Soft= ware_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 Signed-off-by: Jingyi Wang Cc: Peter Maydell Cc: Dave Martin Cc: Marc Zyngier Cc: Mark Rutland Cc: James Morse --- target/arm/sdei.c | 911 ++++++++++++++++++++++++++++++++++++++++++++++++++= ++++ target/arm/sdei.h | 34 ++ 2 files changed, 945 insertions(+) create mode 100644 target/arm/sdei.h diff --git a/target/arm/sdei.c b/target/arm/sdei.c index 7f12d69..b40fa36 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" @@ -84,6 +85,12 @@ static void qemu_sde_cpu_init(QemuSDEState *s) } } =20 +static inline QemuSDECpu *get_sde_cpu(QemuSDEState *s, CPUState *cs) +{ + assert(cs->cpu_index < s->sdei_max_cpus); + return &s->sde_cpus[cs->cpu_index]; +} + static bool is_valid_event_number(int32_t event) { int32_t slot_id; @@ -122,6 +129,910 @@ static QemuSDEProp *get_sde_prop_no_lock(QemuSDEState= *s, int32_t event) return &s->sde_props_state[SDEI_EVENT_TO_SLOT(event)]; } =20 +static QemuSDEProp *get_sde_prop(QemuSDEState *s, int32_t event) +{ + QemuSDEProp *sde_props =3D s->sde_props_state; + + if (!is_valid_event_number(event)) { + return NULL; + } + + event =3D 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 mus= t be + * validated before calling this function. + */ +static QemuSDE *get_sde_no_check(QemuSDEState *s, int32_t event, CPUState = *cs) +{ + QemuSDE **array =3D s->sde_cpus[cs->cpu_index].private_sde_array; + int32_t sde_index =3D SDEI_EVENT_TO_SLOT(event); + QemuSDE *sde; + + if (SDEI_IS_SHARED_EVENT(event)) { + array =3D s->shared_sde_array; + sde_index -=3D PRIVATE_SLOT_COUNT; + } + + sde =3D 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 >=3D 0 && + sde_cpu->normal_running_event >=3D 0; +} + +static int32_t get_running_sde(QemuSDEState *s, CPUState *cs) +{ + QemuSDECpu *sde_cpu =3D get_sde_cpu(s, cs); + + if (sde_cpu->critical_running_event >=3D 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 =3D &ARM_CPU(cs)->env; + int i; + + for (i =3D 0; i < 4; i++) { + args[i] =3D env->xregs[i]; + } +} + +static void sde_save_cpu_ctx(CPUState *cs, QemuSDECpu *sde_cpu, bool criti= cal) +{ + CPUARMState *env =3D &ARM_CPU(cs)->env; + QemuSDECpuCtx *ctx =3D &sde_cpu->ctx[critical ? 1 : 0]; + + memcpy(ctx->xregs, env->xregs, sizeof(ctx->xregs)); + ctx->pc =3D env->pc; + ctx->pstate =3D pstate_read(env); +} + +static void sde_restore_cpu_ctx(QemuSDEState *s, CPUState *cs, bool critic= al) +{ + CPUARMState *env =3D &ARM_CPU(cs)->env; + QemuSDECpu *sde_cpu =3D get_sde_cpu(s, cs); + QemuSDECpuCtx *ctx =3D &sde_cpu->ctx[critical ? 1 : 0]; + + /* + * TODO: we need to optimize to only restore affected registers by cal= ling + * ioctl individialy + */ + kvm_arch_get_registers(cs); + + env->aarch64 =3D ((ctx->pstate & PSTATE_nRW) =3D=3D 0); + memcpy(env->xregs, ctx->xregs, sizeof(ctx->xregs)); + env->pc =3D ctx->pc; + pstate_write(env, ctx->pstate); + aarch64_restore_sp(env, (env->pstate >> 2) & 3); +} + +static void sde_restore_cpu_ctx_for_resume(QemuSDEState *s, + CPUState *cs, + bool critical, + uint64_t resume_addr) +{ + CPUARMState *env =3D &ARM_CPU(cs)->env; + QemuSDECpu *sde_cpu =3D get_sde_cpu(s, cs); + QemuSDECpuCtx *ctx =3D &sde_cpu->ctx[critical ? 1 : 0]; + + /* + * TODO: we need to optimize to only restore affected registers by cal= ling + * ioctl individialy + */ + kvm_arch_get_registers(cs); + + memcpy(env->xregs, ctx->xregs, sizeof(ctx->xregs)); + env->pc =3D resume_addr; + env->aarch64 =3D 1; + /* Constructe pstate in pstate_read() */ + env->daif =3D 0xF << 6; + /* Clear nRW/M[4] and M[3:0] */ + env->pstate &=3D ~0x1F; + /* Set exception mode to EL1h */ + env->pstate |=3D PSTATE_MODE_EL1h; + env->elr_el[1] =3D ctx->pc; + env->banked_spsr[KVM_SPSR_EL1 + 1] =3D ctx->pstate; + aarch64_restore_sp(env, 1); +} + +static void sde_build_cpu_ctx(CPUState *cs, QemuSDECpu *sde_cpu, QemuSDE *= sde) +{ + CPUARMState *env =3D &ARM_CPU(cs)->env; + + env->xregs[0] =3D sde->prop->event_id; + env->xregs[1] =3D sde->ep_argument; + env->xregs[2] =3D env->pc; + env->xregs[3] =3D pstate_read(env); + env->pc =3D sde->ep_address; + env->aarch64 =3D 1; + /* Constructe pstate in pstate_read() */ + env->daif =3D 0xF << 6; + /* Clear nRW/M[4] and M[3:0] */ + env->pstate &=3D ~0x1F; + /* Set exception mode to EL1h */ + env->pstate |=3D PSTATE_MODE_EL1h; + aarch64_restore_sp(env, 1); +} + +static void trigger_sde(CPUState *cs, run_on_cpu_data data) +{ + QemuSDEState *s =3D sde_state; + QemuSDECpu *sde_cpu =3D get_sde_cpu(s, cs); + int32_t event =3D data.host_int; + QemuSDE *sde; + + assert(cs =3D=3D current_cpu); + + if (sde_cpu->masked || sde_cpu->critical_running_event >=3D 0) { + return; + } + + sde =3D get_sde_no_check(s, event, cs); + if (sde->event_id =3D=3D SDEI_INVALID_EVENT_ID) { + /* Some race condition happens! */ + put_sde(sde, cs); + return; + } + + if (sde_cpu->normal_running_event >=3D 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 =3D false; + sde->running =3D true; + + if (sde->prop->is_critical) { + sde_cpu->critical_running_event =3D sde->prop->event_id; + } else { + sde_cpu->normal_running_event =3D 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 int64_t dispatch_single(QemuSDEState *s, QemuSDE *sde, CPUState *cs) +{ + int32_t event =3D sde->prop->event_id; + bool pending =3D sde->pending; + bool enabled =3D sde->enabled; + CPUState *target =3D 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)); + } + return SDEI_SUCCESS; +} + +static void dispatch_cpu(QemuSDEState *s, CPUState *cs, bool is_critical) +{ + QemuSDE *sde; + int i; + + for (i =3D 0; i < PRIVATE_SLOT_COUNT + SHARED_SLOT_COUNT; i++) { + sde =3D get_sde_no_check(s, i, cs); + if (sde->event_id =3D=3D SDEI_INVALID_EVENT_ID) { + put_sde(sde, cs); + continue; + } + if (sde->prop->is_critical !=3D is_critical) { + put_sde(sde, cs); + continue; + } + if (!sde->enabled || !sde->pending || sde->running || + sde->target_cpu !=3D cs) { + 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 =3D 0; + int count =3D PRIVATE_SLOT_COUNT; + int32_t event; + QemuSDEProp *sde_props =3D s->sde_props_state; + + if (is_shared) { + start =3D PRIVATE_SLOT_COUNT; + count =3D PRIVATE_SLOT_COUNT + SHARED_SLOT_COUNT; + } + + qemu_mutex_lock(&s->sdei_interrupt_bind_lock); + for (index =3D start; index < count; index++) { + qemu_mutex_lock(&sde_props[index].lock); + if (sde_props[index].interrupt =3D=3D intid) { + event =3D 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 =3D start; index < count; index++) { + qemu_mutex_lock(&sde_props[index].lock); + if (sde_props[index].event_id < 0) { + event =3D sde_props[index].event_id =3D 0x40000000 | index; + sde_props[index].interrupt =3D intid; + sde_props[index].is_shared =3D is_shared; + sde_props[index].is_critical =3D is_critical; + s->irq_map[intid] =3D 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 *pr= op) +{ + int32_t ret =3D SDEI_SUCCESS; + if (atomic_read(&prop->refcount) > 0) { + ret =3D SDEI_DENIED; + goto unlock_return; + } + + s->irq_map[prop->interrupt] =3D SDEI_INVALID_EVENT_ID; + prop->event_id =3D SDEI_INVALID_EVENT_ID; + prop->interrupt =3D SDEI_INVALID_INTERRUPT; + +unlock_return: + qemu_mutex_unlock(&prop->lock); + qemu_mutex_unlock(&s->sdei_interrupt_bind_lock); + return ret; +} + +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 =3D 0; + + prop =3D get_sde_prop(s, event); + if (!prop) { + return SDEI_INVALID_PARAMETERS; + } + + sde =3D get_sde_no_check(s, event, cs); + if (sde->event_id =3D=3D SDEI_INVALID_EVENT_ID) { + put_sde(sde, cs); + put_sde_prop(prop); + return SDEI_DENIED; + } + + if (sde->running && !force) { + sde->unregister_pending =3D true; + ret =3D SDEI_PENDING; + } else { + atomic_dec(&prop->refcount); + sde->event_id =3D SDEI_INVALID_EVENT_ID; + sde->enabled =3D false; + sde->running =3D false; + sde->pending =3D false; + sde->unregister_pending =3D 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 =3D SDEI_SUCCESS; + int i; + + for (i =3D 0; i < PRIVATE_SLOT_COUNT; i++) { + int64_t ret1; + ret1 =3D unregister_single_sde(s, i, cs, force); + /* Ignore other return values in reset interface */ + if (ret1 =3D=3D SDEI_PENDING) { + ret =3D 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 =3D PRIVATE_SLOT_COUNT; + int64_t ret =3D SDEI_SUCCESS; + + for (i =3D start_event; i < PRIVATE_SLOT_COUNT + SHARED_SLOT_COUNT; i+= +) { + int64_t ret1 =3D unregister_single_sde(s, i, cs, force); + /* Ignore other return values in reset interface */ + if (ret1 =3D=3D SDEI_PENDING) { + ret =3D SDEI_DENIED; + } + } + if (ret) { + return ret; + } + + for (i =3D 0; i < PRIVATE_SLOT_COUNT + SHARED_SLOT_COUNT; i++) { + qemu_mutex_lock(&s->sdei_interrupt_bind_lock); + prop =3D get_sde_prop(s, i); + if (!prop || prop->interrupt =3D=3D SDEI_INVALID_INTERRUPT) { + if (prop) { + put_sde_prop(prop); + } + qemu_mutex_unlock(&s->sdei_interrupt_bind_lock); + continue; + } + ret |=3D sdei_free_event_num_locked(s, prop); + } + + return ret ? SDEI_DENIED : SDEI_SUCCESS; +} + + +static int64_t sdei_event_register(QemuSDEState *s, CPUState *cs, + struct kvm_run *run) +{ + QemuSDE *sde; + QemuSDEProp *prop; + CPUState *target =3D cs; + uint64_t *args =3D (uint64_t *)run->hypercall.args; + int32_t event =3D args[1]; + uint64_t rm_mode =3D SDEI_EVENT_REGISTER_RM_PE; + + prop =3D get_sde_prop(s, event); + if (!prop) { + return SDEI_INVALID_PARAMETERS; + } + + sde =3D get_sde_no_check(s, event, cs); + if (sde->event_id !=3D SDEI_INVALID_EVENT_ID) { + put_sde(sde, cs); + put_sde_prop(prop); + return SDEI_DENIED; + } + + if (prop->is_shared) { + rm_mode =3D args[4] & 1ULL; + if (rm_mode =3D=3D SDEI_EVENT_REGISTER_RM_PE) { + target =3D arm_get_cpu_by_id(args[5]); + if (!target) { + put_sde_prop(prop); + return SDEI_INVALID_PARAMETERS; + } + } + } + + sde->target_cpu =3D target; + sde->ep_address =3D args[2]; + sde->ep_argument =3D args[3]; + sde->prop =3D prop; + sde->routing_mode =3D rm_mode; + sde->event_id =3D 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 =3D (uint64_t *)(run->hypercall.args); + int32_t event =3D args[1]; + + if (!is_valid_event_number(event)) { + return SDEI_INVALID_PARAMETERS; + } + sde =3D get_sde_no_check(s, event, cs); + if (sde->event_id =3D=3D SDEI_INVALID_EVENT_ID) { + put_sde(sde, cs); + return SDEI_INVALID_PARAMETERS; + } + + sde->enabled =3D true; + return dispatch_single(s, sde, cs); +} + +static int64_t sdei_event_disable(QemuSDEState *s, CPUState *cs, + struct kvm_run *run) +{ + QemuSDE *sde; + uint64_t *args =3D (uint64_t *)run->hypercall.args; + int32_t event =3D args[1]; + + if (!is_valid_event_number(event)) { + return SDEI_INVALID_PARAMETERS; + } + sde =3D get_sde_no_check(s, event, cs); + if (sde->event_id =3D=3D SDEI_INVALID_EVENT_ID) { + put_sde(sde, cs); + return SDEI_INVALID_PARAMETERS; + } + + sde->enabled =3D 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 =3D get_sde_cpu(s, cs); + uint64_t *args =3D (uint64_t *)(run->hypercall.args); + uint32_t param_id =3D args[1]; + int critical; + QemuSDECpuCtx *ctx; + + if (param_id >=3D SDEI_PARAM_MAX) { + return SDEI_INVALID_PARAMETERS; + } + + if (sde_cpu->critical_running_event >=3D 0) { + critical =3D 1; + } else if (sde_cpu->normal_running_event >=3D 0) { + critical =3D 0; + } else { + return SDEI_DENIED; + } + + ctx =3D &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 =3D get_sde_cpu(s, cs); + int32_t event; + uint64_t *args =3D (uint64_t *)(run->hypercall.args); + bool is_critical; + + event =3D get_running_sde(s, cs); + if (event < 0) { + return SDEI_DENIED; + } + + assert(is_valid_event_number(event)); + sde =3D get_sde_no_check(s, event, cs); + assert(sde->event_id !=3D SDEI_INVALID_EVENT_ID); + + sde->running =3D false; + is_critical =3D sde->prop->is_critical; + if (sde->unregister_pending) { + atomic_dec(&sde->prop->refcount); + sde->event_id =3D SDEI_INVALID_EVENT_ID; + sde->unregister_pending =3D 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 >=3D 0) { + cpu->critical_running_event =3D SDEI_INVALID_EVENT_ID; + } else { + cpu->normal_running_event =3D 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 *c= s, + struct kvm_run *run) +{ + QemuSDE *sde; + QemuSDECpu *cpu =3D get_sde_cpu(s, cs); + int32_t event; + uint64_t *args =3D (uint64_t *)(run->hypercall.args); + bool is_critical; + uint64_t resume_addr =3D args[1]; + + event =3D get_running_sde(s, cs); + if (event < 0) { + return SDEI_DENIED; + } + + assert(is_valid_event_number(event)); + sde =3D get_sde_no_check(s, event, cs); + assert(sde->event_id !=3D SDEI_INVALID_EVENT_ID); + + sde->running =3D false; + is_critical =3D sde->prop->is_critical; + + if (sde->unregister_pending) { + atomic_dec(&sde->prop->refcount); + sde->event_id =3D SDEI_INVALID_EVENT_ID; + sde->unregister_pending =3D 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 >=3D 0) { + cpu->critical_running_event =3D SDEI_INVALID_EVENT_ID; + } else { + cpu->normal_running_event =3D 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 =3D (uint64_t *)(run->hypercall.args); + int32_t event =3D 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 =3D (uint64_t *)(run->hypercall.args); + int32_t event =3D args[1]; + int64_t status =3D 0; + + if (!is_valid_event(s, event)) { + return SDEI_INVALID_PARAMETERS; + } + + sde =3D get_sde_no_check(s, event, cs); + if (sde->event_id =3D=3D SDEI_INVALID_EVENT_ID) { + put_sde(sde, cs); + return status; + } + + status |=3D SDEI_EVENT_STATUS_REGISTERED; + if (sde->enabled) { + status |=3D SDEI_EVENT_STATUS_ENABLED; + } + if (sde->running) { + status |=3D 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 =3D (uint64_t *)(run->hypercall.args); + int32_t event =3D args[1]; + uint32_t info =3D args[2]; + int64_t ret; + + if (info > SDEI_EVENT_INFO_EV_ROUTING_AFF) { + return SDEI_INVALID_PARAMETERS; + } + + prop =3D get_sde_prop(s, event); + if (!prop) { + return SDEI_INVALID_PARAMETERS; + } + + switch (info) { + case SDEI_EVENT_INFO_EV_TYPE: + ret =3D prop->is_shared; + break; + case SDEI_EVENT_INFO_EV_SIGNALED: + ret =3D (event =3D=3D SDEI_STD_EVT_SOFTWARE_SIGNAL) ? 1 : 0; + break; + case SDEI_EVENT_INFO_EV_PRIORITY: + ret =3D prop->is_critical; + break; + case SDEI_EVENT_INFO_EV_ROUTING_MODE: + case SDEI_EVENT_INFO_EV_ROUTING_AFF: + ret =3D SDEI_INVALID_PARAMETERS; + if (!prop->is_shared) { + break; + } + sde =3D get_sde_no_check(s, event, cs); + if (sde->event_id =3D=3D SDEI_INVALID_EVENT_ID) { + put_sde(sde, cs); + ret =3D SDEI_DENIED; + break; + } + if (info =3D=3D SDEI_EVENT_INFO_EV_ROUTING_MODE) { + ret =3D sde->routing_mode; + } else if (sde->routing_mode =3D=3D SDEI_EVENT_REGISTER_RM_PE) { + ret =3D ARM_CPU(sde->target_cpu)->mp_affinity; + } + put_sde(sde, cs); + break; + default: + ret =3D 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 =3D cs; + uint64_t *args =3D (uint64_t *)run->hypercall.args; + int32_t event =3D args[1]; + uint64_t mode =3D args[2]; + uint64_t affinity =3D args[3]; + + if (mode & ~1ULL) { + return SDEI_INVALID_PARAMETERS; + } + if (mode =3D=3D SDEI_EVENT_REGISTER_RM_PE) { + target =3D 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 =3D get_sde_no_check(s, event, cs); + if (sde->event_id =3D=3D 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 =3D target; + sde->routing_mode =3D 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 =3D get_sde_cpu(s, cs); + if (sde_cpu->masked) { + return 0; + } + sde_cpu->masked =3D true; + return 1; +} + +static int64_t sdei_event_pe_unmask(QemuSDEState *s, CPUState *cs, + struct kvm_run *run) +{ + QemuSDECpu *sde_cpu; + + sde_cpu =3D get_sde_cpu(s, cs); + sde_cpu->masked =3D 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 =3D (uint64_t *)(run->hypercall.args); + uint32_t intid =3D args[1]; + + if (intid < GIC_NR_SGIS || intid >=3D GIC_MAXIRQ) { + return SDEI_INVALID_PARAMETERS; + } + return sdei_alloc_event_num(s, false, intid >=3D 32, intid); +} + +static int64_t sdei_event_interrupt_release(QemuSDEState *s, CPUState *cs, + struct kvm_run *run) +{ + QemuSDEProp *prop; + uint64_t *args =3D (uint64_t *)(run->hypercall.args); + int32_t event =3D args[1]; + + qemu_mutex_lock(&s->sdei_interrupt_bind_lock); + prop =3D get_sde_prop(s, event); + if (!prop) { + qemu_mutex_unlock(&s->sdei_interrupt_bind_lock); + return SDEI_INVALID_PARAMETERS; + } + + return sdei_free_event_num_locked(s, prop); +} + +static int64_t sdei_event_signal(QemuSDEState *s, CPUState *cs, + struct kvm_run *run) +{ + QemuSDE *sde; + CPUState *target_cpu; + uint64_t *args =3D (uint64_t *)(run->hypercall.args); + int32_t event =3D args[1]; + + if (event !=3D SDEI_STD_EVT_SOFTWARE_SIGNAL) { + return SDEI_INVALID_PARAMETERS; + } + + target_cpu =3D arm_get_cpu_by_id(args[2]); + if (!target_cpu) { + return SDEI_INVALID_PARAMETERS; + } + + sde =3D get_sde_no_check(s, event, target_cpu); + if (sde->event_id =3D=3D SDEI_INVALID_EVENT_ID) { + put_sde(sde, cs); + return SDEI_INVALID_PARAMETERS; + } + + sde->pending =3D true; + return dispatch_single(s, sde, target_cpu); +} + +static int64_t sdei_features(QemuSDEState *s, CPUState *cs, struct kvm_run= *run) +{ + uint64_t *args =3D (uint64_t *)(run->hypercall.args); + uint32_t feature =3D args[1]; + + switch (feature) { + case SDEI_FEATURE_BIND_SLOTS: + return ((SHARED_SLOT_COUNT - PLAT_SHARED_SLOT_COUNT) << 16) | + (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[] =3D { + 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 =3D run->hypercall.args[0]; + + if (!sde_state) { + run->hypercall.args[0] =3D 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] =3D SDEI_INVALID_PARAMETERS; + return; + } + + func_id -=3D SDEI_1_0_FN_BASE; + if (func_id < ARRAY_SIZE(sdei_functions) && sdei_functions[func_id]) { + run->hypercall.args[0] =3D sdei_functions[func_id](sde_state, cs, = run); + } else { + run->hypercall.args[0] =3D SDEI_NOT_SUPPORTED; + } +} + static void qemu_shared_sde_init(QemuSDEState *s) { int i; diff --git a/target/arm/sdei.h b/target/arm/sdei.h new file mode 100644 index 0000000..a69a0e4 --- /dev/null +++ b/target/arm/sdei.h @@ -0,0 +1,34 @@ +/* + * ARM SDEI emulation external interfaces + * + * Copyright (c) 2019 HUAWEI TECHNOLOGIES CO., LTD. + * + * Authors: + * Heyi Guo + * Jingyi Wang + * + * 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 f= or + * more details. + * + * You should have received a copy of the GNU General Public License along= with + * this program. If not, see . + */ + +#ifndef QEMU_SDEI_H +#define QEMU_SDEI_H + +#include +#include +#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 --=20 1.8.3.1 From nobody Tue May 7 06:18:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1569341971; cv=none; d=zoho.com; s=zohoarc; b=nne+51VXEXsZce1zvvnenxifhXg+3DgG5yelkRXen017UOwMzX9FgBtrE7iVzrWTBDZQ79LfSrWqhoTzj/YUtmfWCWKbCmA6c0XPijtlWvI+GIxn5LMfnjQOILgnm9nr2V+Hf8ozJT6dzQ1lCCH2joUUuJvDQCP6Fi3nyQoo/gs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1569341971; h=Content-Type:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=EuKJPjrDf7NX+a5XvFCUrlPRclj+CHBxbN+CPsy2qwo=; b=QDFlpdd0FeFw4t6jCQEmyvhHZeBsADVnhzraZcGvNnpT+b7j/MNkmxrCurq1+I/eVNKuW28eH1FCs1/BwxWr0YfrK7VmRgb6x7CDvXc8tHWqmHfCbH0A/Nfpr9HAfjMfbV3FEXaPbIuewAsQRh8CU/pGlqTSey/nfif/2c1cMME= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1569341971665183.04006863356562; Tue, 24 Sep 2019 09:19:31 -0700 (PDT) Received: from localhost ([::1]:47902 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iCnX7-0005O3-3n for importer@patchew.org; Tue, 24 Sep 2019 12:19:21 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48295) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iCmfA-0001LN-Pd for qemu-devel@nongnu.org; Tue, 24 Sep 2019 11:23:38 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iCmf9-0006lk-2o for qemu-devel@nongnu.org; Tue, 24 Sep 2019 11:23:36 -0400 Received: from szxga07-in.huawei.com ([45.249.212.35]:46676 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iCmf4-0006hO-ID; Tue, 24 Sep 2019 11:23:30 -0400 Received: from DGGEMS409-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id 58A3B3FBB55EA3E76511; Tue, 24 Sep 2019 23:23:27 +0800 (CST) Received: from linux-Bxxcye.huawei.com (10.175.104.222) by DGGEMS409-HUB.china.huawei.com (10.3.19.209) with Microsoft SMTP Server id 14.3.439.0; Tue, 24 Sep 2019 23:23:16 +0800 From: Heyi Guo To: , , , Subject: [RFC PATCH 04/12] arm/sdei: add system reset callback Date: Tue, 24 Sep 2019 23:21:43 +0800 Message-ID: <1569338511-3572-5-git-send-email-guoheyi@huawei.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1569338511-3572-1-git-send-email-guoheyi@huawei.com> References: <1569338511-3572-1-git-send-email-guoheyi@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.104.222] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 45.249.212.35 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Mark Rutland , Peter Maydell , James Morse , Marc Zyngier , Jingyi Wang , Heyi Guo , wanghaibin.wang@huawei.com, Dave Martin Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 Signed-off-by: Jingyi Wang Cc: Peter Maydell Cc: Dave Martin Cc: Marc Zyngier Cc: Mark Rutland Cc: James Morse --- target/arm/sdei.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/target/arm/sdei.c b/target/arm/sdei.c index b40fa36..f9a1208 100644 --- a/target/arm/sdei.c +++ b/target/arm/sdei.c @@ -1083,6 +1083,26 @@ static void qemu_sde_init(QemuSDEState *s) qemu_private_sde_init(s); } =20 +static void qemu_sde_reset(void *opaque) +{ + int64_t ret; + CPUState *cs; + QemuSDEState *s =3D opaque; + + CPU_FOREACH(cs) { + QemuSDECpu *sde_cpu =3D get_sde_cpu(s, cs); + sdei_private_reset_common(s, cs, true); + sde_cpu->masked =3D true; + sde_cpu->critical_running_event =3D SDEI_INVALID_EVENT_ID; + sde_cpu->normal_running_event =3D SDEI_INVALID_EVENT_ID; + } + + ret =3D sdei_shared_reset_common(s, first_cpu, true); + if (ret) { + error_report("SDEI system reset failed: 0x%lx", ret); + } +} + static int qemu_sdei_pre_save(void *opaque) { QemuSDEState *s =3D opaque; @@ -1235,6 +1255,7 @@ static void sdei_initfn(Object *obj) sde_state =3D s; =20 qemu_sde_init(s); + qemu_register_reset(qemu_sde_reset, s); } =20 static void qemu_sde_class_init(ObjectClass *klass, void *data) --=20 1.8.3.1 From nobody Tue May 7 06:18:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1569339697; cv=none; d=zoho.com; s=zohoarc; b=KXM+rmLU4fmD0uLNm0ZdPxuqzzIS3Zgz6/wpoFRKcO1DAqqlRPACR2baLTIXQVLcF7Amztuqk+kdVScKM45DAnDafChRsg6b/uaHtZo5F9UeBbgjjXbG7Cp3AD0ssCfLck/PqM9LpuzEX1dWSITosQl562gD+ToXbW/3cm2lIz8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1569339697; h=Content-Type:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=oBwbCPZ7ugU3LWovtaW5F6O/qYDn5839tEDOf4EdNXo=; b=mk9JrSK1vDD2K+ze341TFBaXtT7wPxAHA6UXt+kusUlXMePv2nGYONvZiKgdXMNkEfWyXKwd6E2zdk5CDH7UhETpNOsbneu2mQYAstcKkqB7+kSsigRqYC4XPZIFEblFZwMcfEYCuBBsDnxiuTstGl2WW/a1yUcB0lzUWZwHfpQ= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 156933969702891.76646465805561; Tue, 24 Sep 2019 08:41:37 -0700 (PDT) Received: from localhost ([::1]:47312 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iCmwT-0001GH-Q5 for importer@patchew.org; Tue, 24 Sep 2019 11:41:29 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48379) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iCmfD-0001Q0-Tw for qemu-devel@nongnu.org; Tue, 24 Sep 2019 11:23:41 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iCmfB-0006nk-Va for qemu-devel@nongnu.org; Tue, 24 Sep 2019 11:23:39 -0400 Received: from szxga07-in.huawei.com ([45.249.212.35]:46724 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iCmf4-0006hR-LV; Tue, 24 Sep 2019 11:23:31 -0400 Received: from DGGEMS409-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id 5EA36BE9A1306E7B3A53; Tue, 24 Sep 2019 23:23:27 +0800 (CST) Received: from linux-Bxxcye.huawei.com (10.175.104.222) by DGGEMS409-HUB.china.huawei.com (10.3.19.209) with Microsoft SMTP Server id 14.3.439.0; Tue, 24 Sep 2019 23:23:17 +0800 From: Heyi Guo To: , , , Subject: [RFC PATCH 05/12] arm/sdei: add support to trigger event by GIC interrupt ID Date: Tue, 24 Sep 2019 23:21:44 +0800 Message-ID: <1569338511-3572-6-git-send-email-guoheyi@huawei.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1569338511-3572-1-git-send-email-guoheyi@huawei.com> References: <1569338511-3572-1-git-send-email-guoheyi@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.104.222] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 45.249.212.35 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Mark Rutland , Peter Maydell , Marc Zyngier , James Morse , Heyi Guo , wanghaibin.wang@huawei.com, Dave Martin Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add an external interface to trigger an SDEI event bound to an interrupt by providing GIC interrupt ID. Signed-off-by: Heyi Guo Cc: Peter Maydell Cc: Dave Martin Cc: Marc Zyngier Cc: Mark Rutland Cc: James Morse --- target/arm/sdei.c | 38 ++++++++++++++++++++++++++++++++++++++ target/arm/sdei.h | 7 +++++++ 2 files changed, 45 insertions(+) diff --git a/target/arm/sdei.c b/target/arm/sdei.c index f9a1208..088ed76 100644 --- a/target/arm/sdei.c +++ b/target/arm/sdei.c @@ -453,6 +453,29 @@ static int64_t sdei_version(QemuSDEState *s, CPUState = *cs, struct kvm_run *run) (0ULL << SDEI_VERSION_MINOR_SHIFT); } =20 +static bool inject_event(QemuSDEState *s, CPUState *cs, + int32_t event, int irq) +{ + QemuSDE *sde; + + if (event < 0) { + return false; + } + sde =3D get_sde_no_check(s, event, cs); + if (sde->event_id =3D=3D SDEI_INVALID_EVENT_ID) { + put_sde(sde, cs); + return false; + } + if (irq > 0 && sde->prop->interrupt !=3D irq) { + /* Someone unbinds the interrupt! */ + put_sde(sde, cs); + return false; + } + sde->pending =3D true; + dispatch_single(s, sde, cs); + return true; +} + static int64_t unregister_single_sde(QemuSDEState *s, int32_t event, CPUState *cs, bool force) { @@ -1033,6 +1056,21 @@ void sdei_handle_request(CPUState *cs, struct kvm_ru= n *run) } } =20 +bool trigger_sdei_by_irq(int cpu, int irq) +{ + QemuSDEState *s =3D sde_state; + + if (!s || irq >=3D ARRAY_SIZE(s->irq_map)) { + return false; + } + + if (s->irq_map[irq] =3D=3D SDEI_INVALID_EVENT_ID) { + return false; + } + + return inject_event(s, arm_get_cpu_by_id(cpu), s->irq_map[irq], irq); +} + static void qemu_shared_sde_init(QemuSDEState *s) { int i; diff --git a/target/arm/sdei.h b/target/arm/sdei.h index a69a0e4..a61e788 100644 --- a/target/arm/sdei.h +++ b/target/arm/sdei.h @@ -31,4 +31,11 @@ =20 void sdei_handle_request(CPUState *cs, struct kvm_run *run); =20 +/* + * 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 --=20 1.8.3.1 From nobody Tue May 7 06:18:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1569341676; cv=none; d=zoho.com; s=zohoarc; b=nYvo5liI/iKSpwfwR/xYwlfzP416r39DZgMYC5/25EOQw8okGy6W5mlP5nVOYuQobK/ektol29vojaIAZsIWIASyVWfbSKLBJrCB+YgV+Q7qdGkbB8g/mEwh25+8cm6d+wo+pCIDASc5sIj9rkYLusBkyxKQs/RQFvhhSiZ74uk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1569341676; h=Content-Type:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=ZERZMu1aeDS2JEJ3T4ClJnCqxCkMDJe/TDC0dLTKL9M=; b=IXUcaDXKLmTqFN+8nlsM+GrRE0AvoHO1r6tZeMqAOGDMenLJXvu29+tatxorbz5I3IUYR6Fkii0oqLeUwJ+lulF5KwC4zrwk/d7xVoUTxu8BSXhXFl0RHBnFctqSA0q2X/uQqAFT1o17dUbZ8ll2pfvYw54jOT2Qv3GHgh559p8= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1569341676915557.278883168814; Tue, 24 Sep 2019 09:14:36 -0700 (PDT) Received: from localhost ([::1]:47850 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iCnSS-0001Wj-6i for importer@patchew.org; Tue, 24 Sep 2019 12:14:32 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48309) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iCmfB-0001Li-4Q for qemu-devel@nongnu.org; Tue, 24 Sep 2019 11:23:38 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iCmf9-0006lw-DV for qemu-devel@nongnu.org; Tue, 24 Sep 2019 11:23:36 -0400 Received: from szxga07-in.huawei.com ([45.249.212.35]:46632 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iCmf4-0006hL-N5; Tue, 24 Sep 2019 11:23:31 -0400 Received: from DGGEMS409-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id 51FF67C2680FDC283024; Tue, 24 Sep 2019 23:23:27 +0800 (CST) Received: from linux-Bxxcye.huawei.com (10.175.104.222) by DGGEMS409-HUB.china.huawei.com (10.3.19.209) with Microsoft SMTP Server id 14.3.439.0; Tue, 24 Sep 2019 23:23:18 +0800 From: Heyi Guo To: , , , Subject: [RFC PATCH 06/12] core/irq: add qemu_irq_remove_intercept interface Date: Tue, 24 Sep 2019 23:21:45 +0800 Message-ID: <1569338511-3572-7-git-send-email-guoheyi@huawei.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1569338511-3572-1-git-send-email-guoheyi@huawei.com> References: <1569338511-3572-1-git-send-email-guoheyi@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.104.222] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 45.249.212.35 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Mark Rutland , Peter Maydell , Marc Zyngier , James Morse , Heyi Guo , wanghaibin.wang@huawei.com, Dave Martin Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 Cc: Peter Maydell Cc: Dave Martin Cc: Marc Zyngier Cc: Mark Rutland Cc: James Morse --- 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 7cc0295..114bce6 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) } } =20 +void qemu_irq_remove_intercept(qemu_irq *gpio_in, int n) +{ + int i; + qemu_irq *old_irqs =3D gpio_in[0]->opaque; + for (i =3D 0; i < n; i++) { + gpio_in[i]->handler =3D old_irqs[i]->handler; + gpio_in[i]->opaque =3D old_irqs[i]->opaque; + } + qemu_free_irqs(old_irqs, n); +} + static const TypeInfo irq_type_info =3D { .name =3D TYPE_IRQ, .parent =3D TYPE_OBJECT, diff --git a/include/hw/irq.h b/include/hw/irq.h index fe527f6..1af1db9 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); =20 -/* 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, in= t n); =20 +/* Restore the irq handler intercepted by qemu_irq_intercept_in() */ +void qemu_irq_remove_intercept(qemu_irq *gpio_in, int n); + #endif --=20 1.8.3.1 From nobody Tue May 7 06:18:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1569342171; cv=none; d=zoho.com; s=zohoarc; b=bB/VVraXkVlTlI1rjbXnCHHPYLlxPl1RYefo3uUNB1h2118fg6tWMzmI5t4DUH0NFgZqNZmG0RZrDxX+zRnzxnb6XKXHftO+qH7eG0fzDgb4P9s0C9KJLHLZ4KTdDKp4oK+LM8Y3Vl5cDuws4K75ldRLapZReDbKT5WKPpj5i1g= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1569342171; h=Content-Type:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=ag4JIzr76RH4rV+kgbKMh+Ar4uo0egEvaYaik4HpEMA=; b=T7zlIsHUXZIHFPDIC75yLZ9Taoe+2O2FAN4KbxvYmwYjj4a2GEypNj0LGr4HPm1aslEOsNnCdI9RdwKtFY/X6o/3F7HHF/zJbGbhn9ttmFAJmRrwN0k+ViYa7mQTdzb7IqzM+R819s7MiNT5mbzKZjVm4CaeTiZFkp3kIXsmAJg= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1569342170869838.9456187240734; Tue, 24 Sep 2019 09:22:50 -0700 (PDT) Received: from localhost ([::1]:47954 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iCnaT-0001Oz-Da for importer@patchew.org; Tue, 24 Sep 2019 12:22:49 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48383) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iCmfE-0001QR-AF for qemu-devel@nongnu.org; Tue, 24 Sep 2019 11:23:42 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iCmfB-0006nJ-EI for qemu-devel@nongnu.org; Tue, 24 Sep 2019 11:23:40 -0400 Received: from szxga07-in.huawei.com ([45.249.212.35]:46766 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iCmf4-0006hV-QG; Tue, 24 Sep 2019 11:23:31 -0400 Received: from DGGEMS409-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id 652C98126B7940A2D8D7; Tue, 24 Sep 2019 23:23:27 +0800 (CST) Received: from linux-Bxxcye.huawei.com (10.175.104.222) by DGGEMS409-HUB.china.huawei.com (10.3.19.209) with Microsoft SMTP Server id 14.3.439.0; Tue, 24 Sep 2019 23:23:18 +0800 From: Heyi Guo To: , , , Subject: [RFC PATCH 07/12] arm/sdei: override qemu_irq handler when binding interrupt Date: Tue, 24 Sep 2019 23:21:46 +0800 Message-ID: <1569338511-3572-8-git-send-email-guoheyi@huawei.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1569338511-3572-1-git-send-email-guoheyi@huawei.com> References: <1569338511-3572-1-git-send-email-guoheyi@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.104.222] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 45.249.212.35 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Mark Rutland , Peter Maydell , Marc Zyngier , James Morse , Heyi Guo , wanghaibin.wang@huawei.com, Dave Martin Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 Cc: Peter Maydell Cc: Dave Martin Cc: Marc Zyngier Cc: Mark Rutland Cc: James Morse --- target/arm/sdei.c | 137 ++++++++++++++++++++++++++++++++++++++++++++++= ++-- target/arm/sdei_int.h | 3 ++ 2 files changed, 137 insertions(+), 3 deletions(-) diff --git a/target/arm/sdei.c b/target/arm/sdei.c index 088ed76..9ceb131 100644 --- a/target/arm/sdei.c +++ b/target/arm/sdei.c @@ -85,6 +85,24 @@ static void qemu_sde_cpu_init(QemuSDEState *s) } } =20 +static int gic_int_to_irq(int num_irq, int intid, int cpu) +{ + if (intid >=3D 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 -=3D num_irq - GIC_INTERNAL; + *cpu =3D irq / GIC_INTERNAL; + return irq % GIC_INTERNAL; +} + static inline QemuSDECpu *get_sde_cpu(QemuSDEState *s, CPUState *cs) { assert(cs->cpu_index < s->sdei_max_cpus); @@ -381,6 +399,76 @@ static void dispatch_cpu(QemuSDEState *s, CPUState *cs= , bool is_critical) } } =20 +static void qemu_sdei_irq_handler(void *opaque, int irq, int level) +{ + int cpu =3D 0; + irq =3D 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 int= id) +{ + qemu_irq irq; + QemuSDE *sde; + CPUState *cs; + int cpu; + + /* SPI */ + if (intid >=3D GIC_INTERNAL) { + cs =3D arm_get_cpu_by_id(0); + irq =3D 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 =3D get_sde_no_check(s, event, cs); + sde->irq =3D irq; + put_sde(sde, cs); + return; + } + /* PPI */ + for (cpu =3D 0; cpu < s->sdei_max_cpus; cpu++) { + cs =3D arm_get_cpu_by_id(cpu); + irq =3D qdev_get_gpio_in(s->gic_dev, + gic_int_to_irq(s->num_irq, intid, cpu)); + if (irq) { + qemu_irq_intercept_in(&irq, qemu_sdei_irq_handler, 1); + } + sde =3D get_sde_no_check(s, event, cs); + sde->irq =3D irq; + put_sde(sde, cs); + } +} + +static void restore_qemu_irq(QemuSDEState *s, int32_t event, uint32_t inti= d) +{ + QemuSDE *sde; + CPUState *cs; + int cpu; + + /* SPI */ + if (intid >=3D GIC_INTERNAL) { + cs =3D arm_get_cpu_by_id(0); + sde =3D get_sde_no_check(s, event, cs); + if (sde->irq) { + qemu_irq_remove_intercept(&sde->irq, 1); + sde->irq =3D NULL; + } + put_sde(sde, cs); + return; + } + /* PPI */ + for (cpu =3D 0; cpu < s->sdei_max_cpus; cpu++) { + cs =3D arm_get_cpu_by_id(cpu); + sde =3D get_sde_no_check(s, event, cs); + if (sde->irq) { + qemu_irq_remove_intercept(&sde->irq, 1); + sde->irq =3D NULL; + } + put_sde(sde, cs); + } +} + static int32_t sdei_alloc_event_num(QemuSDEState *s, bool is_critical, bool is_shared, int intid) { @@ -414,6 +502,7 @@ static int32_t sdei_alloc_event_num(QemuSDEState *s, bo= ol is_critical, sde_props[index].interrupt =3D intid; sde_props[index].is_shared =3D is_shared; sde_props[index].is_critical =3D is_critical; + override_qemu_irq(s, event, intid); s->irq_map[intid] =3D event; qemu_mutex_unlock(&sde_props[index].lock); qemu_mutex_unlock(&s->sdei_interrupt_bind_lock); @@ -433,6 +522,7 @@ static int32_t sdei_free_event_num_locked(QemuSDEState = *s, QemuSDEProp *prop) goto unlock_return; } =20 + restore_qemu_irq(s, prop->event_id, prop->interrupt); s->irq_map[prop->interrupt] =3D SDEI_INVALID_EVENT_ID; prop->event_id =3D SDEI_INVALID_EVENT_ID; prop->interrupt =3D SDEI_INVALID_INTERRUPT; @@ -929,13 +1019,33 @@ static int64_t sdei_event_pe_unmask(QemuSDEState *s,= CPUState *cs, return SDEI_SUCCESS; } =20 +static int dev_walkerfn(DeviceState *dev, void *opaque) +{ + QemuSDEState *s =3D opaque; + + if (object_dynamic_cast(OBJECT(dev), TYPE_ARM_GICV3_COMMON)) { + GICv3State *gic =3D ARM_GICV3_COMMON(dev); + s->num_irq =3D gic->num_irq; + s->gic_dev =3D dev; + return -1; + } + + if (object_dynamic_cast(OBJECT(dev), TYPE_ARM_GIC_COMMON)) { + GICState *gic =3D ARM_GIC_COMMON(dev); + s->num_irq =3D gic->num_irq; + s->gic_dev =3D dev; + return -1; + } + return 0; +} + static int64_t sdei_event_interrupt_bind(QemuSDEState *s, CPUState *cs, struct kvm_run *run) { uint64_t *args =3D (uint64_t *)(run->hypercall.args); uint32_t intid =3D args[1]; =20 - if (intid < GIC_NR_SGIS || intid >=3D GIC_MAXIRQ) { + if (intid < GIC_NR_SGIS || intid >=3D s->num_irq) { return SDEI_INVALID_PARAMETERS; } return sdei_alloc_event_num(s, false, intid >=3D 32, intid); @@ -1042,6 +1152,17 @@ void sdei_handle_request(CPUState *cs, struct kvm_ru= n *run) return; } =20 + 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] =3D 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] =3D SDEI_INVALID_PARAMETERS; @@ -1198,9 +1319,19 @@ static int qemu_sdei_post_load(void *opaque, int ver= sion_id) } } =20 + /* 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 =3D 0; i < PRIVATE_SLOT_COUNT + SHARED_SLOT_COUNT; i++) { - if (sde_props[i].interrupt !=3D SDEI_INVALID_INTERRUPT) { - s->irq_map[sde_props[i].interrupt] =3D sde_props[i].event_id; + int intid =3D sde_props[i].interrupt; + if (intid !=3D SDEI_INVALID_INTERRUPT) { + s->irq_map[intid] =3D sde_props[i].event_id; + override_qemu_irq(s, sde_props[i].event_id, intid); } } =20 diff --git a/target/arm/sdei_int.h b/target/arm/sdei_int.h index 7f69507..3930591 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; @@ -95,9 +96,11 @@ typedef struct QemuSDECpu { =20 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; --=20 1.8.3.1 From nobody Tue May 7 06:18:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1569342371; cv=none; d=zoho.com; s=zohoarc; b=IIkDtghBw6yxvAOHyrymd39SRQPUkNA5j8CeyiSPPtpmrVEInubihBXCtH3q087HgovXfSP5vATwLAEiT1HqIH4HV402vp9akjiRiybs3a8LFxxaGOIGvs0xbH19BisethKzQDfGN32HGTaMJX5PxDOia4YPPyv12ArQufdwISU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1569342371; h=Content-Type:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=yFKjSRgiciDJ763BqbZ9Jg3DaQ6xMuxeqseqISVZluQ=; b=QqJle9f8YNwgSRsCVwjH+JBT5wkh8dUcSJDvAuJaKjyk548O2W6bkXVoWF3RAMwjSR4sLkbFvzD3kVPbnNMZXAKKbyE/rJaRKx02lKPRZeNbb0gIUQSb3jlgTW8ULuliKhOb51ulMr4L2R7Owrc+xQM1Aj6iCX3rhdJne346Z/Q= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1569342371610672.6868870471649; Tue, 24 Sep 2019 09:26:11 -0700 (PDT) Received: from localhost ([::1]:48012 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iCndh-0005UW-Um for importer@patchew.org; Tue, 24 Sep 2019 12:26:09 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48407) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iCmfF-0001Rg-6z for qemu-devel@nongnu.org; Tue, 24 Sep 2019 11:23:42 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iCmfD-0006oQ-8S for qemu-devel@nongnu.org; Tue, 24 Sep 2019 11:23:40 -0400 Received: from szxga07-in.huawei.com ([45.249.212.35]:46880 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iCmf8-0006jm-7H; Tue, 24 Sep 2019 11:23:34 -0400 Received: from DGGEMS409-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id 72028C8DBC18647CE88C; Tue, 24 Sep 2019 23:23:27 +0800 (CST) Received: from linux-Bxxcye.huawei.com (10.175.104.222) by DGGEMS409-HUB.china.huawei.com (10.3.19.209) with Microsoft SMTP Server id 14.3.439.0; Tue, 24 Sep 2019 23:23:19 +0800 From: Heyi Guo To: , , , Subject: [RFC PATCH 08/12] arm/sdei: add support to register interrupt bind notifier Date: Tue, 24 Sep 2019 23:21:47 +0800 Message-ID: <1569338511-3572-9-git-send-email-guoheyi@huawei.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1569338511-3572-1-git-send-email-guoheyi@huawei.com> References: <1569338511-3572-1-git-send-email-guoheyi@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.104.222] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 45.249.212.35 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Mark Rutland , Peter Maydell , Marc Zyngier , James Morse , Heyi Guo , wanghaibin.wang@huawei.com, Dave Martin Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 Cc: Peter Maydell Cc: Dave Martin Cc: Marc Zyngier Cc: Mark Rutland Cc: James Morse --- target/arm/sdei.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ target/arm/sdei.h | 17 +++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/target/arm/sdei.c b/target/arm/sdei.c index 9ceb131..efdb681 100644 --- a/target/arm/sdei.c +++ b/target/arm/sdei.c @@ -45,6 +45,52 @@ =20 static QemuSDEState *sde_state; =20 +typedef struct QemuSDEIBindNotifyEntry { + QTAILQ_ENTRY(QemuSDEIBindNotifyEntry) entry; + QemuSDEIBindNotify *func; + void *opaque; + int irq; +} QemuSDEIBindNotifyEntry; + +static QTAILQ_HEAD(, QemuSDEIBindNotifyEntry) bind_notifiers =3D + QTAILQ_HEAD_INITIALIZER(bind_notifiers); + +void qemu_register_sdei_bind_notifier(QemuSDEIBindNotify *func, + void *opaque, int irq) +{ + QemuSDEIBindNotifyEntry *be =3D g_new0(QemuSDEIBindNotifyEntry, 1); + + be->func =3D func; + be->opaque =3D opaque; + be->irq =3D 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 =3D=3D func && be->opaque =3D=3D opaque && be->irq = =3D=3D 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 =3D=3D irq) { + be->func(be->opaque, irq, event, bind); + } + } +} + static void qemu_sde_prop_init(QemuSDEState *s) { QemuSDEProp *sde_props =3D s->sde_props_state; @@ -502,6 +548,7 @@ static int32_t sdei_alloc_event_num(QemuSDEState *s, bo= ol is_critical, sde_props[index].interrupt =3D intid; sde_props[index].is_shared =3D is_shared; sde_props[index].is_critical =3D is_critical; + sdei_notify_bind(intid, event, true); override_qemu_irq(s, event, intid); s->irq_map[intid] =3D event; qemu_mutex_unlock(&sde_props[index].lock); @@ -522,6 +569,7 @@ static int32_t sdei_free_event_num_locked(QemuSDEState = *s, QemuSDEProp *prop) goto unlock_return; } =20 + sdei_notify_bind(prop->interrupt, prop->event_id, false); restore_qemu_irq(s, prop->event_id, prop->interrupt); s->irq_map[prop->interrupt] =3D SDEI_INVALID_EVENT_ID; prop->event_id =3D SDEI_INVALID_EVENT_ID; @@ -1331,6 +1379,7 @@ static int qemu_sdei_post_load(void *opaque, int vers= ion_id) int intid =3D sde_props[i].interrupt; if (intid !=3D SDEI_INVALID_INTERRUPT) { s->irq_map[intid] =3D sde_props[i].event_id; + sdei_notify_bind(intid, sde_props[i].event_id, true); override_qemu_irq(s, sde_props[i].event_id, intid); } } diff --git a/target/arm/sdei.h b/target/arm/sdei.h index a61e788..feaaf1a 100644 --- a/target/arm/sdei.h +++ b/target/arm/sdei.h @@ -38,4 +38,21 @@ void sdei_handle_request(CPUState *cs, struct kvm_run *r= un); */ bool trigger_sdei_by_irq(int cpu, int irq); =20 +/* + * Notify callback prototype; the argument "bind" tells whether it is a bi= nd + * 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 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 --=20 1.8.3.1 From nobody Tue May 7 06:18:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1569339469; cv=none; d=zoho.com; s=zohoarc; b=PzyUw/xL93V5ixrbBPWAkSfYdz/R5digLhjCvH2ybmj2lGOhQJik24no0qQiE7FXjXcPespXuTaNu4qnWNSRlCAfdzU+oVEztH/F7wnSsdfSXzwyO9gnDmcwUg0P/BXoVLsfVTStTWCRFaUEKEMebF18FJmhwlSsvSdxss9GLY4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1569339469; h=Content-Type:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=LMemZ/ho25Nyia6mX05qF81h1XJ6AkNPpi5zAW4ZYEM=; b=kv6ViEarGWMTgUf2+qfR8iI8EmtJ9KhtEtX7wsPLRQw8Irh6n9AmDFlVp8CxTdzt2+kSQiTFjtmGkeaLgUZORpM6IWDuUNaCGkms6uSRp43aLhEVAnEyjyVvXSM68KdCfWGKPoeQWQ4If4ZfiEJ16jo2jK/5O+ugdkBRNnmhnj0= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1569339469368412.7366421332472; Tue, 24 Sep 2019 08:37:49 -0700 (PDT) Received: from localhost ([::1]:47248 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iCmsr-0005jL-HT for importer@patchew.org; Tue, 24 Sep 2019 11:37:45 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48381) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iCmfE-0001QJ-6H for qemu-devel@nongnu.org; Tue, 24 Sep 2019 11:23:41 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iCmfC-0006o6-KC for qemu-devel@nongnu.org; Tue, 24 Sep 2019 11:23:39 -0400 Received: from szxga04-in.huawei.com ([45.249.212.190]:2176 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iCmf4-0006hX-Hg; Tue, 24 Sep 2019 11:23:30 -0400 Received: from DGGEMS409-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id 89D0CC4FB6F9F57E2490; Tue, 24 Sep 2019 23:23:27 +0800 (CST) Received: from linux-Bxxcye.huawei.com (10.175.104.222) by DGGEMS409-HUB.china.huawei.com (10.3.19.209) with Microsoft SMTP Server id 14.3.439.0; Tue, 24 Sep 2019 23:23:20 +0800 From: Heyi Guo To: , , , Subject: [RFC PATCH 09/12] linux-headers/kvm.h: add capability to forward hypercall Date: Tue, 24 Sep 2019 23:21:48 +0800 Message-ID: <1569338511-3572-10-git-send-email-guoheyi@huawei.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1569338511-3572-1-git-send-email-guoheyi@huawei.com> References: <1569338511-3572-1-git-send-email-guoheyi@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.104.222] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 45.249.212.190 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Mark Rutland , Peter Maydell , "Michael S. Tsirkin" , Marc Zyngier , Cornelia Huck , James Morse , Paolo Bonzini , Heyi Guo , wanghaibin.wang@huawei.com, Dave Martin Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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. We also use an additional argument to pass exception bit mask, to request KVM to forward all hypercalls except the classes specified in the bit mask. Currently only PSCI can be set as exception, so that we can still keep consistent with the original PSCI processing flow. Signed-off-by: Heyi Guo Cc: Peter Maydell Cc: Dave Martin Cc: Marc Zyngier Cc: Mark Rutland Cc: James Morse Cc: "Michael S. Tsirkin" Cc: Cornelia Huck Cc: Paolo Bonzini --- linux-headers/linux/kvm.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h index 18892d6..20e8a68 100644 --- a/linux-headers/linux/kvm.h +++ b/linux-headers/linux/kvm.h @@ -711,6 +711,8 @@ struct kvm_enable_cap { __u8 pad[64]; }; =20 +#define KVM_CAP_FORWARD_HYPERCALL_EXCL_PSCI (1 << 0) + /* for KVM_PPC_GET_PVINFO */ =20 #define KVM_PPC_PVINFO_FLAGS_EV_IDLE (1<<0) @@ -995,6 +997,7 @@ struct kvm_ppc_resize_hpt { #define KVM_CAP_ARM_SVE 170 #define KVM_CAP_ARM_PTRAUTH_ADDRESS 171 #define KVM_CAP_ARM_PTRAUTH_GENERIC 172 +#define KVM_CAP_FORWARD_HYPERCALL 174 =20 #ifdef KVM_CAP_IRQ_ROUTING =20 --=20 1.8.3.1 From nobody Tue May 7 06:18:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1569339117; cv=none; d=zoho.com; s=zohoarc; b=cbMhCeSzFBnjDoJJAm0A53uCZ4UCMivX1nX5V89dmZovnJm2ykkZ/bE74ruemVfG8APM8/QlMspKktyfbe/pTnBS/HlrMu9BsaAutWhz4FiC3bF5dfybbq7MYn8xYIU8SkNf6oj/+MDEzkqktxOz6Q6Rgowm+6rdajs+jzQ3FWM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1569339117; h=Content-Type:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=HhwV4avSfEAAKmJDdq9oL4uXC97ibt+6uxV01E/qz0w=; b=AHeQcyVedqajcKTd62clEjPBA+FFCg1tJwzQfSFVid4CYRl9qSB3HN+vNUC4v/kqhOfANQEMxWMhj/3dkDC/47MeVcTUPdlW7pnkbzXbFtVfVUSDsz9XCPvFuGi+puXTwcaKTqMNuUjH2MwVGKPLrFmyLF/cZdZsbgCq3GdQU+o= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1569339117673833.239065171066; Tue, 24 Sep 2019 08:31:57 -0700 (PDT) Received: from localhost ([::1]:47172 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iCmnD-000889-3P for importer@patchew.org; Tue, 24 Sep 2019 11:31:55 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48316) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iCmfB-0001M0-AC for qemu-devel@nongnu.org; Tue, 24 Sep 2019 11:23:38 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iCmf9-0006lp-8X for qemu-devel@nongnu.org; Tue, 24 Sep 2019 11:23:37 -0400 Received: from szxga07-in.huawei.com ([45.249.212.35]:46810 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iCmf4-0006hW-NK; Tue, 24 Sep 2019 11:23:31 -0400 Received: from DGGEMS409-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id 6C35B257579530C63335; Tue, 24 Sep 2019 23:23:27 +0800 (CST) Received: from linux-Bxxcye.huawei.com (10.175.104.222) by DGGEMS409-HUB.china.huawei.com (10.3.19.209) with Microsoft SMTP Server id 14.3.439.0; Tue, 24 Sep 2019 23:23:21 +0800 From: Heyi Guo To: , , , Subject: [RFC PATCH 10/12] arm/sdei: check KVM cap and enable SDEI Date: Tue, 24 Sep 2019 23:21:49 +0800 Message-ID: <1569338511-3572-11-git-send-email-guoheyi@huawei.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1569338511-3572-1-git-send-email-guoheyi@huawei.com> References: <1569338511-3572-1-git-send-email-guoheyi@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.104.222] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 45.249.212.35 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Mark Rutland , Peter Maydell , Marc Zyngier , James Morse , Heyi Guo , wanghaibin.wang@huawei.com, Dave Martin Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Check KVM hypercall forward capability and enable it, and set global flag "sdei_enabled" to true if everything works well. Signed-off-by: Heyi Guo Cc: Peter Maydell Cc: Dave Martin Cc: Marc Zyngier Cc: Mark Rutland Cc: James Morse --- target/arm/sdei.c | 17 +++++++++++++++++ target/arm/sdei.h | 2 ++ 2 files changed, 19 insertions(+) diff --git a/target/arm/sdei.c b/target/arm/sdei.c index efdb681..000545e 100644 --- a/target/arm/sdei.c +++ b/target/arm/sdei.c @@ -43,6 +43,7 @@ #define TYPE_QEMU_SDEI "qemu_sdei" #define QEMU_SDEI(obj) OBJECT_CHECK(QemuSDEState, (obj), TYPE_QEMU_SDEI) =20 +bool sdei_enabled; static QemuSDEState *sde_state; =20 typedef struct QemuSDEIBindNotifyEntry { @@ -1465,6 +1466,7 @@ static const VMStateDescription vmstate_sde_state =3D= { static void sdei_initfn(Object *obj) { QemuSDEState *s =3D QEMU_SDEI(obj); + KVMState *kvm =3D KVM_STATE(current_machine->accelerator); =20 if (sde_state) { error_report("Only one SDEI dispatcher is allowed!"); @@ -1474,6 +1476,21 @@ static void sdei_initfn(Object *obj) =20 qemu_sde_init(s); qemu_register_reset(qemu_sde_reset, s); + + if (kvm_check_extension(kvm, KVM_CAP_FORWARD_HYPERCALL)) { + int ret; + ret =3D kvm_vm_enable_cap(kvm, KVM_CAP_FORWARD_HYPERCALL, 0, + KVM_CAP_FORWARD_HYPERCALL_EXCL_PSCI); + if (ret < 0) { + error_report("Enable hypercall forwarding failed: %s", + strerror(-ret)); + abort(); + } + sdei_enabled =3D true; + info_report("qemu sdei enabled"); + } else { + info_report("KVM does not support forwarding hypercall."); + } } =20 static void qemu_sde_class_init(ObjectClass *klass, void *data) diff --git a/target/arm/sdei.h b/target/arm/sdei.h index feaaf1a..95e7d8d 100644 --- a/target/arm/sdei.h +++ b/target/arm/sdei.h @@ -29,6 +29,8 @@ =20 #define SDEI_MAX_REQ SDEI_1_0_FN(0x12) =20 +extern bool sdei_enabled; + void sdei_handle_request(CPUState *cs, struct kvm_run *run); =20 /* --=20 1.8.3.1 From nobody Tue May 7 06:18:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1569339877; cv=none; d=zoho.com; s=zohoarc; b=JXe6PZ6A0eUJt30KoKuHJmJ+gGs6xfzHBA/qQEEj4PwRbL9/nlmsCzJLAXVZIZrp8Iv0IuH0iGEjo9hUXTV1QjRqpfc4EvcWeroOOxaxbbXnML5pHMM1oK+dmMG1iEPWJMkSZFh0GHkY/Niw1zT7i/KdFJULespF7l3umzV/Llo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1569339877; h=Content-Type:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=Zaf7jH7RLCIGJHYoFCzKghMK9eIdsm+02Rbyu7l18FU=; b=bqFC8coEWtj0B2iizrKP+22vRrwSj2zhuDQdITD8Zpp4XuCHuUxPV+Jp+VjPnxAptHDYQCJdknCV6DxDPgPvIIzTmmcZ5v2IvYVccNz2vhxjpO8bt9wJVcDlJpn49O2NG8QWcHSlKW5JU5yY57OahUQ7KvmlwBmEU+iOt/4NNcQ= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1569339877588394.5147451501648; Tue, 24 Sep 2019 08:44:37 -0700 (PDT) Received: from localhost ([::1]:47360 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iCmzU-0004qo-6M for importer@patchew.org; Tue, 24 Sep 2019 11:44:36 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48405) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iCmfF-0001Rc-4h for qemu-devel@nongnu.org; Tue, 24 Sep 2019 11:23:42 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iCmfD-0006ob-G5 for qemu-devel@nongnu.org; Tue, 24 Sep 2019 11:23:40 -0400 Received: from szxga07-in.huawei.com ([45.249.212.35]:46946 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iCmf9-0006kP-Co; Tue, 24 Sep 2019 11:23:35 -0400 Received: from DGGEMS409-HUB.china.huawei.com (unknown [172.30.72.58]) by Forcepoint Email with ESMTP id 619AEE0D577D65100598; Tue, 24 Sep 2019 23:23:32 +0800 (CST) Received: from linux-Bxxcye.huawei.com (10.175.104.222) by DGGEMS409-HUB.china.huawei.com (10.3.19.209) with Microsoft SMTP Server id 14.3.439.0; Tue, 24 Sep 2019 23:23:21 +0800 From: Heyi Guo To: , , , Subject: [RFC PATCH 11/12] arm/kvm: handle guest exit of hypercall Date: Tue, 24 Sep 2019 23:21:50 +0800 Message-ID: <1569338511-3572-12-git-send-email-guoheyi@huawei.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1569338511-3572-1-git-send-email-guoheyi@huawei.com> References: <1569338511-3572-1-git-send-email-guoheyi@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.104.222] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 45.249.212.35 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Mark Rutland , Peter Maydell , Marc Zyngier , James Morse , Heyi Guo , wanghaibin.wang@huawei.com, Dave Martin Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 Cc: Peter Maydell Cc: Dave Martin Cc: Marc Zyngier Cc: Mark Rutland Cc: James Morse --- target/arm/kvm.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/target/arm/kvm.c b/target/arm/kvm.c index b2eaa50..97a67b1 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" =20 const KVMCapabilityInfo kvm_arch_required_capabilities[] =3D { KVM_CAP_LAST_INFO @@ -668,6 +669,19 @@ MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_= run *run) } =20 =20 +static void kvm_arm_handle_hypercall(CPUState *cs, struct kvm_run *run) +{ + uint32_t func_id =3D run->hypercall.args[0]; + + if (sdei_enabled && + func_id >=3D SDEI_1_0_FN_BASE && func_id <=3D SDEI_MAX_REQ) { + sdei_handle_request(cs, run); + } else { + run->hypercall.args[0] =3D -1; + } +} + + int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) { int ret =3D 0; @@ -678,6 +692,9 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *= run) ret =3D 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); --=20 1.8.3.1 From nobody Tue May 7 06:18:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1569341977; cv=none; d=zoho.com; s=zohoarc; b=Gj2zw2mHjiEk912y+04xvFEQsEsbowy5h8rfPI91rVyZMxJqNv6zh6SMWK1G4W2IBaH+5ez4hv7RL6N6D0OppPgkoIMkuk2XQi/oRy72b29iu0VSys9vidXB7NLGqNEk4b7Jc7PjtxknjpHSDonwPIdFhecBnxYerAgowCrnJZc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1569341977; h=Content-Type:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=kfl6DiOy055sPl0nf/x/Ef5GNGj2KKA7gRbEeujHzVw=; b=EhttulD0FYASQfVz86gFubhjH06HcICskFXKTp3Lh4XXBSDv24p+qAnlm2qJnrmkUovGRpvn9nkehfk+awOfnUmWD/bfdSXOC85l6xqxllZk08Brc9ZW48NCxrJ5RAX4ZFtltdhZxe1oqnV2xfpzdxWkeovvxXset/huVLmPPX0= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1569341977671532.6236850678071; Tue, 24 Sep 2019 09:19:37 -0700 (PDT) Received: from localhost ([::1]:47904 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iCnXD-0005ZZ-Kh for importer@patchew.org; Tue, 24 Sep 2019 12:19:27 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48410) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iCmfF-0001Rq-9r for qemu-devel@nongnu.org; Tue, 24 Sep 2019 11:23:42 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iCmfD-0006oq-QS for qemu-devel@nongnu.org; Tue, 24 Sep 2019 11:23:41 -0400 Received: from szxga07-in.huawei.com ([45.249.212.35]:46984 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iCmf9-0006kQ-6x; Tue, 24 Sep 2019 11:23:35 -0400 Received: from DGGEMS409-HUB.china.huawei.com (unknown [172.30.72.58]) by Forcepoint Email with ESMTP id 683D193003537AC7CFD4; Tue, 24 Sep 2019 23:23:32 +0800 (CST) Received: from linux-Bxxcye.huawei.com (10.175.104.222) by DGGEMS409-HUB.china.huawei.com (10.3.19.209) with Microsoft SMTP Server id 14.3.439.0; Tue, 24 Sep 2019 23:23:22 +0800 From: Heyi Guo To: , , , Subject: [RFC PATCH 12/12] virt/acpi: add SDEI table if SDEI is enabled Date: Tue, 24 Sep 2019 23:21:51 +0800 Message-ID: <1569338511-3572-13-git-send-email-guoheyi@huawei.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1569338511-3572-1-git-send-email-guoheyi@huawei.com> References: <1569338511-3572-1-git-send-email-guoheyi@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.104.222] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 45.249.212.35 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Mark Rutland , Peter Maydell , "Michael S. Tsirkin" , Marc Zyngier , Shannon Zhao , James Morse , Igor Mammedov , Heyi Guo , wanghaibin.wang@huawei.com, Dave Martin Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add SDEI table if SDEI is enabled, so that guest OS can get aware and utilize the interfaces. Signed-off-by: Heyi Guo Cc: Peter Maydell Cc: Dave Martin Cc: Marc Zyngier Cc: Mark Rutland Cc: James Morse Cc: Shannon Zhao Cc: "Michael S. Tsirkin" Cc: Igor Mammedov --- hw/arm/virt-acpi-build.c | 16 ++++++++++++++++ include/hw/acpi/acpi-defs.h | 5 +++++ 2 files changed, 21 insertions(+) diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index 6cdf156..1088214 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,16 @@ build_iort(GArray *table_data, BIOSLinker *linker, Vir= tMachineState *vms) } =20 static void +build_sdei(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) +{ + int sdei_start =3D table_data->len; + + (void)acpi_data_push(table_data, sizeof(AcpiSdei)); + build_header(linker, table_data, (void *)(table_data->data + sdei_star= t), + "SDEI", table_data->len - sdei_start, 1, NULL, NULL); +} + +static void build_spcr(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) { AcpiSerialPortConsoleRedirection *spcr; @@ -796,6 +807,11 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildT= ables *tables) acpi_add_table(table_offsets, tables_blob); build_spcr(tables_blob, tables->linker, vms); =20 + 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); diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h index 57a3f58..0a2265d 100644 --- a/include/hw/acpi/acpi-defs.h +++ b/include/hw/acpi/acpi-defs.h @@ -634,4 +634,9 @@ struct AcpiIortRC { } QEMU_PACKED; typedef struct AcpiIortRC AcpiIortRC; =20 +struct AcpiSdei { + ACPI_TABLE_HEADER_DEF /* ACPI common table header */ +} QEMU_PACKED; +typedef struct AcpiSdei AcpiSdei; + #endif --=20 1.8.3.1