Received: by 2002:a25:c205:0:0:0:0:0 with SMTP id s5csp4882364ybf; Wed, 4 Mar 2020 12:37:19 -0800 (PST) X-Google-Smtp-Source: ADFU+vtwYgKs55jNpLRlZARNyEokoqiajkFOpz6CjDxkljtb/V6naEo7OqTvyGzMI0V3yR/VtkJ9 X-Received: by 2002:aca:b4c3:: with SMTP id d186mr2992737oif.131.1583354239730; Wed, 04 Mar 2020 12:37:19 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1583354239; cv=none; d=google.com; s=arc-20160816; b=cxNY3gDg2hkSTrAlwX4pnSAU+6VzpsrwkgsHP50J+Q+HU0u/2/YK2V7jkDledA+t58 M/lIaJ4fusB0RL64miLQLpnBkiWLM8KzWHKNCUpIQV/D6SVh/Iu4nZrAPnDdoavRwABc 3KDuxPPLtcj7AYdLxClyJqq78DqIYykL/OGX+XtvyAq3B61MvAuFSUXXc6Lqdl355MIr CfDlcyoShfAlG/mrCL9hKZLZLsj2hvsoC1gXSMfgcMcjrBdS2gGfcGuUeoeD1ujZuq01 Sd+M/jgi25h1Hs7zxxGJ7TZlvtt8hRxOl0pMsYw/JguKEb8Spfy86IvbW8g5s6vptESl YSjw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=IhOlXet0QlQaqL7Li8pPoRa38GLb6EGH0nde47zWC3w=; b=V9DGXX/LrHxhfz3Q5jQDQNjXGhcUKNYGwUlKEAJjzJYwrfIeST4l+WQIku0vImj5JU 4e00vCsJcXNfoWxL1gd40pYmyA8AVXvuqSq/+b94GbyFBXqz/JgB2y/cYiiLDvytRuTc uWb6/0pracgVP7qAoxTGsEexucqKB+ru6Kw52dU2gLi0SIaQao1/UWA6K9h/vfSyhrSF L5vNVIKmC0EUqFAHjQYdU4pa4Oeb+IL0JIKioCk2MJUh8wqxXGQWO+X3CF6GHIGp7n8w fXJhpfBiCvkbquTlj5lIZv+OzsQ43S6WMc1FAzHiQfb/W49Y5+DoRuttFdtU5+MBzEo7 uk3A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=HCiBvg0C; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id t1si1839199oic.140.2020.03.04.12.37.07; Wed, 04 Mar 2020 12:37:19 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=HCiBvg0C; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388519AbgCDUgl (ORCPT + 99 others); Wed, 4 Mar 2020 15:36:41 -0500 Received: from mail.kernel.org ([198.145.29.99]:36712 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2388504AbgCDUgk (ORCPT ); Wed, 4 Mar 2020 15:36:40 -0500 Received: from disco-boy.misterjones.org (disco-boy.misterjones.org [51.254.78.96]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 540EC21556; Wed, 4 Mar 2020 20:36:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1583354199; bh=FUJpoSbHjQOCLsMJclmjToiLjlEFsimNaSCwFeQkIrY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HCiBvg0CZ/ks/xA+7vpaSmwbz7zQtcTIt0EENnqMHaJmY5cP7B1lVg2SdnYLl/Get QzLHWVXyLC486+uD+umXTzn9xPP6fvS9ZRMes4xAb6nTSgXmGEvnEU7Izkibs08zHa vefG3KTaDt44wyB0BQt/FKWJio+sC3OFpRC6Wm8A= Received: from 78.163-31-62.static.virginmediabusiness.co.uk ([62.31.163.78] helo=why.lan) by disco-boy.misterjones.org with esmtpsa (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1j9ajF-00A59R-Ls; Wed, 04 Mar 2020 20:34:53 +0000 From: Marc Zyngier To: linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Lorenzo Pieralisi , Jason Cooper , Robert Richter , Thomas Gleixner , Zenghui Yu , Eric Auger , James Morse , Julien Thierry , Suzuki K Poulose Subject: [PATCH v5 19/23] KVM: arm64: GICv4.1: Allow SGIs to switch between HW and SW interrupts Date: Wed, 4 Mar 2020 20:33:26 +0000 Message-Id: <20200304203330.4967-20-maz@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200304203330.4967-1-maz@kernel.org> References: <20200304203330.4967-1-maz@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SA-Exim-Connect-IP: 62.31.163.78 X-SA-Exim-Rcpt-To: linux-arm-kernel@lists.infradead.org, kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, lorenzo.pieralisi@arm.com, jason@lakedaemon.net, rrichter@marvell.com, tglx@linutronix.de, yuzenghui@huawei.com, eric.auger@redhat.com, james.morse@arm.com, julien.thierry.kdev@gmail.com, suzuki.poulose@arm.com X-SA-Exim-Mail-From: maz@kernel.org X-SA-Exim-Scanned: No (on disco-boy.misterjones.org); SAEximRunCond expanded to false Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org In order to let a guest buy in the new, active-less SGIs, we need to be able to switch between the two modes. Handle this by stopping all guest activity, transfer the state from one mode to the other, and resume the guest. Nothing calls this code so far, but a later patch will plug it into the MMIO emulation. Signed-off-by: Marc Zyngier --- include/kvm/arm_vgic.h | 3 ++ virt/kvm/arm/vgic/vgic-v4.c | 94 +++++++++++++++++++++++++++++++++++++ virt/kvm/arm/vgic/vgic.h | 1 + 3 files changed, 98 insertions(+) diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index 63457908c9c4..69f4164d6477 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -231,6 +231,9 @@ struct vgic_dist { /* distributor enabled */ bool enabled; + /* Wants SGIs without active state */ + bool nassgireq; + struct vgic_irq *spis; struct vgic_io_device dist_iodev; diff --git a/virt/kvm/arm/vgic/vgic-v4.c b/virt/kvm/arm/vgic/vgic-v4.c index c2fcde104ea2..a65dc1c85363 100644 --- a/virt/kvm/arm/vgic/vgic-v4.c +++ b/virt/kvm/arm/vgic/vgic-v4.c @@ -97,6 +97,100 @@ static irqreturn_t vgic_v4_doorbell_handler(int irq, void *info) return IRQ_HANDLED; } +static void vgic_v4_sync_sgi_config(struct its_vpe *vpe, struct vgic_irq *irq) +{ + vpe->sgi_config[irq->intid].enabled = irq->enabled; + vpe->sgi_config[irq->intid].group = irq->group; + vpe->sgi_config[irq->intid].priority = irq->priority; +} + +static void vgic_v4_enable_vsgis(struct kvm_vcpu *vcpu) +{ + struct its_vpe *vpe = &vcpu->arch.vgic_cpu.vgic_v3.its_vpe; + int i; + + /* + * With GICv4.1, every virtual SGI can be directly injected. So + * let's pretend that they are HW interrupts, tied to a host + * IRQ. The SGI code will do its magic. + */ + for (i = 0; i < VGIC_NR_SGIS; i++) { + struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, i); + struct irq_desc *desc; + int ret; + + if (irq->hw) { + vgic_put_irq(vcpu->kvm, irq); + continue; + } + + irq->hw = true; + irq->host_irq = irq_find_mapping(vpe->sgi_domain, i); + + /* Transfer the full irq state to the vPE */ + vgic_v4_sync_sgi_config(vpe, irq); + desc = irq_to_desc(irq->host_irq); + ret = irq_domain_activate_irq(irq_desc_get_irq_data(desc), + false); + if (!WARN_ON(ret)) { + /* Transfer pending state */ + ret = irq_set_irqchip_state(irq->host_irq, + IRQCHIP_STATE_PENDING, + irq->pending_latch); + WARN_ON(ret); + irq->pending_latch = false; + } + + vgic_put_irq(vcpu->kvm, irq); + } +} + +static void vgic_v4_disable_vsgis(struct kvm_vcpu *vcpu) +{ + int i; + + for (i = 0; i < VGIC_NR_SGIS; i++) { + struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, i); + struct irq_desc *desc; + int ret; + + if (!irq->hw) { + vgic_put_irq(vcpu->kvm, irq); + continue; + } + + irq->hw = false; + ret = irq_get_irqchip_state(irq->host_irq, + IRQCHIP_STATE_PENDING, + &irq->pending_latch); + WARN_ON(ret); + + desc = irq_to_desc(irq->host_irq); + irq_domain_deactivate_irq(irq_desc_get_irq_data(desc)); + + vgic_put_irq(vcpu->kvm, irq); + } +} + +/* Must be called with the kvm lock held */ +void vgic_v4_configure_vsgis(struct kvm *kvm) +{ + struct vgic_dist *dist = &kvm->arch.vgic; + struct kvm_vcpu *vcpu; + int i; + + kvm_arm_halt_guest(kvm); + + kvm_for_each_vcpu(i, vcpu, kvm) { + if (dist->nassgireq) + vgic_v4_enable_vsgis(vcpu); + else + vgic_v4_disable_vsgis(vcpu); + } + + kvm_arm_resume_guest(kvm); +} + /** * vgic_v4_init - Initialize the GICv4 data structures * @kvm: Pointer to the VM being initialized diff --git a/virt/kvm/arm/vgic/vgic.h b/virt/kvm/arm/vgic/vgic.h index c7fefd6b1c80..769e4802645e 100644 --- a/virt/kvm/arm/vgic/vgic.h +++ b/virt/kvm/arm/vgic/vgic.h @@ -316,5 +316,6 @@ void vgic_its_invalidate_cache(struct kvm *kvm); bool vgic_supports_direct_msis(struct kvm *kvm); int vgic_v4_init(struct kvm *kvm); void vgic_v4_teardown(struct kvm *kvm); +void vgic_v4_configure_vsgis(struct kvm *kvm); #endif -- 2.20.1