From patchwork Fri May 29 09:53:24 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 6506441 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 78B52C0020 for ; Fri, 29 May 2015 09:53:55 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 981D8205FD for ; Fri, 29 May 2015 09:53:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 72E1C205F7 for ; Fri, 29 May 2015 09:53:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755946AbbE2Jxu (ORCPT ); Fri, 29 May 2015 05:53:50 -0400 Received: from foss.arm.com ([217.140.101.70]:57062 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755949AbbE2Jxm (ORCPT ); Fri, 29 May 2015 05:53:42 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 4B2BE69E; Fri, 29 May 2015 02:53:31 -0700 (PDT) Received: from e104803-lin.lan (unknown [10.1.203.153]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id BEEC13F251; Fri, 29 May 2015 02:53:40 -0700 (PDT) From: Andre Przywara To: christoffer.dall@linaro.org, marc.zyngier@arm.com Cc: kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org, kvm@vger.kernel.org Subject: [PATCH 08/13] KVM: arm64: add data structures to model ITS interrupt translation Date: Fri, 29 May 2015 10:53:24 +0100 Message-Id: <1432893209-27313-9-git-send-email-andre.przywara@arm.com> X-Mailer: git-send-email 2.3.5 In-Reply-To: <1432893209-27313-1-git-send-email-andre.przywara@arm.com> References: <1432893209-27313-1-git-send-email-andre.przywara@arm.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The GICv3 Interrupt Translation Service (ITS) uses tables in memory to allow a sophisticated interrupt routing. It features device tables, an interrupt table per device and a table connecting "collections" to actual CPUs (aka. redistributors in the GICv3 lingo). Since the interrupt numbers for the LPIs are allocated quite sparsely and the range can be quite huge (8192 LPIs being the minimum), using bitmaps or arrays for storing information is a waste of memory. We use linked lists instead, which we iterate linearily. This works very well with the actual number of LPIs/MSIs in the guest being quite low. Should the number of LPIs exceed the number where iterating the lists becomes painful, we can later revisit this and use more efficient data structures. Signed-off-by: Andre Przywara Reviewed-by: Eric Auger --- include/kvm/arm_vgic.h | 3 +++ virt/kvm/arm/its-emul.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h index 3b8e3a1..fa17df6 100644 --- a/include/kvm/arm_vgic.h +++ b/include/kvm/arm_vgic.h @@ -25,6 +25,7 @@ #include #include #include +#include #define VGIC_NR_IRQS_LEGACY 256 #define VGIC_NR_SGIS 16 @@ -162,6 +163,8 @@ struct vgic_its { u64 cbaser; int creadr; int cwriter; + struct list_head device_list; + struct list_head collection_list; }; struct vgic_dist { diff --git a/virt/kvm/arm/its-emul.c b/virt/kvm/arm/its-emul.c index 82bc34a..f0f4a9c 100644 --- a/virt/kvm/arm/its-emul.c +++ b/virt/kvm/arm/its-emul.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -32,6 +33,25 @@ #include "vgic.h" #include "its-emul.h" +struct its_device { + struct list_head dev_list; + struct list_head itt; + u32 device_id; +}; + +struct its_collection { + struct list_head coll_list; + u32 collection_id; + u32 target_addr; +}; + +struct its_itte { + struct list_head itte_list; + struct its_collection *collection; + u32 lpi; + u32 event_id; +}; + #define BASER_BASE_ADDRESS(x) ((x) & 0xfffffffff000ULL) /* distributor lock is hold by the VGIC MMIO handler */ @@ -280,6 +300,9 @@ int vits_init(struct kvm *kvm) spin_lock_init(&its->lock); + INIT_LIST_HEAD(&its->device_list); + INIT_LIST_HEAD(&its->collection_list); + its->enabled = false; return -ENXIO; @@ -289,11 +312,33 @@ void vits_destroy(struct kvm *kvm) { struct vgic_dist *dist = &kvm->arch.vgic; struct vgic_its *its = &dist->its; + struct its_device *dev; + struct its_itte *itte; + struct list_head *dev_cur, *dev_temp; + struct list_head *cur, *temp; if (!vgic_has_its(kvm)) return; + spin_lock(&its->lock); + list_for_each_safe(dev_cur, dev_temp, &its->device_list) { + dev = container_of(dev_cur, struct its_device, dev_list); + list_for_each_safe(cur, temp, &dev->itt) { + itte = (container_of(cur, struct its_itte, itte_list)); + list_del(cur); + kfree(itte); + } + list_del(dev_cur); + kfree(dev); + } + + list_for_each_safe(cur, temp, &its->collection_list) { + list_del(cur); + kfree(container_of(cur, struct its_collection, coll_list)); + } + kfree(dist->pendbaser); its->enabled = false; + spin_unlock(&its->lock); }