Received: by 2002:a25:1506:0:0:0:0:0 with SMTP id 6csp1866789ybv; Fri, 14 Feb 2020 07:21:45 -0800 (PST) X-Google-Smtp-Source: APXvYqxMOnn2cIrVzs0v50yJqckIDzB2AF3MsrqKPtY2O4TbIid25m+xwGPP1Gc07VeXAuvorJUW X-Received: by 2002:a9d:74c4:: with SMTP id a4mr2766922otl.119.1581693704631; Fri, 14 Feb 2020 07:21:44 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1581693704; cv=none; d=google.com; s=arc-20160816; b=ecBFphQ3sBz1r38SjGUgKNSxsHMcBQBbm2uWsfxdbBjMuwb5RfYAVp1nuRaDwLwkKK QrgKoN3Ih6UrTvQ2oWCc8RWngsMoWNWg5P1CGjKBgHO2bt8kwwu5sixFs1y/83k9sTwG UlIvTqpgKycGYk/71qLfx+67JqGUEeADBgwigS5Aun2FwN5GLQ+KiseT5XPR4/TDHUhS OTm6qS+oYIpJLfFILDa26dZCHGSJ9eGT4yTCdJdG32mf3uTGFuYn96guhPE6th38kFYv F0gLyKgA73MzbYTmgee7O6N4K7gLjBcSEP8zA06WX24iH1ANbXm4uUJqGajuYIAo1m7L 7cgQ== 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=U1SLgM9EuyHRxyq8+9TxpoR7JSl1KdweaQNEwdlsOcY=; b=W7l7tsbtmCtebnMuv+8e+coC6bS1Px9/ave4CE+z2IaJ57Yh9T7CP5rGKMycL2ICA4 YQM6CTxI8XjcLJjxZUmRVFfRhmQAG4SLFjOPn0JzeeO9WgXa8R0AWZbCYLT213kAE5h5 zTzWsmFU9KX7z9K6+1uog6wklrQx+LhuefpbRcJuS+TH9IQLpk+m4oyYbEOdpkbHBK3T MermVjtuZ081l4a+1N8LQSP/dA43USFO1jqWhpZrJr8kvpXvAuz8zxd5/rSRkFepHqoX xEnqPT4EpCWpUD1cfdI/vZ2E1rg8I1xv8JTDhABGNFKFzXhxzKBvsRujkwbcdEETxXVg M94g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=QsF85+YH; 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 a11si2987116otq.223.2020.02.14.07.21.32; Fri, 14 Feb 2020 07:21:44 -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=QsF85+YH; 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 S2387591AbgBNPVQ (ORCPT + 99 others); Fri, 14 Feb 2020 10:21:16 -0500 Received: from mail.kernel.org ([198.145.29.99]:34392 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387570AbgBNPVP (ORCPT ); Fri, 14 Feb 2020 10:21:15 -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 743702082F; Fri, 14 Feb 2020 15:21:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1581693674; bh=569NeW8Dm5AkGLXd1hzDBfiVUVN9Yy66W/d/qknuHC4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QsF85+YHSPrNVsA48g/Z8BWYatwIgxNCLX4lMER68E1IKun9naiwygADMAlQgFWfk kimOtcjlWvJ1ie5m4BQDJkwu3t3snNLfl90YoVf34cLz8gJJ2WwZ0dIrxM0+VhGD5X FLFCDylfAl7XwCaW8WlvOSm1tJNk5MnDbkpZre5Q= 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 1j2cPn-0057sw-MG; Fri, 14 Feb 2020 14:57:59 +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 v4 16/20] KVM: arm64: GICv4.1: Allow SGIs to switch between HW and SW interrupts Date: Fri, 14 Feb 2020 14:57:32 +0000 Message-Id: <20200214145736.18550-17-maz@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200214145736.18550-1-maz@kernel.org> References: <20200214145736.18550-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. Signed-off-by: Marc Zyngier --- include/kvm/arm_vgic.h | 3 ++ virt/kvm/arm/vgic/vgic-v3.c | 2 + virt/kvm/arm/vgic/vgic-v4.c | 96 +++++++++++++++++++++++++++++++++++++ virt/kvm/arm/vgic/vgic.h | 1 + 4 files changed, 102 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-v3.c b/virt/kvm/arm/vgic/vgic-v3.c index 1bc09b523486..2c9fc13e2c59 100644 --- a/virt/kvm/arm/vgic/vgic-v3.c +++ b/virt/kvm/arm/vgic/vgic-v3.c @@ -540,6 +540,8 @@ int vgic_v3_map_resources(struct kvm *kvm) goto out; } + if (kvm_vgic_global_state.has_gicv4_1) + vgic_v4_configure_vsgis(kvm); dist->ready = true; out: diff --git a/virt/kvm/arm/vgic/vgic-v4.c b/virt/kvm/arm/vgic/vgic-v4.c index c2fcde104ea2..063785fd2dc7 100644 --- a/virt/kvm/arm/vgic/vgic-v4.c +++ b/virt/kvm/arm/vgic/vgic-v4.c @@ -97,6 +97,102 @@ 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); + vgic_v4_sync_sgi_config(vpe, irq); + /* + * SGIs are initialised as disabled. Enable them if + * required by the rest of the VGIC init code. + */ + 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