Received: by 2002:a05:6a10:f347:0:0:0:0 with SMTP id d7csp631380pxu; Sun, 22 Nov 2020 22:58:12 -0800 (PST) X-Google-Smtp-Source: ABdhPJzvulQUzXuzo3hCi4bmXg8QtTtirRSpR9Gt7knC5JDrQ8zEnTYZxdIIw3TaCQbrCohdrDFn X-Received: by 2002:a05:6402:1a22:: with SMTP id be2mr24229696edb.102.1606114691795; Sun, 22 Nov 2020 22:58:11 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1606114691; cv=none; d=google.com; s=arc-20160816; b=Y4QdDagVcnY4OmNtbpzmXaP27yI9RlRtrhznfou8FkuGo1SS/isiz9UKUCiyDsOKGq h9hBduChHCNDXIKZwTLjkpNNuMH78tF1t9C18epde+Qs3/kCC9Hd8WPrw0QD++PzeBEF /MN2P0R8mog9hTJFumJDvh6cpBpqGbntUgqexX3/Y2fLAnm6FLtfU/bEBaRmrtpcGu/t cesGDehM76mCSMmKi6tzRresBxvj4Zam5upAWS/qlKAHzDFpQYJcyAvd476XMIV1t31h PcTEGrf+IfSHYxaMcDvkXgwhBDNzBoOPr2t0jWOCSO2GN59f+ciUqGpiSw2vg8HBo9Rd lCzg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=1TY9AAoowySAODbiqK3MZp1+QzdSnmSXs+9PIuhcX1E=; b=o6n/Kuyr0/+gvocrgZg6bQUJYnOXeKTRmW+NpJxMRJrfiT9WbKASv/2k3ZzHpZOT5X xltyFWB4Ca0s/vG2ZZmUCBVJDya8Y/3i/McrJcXDy8vss+wiR1wOQJ70qGGuOhNzt8Kl qVYg8aCfmAKL3/v7OcPF8eceajtznjdGV9uGd415aUn8ZLihKooBpHgUYrDcST8sQwnr VMVI6Qbi8kNU6PVonE6PR4pbQc1volwZxLJF0D8NBWHjQSgGYKArYaiD/ORVDKwdkACF MsGgrEdtLXH/BQ7kuDmDRafmmLE3q3tMrAvxr6qeJKIkRXTXVSVy2FyaQtBfT/nqv4q7 baiQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id mu6si5539143ejb.302.2020.11.22.22.57.49; Sun, 22 Nov 2020 22:58:11 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727916AbgKWGzA (ORCPT + 99 others); Mon, 23 Nov 2020 01:55:00 -0500 Received: from szxga05-in.huawei.com ([45.249.212.191]:8012 "EHLO szxga05-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725275AbgKWGy7 (ORCPT ); Mon, 23 Nov 2020 01:54:59 -0500 Received: from DGGEMS405-HUB.china.huawei.com (unknown [172.30.72.59]) by szxga05-in.huawei.com (SkyGuard) with ESMTP id 4CfdDn1KpJzhg2v; Mon, 23 Nov 2020 14:54:33 +0800 (CST) Received: from DESKTOP-7FEPK9S.china.huawei.com (10.174.187.74) by DGGEMS405-HUB.china.huawei.com (10.3.19.205) with Microsoft SMTP Server id 14.3.487.0; Mon, 23 Nov 2020 14:54:43 +0800 From: Shenming Lu To: Marc Zyngier , James Morse , "Julien Thierry" , Suzuki K Poulose , Eric Auger , , , , , Christoffer Dall CC: Alex Williamson , Kirti Wankhede , Cornelia Huck , Neo Jia , , , Subject: [RFC PATCH v1 2/4] KVM: arm64: GICv4.1: Try to save hw pending state in save_pending_tables Date: Mon, 23 Nov 2020 14:54:08 +0800 Message-ID: <20201123065410.1915-3-lushenming@huawei.com> X-Mailer: git-send-email 2.27.0.windows.1 In-Reply-To: <20201123065410.1915-1-lushenming@huawei.com> References: <20201123065410.1915-1-lushenming@huawei.com> MIME-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8bit X-Originating-IP: [10.174.187.74] X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org After pausing all vCPUs and devices capable of interrupting, in order to save the information of all interrupts, besides flushing the pending states in kvm’s vgic, we also try to flush the states of VLPIs in the virtual pending tables into guest RAM, but we need to have GICv4.1 and safely unmap the vPEs first. Signed-off-by: Shenming Lu --- arch/arm64/kvm/vgic/vgic-v3.c | 62 +++++++++++++++++++++++++++++++---- 1 file changed, 56 insertions(+), 6 deletions(-) diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c index 9cdf39a94a63..e1b3aa4b2b12 100644 --- a/arch/arm64/kvm/vgic/vgic-v3.c +++ b/arch/arm64/kvm/vgic/vgic-v3.c @@ -1,6 +1,8 @@ // SPDX-License-Identifier: GPL-2.0-only #include +#include +#include #include #include #include @@ -356,6 +358,39 @@ int vgic_v3_lpi_sync_pending_status(struct kvm *kvm, struct vgic_irq *irq) return 0; } +/* + * With GICv4.1, we can get the VLPI's pending state after unmapping + * the vPE. The deactivation of the doorbell interrupt will trigger + * the unmapping of the associated vPE. + */ +static void get_vlpi_state_pre(struct vgic_dist *dist) +{ + struct irq_desc *desc; + int i; + + if (!kvm_vgic_global_state.has_gicv4_1) + return; + + for (i = 0; i < dist->its_vm.nr_vpes; i++) { + desc = irq_to_desc(dist->its_vm.vpes[i]->irq); + irq_domain_deactivate_irq(irq_desc_get_irq_data(desc)); + } +} + +static void get_vlpi_state_post(struct vgic_dist *dist) +{ + struct irq_desc *desc; + int i; + + if (!kvm_vgic_global_state.has_gicv4_1) + return; + + for (i = 0; i < dist->its_vm.nr_vpes; i++) { + desc = irq_to_desc(dist->its_vm.vpes[i]->irq); + irq_domain_activate_irq(irq_desc_get_irq_data(desc), false); + } +} + /** * vgic_v3_save_pending_tables - Save the pending tables into guest RAM * kvm lock and all vcpu lock must be held @@ -365,14 +400,17 @@ int vgic_v3_save_pending_tables(struct kvm *kvm) struct vgic_dist *dist = &kvm->arch.vgic; struct vgic_irq *irq; gpa_t last_ptr = ~(gpa_t)0; - int ret; + int ret = 0; u8 val; + get_vlpi_state_pre(dist); + list_for_each_entry(irq, &dist->lpi_list_head, lpi_list) { int byte_offset, bit_nr; struct kvm_vcpu *vcpu; gpa_t pendbase, ptr; bool stored; + bool is_pending = irq->pending_latch; vcpu = irq->target_vcpu; if (!vcpu) @@ -387,24 +425,36 @@ int vgic_v3_save_pending_tables(struct kvm *kvm) if (ptr != last_ptr) { ret = kvm_read_guest_lock(kvm, ptr, &val, 1); if (ret) - return ret; + goto out; last_ptr = ptr; } stored = val & (1U << bit_nr); - if (stored == irq->pending_latch) + + /* also flush hw pending state */ + if (irq->hw) { + WARN_RATELIMIT(irq_get_irqchip_state(irq->host_irq, + IRQCHIP_STATE_PENDING, &is_pending), + "IRQ %d", irq->host_irq); + } + + if (stored == is_pending) continue; - if (irq->pending_latch) + if (is_pending) val |= 1 << bit_nr; else val &= ~(1 << bit_nr); ret = kvm_write_guest_lock(kvm, ptr, &val, 1); if (ret) - return ret; + goto out; } - return 0; + +out: + get_vlpi_state_post(dist); + + return ret; } /** -- 2.23.0