From patchwork Tue May 9 10:44:50 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoffer Dall X-Patchwork-Id: 9717657 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 3AEB960364 for ; Tue, 9 May 2017 11:05:36 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2DFF0283F2 for ; Tue, 9 May 2017 11:05:36 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 20C61283FD; Tue, 9 May 2017 11:05:36 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 9D509283F2 for ; Tue, 9 May 2017 11:05:35 +0000 (UTC) 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:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id: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=FxAVatIDD+zGlOYyeptND9bA/ndckp0AGiTJvTW+SDw=; b=FHbgv56Frdi3VQ00KQr7WerzK9 YVLFyArFDX7kzM+RDo42QXITV85IBI3ZQe3qdq001djbfy7dIoCz0dpK5fRPz+req+2FkNkHS8SqM gX4TulWSfmAZoqkPsjJ6WXwmA+FA/nUpOJr4A5Yo9d5GYx5qphgvZiprcH+eCJHkvtbSDVU/TMLZd kzAE0H32poEPNGcuF2DXeVgrUQYXZbJk0tRARTPNjaaBghfghlP6+pf4JnlOJtTfdlW8WQs41WXxl QiIGM+u7jHbscI16qjJzNOBQkeTKK/r0PdngS0EjCkfqkke+uDDcfp4fw342e/UrJ49q98KgMHrbq 7rQu9gpg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1d82xT-0002qo-4A; Tue, 09 May 2017 11:05:35 +0000 Received: from merlin.infradead.org ([2001:4978:20e::2]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1d82xR-0002pf-S8 for linux-arm-kernel@bombadil.infradead.org; Tue, 09 May 2017 11:05:33 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=merlin.20170209; h=References:In-Reply-To:Message-Id:Date: Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=gY5dRqVPI1AZRpn2k9nw3y9b8InDai4VDn5r9kj/mpU=; b=sk7B+PDXxDwKnKiad++kIe++I /QFCYaaOvzq/dKjxiYvCmsUmMsZS4UDviTt7lLE/agcBhAGoSOXgSmrPvOvZlDfJHJzgoRxM4RCmU Sm+0hLYgfJmBqyCFQTow/wpLdF0tSPZzK7mnjzVebXo0o+SGZoWr+0FpbsL5+JVBigkhKLorh321L 6fcbqqC5ngx3i93R50iry/pPyuruiwwR6KI4UyIz8HIID+l/GS3KXC6mEl1Y/S2BSJ9oA7vights+ K3Gue2mrfo2PTEu5/tuTymkgOw1ZzHk87BiG0g67Swk93knb1g/o1GIDGvBEh4oztwrXxiX97n+6R Uc/HjgvWg==; Received: from mail-qk0-x22c.google.com ([2607:f8b0:400d:c09::22c]) by merlin.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1d82eP-00071Q-Vv for linux-arm-kernel@lists.infradead.org; Tue, 09 May 2017 10:45:55 +0000 Received: by mail-qk0-x22c.google.com with SMTP id a72so58965466qkj.2 for ; Tue, 09 May 2017 03:45:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=gY5dRqVPI1AZRpn2k9nw3y9b8InDai4VDn5r9kj/mpU=; b=CKqUmZsRGJnjgPbvgBjQELo7tA3Y4kU3XZiZ5jdenUlo+CJc/4dt8vFe4/Has0lo+s V7WJ55XxgGFic9FafyccxjBcDRzL+9tOsRbWXmv2UMMuiogtPO1TS/U7tVj1MpdL7L7j ihCdK1USfTIz1UG6AoOp9cO/cq2wuimI818HI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=gY5dRqVPI1AZRpn2k9nw3y9b8InDai4VDn5r9kj/mpU=; b=Mqv8OqJtcL4VFYfqXifAzIigBorbw/g9w+SyeOi2GolVy9Z4EDBWb6b4uq3s1xw7fp ZVq0ga7ygD0+vijXsn0GO/9J4uNNcfIuwIeXJEfxpAX0WhddVIYtMFgFMLdWyGDgvf4h Qn8uH1naOEZSYjGVrmjLAvMTvg9BPCuFUnupvodMNTSitdZf67GzEWWgR5tSLslCSf5j v/I+aVU1qhq/G/+6UOcLS7hz1uqPm7SbuvqQBKcUxeK7L4SKw56C3LVlqt83n0cUmhRw 2djP13MFx7IoSI1G2jRsSKXnz+arxTjQx09mQPt02Ys5a1qbvYnZniXSheWBttB05v2B hKBQ== X-Gm-Message-State: AODbwcDkwbDuG+pXuyHb5CfHd4w7K5rUPNpLxleFHEr/5crKRKYN4M+t RIkCZ5N6sSD+pFmV X-Received: by 10.80.158.99 with SMTP id z90mr13288378ede.50.1494326732502; Tue, 09 May 2017 03:45:32 -0700 (PDT) Received: from localhost.localdomain (xd93ddc2d.cust.hiper.dk. [217.61.220.45]) by smtp.gmail.com with ESMTPSA id o30sm2331510edc.42.2017.05.09.03.45.31 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 09 May 2017 03:45:32 -0700 (PDT) From: Christoffer Dall To: Paolo Bonzini , =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= Subject: [PULL 21/37] KVM: arm64: vgic-its: Collection table save/restore Date: Tue, 9 May 2017 12:44:50 +0200 Message-Id: <20170509104506.30929-22-cdall@linaro.org> X-Mailer: git-send-email 2.9.0 In-Reply-To: <20170509104506.30929-1-cdall@linaro.org> References: <20170509104506.30929-1-cdall@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170509_064554_148819_10346C95 X-CRM114-Status: GOOD ( 18.33 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Marc Zyngier , Eric Auger , kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Eric Auger The save path copies the collection entries into guest RAM at the GPA specified in the BASER register. This obviously requires the BASER to be set. The last written element is a dummy collection table entry. We do not index by collection ID as the collection entry can fit into 8 bytes while containing the collection ID. On restore path we re-allocate the collection objects. Signed-off-by: Eric Auger Reviewed-by: Christoffer Dall Reviewed-by: Marc Zyngier --- virt/kvm/arm/vgic/vgic-its.c | 100 ++++++++++++++++++++++++++++++++++++++++++- virt/kvm/arm/vgic/vgic.h | 9 ++++ 2 files changed, 107 insertions(+), 2 deletions(-) diff --git a/virt/kvm/arm/vgic/vgic-its.c b/virt/kvm/arm/vgic/vgic-its.c index d5c0057..5523f0a 100644 --- a/virt/kvm/arm/vgic/vgic-its.c +++ b/virt/kvm/arm/vgic/vgic-its.c @@ -1838,13 +1838,89 @@ static int vgic_its_restore_device_tables(struct vgic_its *its) return -ENXIO; } +static int vgic_its_save_cte(struct vgic_its *its, + struct its_collection *collection, + gpa_t gpa, int esz) +{ + u64 val; + + val = (1ULL << KVM_ITS_CTE_VALID_SHIFT | + ((u64)collection->target_addr << KVM_ITS_CTE_RDBASE_SHIFT) | + collection->collection_id); + val = cpu_to_le64(val); + return kvm_write_guest(its->dev->kvm, gpa, &val, esz); +} + +static int vgic_its_restore_cte(struct vgic_its *its, gpa_t gpa, int esz) +{ + struct its_collection *collection; + struct kvm *kvm = its->dev->kvm; + u32 target_addr, coll_id; + u64 val; + int ret; + + BUG_ON(esz > sizeof(val)); + ret = kvm_read_guest(kvm, gpa, &val, esz); + if (ret) + return ret; + val = le64_to_cpu(val); + if (!(val & KVM_ITS_CTE_VALID_MASK)) + return 0; + + target_addr = (u32)(val >> KVM_ITS_CTE_RDBASE_SHIFT); + coll_id = val & KVM_ITS_CTE_ICID_MASK; + + if (target_addr >= atomic_read(&kvm->online_vcpus)) + return -EINVAL; + + collection = find_collection(its, coll_id); + if (collection) + return -EEXIST; + ret = vgic_its_alloc_collection(its, &collection, coll_id); + if (ret) + return ret; + collection->target_addr = target_addr; + return 1; +} + /** * vgic_its_save_collection_table - Save the collection table into * guest RAM */ static int vgic_its_save_collection_table(struct vgic_its *its) { - return -ENXIO; + const struct vgic_its_abi *abi = vgic_its_get_abi(its); + struct its_collection *collection; + u64 val; + gpa_t gpa; + size_t max_size, filled = 0; + int ret, cte_esz = abi->cte_esz; + + gpa = BASER_ADDRESS(its->baser_coll_table); + if (!gpa) + return 0; + + max_size = GITS_BASER_NR_PAGES(its->baser_coll_table) * SZ_64K; + + list_for_each_entry(collection, &its->collection_list, coll_list) { + ret = vgic_its_save_cte(its, collection, gpa, cte_esz); + if (ret) + return ret; + gpa += cte_esz; + filled += cte_esz; + } + + if (filled == max_size) + return 0; + + /* + * table is not fully filled, add a last dummy element + * with valid bit unset + */ + val = 0; + BUG_ON(cte_esz > sizeof(val)); + ret = kvm_write_guest(its->dev->kvm, gpa, &val, cte_esz); + return ret; } /** @@ -1854,7 +1930,27 @@ static int vgic_its_save_collection_table(struct vgic_its *its) */ static int vgic_its_restore_collection_table(struct vgic_its *its) { - return -ENXIO; + const struct vgic_its_abi *abi = vgic_its_get_abi(its); + int cte_esz = abi->cte_esz; + size_t max_size, read = 0; + gpa_t gpa; + int ret; + + if (!(its->baser_coll_table & GITS_BASER_VALID)) + return 0; + + gpa = BASER_ADDRESS(its->baser_coll_table); + + max_size = GITS_BASER_NR_PAGES(its->baser_coll_table) * SZ_64K; + + while (read < max_size) { + ret = vgic_its_restore_cte(its, gpa, cte_esz); + if (ret <= 0) + break; + gpa += cte_esz; + read += cte_esz; + } + return ret; } /** diff --git a/virt/kvm/arm/vgic/vgic.h b/virt/kvm/arm/vgic/vgic.h index 79768c8..757de7a 100644 --- a/virt/kvm/arm/vgic/vgic.h +++ b/virt/kvm/arm/vgic/vgic.h @@ -73,6 +73,15 @@ KVM_REG_ARM_VGIC_SYSREG_CRM_MASK | \ KVM_REG_ARM_VGIC_SYSREG_OP2_MASK) +/* + * As per Documentation/virtual/kvm/devices/arm-vgic-its.txt, + * below macros are defined for ITS table entry encoding. + */ +#define KVM_ITS_CTE_VALID_SHIFT 63 +#define KVM_ITS_CTE_VALID_MASK BIT_ULL(63) +#define KVM_ITS_CTE_RDBASE_SHIFT 16 +#define KVM_ITS_CTE_ICID_MASK GENMASK_ULL(15, 0) + static inline bool irq_is_pending(struct vgic_irq *irq) { if (irq->config == VGIC_CONFIG_EDGE)