From patchwork Tue Sep 24 15:21:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heyi Guo X-Patchwork-Id: 11159085 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3887413B1 for ; Tue, 24 Sep 2019 15:24:24 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 08EC920665 for ; Tue, 24 Sep 2019 15:24:24 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="WuGfWJfx" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 08EC920665 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=huawei.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=nd7uolZOifZBI6OObpReqa4Mb9N+9WiR+28AwfPOou8=; b=WuGfWJfxvGRkKs +Qr2u9Oi3UxZeDsiVreQ3EH1n/MkpKxu7ccCIUknUeHJjjXMKfUnaq83X2EGsSg+T2f5JnGbS1t/n Z5T9322Mvmy4aadpxfZYrLdjerapcLmIeI3nrG0UxDQ0zThD3X+LS2S9w13z5P2o3HjnpHhcFkZOv qaHwxDZeQ47mn0ziLIFTakIcn6REi+z0wKmVoFaWbuQUwm2mzUUwbXUmSHZ2F8NjSBRqmscF7Bs4N RscfajTacRb4RWsLSYGery0UxoJvg+SinOnXAigy5Nd+nEhcXyz6F5iiOcL/Vvzu8r23m/4WAz2p4 sabcte4IH0tEFzDdb9yw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.2 #3 (Red Hat Linux)) id 1iCmfr-0003kx-CI; Tue, 24 Sep 2019 15:24:19 +0000 Received: from szxga05-in.huawei.com ([45.249.212.191] helo=huawei.com) by bombadil.infradead.org with esmtps (Exim 4.92.2 #3 (Red Hat Linux)) id 1iCmf0-00030z-6W for linux-arm-kernel@lists.infradead.org; Tue, 24 Sep 2019 15:23:30 +0000 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-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190924_082326_960521_9BD6DAF5 X-CRM114-Status: UNSURE ( 8.80 ) X-CRM114-Notice: Please train this message. X-Spam-Score: -1.5 (-) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-1.5 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [45.249.212.191 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -0.0 SPF_HELO_PASS SPF: HELO matches SPF record 0.8 UPPERCASE_50_75 message body is 50-75% uppercase X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 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 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org 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_VERSION_VENDOR_MASK) + +/* SDEI return values */ +#define SDEI_SUCCESS 0 +#define SDEI_NOT_SUPPORTED -1 +#define SDEI_INVALID_PARAMETERS -2 +#define SDEI_DENIED -3 +#define SDEI_PENDING -5 +#define SDEI_OUT_OF_RESOURCE -10 + +/* EVENT_REGISTER flags */ +#define SDEI_EVENT_REGISTER_RM_ANY 0 +#define SDEI_EVENT_REGISTER_RM_PE 1 + +/* EVENT_STATUS return value bits */ +#define SDEI_EVENT_STATUS_RUNNING 2 +#define SDEI_EVENT_STATUS_ENABLED 1 +#define SDEI_EVENT_STATUS_REGISTERED 0 + +/* EVENT_COMPLETE status values */ +#define SDEI_EV_HANDLED 0 +#define SDEI_EV_FAILED 1 + +/* GET_INFO values */ +#define SDEI_EVENT_INFO_EV_TYPE 0 +#define SDEI_EVENT_INFO_EV_SIGNALED 1 +#define SDEI_EVENT_INFO_EV_PRIORITY 2 +#define SDEI_EVENT_INFO_EV_ROUTING_MODE 3 +#define SDEI_EVENT_INFO_EV_ROUTING_AFF 4 + +/* and their results */ +#define SDEI_EVENT_TYPE_PRIVATE 0 +#define SDEI_EVENT_TYPE_SHARED 1 +#define SDEI_EVENT_PRIORITY_NORMAL 0 +#define SDEI_EVENT_PRIORITY_CRITICAL 1 + +#endif /* _UAPI_LINUX_ARM_SDEI_H */ From patchwork Tue Sep 24 15:21:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heyi Guo X-Patchwork-Id: 11159083 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DD69B13B1 for ; Tue, 24 Sep 2019 15:23:59 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B503F20665 for ; Tue, 24 Sep 2019 15:23:59 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="n9t8l7Dd" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B503F20665 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=huawei.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=c//nJwhbw1mlE4JWVkXkTeJwZP7sRwPtKdqzCGScms0=; b=n9t8l7Ddkwxmpo rBJX0hioejWAvjYyPkLy0DSTVsbyaVcZ0wloNHWVYpMs5cyYOS+Mngo9ov6pHHB1BwjC93oPF4hWD II8ZHwtfzzySYWSXktpZzZQ/Wi7+3Kcd4L+e4vRptpzM9NMklA8U95kZb6iTi7UyfY9v/c2sSlw+x mMeiY+VdtHdO+e5wSSHIU2TIS0Jj3WI1ETCJzeyH2XaeQczESdaOGrq1QbD9Ixw9wxf4uio9htuuW hhfodvOv41Fiv1euoDoggGmT2fXxl20UpkXx5e9vpKX47jld6HMno0Nq378Tv9lQbVsqiuowtPRsc 1LMjAtG175ehUFCf1x2A==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.2 #3 (Red Hat Linux)) id 1iCmfW-0003Rx-Sh; Tue, 24 Sep 2019 15:23:58 +0000 Received: from szxga05-in.huawei.com ([45.249.212.191] helo=huawei.com) by bombadil.infradead.org with esmtps (Exim 4.92.2 #3 (Red Hat Linux)) id 1iCmez-00030y-CM for linux-arm-kernel@lists.infradead.org; Tue, 24 Sep 2019 15:23:29 +0000 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-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190924_082325_913959_B354CF6A X-CRM114-Status: GOOD ( 21.62 ) X-Spam-Score: -2.3 (--) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-2.3 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [45.249.212.191 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -0.0 SPF_HELO_PASS SPF: HELO matches SPF record X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 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 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org 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) += machine.o arch_dump.o monitor.o obj-$(CONFIG_SOFTMMU) += arm-powerctl.o obj-$(CONFIG_KVM) += kvm.o +obj-$(CONFIG_KVM) += sdei.o obj-$(call land,$(CONFIG_KVM),$(call lnot,$(TARGET_AARCH64))) += kvm32.o obj-$(call land,$(CONFIG_KVM),$(TARGET_AARCH64)) += kvm64.o obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o 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 for + * 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 = s->sde_props_state; + int i; + for (i = 0; i < ARRAY_SIZE(s->sde_props_state); i++) { + sde_props[i].event_id = SDEI_INVALID_EVENT_ID; + sde_props[i].interrupt = SDEI_INVALID_INTERRUPT; + sde_props[i].sde_index = i >= PRIVATE_SLOT_COUNT ? + i - PRIVATE_SLOT_COUNT : i; + + qemu_mutex_init(&(sde_props[i].lock)); + sde_props[i].refcount = 0; + } + sde_props[0].event_id = SDEI_STD_EVT_SOFTWARE_SIGNAL; + sde_props[0].interrupt = SDEI_INVALID_INTERRUPT; + sde_props[0].is_shared = false; + sde_props[0].is_critical = false; + + for (i = 0; i < ARRAY_SIZE(s->irq_map); i++) { + s->irq_map[i] = SDEI_INVALID_EVENT_ID; + } + + qemu_mutex_init(&s->sdei_interrupt_bind_lock); +} + +static void qemu_sde_cpu_init(QemuSDEState *s) +{ + int i; + QemuSDECpu *sde_cpus; + + s->sdei_max_cpus = current_machine->smp.max_cpus; + s->sde_cpus = g_new0(QemuSDECpu, s->sdei_max_cpus); + sde_cpus = s->sde_cpus; + for (i = 0; i < s->sdei_max_cpus; i++) { + sde_cpus[i].masked = true; + sde_cpus[i].critical_running_event = SDEI_INVALID_EVENT_ID; + sde_cpus[i].normal_running_event = SDEI_INVALID_EVENT_ID; + } +} + +static bool is_valid_event_number(int32_t event) +{ + int32_t slot_id; + + if (event < 0 || (event & 0x3F000000)) { + return false; + } + + slot_id = SDEI_EVENT_TO_SLOT(event); + if (slot_id >= PRIVATE_SLOT_COUNT + SHARED_SLOT_COUNT) { + return false; + } + + return true; +} + +static bool is_valid_event(QemuSDEState *s, int32_t event) +{ + if (!is_valid_event_number(event)) { + return false; + } + + if (s->sde_props_state[SDEI_EVENT_TO_SLOT(event)].event_id != event) { + return false; + } + + return true; +} + +static QemuSDEProp *get_sde_prop_no_lock(QemuSDEState *s, int32_t event) +{ + if (!is_valid_event(s, event)) { + return NULL; + } + + return &s->sde_props_state[SDEI_EVENT_TO_SLOT(event)]; +} + +static void qemu_shared_sde_init(QemuSDEState *s) +{ + int i; + for (i = 0; i < SHARED_SLOT_COUNT; i++) { + QemuSDE *sde; + sde = s->shared_sde_array[i]; + if (!sde) { + sde = g_new0(QemuSDE, 1); + } + sde->event_id = SDEI_INVALID_EVENT_ID; + sde->enabled = false; + sde->running = false; + sde->pending = false; + sde->unregister_pending = false; + qemu_mutex_init(&sde->lock); + s->shared_sde_array[i] = sde; + } +} + +static void qemu_private_sde_init(QemuSDEState *s) +{ + int i, j; + for (i = 0; i < s->sdei_max_cpus; i++) { + QemuSDE **array = s->sde_cpus[i].private_sde_array; + for (j = 0; j < PRIVATE_SLOT_COUNT; j++) { + QemuSDE *sde; + sde = array[j]; + if (!sde) { + sde = g_new0(QemuSDE, 1); + } + sde->event_id = SDEI_INVALID_EVENT_ID; + sde->enabled = false; + sde->running = false; + sde->pending = false; + sde->unregister_pending = false; + qemu_mutex_init(&sde->lock); + array[j] = 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 = opaque; + QemuSDE **array; + int i, j; + + for (i = 0; i < s->sdei_max_cpus; i++) { + array = s->sde_cpus[i].private_sde_array; + for (j = 0; j < PRIVATE_SLOT_COUNT; j++) { + QemuSDE *sde = array[j]; + if (sde->event_id != SDEI_INVALID_EVENT_ID) { + sde->event_id = sde->prop->event_id; + sde->cpu_affinity = ARM_CPU(sde->target_cpu)->mp_affinity; + } + } + } + + array = s->shared_sde_array; + for (j = 0; j < SHARED_SLOT_COUNT; j++) { + QemuSDE *sde = array[j]; + if (sde->event_id != SDEI_INVALID_EVENT_ID) { + sde->event_id = sde->prop->event_id; + sde->cpu_affinity = ARM_CPU(sde->target_cpu)->mp_affinity; + } + } + + return 0; +} + + +static int qemu_sdei_post_load(void *opaque, int version_id) +{ + QemuSDEState *s = opaque; + QemuSDEProp *sde_props = s->sde_props_state; + QemuSDE **array; + int i, j; + + for (i = 0; i < s->sdei_max_cpus; i++) { + array = s->sde_cpus[i].private_sde_array; + for (j = 0; j < PRIVATE_SLOT_COUNT; j++) { + QemuSDE *sde = array[j]; + if (sde->event_id != SDEI_INVALID_EVENT_ID) { + sde->prop = get_sde_prop_no_lock(s, sde->event_id); + sde->target_cpu = arm_get_cpu_by_id(sde->cpu_affinity); + } + } + } + + array = s->shared_sde_array; + for (j = 0; j < SHARED_SLOT_COUNT; j++) { + QemuSDE *sde = array[j]; + if (sde->event_id != SDEI_INVALID_EVENT_ID) { + sde->prop = get_sde_prop_no_lock(s, sde->event_id); + sde->target_cpu = arm_get_cpu_by_id(sde->cpu_affinity); + } + } + + for (i = 0; i < PRIVATE_SLOT_COUNT + SHARED_SLOT_COUNT; i++) { + if (sde_props[i].interrupt != SDEI_INVALID_INTERRUPT) { + s->irq_map[sde_props[i].interrupt] = sde_props[i].event_id; + } + } + + return 0; +} + +static const VMStateDescription vmstate_sdes = { + .name = "qemu_sdei/sdes", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_BOOL(enabled, QemuSDE), + VMSTATE_BOOL(running, QemuSDE), + VMSTATE_BOOL(pending, QemuSDE), + VMSTATE_BOOL(unregister_pending, QemuSDE), + VMSTATE_UINT64(ep_address, QemuSDE), + VMSTATE_UINT64(ep_argument, QemuSDE), + VMSTATE_UINT64(routing_mode, QemuSDE), + VMSTATE_INT32(event_id, QemuSDE), + VMSTATE_UINT64(cpu_affinity, QemuSDE), + VMSTATE_END_OF_LIST() + } +}; + +static const VMStateDescription vmstate_sde_props = { + .name = "qemu_sdei/sde_props", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_INT32(event_id, QemuSDEProp), + VMSTATE_INT32(interrupt, QemuSDEProp), + VMSTATE_BOOL(is_shared, QemuSDEProp), + VMSTATE_BOOL(is_critical, QemuSDEProp), + VMSTATE_INT32(sde_index, QemuSDEProp), + VMSTATE_INT32(refcount, QemuSDEProp), + VMSTATE_END_OF_LIST() + } +}; + +static const VMStateDescription vmstate_sde_cpu = { + .name = "qemu_sdei/sde_cpu", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_ARRAY_OF_POINTER_TO_STRUCT(private_sde_array, QemuSDECpu, + PRIVATE_SLOT_COUNT, 1, + vmstate_sdes, QemuSDE), + VMSTATE_UINT64_ARRAY(ctx[0].xregs, QemuSDECpu, 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 = { + .name = "qemu_sdei", + .version_id = 1, + .minimum_version_id = 1, + .pre_save = qemu_sdei_pre_save, + .post_load = qemu_sdei_post_load, + .fields = (VMStateField[]) { + VMSTATE_STRUCT_ARRAY(sde_props_state, QemuSDEState, + PRIVATE_SLOT_COUNT + SHARED_SLOT_COUNT, 1, + vmstate_sde_props, QemuSDEProp), + VMSTATE_ARRAY_OF_POINTER_TO_STRUCT(shared_sde_array, QemuSDEState, + SHARED_SLOT_COUNT, 1, + vmstate_sdes, QemuSDE), + VMSTATE_STRUCT_VARRAY_POINTER_INT32(sde_cpus, QemuSDEState, + sdei_max_cpus, + vmstate_sde_cpu, QemuSDECpu), + VMSTATE_END_OF_LIST() + } +}; + + +static void sdei_initfn(Object *obj) +{ + QemuSDEState *s = QEMU_SDEI(obj); + + if (sde_state) { + error_report("Only one SDEI dispatcher is allowed!"); + abort(); + } + sde_state = s; + + qemu_sde_init(s); +} + +static void qemu_sde_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->desc = "SDEI_QEMU"; + dc->vmsd = &vmstate_sde_state; + dc->user_creatable = true; +} + +static const TypeInfo sde_qemu_info = { + .name = TYPE_QEMU_SDEI, + .parent = TYPE_DEVICE, + .instance_size = sizeof(QemuSDEState), + .instance_init = sdei_initfn, + .class_init = qemu_sde_class_init, +}; + +static void register_types(void) +{ + type_register_static(&sde_qemu_info); +} + +type_init(register_types); diff --git a/target/arm/sdei_int.h b/target/arm/sdei_int.h new file mode 100644 index 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 for + * 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) >= PRIVATE_SLOT_COUNT) + +typedef enum { + SDEI_PRIO_NORMAL = 0, + SDEI_PRIO_CRITICAL = 1, +} QemuSDEIPriority; + +typedef struct QemuSDEProp { + QemuMutex lock; + int32_t event_id; + int interrupt; + bool is_shared; + bool is_critical; + /* This is the internal index for private or shared SDE */ + int sde_index; + int refcount; +} QemuSDEProp; + +typedef struct QemuSDE { + QemuSDEProp *prop; + CPUState *target_cpu; + QemuMutex lock; + bool enabled; + bool running; + bool pending; + bool unregister_pending; + uint64_t ep_address; + uint64_t ep_argument; + uint64_t routing_mode; + int32_t event_id; + /* + * For it is not easy to save the pointer target_cpu during migration, we + * add below field to save the corresponding numerical values. + */ + uint64_t cpu_affinity; +} QemuSDE; + +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 From patchwork Tue Sep 24 15:21:42 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heyi Guo X-Patchwork-Id: 11159091 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 06AAC14ED for ; Tue, 24 Sep 2019 15:24:58 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D5BFF20665 for ; Tue, 24 Sep 2019 15:24:57 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="h1sxaXvp" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D5BFF20665 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=huawei.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=YivK7QD4nWPQosDsPoXuhDilpfHyZoB0XWIIGhwG+R4=; b=h1sxaXvpoE1olc TKaSY5nSDCyyZO8WS0QOOC+X2m7kngAb1k2AqaATqmhwjFqw7q9BxUOd9Ed9ywooJCGoVBXvZIBKC +5cgpcpOtQg8s3sDSJh6i0Tq22UrxRdin3MpfaSm/uBEDMnl+/Z+LmOjLMfwRilWP4UajreHNTf11 wLJghD9cQyas3JZtGAlkIdfwAwgcAqnCS8I5J2TFgq929bvubjhCJNbT8du9SgTdibjkpG3FRrqbr kuV7C2JDhEA5Otiozl3Pr3UT/brTJJPKCjngbFbtx5ZsDB/y8WGEOA19JCrN1nvVVz8lejfl/srNh 3gAjV2ecE3Dec4uDFelw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.2 #3 (Red Hat Linux)) id 1iCmgT-0004F0-95; Tue, 24 Sep 2019 15:24:57 +0000 Received: from szxga05-in.huawei.com ([45.249.212.191] helo=huawei.com) by bombadil.infradead.org with esmtps (Exim 4.92.2 #3 (Red Hat Linux)) id 1iCmf0-000314-Qf for linux-arm-kernel@lists.infradead.org; Tue, 24 Sep 2019 15:23:32 +0000 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-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190924_082328_270518_BE0E07E7 X-CRM114-Status: GOOD ( 15.76 ) X-Spam-Score: -2.3 (--) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-2.3 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [45.249.212.191 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -0.0 SPF_HELO_PASS SPF: HELO matches SPF record X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 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 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Add support for all interfaces defined in ARM SDEI 1.0 spec. http://infocenter.arm.com/help/topic/com.arm.doc.den0054a/ARM_DEN0054A_Software_Delegated_Exception_Interface.pdf The exit reason KVM_EXIT_HYPERCALL is used to indicate it is an HVC/SMC forward, and the structure kvm_run->hypercall is used to pass arguments and return values between KVM and qemu: Input: nr: the immediate value of SMC/HVC calls; not really used today. args[6]: x0..x5 (This is not fully conform with SMCCC which requires x6 as argument as well, but we can use GET_ONE_REG ioctl for such rare case). Return: args[0..3]: x0..x3 as defined in SMCCC. We rely on KVM to extract args[0..3] and write them to x0..x3 when hypercall exit returns. Signed-off-by: Heyi Guo 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) } } +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)]; } +static QemuSDEProp *get_sde_prop(QemuSDEState *s, int32_t event) +{ + QemuSDEProp *sde_props = s->sde_props_state; + + if (!is_valid_event_number(event)) { + return NULL; + } + + event = SDEI_EVENT_TO_SLOT(event); + + qemu_mutex_lock(&sde_props[event].lock); + if (sde_props[event].event_id < 0) { + qemu_mutex_unlock(&sde_props[event].lock); + return NULL; + } + return &sde_props[event]; +} + +static void put_sde_prop(QemuSDEProp *prop) +{ + qemu_mutex_unlock(&prop->lock); +} + +static void sde_slot_lock(QemuSDE *sde, CPUState *cs) +{ + qemu_mutex_lock(&sde->lock); +} + +static void sde_slot_unlock(QemuSDE *sde, CPUState *cs) +{ + qemu_mutex_unlock(&sde->lock); +} + +/* + * It will always return a pointer to a preallocated sde; event number must be + * validated before calling this function. + */ +static QemuSDE *get_sde_no_check(QemuSDEState *s, int32_t event, CPUState *cs) +{ + QemuSDE **array = s->sde_cpus[cs->cpu_index].private_sde_array; + int32_t sde_index = SDEI_EVENT_TO_SLOT(event); + QemuSDE *sde; + + if (SDEI_IS_SHARED_EVENT(event)) { + array = s->shared_sde_array; + sde_index -= PRIVATE_SLOT_COUNT; + } + + sde = array[sde_index]; + sde_slot_lock(sde, cs); + return sde; +} + +static void put_sde(QemuSDE *sde, CPUState *cs) +{ + sde_slot_unlock(sde, cs); +} + +static inline bool is_sde_nested(QemuSDECpu *sde_cpu) +{ + return sde_cpu->critical_running_event >= 0 && + sde_cpu->normal_running_event >= 0; +} + +static int32_t get_running_sde(QemuSDEState *s, CPUState *cs) +{ + QemuSDECpu *sde_cpu = get_sde_cpu(s, cs); + + if (sde_cpu->critical_running_event >= 0) { + return sde_cpu->critical_running_event; + } + return sde_cpu->normal_running_event; +} + +static void override_return_value(CPUState *cs, uint64_t *args) +{ + CPUARMState *env = &ARM_CPU(cs)->env; + int i; + + for (i = 0; i < 4; i++) { + args[i] = env->xregs[i]; + } +} + +static void sde_save_cpu_ctx(CPUState *cs, QemuSDECpu *sde_cpu, bool critical) +{ + CPUARMState *env = &ARM_CPU(cs)->env; + QemuSDECpuCtx *ctx = &sde_cpu->ctx[critical ? 1 : 0]; + + memcpy(ctx->xregs, env->xregs, sizeof(ctx->xregs)); + ctx->pc = env->pc; + ctx->pstate = pstate_read(env); +} + +static void sde_restore_cpu_ctx(QemuSDEState *s, CPUState *cs, bool critical) +{ + CPUARMState *env = &ARM_CPU(cs)->env; + QemuSDECpu *sde_cpu = get_sde_cpu(s, cs); + QemuSDECpuCtx *ctx = &sde_cpu->ctx[critical ? 1 : 0]; + + /* + * TODO: we need to optimize to only restore affected registers by calling + * ioctl individialy + */ + kvm_arch_get_registers(cs); + + env->aarch64 = ((ctx->pstate & PSTATE_nRW) == 0); + memcpy(env->xregs, ctx->xregs, sizeof(ctx->xregs)); + env->pc = ctx->pc; + pstate_write(env, ctx->pstate); + aarch64_restore_sp(env, (env->pstate >> 2) & 3); +} + +static void sde_restore_cpu_ctx_for_resume(QemuSDEState *s, + CPUState *cs, + bool critical, + uint64_t resume_addr) +{ + CPUARMState *env = &ARM_CPU(cs)->env; + QemuSDECpu *sde_cpu = get_sde_cpu(s, cs); + QemuSDECpuCtx *ctx = &sde_cpu->ctx[critical ? 1 : 0]; + + /* + * TODO: we need to optimize to only restore affected registers by calling + * ioctl individialy + */ + kvm_arch_get_registers(cs); + + memcpy(env->xregs, ctx->xregs, sizeof(ctx->xregs)); + env->pc = resume_addr; + env->aarch64 = 1; + /* Constructe pstate in pstate_read() */ + env->daif = 0xF << 6; + /* Clear nRW/M[4] and M[3:0] */ + env->pstate &= ~0x1F; + /* Set exception mode to EL1h */ + env->pstate |= PSTATE_MODE_EL1h; + env->elr_el[1] = ctx->pc; + env->banked_spsr[KVM_SPSR_EL1 + 1] = ctx->pstate; + aarch64_restore_sp(env, 1); +} + +static void sde_build_cpu_ctx(CPUState *cs, QemuSDECpu *sde_cpu, QemuSDE *sde) +{ + CPUARMState *env = &ARM_CPU(cs)->env; + + env->xregs[0] = sde->prop->event_id; + env->xregs[1] = sde->ep_argument; + env->xregs[2] = env->pc; + env->xregs[3] = pstate_read(env); + env->pc = sde->ep_address; + env->aarch64 = 1; + /* Constructe pstate in pstate_read() */ + env->daif = 0xF << 6; + /* Clear nRW/M[4] and M[3:0] */ + env->pstate &= ~0x1F; + /* Set exception mode to EL1h */ + env->pstate |= PSTATE_MODE_EL1h; + aarch64_restore_sp(env, 1); +} + +static void trigger_sde(CPUState *cs, run_on_cpu_data data) +{ + QemuSDEState *s = sde_state; + QemuSDECpu *sde_cpu = get_sde_cpu(s, cs); + int32_t event = data.host_int; + QemuSDE *sde; + + assert(cs == current_cpu); + + if (sde_cpu->masked || sde_cpu->critical_running_event >= 0) { + return; + } + + sde = get_sde_no_check(s, event, cs); + if (sde->event_id == SDEI_INVALID_EVENT_ID) { + /* Some race condition happens! */ + put_sde(sde, cs); + return; + } + + if (sde_cpu->normal_running_event >= 0 && !sde->prop->is_critical) { + put_sde(sde, cs); + return; + } + + if (!sde->enabled || !sde->pending || sde->running) { + /* Some race condition happens! */ + put_sde(sde, cs); + return; + } + + sde->pending = false; + sde->running = true; + + if (sde->prop->is_critical) { + sde_cpu->critical_running_event = sde->prop->event_id; + } else { + sde_cpu->normal_running_event = sde->prop->event_id; + } + + kvm_arch_get_registers(cs); + sde_save_cpu_ctx(cs, sde_cpu, sde->prop->is_critical); + sde_build_cpu_ctx(cs, sde_cpu, sde); + kvm_arch_put_registers(cs, 1); + put_sde(sde, cs); +} + +static int64_t dispatch_single(QemuSDEState *s, QemuSDE *sde, CPUState *cs) +{ + int32_t event = sde->prop->event_id; + bool pending = sde->pending; + bool enabled = sde->enabled; + CPUState *target = sde->target_cpu; + put_sde(sde, cs); + + if (pending && enabled) { + /* + * TODO: we need to find a free-unmasked PE to trigger for shared + * unpinned event + */ + async_run_on_cpu(target, trigger_sde, + RUN_ON_CPU_HOST_INT(event)); + } + return SDEI_SUCCESS; +} + +static void dispatch_cpu(QemuSDEState *s, CPUState *cs, bool is_critical) +{ + QemuSDE *sde; + int i; + + for (i = 0; i < PRIVATE_SLOT_COUNT + SHARED_SLOT_COUNT; i++) { + sde = get_sde_no_check(s, i, cs); + if (sde->event_id == SDEI_INVALID_EVENT_ID) { + put_sde(sde, cs); + continue; + } + if (sde->prop->is_critical != is_critical) { + put_sde(sde, cs); + continue; + } + if (!sde->enabled || !sde->pending || sde->running || + sde->target_cpu != 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 = 0; + int count = PRIVATE_SLOT_COUNT; + int32_t event; + QemuSDEProp *sde_props = s->sde_props_state; + + if (is_shared) { + start = PRIVATE_SLOT_COUNT; + count = PRIVATE_SLOT_COUNT + SHARED_SLOT_COUNT; + } + + qemu_mutex_lock(&s->sdei_interrupt_bind_lock); + for (index = start; index < count; index++) { + qemu_mutex_lock(&sde_props[index].lock); + if (sde_props[index].interrupt == intid) { + event = sde_props[index].event_id; + qemu_mutex_unlock(&sde_props[index].lock); + qemu_mutex_unlock(&s->sdei_interrupt_bind_lock); + return event; + } + qemu_mutex_unlock(&sde_props[index].lock); + } + + for (index = start; index < count; index++) { + qemu_mutex_lock(&sde_props[index].lock); + if (sde_props[index].event_id < 0) { + event = sde_props[index].event_id = 0x40000000 | index; + sde_props[index].interrupt = intid; + sde_props[index].is_shared = is_shared; + sde_props[index].is_critical = is_critical; + s->irq_map[intid] = event; + qemu_mutex_unlock(&sde_props[index].lock); + qemu_mutex_unlock(&s->sdei_interrupt_bind_lock); + return event; + } + qemu_mutex_unlock(&sde_props[index].lock); + } + qemu_mutex_unlock(&s->sdei_interrupt_bind_lock); + return SDEI_OUT_OF_RESOURCE; +} + +static int32_t sdei_free_event_num_locked(QemuSDEState *s, QemuSDEProp *prop) +{ + int32_t ret = SDEI_SUCCESS; + if (atomic_read(&prop->refcount) > 0) { + ret = SDEI_DENIED; + goto unlock_return; + } + + s->irq_map[prop->interrupt] = SDEI_INVALID_EVENT_ID; + prop->event_id = SDEI_INVALID_EVENT_ID; + prop->interrupt = 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 = 0; + + prop = get_sde_prop(s, event); + if (!prop) { + return SDEI_INVALID_PARAMETERS; + } + + sde = get_sde_no_check(s, event, cs); + if (sde->event_id == SDEI_INVALID_EVENT_ID) { + put_sde(sde, cs); + put_sde_prop(prop); + return SDEI_DENIED; + } + + if (sde->running && !force) { + sde->unregister_pending = true; + ret = SDEI_PENDING; + } else { + atomic_dec(&prop->refcount); + sde->event_id = SDEI_INVALID_EVENT_ID; + sde->enabled = false; + sde->running = false; + sde->pending = false; + sde->unregister_pending = false; + } + put_sde(sde, cs); + put_sde_prop(prop); + return ret; +} + +static int64_t sdei_private_reset_common(QemuSDEState *s, CPUState *cs, + bool force) +{ + int64_t ret = SDEI_SUCCESS; + int i; + + for (i = 0; i < PRIVATE_SLOT_COUNT; i++) { + int64_t ret1; + ret1 = unregister_single_sde(s, i, cs, force); + /* Ignore other return values in reset interface */ + if (ret1 == SDEI_PENDING) { + ret = SDEI_DENIED; + } + } + + return ret; +} + +static int64_t sdei_shared_reset_common(QemuSDEState *s, CPUState *cs, + bool force) +{ + int i; + QemuSDEProp *prop; + int32_t start_event = PRIVATE_SLOT_COUNT; + int64_t ret = SDEI_SUCCESS; + + for (i = start_event; i < PRIVATE_SLOT_COUNT + SHARED_SLOT_COUNT; i++) { + int64_t ret1 = unregister_single_sde(s, i, cs, force); + /* Ignore other return values in reset interface */ + if (ret1 == SDEI_PENDING) { + ret = SDEI_DENIED; + } + } + if (ret) { + return ret; + } + + for (i = 0; i < PRIVATE_SLOT_COUNT + SHARED_SLOT_COUNT; i++) { + qemu_mutex_lock(&s->sdei_interrupt_bind_lock); + prop = get_sde_prop(s, i); + if (!prop || prop->interrupt == SDEI_INVALID_INTERRUPT) { + if (prop) { + put_sde_prop(prop); + } + qemu_mutex_unlock(&s->sdei_interrupt_bind_lock); + continue; + } + ret |= 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 = cs; + uint64_t *args = (uint64_t *)run->hypercall.args; + int32_t event = args[1]; + uint64_t rm_mode = SDEI_EVENT_REGISTER_RM_PE; + + prop = get_sde_prop(s, event); + if (!prop) { + return SDEI_INVALID_PARAMETERS; + } + + sde = get_sde_no_check(s, event, cs); + if (sde->event_id != SDEI_INVALID_EVENT_ID) { + put_sde(sde, cs); + put_sde_prop(prop); + return SDEI_DENIED; + } + + if (prop->is_shared) { + rm_mode = args[4] & 1ULL; + if (rm_mode == SDEI_EVENT_REGISTER_RM_PE) { + target = arm_get_cpu_by_id(args[5]); + if (!target) { + put_sde_prop(prop); + return SDEI_INVALID_PARAMETERS; + } + } + } + + sde->target_cpu = target; + sde->ep_address = args[2]; + sde->ep_argument = args[3]; + sde->prop = prop; + sde->routing_mode = rm_mode; + sde->event_id = prop->event_id; + + put_sde(sde, cs); + atomic_inc(&prop->refcount); + put_sde_prop(prop); + + return SDEI_SUCCESS; +} + +static int64_t sdei_event_enable(QemuSDEState *s, CPUState *cs, + struct kvm_run *run) +{ + QemuSDE *sde; + uint64_t *args = (uint64_t *)(run->hypercall.args); + int32_t event = args[1]; + + if (!is_valid_event_number(event)) { + return SDEI_INVALID_PARAMETERS; + } + sde = get_sde_no_check(s, event, cs); + if (sde->event_id == SDEI_INVALID_EVENT_ID) { + put_sde(sde, cs); + return SDEI_INVALID_PARAMETERS; + } + + sde->enabled = true; + 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 = (uint64_t *)run->hypercall.args; + int32_t event = args[1]; + + if (!is_valid_event_number(event)) { + return SDEI_INVALID_PARAMETERS; + } + sde = get_sde_no_check(s, event, cs); + if (sde->event_id == SDEI_INVALID_EVENT_ID) { + put_sde(sde, cs); + return SDEI_INVALID_PARAMETERS; + } + + sde->enabled = false; + put_sde(sde, cs); + return SDEI_SUCCESS; +} + +static int64_t sdei_event_context(QemuSDEState *s, CPUState *cs, + struct kvm_run *run) +{ + QemuSDECpu *sde_cpu = get_sde_cpu(s, cs); + uint64_t *args = (uint64_t *)(run->hypercall.args); + uint32_t param_id = args[1]; + int critical; + QemuSDECpuCtx *ctx; + + if (param_id >= SDEI_PARAM_MAX) { + return SDEI_INVALID_PARAMETERS; + } + + if (sde_cpu->critical_running_event >= 0) { + critical = 1; + } else if (sde_cpu->normal_running_event >= 0) { + critical = 0; + } else { + return SDEI_DENIED; + } + + ctx = &sde_cpu->ctx[critical]; + return ctx->xregs[param_id]; +} + +static int64_t sdei_event_complete(QemuSDEState *s, CPUState *cs, + struct kvm_run *run) +{ + QemuSDE *sde; + QemuSDECpu *cpu = get_sde_cpu(s, cs); + int32_t event; + uint64_t *args = (uint64_t *)(run->hypercall.args); + bool is_critical; + + event = get_running_sde(s, cs); + if (event < 0) { + return SDEI_DENIED; + } + + assert(is_valid_event_number(event)); + sde = get_sde_no_check(s, event, cs); + assert(sde->event_id != SDEI_INVALID_EVENT_ID); + + sde->running = false; + is_critical = sde->prop->is_critical; + if (sde->unregister_pending) { + atomic_dec(&sde->prop->refcount); + sde->event_id = SDEI_INVALID_EVENT_ID; + sde->unregister_pending = false; + } + put_sde(sde, cs); + + sde_restore_cpu_ctx(s, cs, is_critical); + + kvm_arch_put_registers(cs, 1); + override_return_value(cs, args); + if (cpu->critical_running_event >= 0) { + cpu->critical_running_event = SDEI_INVALID_EVENT_ID; + } else { + cpu->normal_running_event = SDEI_INVALID_EVENT_ID; + } + + /* TODO: we should not queue more than one sde in work queue */ + dispatch_cpu(s, cs, true); + if (cpu->critical_running_event < 0 && cpu->normal_running_event < 0) { + dispatch_cpu(s, cs, false); + } + return args[0]; +} + +static int64_t sdei_event_complete_and_resume(QemuSDEState *s, CPUState *cs, + struct kvm_run *run) +{ + QemuSDE *sde; + QemuSDECpu *cpu = get_sde_cpu(s, cs); + int32_t event; + uint64_t *args = (uint64_t *)(run->hypercall.args); + bool is_critical; + uint64_t resume_addr = args[1]; + + event = get_running_sde(s, cs); + if (event < 0) { + return SDEI_DENIED; + } + + assert(is_valid_event_number(event)); + sde = get_sde_no_check(s, event, cs); + assert(sde->event_id != SDEI_INVALID_EVENT_ID); + + sde->running = false; + is_critical = sde->prop->is_critical; + + if (sde->unregister_pending) { + atomic_dec(&sde->prop->refcount); + sde->event_id = SDEI_INVALID_EVENT_ID; + sde->unregister_pending = false; + } + put_sde(sde, cs); + + sde_restore_cpu_ctx_for_resume(s, cs, is_critical, resume_addr); + kvm_arch_put_registers(cs, 1); + + override_return_value(cs, args); + if (cpu->critical_running_event >= 0) { + cpu->critical_running_event = SDEI_INVALID_EVENT_ID; + } else { + cpu->normal_running_event = SDEI_INVALID_EVENT_ID; + } + + dispatch_cpu(s, cs, true); + if (cpu->critical_running_event < 0 && cpu->normal_running_event < 0) { + dispatch_cpu(s, cs, false); + } + return args[0]; +} + +static int64_t sdei_event_unregister(QemuSDEState *s, CPUState *cs, + struct kvm_run *run) +{ + uint64_t *args = (uint64_t *)(run->hypercall.args); + int32_t event = args[1]; + + return unregister_single_sde(s, event, cs, false); +} + +static int64_t sdei_event_status(QemuSDEState *s, CPUState *cs, + struct kvm_run *run) +{ + QemuSDE *sde; + uint64_t *args = (uint64_t *)(run->hypercall.args); + int32_t event = args[1]; + int64_t status = 0; + + if (!is_valid_event(s, event)) { + return SDEI_INVALID_PARAMETERS; + } + + sde = get_sde_no_check(s, event, cs); + if (sde->event_id == SDEI_INVALID_EVENT_ID) { + put_sde(sde, cs); + return status; + } + + status |= SDEI_EVENT_STATUS_REGISTERED; + if (sde->enabled) { + status |= SDEI_EVENT_STATUS_ENABLED; + } + if (sde->running) { + status |= SDEI_EVENT_STATUS_RUNNING; + } + put_sde(sde, cs); + return status; +} + +static int64_t sdei_event_get_info(QemuSDEState *s, CPUState *cs, + struct kvm_run *run) +{ + QemuSDEProp *prop; + QemuSDE *sde; + uint64_t *args = (uint64_t *)(run->hypercall.args); + int32_t event = args[1]; + uint32_t info = args[2]; + int64_t ret; + + if (info > SDEI_EVENT_INFO_EV_ROUTING_AFF) { + return SDEI_INVALID_PARAMETERS; + } + + prop = get_sde_prop(s, event); + if (!prop) { + return SDEI_INVALID_PARAMETERS; + } + + switch (info) { + case SDEI_EVENT_INFO_EV_TYPE: + ret = prop->is_shared; + break; + case SDEI_EVENT_INFO_EV_SIGNALED: + ret = (event == SDEI_STD_EVT_SOFTWARE_SIGNAL) ? 1 : 0; + break; + case SDEI_EVENT_INFO_EV_PRIORITY: + ret = prop->is_critical; + break; + case SDEI_EVENT_INFO_EV_ROUTING_MODE: + case SDEI_EVENT_INFO_EV_ROUTING_AFF: + ret = SDEI_INVALID_PARAMETERS; + if (!prop->is_shared) { + break; + } + sde = get_sde_no_check(s, event, cs); + if (sde->event_id == SDEI_INVALID_EVENT_ID) { + put_sde(sde, cs); + ret = SDEI_DENIED; + break; + } + if (info == SDEI_EVENT_INFO_EV_ROUTING_MODE) { + ret = sde->routing_mode; + } else if (sde->routing_mode == SDEI_EVENT_REGISTER_RM_PE) { + ret = ARM_CPU(sde->target_cpu)->mp_affinity; + } + put_sde(sde, cs); + break; + default: + ret = SDEI_NOT_SUPPORTED; + } + put_sde_prop(prop); + return ret; +} + +static int64_t sdei_event_routing_set(QemuSDEState *s, CPUState *cs, + struct kvm_run *run) +{ + QemuSDE *sde; + CPUState *target = cs; + uint64_t *args = (uint64_t *)run->hypercall.args; + int32_t event = args[1]; + uint64_t mode = args[2]; + uint64_t affinity = args[3]; + + if (mode & ~1ULL) { + return SDEI_INVALID_PARAMETERS; + } + if (mode == SDEI_EVENT_REGISTER_RM_PE) { + target = arm_get_cpu_by_id(affinity); + if (!target) { + return SDEI_INVALID_PARAMETERS; + } + } + + if (!is_valid_event(s, event) || !SDEI_IS_SHARED_EVENT(event)) { + return SDEI_INVALID_PARAMETERS; + } + + sde = get_sde_no_check(s, event, cs); + if (sde->event_id == SDEI_INVALID_EVENT_ID) { + put_sde(sde, cs); + return SDEI_DENIED; + } + if (sde->enabled || sde->running || + sde->pending || sde->unregister_pending) { + put_sde(sde, cs); + return SDEI_DENIED; + } + + sde->target_cpu = target; + sde->routing_mode = mode; + put_sde(sde, cs); + + return SDEI_SUCCESS; +} + +static int64_t sdei_event_pe_mask(QemuSDEState *s, CPUState *cs, + struct kvm_run *run) +{ + QemuSDECpu *sde_cpu; + + sde_cpu = get_sde_cpu(s, cs); + if (sde_cpu->masked) { + return 0; + } + sde_cpu->masked = true; + return 1; +} + +static int64_t sdei_event_pe_unmask(QemuSDEState *s, CPUState *cs, + struct kvm_run *run) +{ + QemuSDECpu *sde_cpu; + + sde_cpu = get_sde_cpu(s, cs); + sde_cpu->masked = false; + dispatch_cpu(s, cs, true); + dispatch_cpu(s, cs, false); + return SDEI_SUCCESS; +} + +static int64_t sdei_event_interrupt_bind(QemuSDEState *s, CPUState *cs, + struct kvm_run *run) +{ + uint64_t *args = (uint64_t *)(run->hypercall.args); + uint32_t intid = args[1]; + + if (intid < GIC_NR_SGIS || intid >= GIC_MAXIRQ) { + return SDEI_INVALID_PARAMETERS; + } + return sdei_alloc_event_num(s, false, intid >= 32, intid); +} + +static int64_t sdei_event_interrupt_release(QemuSDEState *s, CPUState *cs, + struct kvm_run *run) +{ + QemuSDEProp *prop; + uint64_t *args = (uint64_t *)(run->hypercall.args); + int32_t event = args[1]; + + qemu_mutex_lock(&s->sdei_interrupt_bind_lock); + prop = get_sde_prop(s, event); + if (!prop) { + qemu_mutex_unlock(&s->sdei_interrupt_bind_lock); + return SDEI_INVALID_PARAMETERS; + } + + 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 = (uint64_t *)(run->hypercall.args); + int32_t event = args[1]; + + if (event != SDEI_STD_EVT_SOFTWARE_SIGNAL) { + return SDEI_INVALID_PARAMETERS; + } + + target_cpu = arm_get_cpu_by_id(args[2]); + if (!target_cpu) { + return SDEI_INVALID_PARAMETERS; + } + + sde = get_sde_no_check(s, event, target_cpu); + if (sde->event_id == SDEI_INVALID_EVENT_ID) { + put_sde(sde, cs); + return SDEI_INVALID_PARAMETERS; + } + + sde->pending = true; + return dispatch_single(s, sde, target_cpu); +} + +static int64_t sdei_features(QemuSDEState *s, CPUState *cs, struct kvm_run *run) +{ + uint64_t *args = (uint64_t *)(run->hypercall.args); + uint32_t feature = args[1]; + + switch (feature) { + case SDEI_FEATURE_BIND_SLOTS: + return ((SHARED_SLOT_COUNT - PLAT_SHARED_SLOT_COUNT) << 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[] = { + sdei_version, + sdei_event_register, + sdei_event_enable, + sdei_event_disable, + sdei_event_context, + sdei_event_complete, + sdei_event_complete_and_resume, + sdei_event_unregister, + sdei_event_status, + sdei_event_get_info, + sdei_event_routing_set, + sdei_event_pe_mask, + sdei_event_pe_unmask, + sdei_event_interrupt_bind, + sdei_event_interrupt_release, + sdei_event_signal, + sdei_features, + sdei_private_reset, + sdei_shared_reset, +}; + +void sdei_handle_request(CPUState *cs, struct kvm_run *run) +{ + uint32_t func_id = run->hypercall.args[0]; + + if (!sde_state) { + run->hypercall.args[0] = SDEI_NOT_SUPPORTED; + return; + } + + if (func_id < SDEI_1_0_FN_BASE || func_id > SDEI_MAX_REQ) { + error_report("Invalid SDEI function ID: 0x%x", func_id); + run->hypercall.args[0] = SDEI_INVALID_PARAMETERS; + return; + } + + func_id -= SDEI_1_0_FN_BASE; + if (func_id < ARRAY_SIZE(sdei_functions) && sdei_functions[func_id]) { + run->hypercall.args[0] = sdei_functions[func_id](sde_state, cs, run); + } else { + run->hypercall.args[0] = SDEI_NOT_SUPPORTED; + } +} + static void 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 for + * 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 From patchwork Tue Sep 24 15:21:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heyi Guo X-Patchwork-Id: 11159095 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C39EA14ED for ; Tue, 24 Sep 2019 15:25:41 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A148D214DA for ; Tue, 24 Sep 2019 15:25:41 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="VTxH7+E0" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A148D214DA Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=huawei.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=3+9e6rb0nsnrsZFOYbSl/VLkP7ltwzNnK+7AQWi7P5w=; b=VTxH7+E00ttwkF whVr6PY0AhdJzQTZyn9Lv2BDaeSM8t5i8vVH3+9celuzvRHLlovARvwD5AbXxLEUuzS1ZoXj00gUh 73GGQM7BYM0qgcAFC5lW/EJHmC/lXqXExJrbO9BW73cXNqNlTI2uU3nm5+2qebmwbC5YEoqrWafmn nvz1+72h7h8tre8D1Or3yMLZz6sKX1O2lPDZ9pij1YAPkoX8loLJZYX8pp904eNQLkrzhQgpRBL/Z ewZE2U6Czzd9Vr0E6xlcU4lrjisKNHQzQ2jzn/4y6UibrPPZ9ISuuQUub8AhOHeaOeVKk5t6u4Rlx VsTRSuyPO7kDHm1R1BSA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.2 #3 (Red Hat Linux)) id 1iCmhA-0005uz-WE; Tue, 24 Sep 2019 15:25:41 +0000 Received: from szxga07-in.huawei.com ([45.249.212.35] helo=huawei.com) by bombadil.infradead.org with esmtps (Exim 4.92.2 #3 (Red Hat Linux)) id 1iCmf3-00035V-N2 for linux-arm-kernel@lists.infradead.org; Tue, 24 Sep 2019 15:23:32 +0000 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-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190924_082330_145912_30AAE75C X-CRM114-Status: UNSURE ( 9.47 ) X-CRM114-Notice: Please train this message. X-Spam-Score: -2.3 (--) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-2.3 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [45.249.212.35 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -0.0 SPF_HELO_PASS SPF: HELO matches SPF record X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 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 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org 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); } +static void qemu_sde_reset(void *opaque) +{ + int64_t ret; + CPUState *cs; + QemuSDEState *s = opaque; + + CPU_FOREACH(cs) { + QemuSDECpu *sde_cpu = get_sde_cpu(s, cs); + sdei_private_reset_common(s, cs, true); + sde_cpu->masked = true; + sde_cpu->critical_running_event = SDEI_INVALID_EVENT_ID; + sde_cpu->normal_running_event = SDEI_INVALID_EVENT_ID; + } + + ret = sdei_shared_reset_common(s, first_cpu, true); + if (ret) { + error_report("SDEI system reset failed: 0x%lx", ret); + } +} + static int qemu_sdei_pre_save(void *opaque) { QemuSDEState *s = opaque; @@ -1235,6 +1255,7 @@ static void sdei_initfn(Object *obj) sde_state = s; qemu_sde_init(s); + qemu_register_reset(qemu_sde_reset, s); } static void qemu_sde_class_init(ObjectClass *klass, void *data) From patchwork Tue Sep 24 15:21:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heyi Guo X-Patchwork-Id: 11159089 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0877014ED for ; Tue, 24 Sep 2019 15:24:42 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id DA339214DA for ; Tue, 24 Sep 2019 15:24:41 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="HGrmv5PP" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org DA339214DA Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=huawei.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=NTXcvceS0kxtDDP9Ub+KTsPtF0Rb0rzj/igVRJLcJgY=; b=HGrmv5PPzPEzfN EidUt1Q9jF80QdOZKsx2nX9IskOzA3+MPUYmbintGKWQZuKBnv8VEufyvAGlhHkSeuLQHnLdx5SUF 7GXfKrrOCjNT7GHUb2hB8Upq8j9WUwW/j5YD/81HNRxZUqN/qgzsaf18uzVUgjBGShsnXU4BffVWk hlVw5HJWe1hW0QY5coQ+WWY6JMs8XNjiLUqZvaF6u5ACZmM4Vci6qtQ+BduTGYC3/gvjiCdJ3Kkcd ReC/Fl8bU36QjdLSjmOGxsjjltpwX0/Z2rXiqKtoaNYzxbEn9i7Uky8wzpkXFE1GRb4fRf42X+dB3 bbZ+4UpwcjnfuuCMLLAA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.2 #3 (Red Hat Linux)) id 1iCmgC-00040J-L3; Tue, 24 Sep 2019 15:24:40 +0000 Received: from szxga07-in.huawei.com ([45.249.212.35] helo=huawei.com) by bombadil.infradead.org with esmtps (Exim 4.92.2 #3 (Red Hat Linux)) id 1iCmf3-00035h-Nt for linux-arm-kernel@lists.infradead.org; Tue, 24 Sep 2019 15:23:31 +0000 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-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190924_082330_136642_1DA6E721 X-CRM114-Status: GOOD ( 11.38 ) X-Spam-Score: -2.3 (--) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-2.3 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [45.249.212.35 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -0.0 SPF_HELO_PASS SPF: HELO matches SPF record X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 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 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org 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); } +static bool inject_event(QemuSDEState *s, CPUState *cs, + int32_t event, int irq) +{ + QemuSDE *sde; + + if (event < 0) { + return false; + } + sde = get_sde_no_check(s, event, cs); + if (sde->event_id == SDEI_INVALID_EVENT_ID) { + put_sde(sde, cs); + return false; + } + if (irq > 0 && sde->prop->interrupt != irq) { + /* Someone unbinds the interrupt! */ + put_sde(sde, cs); + return false; + } + sde->pending = true; + dispatch_single(s, sde, cs); + return true; +} + static int64_t unregister_single_sde(QemuSDEState *s, int32_t event, CPUState *cs, bool force) { @@ -1033,6 +1056,21 @@ void sdei_handle_request(CPUState *cs, struct kvm_run *run) } } +bool trigger_sdei_by_irq(int cpu, int irq) +{ + QemuSDEState *s = sde_state; + + if (!s || irq >= ARRAY_SIZE(s->irq_map)) { + return false; + } + + if (s->irq_map[irq] == SDEI_INVALID_EVENT_ID) { + return false; + } + + return inject_event(s, 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 @@ void sdei_handle_request(CPUState *cs, struct kvm_run *run); +/* + * Trigger an SDEI event bound to an interrupt. + * Return true if event has been triggered successfully. + * Return false if event has not been triggered for some reason. + */ +bool trigger_sdei_by_irq(int cpu, int irq); + #endif From patchwork Tue Sep 24 15:21:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heyi Guo X-Patchwork-Id: 11159093 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AF96B13B1 for ; Tue, 24 Sep 2019 15:25:25 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 8CC8120665 for ; Tue, 24 Sep 2019 15:25:25 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="cAzHUAoN" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8CC8120665 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=huawei.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=woLxIxKZrybuY/S7MaKq/4e4e56Bj6RlV1ZQ16WR2xA=; b=cAzHUAoN6lBPIm fMGNF7obzOdHwsKZncVYmaymBsqHczDTP7OkYeQg2wE0p8mfoUc0OhzCAdiDK1fQBJgVSZ3OLabK/ 9u8+tzGHTv7GeioLD8SReMNGMNFobwhnNPoO+cWbCzofeCIM4Yvp2d/K7ZL/PVKnfW6leFT1R4Qc1 zQ/2DQVp5hLYx0VtflHaVvZx99bWNaLPuufngkjYjo+NgyBRukHDNmeJP/DP3Mf2Wj0NXHP8NlJmR /Gsjx9UHn49O6oCbKiREvi8xy6EhfoSjp0ItBeRBOPThdEhxPC4+j+14MAt2D8/YfRdXu96zWp/DJ rMyMa/aOgdXtGqMrWO5Q==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.2 #3 (Red Hat Linux)) id 1iCmgu-0005h9-3J; Tue, 24 Sep 2019 15:25:24 +0000 Received: from szxga07-in.huawei.com ([45.249.212.35] helo=huawei.com) by bombadil.infradead.org with esmtps (Exim 4.92.2 #3 (Red Hat Linux)) id 1iCmf3-00035S-Vk for linux-arm-kernel@lists.infradead.org; Tue, 24 Sep 2019 15:23:32 +0000 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-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190924_082330_568426_692A8810 X-CRM114-Status: GOOD ( 11.23 ) X-Spam-Score: -2.3 (--) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-2.3 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [45.249.212.35 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -0.0 SPF_HELO_PASS SPF: HELO matches SPF record X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 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 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org 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) } } +void qemu_irq_remove_intercept(qemu_irq *gpio_in, int n) +{ + int i; + qemu_irq *old_irqs = gpio_in[0]->opaque; + for (i = 0; i < n; i++) { + gpio_in[i]->handler = old_irqs[i]->handler; + gpio_in[i]->opaque = old_irqs[i]->opaque; + } + qemu_free_irqs(old_irqs, n); +} + static const TypeInfo irq_type_info = { .name = TYPE_IRQ, .parent = TYPE_OBJECT, diff --git a/include/hw/irq.h b/include/hw/irq.h index 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); -/* For internal use in qtest. Similar to qemu_irq_split, but operating - on an existing vector of qemu_irq. */ +/* + * Similar to qemu_irq_split, but operating on an existing vector of qemu_irq. + */ void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n); +/* Restore the irq handler intercepted by qemu_irq_intercept_in() */ +void qemu_irq_remove_intercept(qemu_irq *gpio_in, int n); + #endif From patchwork Tue Sep 24 15:21:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heyi Guo X-Patchwork-Id: 11159101 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 534E114ED for ; Tue, 24 Sep 2019 15:26:19 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 3112B20665 for ; Tue, 24 Sep 2019 15:26:19 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="ApuoNlMA" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3112B20665 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=huawei.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=/HkCwivEzFX0w+01j3kPMpZvFaLUyBhnpG6fwH64kxU=; b=ApuoNlMANFWZOp nridJFsk27NvLPs1b8rDX4hUDd69R249OBzlyWCPNjMK2W0eTOw2ZmEOOelA3veZz0pWBDdg3WB27 YaQKtJw9/YKkffbEbbOCRjublI+2bwgG4GRaTm/bFYgCxm5sb1RXh4QrIg0w9Qb/IaJ732pGzgTrj j4IfWuyhrFqgGCvVHfKye3/2NszrFPVYT6gANEE6phMPPWzYvcpIpZg4tkJgnmWDk6N4T0Izl5svW owOmv/45ZrSuFCFs0upDhm24UWglHnMeyt82Kf66+ISP/jmBqB7OATE9dtM+VkdSZNVOYvj4KdrDE Ty7jhxCUHWwE4dXxh0Uw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.2 #3 (Red Hat Linux)) id 1iCmhj-0006O4-Td; Tue, 24 Sep 2019 15:26:16 +0000 Received: from szxga07-in.huawei.com ([45.249.212.35] helo=huawei.com) by bombadil.infradead.org with esmtps (Exim 4.92.2 #3 (Red Hat Linux)) id 1iCmf4-00035i-HZ for linux-arm-kernel@lists.infradead.org; Tue, 24 Sep 2019 15:23:33 +0000 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-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190924_082331_358997_5E107C8F X-CRM114-Status: GOOD ( 15.60 ) X-Spam-Score: -2.3 (--) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-2.3 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [45.249.212.35 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -0.0 SPF_HELO_PASS SPF: HELO matches SPF record X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 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 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org 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) } } +static int gic_int_to_irq(int num_irq, int intid, int cpu) +{ + if (intid >= GIC_INTERNAL) { + return intid - GIC_INTERNAL; + } + return num_irq - GIC_INTERNAL + cpu * GIC_INTERNAL + intid; +} + +static int irq_to_gic_int(int num_irq, int irq, int *cpu) +{ + if (irq < num_irq - GIC_INTERNAL) { + return irq + GIC_INTERNAL; + } + irq -= num_irq - GIC_INTERNAL; + *cpu = irq / GIC_INTERNAL; + return irq % GIC_INTERNAL; +} + static inline QemuSDECpu *get_sde_cpu(QemuSDEState *s, CPUState *cs) { assert(cs->cpu_index < s->sdei_max_cpus); @@ -381,6 +399,76 @@ static void dispatch_cpu(QemuSDEState *s, CPUState *cs, bool is_critical) } } +static void qemu_sdei_irq_handler(void *opaque, int irq, int level) +{ + int cpu = 0; + irq = irq_to_gic_int(sde_state->num_irq, irq, &cpu); + trigger_sdei_by_irq(cpu, irq); +} + +static void override_qemu_irq(QemuSDEState *s, int32_t event, uint32_t intid) +{ + qemu_irq irq; + QemuSDE *sde; + CPUState *cs; + int cpu; + + /* SPI */ + if (intid >= GIC_INTERNAL) { + cs = arm_get_cpu_by_id(0); + irq = qdev_get_gpio_in(s->gic_dev, + gic_int_to_irq(s->num_irq, intid, 0)); + if (irq) { + qemu_irq_intercept_in(&irq, qemu_sdei_irq_handler, 1); + } + sde = get_sde_no_check(s, event, cs); + sde->irq = irq; + put_sde(sde, cs); + return; + } + /* PPI */ + for (cpu = 0; cpu < s->sdei_max_cpus; cpu++) { + cs = arm_get_cpu_by_id(cpu); + irq = 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 = get_sde_no_check(s, event, cs); + sde->irq = irq; + put_sde(sde, cs); + } +} + +static void restore_qemu_irq(QemuSDEState *s, int32_t event, uint32_t intid) +{ + QemuSDE *sde; + CPUState *cs; + int cpu; + + /* SPI */ + if (intid >= GIC_INTERNAL) { + cs = arm_get_cpu_by_id(0); + sde = get_sde_no_check(s, event, cs); + if (sde->irq) { + qemu_irq_remove_intercept(&sde->irq, 1); + sde->irq = NULL; + } + put_sde(sde, cs); + return; + } + /* PPI */ + for (cpu = 0; cpu < s->sdei_max_cpus; cpu++) { + cs = arm_get_cpu_by_id(cpu); + sde = get_sde_no_check(s, event, cs); + if (sde->irq) { + qemu_irq_remove_intercept(&sde->irq, 1); + sde->irq = NULL; + } + put_sde(sde, cs); + } +} + 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, bool is_critical, sde_props[index].interrupt = intid; sde_props[index].is_shared = is_shared; sde_props[index].is_critical = is_critical; + override_qemu_irq(s, event, intid); s->irq_map[intid] = event; qemu_mutex_unlock(&sde_props[index].lock); qemu_mutex_unlock(&s->sdei_interrupt_bind_lock); @@ -433,6 +522,7 @@ static int32_t sdei_free_event_num_locked(QemuSDEState *s, QemuSDEProp *prop) goto unlock_return; } + restore_qemu_irq(s, prop->event_id, prop->interrupt); s->irq_map[prop->interrupt] = SDEI_INVALID_EVENT_ID; prop->event_id = SDEI_INVALID_EVENT_ID; prop->interrupt = SDEI_INVALID_INTERRUPT; @@ -929,13 +1019,33 @@ static int64_t sdei_event_pe_unmask(QemuSDEState *s, CPUState *cs, return SDEI_SUCCESS; } +static int dev_walkerfn(DeviceState *dev, void *opaque) +{ + QemuSDEState *s = opaque; + + if (object_dynamic_cast(OBJECT(dev), TYPE_ARM_GICV3_COMMON)) { + GICv3State *gic = ARM_GICV3_COMMON(dev); + s->num_irq = gic->num_irq; + s->gic_dev = dev; + return -1; + } + + if (object_dynamic_cast(OBJECT(dev), TYPE_ARM_GIC_COMMON)) { + GICState *gic = ARM_GIC_COMMON(dev); + s->num_irq = gic->num_irq; + s->gic_dev = dev; + return -1; + } + return 0; +} + static int64_t sdei_event_interrupt_bind(QemuSDEState *s, CPUState *cs, struct kvm_run *run) { uint64_t *args = (uint64_t *)(run->hypercall.args); uint32_t intid = args[1]; - if (intid < GIC_NR_SGIS || intid >= GIC_MAXIRQ) { + if (intid < GIC_NR_SGIS || intid >= s->num_irq) { return SDEI_INVALID_PARAMETERS; } return sdei_alloc_event_num(s, false, intid >= 32, intid); @@ -1042,6 +1152,17 @@ void sdei_handle_request(CPUState *cs, struct kvm_run *run) return; } + if (!sde_state->gic_dev) { + /* Search for ARM GIC device */ + qbus_walk_children(sysbus_get_default(), dev_walkerfn, + NULL, NULL, NULL, sde_state); + if (!sde_state->gic_dev) { + error_report("Cannot find ARM GIC device!"); + run->hypercall.args[0] = SDEI_NOT_SUPPORTED; + return; + } + } + if (func_id < SDEI_1_0_FN_BASE || func_id > SDEI_MAX_REQ) { error_report("Invalid SDEI function ID: 0x%x", func_id); run->hypercall.args[0] = SDEI_INVALID_PARAMETERS; @@ -1198,9 +1319,19 @@ static int qemu_sdei_post_load(void *opaque, int version_id) } } + /* Search for ARM GIC device */ + qbus_walk_children(sysbus_get_default(), dev_walkerfn, + NULL, NULL, NULL, s); + if (!s->gic_dev) { + error_report("Cannot find ARM GIC device!"); + return 0; + } + for (i = 0; i < PRIVATE_SLOT_COUNT + SHARED_SLOT_COUNT; i++) { - if (sde_props[i].interrupt != SDEI_INVALID_INTERRUPT) { - s->irq_map[sde_props[i].interrupt] = sde_props[i].event_id; + int intid = sde_props[i].interrupt; + if (intid != SDEI_INVALID_INTERRUPT) { + s->irq_map[intid] = sde_props[i].event_id; + override_qemu_irq(s, sde_props[i].event_id, intid); } } diff --git a/target/arm/sdei_int.h b/target/arm/sdei_int.h index 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 { 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; From patchwork Tue Sep 24 15:21:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heyi Guo X-Patchwork-Id: 11159103 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id F36BA14ED for ; Tue, 24 Sep 2019 15:26:38 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D069920665 for ; Tue, 24 Sep 2019 15:26:38 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="kPisyecQ" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D069920665 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=huawei.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=RH49JJP+kkznSkscmf8TkpbGuFPzkqGYONij81+MGyo=; b=kPisyecQoZjlHN fm6dqAMBhl4dNi2xfjZrgroT0VQx/9qtBOF49ObsRICnvhohWX0U9kF1th1SepnsI4kXPOgEB5ME4 KgDyAFCllgj9+Ub8owH9lWDsCV/iPLmFlb4Y5vd6OYOqso3V/1+8H2xRP7sHVePEp5eRNaGKZ/euX I9VT826LHBLrUgSgUcEqovYI6xcxo30pBdzRpOYecFCvuAn+am8klSX/1uucwPEmyI+vFWILtxsBM dUKqpXxG6mZFQAF6W1Vb/7Ox/pIMv7+cWMOSkfy1veMJmlrVrgwGT8N7hOGjGlkUn//NcgMHILDYw 7XkAEF6zWStEuOrrDFOQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.2 #3 (Red Hat Linux)) id 1iCmi6-0006fz-7H; Tue, 24 Sep 2019 15:26:38 +0000 Received: from szxga07-in.huawei.com ([45.249.212.35] helo=huawei.com) by bombadil.infradead.org with esmtps (Exim 4.92.2 #3 (Red Hat Linux)) id 1iCmf8-00039b-LX for linux-arm-kernel@lists.infradead.org; Tue, 24 Sep 2019 15:23:36 +0000 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-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190924_082335_030766_3A35F518 X-CRM114-Status: GOOD ( 11.39 ) X-Spam-Score: -2.3 (--) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-2.3 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [45.249.212.35 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -0.0 SPF_HELO_PASS SPF: HELO matches SPF record X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 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 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org 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 @@ static QemuSDEState *sde_state; +typedef struct QemuSDEIBindNotifyEntry { + QTAILQ_ENTRY(QemuSDEIBindNotifyEntry) entry; + QemuSDEIBindNotify *func; + void *opaque; + int irq; +} QemuSDEIBindNotifyEntry; + +static QTAILQ_HEAD(, QemuSDEIBindNotifyEntry) bind_notifiers = + QTAILQ_HEAD_INITIALIZER(bind_notifiers); + +void qemu_register_sdei_bind_notifier(QemuSDEIBindNotify *func, + void *opaque, int irq) +{ + QemuSDEIBindNotifyEntry *be = g_new0(QemuSDEIBindNotifyEntry, 1); + + be->func = func; + be->opaque = opaque; + be->irq = irq; + QTAILQ_INSERT_TAIL(&bind_notifiers, be, entry); +} + +void qemu_unregister_sdei_bind_notifier(QemuSDEIBindNotify *func, + void *opaque, int irq) +{ + QemuSDEIBindNotifyEntry *be; + + QTAILQ_FOREACH(be, &bind_notifiers, entry) { + if (be->func == func && be->opaque == opaque && be->irq == irq) { + QTAILQ_REMOVE(&bind_notifiers, be, entry); + g_free(be); + return; + } + } +} + +static void sdei_notify_bind(int irq, int32_t event, bool bind) +{ + QemuSDEIBindNotifyEntry *be, *nbe; + + QTAILQ_FOREACH_SAFE(be, &bind_notifiers, entry, nbe) { + if (be->irq == irq) { + be->func(be->opaque, irq, event, bind); + } + } +} + static void qemu_sde_prop_init(QemuSDEState *s) { QemuSDEProp *sde_props = s->sde_props_state; @@ -502,6 +548,7 @@ static int32_t sdei_alloc_event_num(QemuSDEState *s, bool is_critical, sde_props[index].interrupt = intid; sde_props[index].is_shared = is_shared; sde_props[index].is_critical = is_critical; + sdei_notify_bind(intid, event, true); override_qemu_irq(s, event, intid); s->irq_map[intid] = event; qemu_mutex_unlock(&sde_props[index].lock); @@ -522,6 +569,7 @@ static int32_t sdei_free_event_num_locked(QemuSDEState *s, QemuSDEProp *prop) goto unlock_return; } + sdei_notify_bind(prop->interrupt, prop->event_id, false); restore_qemu_irq(s, prop->event_id, prop->interrupt); s->irq_map[prop->interrupt] = SDEI_INVALID_EVENT_ID; prop->event_id = SDEI_INVALID_EVENT_ID; @@ -1331,6 +1379,7 @@ static int qemu_sdei_post_load(void *opaque, int version_id) int intid = sde_props[i].interrupt; if (intid != SDEI_INVALID_INTERRUPT) { s->irq_map[intid] = 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 *run); */ bool trigger_sdei_by_irq(int cpu, int irq); +/* + * Notify callback prototype; the argument "bind" tells whether it is a bind + * operation or unbind one. + */ +typedef void QemuSDEIBindNotify(void *opaque, int irq, + int32_t event, bool bind); +/* + * Register a notify callback for a specific interrupt bind operation; the + * client 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 From patchwork Tue Sep 24 15:21:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heyi Guo X-Patchwork-Id: 11159107 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BCEF413B1 for ; Tue, 24 Sep 2019 15:27:15 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 9A3E1214DA for ; Tue, 24 Sep 2019 15:27:15 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="HtQL3Acn" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 9A3E1214DA Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=huawei.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=ysOtPJroHNAvh0PR9p7izRbcyJk95ET0WUCjR7sF7cs=; b=HtQL3AcnwHfRrg xc2pZVwnaF4y437n/ESp4Mw4qwLM/FlafzUJE1lzFAYoJ2jlGD0dFQCWeJOEVHzIbNZCsSBrDK9Eo Ifk2PqiJYy5pf6kij1xFrKSCCj1vL3VQ38X26BT3CZJ1Z+6dBMNi+KNFOOiPw8lN1jgrCMb57w9DH p6cftcZ7wA1YdgvK0hH94PYFy4g0783VvDxnqO5WoKZe3dY59UVKaf0me8zHt0vOYqdpQt1zxn/XO 0AbIgepmcErHQ/vlstW/W2ZB7Z28k60VVBL7Nbm3bfcynGM+VipPMgYdMeWdsyqG+vj97VOQDFVk2 rLljgiYSWIhW5llO5Eeg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.2 #3 (Red Hat Linux)) id 1iCmih-0007FB-50; Tue, 24 Sep 2019 15:27:15 +0000 Received: from szxga04-in.huawei.com ([45.249.212.190] helo=huawei.com) by bombadil.infradead.org with esmtps (Exim 4.92.2 #3 (Red Hat Linux)) id 1iCmf8-00036H-4R for linux-arm-kernel@lists.infradead.org; Tue, 24 Sep 2019 15:23:37 +0000 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-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190924_082336_096419_90E7115E X-CRM114-Status: UNSURE ( 9.40 ) X-CRM114-Notice: Please train this message. X-Spam-Score: -2.3 (--) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-2.3 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [45.249.212.190 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -0.0 SPF_HELO_PASS SPF: HELO matches SPF record X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 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 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org 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]; }; +#define KVM_CAP_FORWARD_HYPERCALL_EXCL_PSCI (1 << 0) + /* for KVM_PPC_GET_PVINFO */ #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 #ifdef KVM_CAP_IRQ_ROUTING From patchwork Tue Sep 24 15:21:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heyi Guo X-Patchwork-Id: 11159097 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B38A814ED for ; Tue, 24 Sep 2019 15:25:59 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 917A320665 for ; Tue, 24 Sep 2019 15:25:59 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="FojHN+Dr" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 917A320665 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=huawei.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=Jyovbc7V4oVPDcWcpLfTepDstqtPno4JElT1TdOwCsU=; b=FojHN+DrffC/BD LpCVEmoGC637vzMblzHobV9a3Q3WYEMIAGJRfUKDTYJ9Yh2mpFPxuVgcCD8NLfPCBZJZJyrsPMqs3 jWxGqmUSjMMYWiwFUws2WEYNhOAE+FmlLP2cRQvW61WPywsrJoNny8kXLFnMRLolk9DK8Y7AVNAv5 v/rURFiCuBAgEUSHEPjwRMjQrU2LCZrZvBdWlmkVNCGlyDYI/sd403Cx+OvybdNxyz4/QdaEnB+/4 OVtaLSMSkYF2RA77HgT1sPkQ8Y67XEaAAMT7mUgiloBFifNH9br5lPoSI0mft0U7vKRsEO8MQ2fjV oxo7WiuXq10uazzJn45g==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.2 #3 (Red Hat Linux)) id 1iCmhS-00069H-RY; Tue, 24 Sep 2019 15:25:58 +0000 Received: from szxga07-in.huawei.com ([45.249.212.35] helo=huawei.com) by bombadil.infradead.org with esmtps (Exim 4.92.2 #3 (Red Hat Linux)) id 1iCmf3-00035j-Mp for linux-arm-kernel@lists.infradead.org; Tue, 24 Sep 2019 15:23:33 +0000 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-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190924_082330_754024_6A2B69E7 X-CRM114-Status: GOOD ( 10.61 ) X-Spam-Score: -2.3 (--) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-2.3 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [45.249.212.35 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -0.0 SPF_HELO_PASS SPF: HELO matches SPF record X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 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 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org 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) +bool sdei_enabled; static QemuSDEState *sde_state; typedef struct QemuSDEIBindNotifyEntry { @@ -1465,6 +1466,7 @@ static const VMStateDescription vmstate_sde_state = { static void sdei_initfn(Object *obj) { QemuSDEState *s = QEMU_SDEI(obj); + KVMState *kvm = KVM_STATE(current_machine->accelerator); if (sde_state) { error_report("Only one SDEI dispatcher is allowed!"); @@ -1474,6 +1476,21 @@ static void sdei_initfn(Object *obj) qemu_sde_init(s); qemu_register_reset(qemu_sde_reset, s); + + if (kvm_check_extension(kvm, KVM_CAP_FORWARD_HYPERCALL)) { + int ret; + ret = kvm_vm_enable_cap(kvm, KVM_CAP_FORWARD_HYPERCALL, 0, + KVM_CAP_FORWARD_HYPERCALL_EXCL_PSCI); + if (ret < 0) { + error_report("Enable hypercall forwarding failed: %s", + strerror(-ret)); + abort(); + } + sdei_enabled = true; + info_report("qemu sdei enabled"); + } else { + info_report("KVM does not support forwarding hypercall."); + } } static void qemu_sde_class_init(ObjectClass *klass, void *data) diff --git a/target/arm/sdei.h b/target/arm/sdei.h index feaaf1a..95e7d8d 100644 --- a/target/arm/sdei.h +++ b/target/arm/sdei.h @@ -29,6 +29,8 @@ #define SDEI_MAX_REQ SDEI_1_0_FN(0x12) +extern bool sdei_enabled; + void sdei_handle_request(CPUState *cs, struct kvm_run *run); /* From patchwork Tue Sep 24 15:21:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heyi Guo X-Patchwork-Id: 11159105 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5AEDC14ED for ; Tue, 24 Sep 2019 15:27:00 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 38E1F20665 for ; Tue, 24 Sep 2019 15:27:00 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="ERrQrkQ5" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 38E1F20665 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=huawei.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=fEmeFgjSnUVeB5amDk4utnPtCwanS/+eaFKeufatnNY=; b=ERrQrkQ5kBfmV8 OPtgFqZfz5gu9hPSigEbRmfWWIUIe6jL1udBYMDkCmJXLxkeOab7RXXeLe1+9EhrJ4NSbCbadglZh tYy0fadDAybKojQU3Xew4/zc7CILpSc9rtz1Wjb7rp5n6XlpRPj6KEgffs4u1uwlVQ3WHhJBGYDP2 L73Ww01xf1fjVsMHns+mTNm+8LMhgZvgYRVXcw4XINbtSR9v7aJuCh3jAmSAm8pYo54tTTh0GKVLx JLCy3TFqVhgYccII1gk/C0sH+l1J/zzcDUHtr/btG4aeqkgTO3LAS/37XFGRgs6LS60mUBrHI2vGC lwklux5BLbdYv94ByjUg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.2 #3 (Red Hat Linux)) id 1iCmiQ-0006zO-F7; Tue, 24 Sep 2019 15:26:58 +0000 Received: from szxga07-in.huawei.com ([45.249.212.35] helo=huawei.com) by bombadil.infradead.org with esmtps (Exim 4.92.2 #3 (Red Hat Linux)) id 1iCmf8-0003A0-3A for linux-arm-kernel@lists.infradead.org; Tue, 24 Sep 2019 15:23:36 +0000 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-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190924_082334_728354_808CD7C8 X-CRM114-Status: GOOD ( 10.14 ) X-Spam-Score: -2.3 (--) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-2.3 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [45.249.212.35 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -0.0 SPF_HELO_PASS SPF: HELO matches SPF record X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 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 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org 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" const KVMCapabilityInfo kvm_arch_required_capabilities[] = { KVM_CAP_LAST_INFO @@ -668,6 +669,19 @@ MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run) } +static void kvm_arm_handle_hypercall(CPUState *cs, struct kvm_run *run) +{ + uint32_t func_id = run->hypercall.args[0]; + + if (sdei_enabled && + func_id >= SDEI_1_0_FN_BASE && func_id <= SDEI_MAX_REQ) { + sdei_handle_request(cs, run); + } else { + run->hypercall.args[0] = -1; + } +} + + int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) { int ret = 0; @@ -678,6 +692,9 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) ret = EXCP_DEBUG; } /* otherwise return to guest */ break; + case KVM_EXIT_HYPERCALL: + kvm_arm_handle_hypercall(cs, run); + break; default: qemu_log_mask(LOG_UNIMP, "%s: un-handled exit reason %d\n", __func__, run->exit_reason); From patchwork Tue Sep 24 15:21:51 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heyi Guo X-Patchwork-Id: 11159109 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7612613B1 for ; Tue, 24 Sep 2019 15:27:35 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 537A0214DA for ; Tue, 24 Sep 2019 15:27:35 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="fRJk7AIE" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 537A0214DA Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=huawei.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=B5A8r6zI4myBmYPYmWL1YXBNAfltRTyh0sc2E+qpHo4=; b=fRJk7AIElEmp63 uGjNgQzM7r9GnOFapr97wGuDgZTlOXkd52GUSRY7oDlnQZWyFDcIC683JRlMZ9nSCPZ42hJUJkNfV eZxnxLTyQUQOlTJtoXozupm2WSh93rK4P2fF/7TE+Quio4NpjrAiTL3g4ZPCZ5hNOiQjDvr53+Fqo T3Xe4mj+4POqXe/cd8mdh+NmRZrGP7VKe5xjXt/+pD4ZTNn+N+3IkJIzMscIHeWwJnYllZnaQCrAa pV5S4E5c3/6e+z4bXuX1vG3d61pjIkFvehrnckXpE9uyIrOM4Hcr247nd7ufbAY68U1Qup4a0LerZ Icf3NBg8ZjKfb/IrKfHA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.2 #3 (Red Hat Linux)) id 1iCmj0-0007Ua-N7; Tue, 24 Sep 2019 15:27:34 +0000 Received: from szxga07-in.huawei.com ([45.249.212.35] helo=huawei.com) by bombadil.infradead.org with esmtps (Exim 4.92.2 #3 (Red Hat Linux)) id 1iCmf9-0003AQ-HV for linux-arm-kernel@lists.infradead.org; Tue, 24 Sep 2019 15:23:37 +0000 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-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190924_082336_099380_BDEC79FF X-CRM114-Status: UNSURE ( 9.68 ) X-CRM114-Notice: Please train this message. X-Spam-Score: -2.3 (--) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-2.3 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [45.249.212.35 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -0.0 SPF_HELO_PASS SPF: HELO matches SPF record X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 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 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org 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, VirtMachineState *vms) } static void +build_sdei(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) +{ + int sdei_start = table_data->len; + + (void)acpi_data_push(table_data, sizeof(AcpiSdei)); + build_header(linker, table_data, (void *)(table_data->data + sdei_start), + "SDEI", table_data->len - sdei_start, 1, NULL, NULL); +} + +static void build_spcr(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) { AcpiSerialPortConsoleRedirection *spcr; @@ -796,6 +807,11 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables) acpi_add_table(table_offsets, tables_blob); build_spcr(tables_blob, tables->linker, vms); + if (sdei_enabled) { + acpi_add_table(table_offsets, tables_blob); + build_sdei(tables_blob, tables->linker, vms); + } + if (ms->numa_state->num_nodes > 0) { acpi_add_table(table_offsets, tables_blob); build_srat(tables_blob, tables->linker, vms); 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; +struct AcpiSdei { + ACPI_TABLE_HEADER_DEF /* ACPI common table header */ +} QEMU_PACKED; +typedef struct AcpiSdei AcpiSdei; + #endif