From patchwork Fri Mar 31 18:05:17 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 9657097 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 E4BE760352 for ; Fri, 31 Mar 2017 18:05:59 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D93BB286B7 for ; Fri, 31 Mar 2017 18:05:59 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CDF8D286EF; Fri, 31 Mar 2017 18:05:59 +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=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 6A309286F1 for ; Fri, 31 Mar 2017 18:05:59 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cu0tv-0005mD-Me; Fri, 31 Mar 2017 18:03:55 +0000 Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cu0tu-0005jL-Dj for xen-devel@lists.xenproject.org; Fri, 31 Mar 2017 18:03:54 +0000 Received: from [85.158.137.68] by server-7.bemta-3.messagelabs.com id 83/1F-23854-90A9ED85; Fri, 31 Mar 2017 18:03:53 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrCLMWRWlGSWpSXmKPExsVysyfVTZdj1r0 Ig2mn+C2+b5nM5MDocfjDFZYAxijWzLyk/IoE1oxlqz6wFhxUqDi7ZiZzA+NBiS5GLg4hgU2M Ei/PTGHpYuQEcpYzSnxtUgGx2QR0JXbcfM0MYosIhEo8XfAdyObgYBaolOhexA8SFhawkLi16 CcriM0ioCpx/c45JhCbV8BGomH3BLCREgJyEg3n74ON4QSKz9/1gxVilbVEw6e7zBMYuRcwMq xiVC9OLSpLLdK11EsqykzPKMlNzMzRNTQw1stNLS5OTE/NSUwq1kvOz93ECPRtPQMD4w7G1z+ dDjFKcjApifJ+L74XIcSXlJ9SmZFYnBFfVJqTWnyIUYaDQ0mC9/oMoJxgUWp6akVaZg4wyGDS Ehw8SiK8UjOB0rzFBYm5xZnpEKlTjIpS4rzHQPoEQBIZpXlwbbDAvsQoKyXMy8jAwCDEU5Bal JtZgir/ilGcg1FJmFcVZDxPZl4J3PRXQIuZgBZbfL0LsrgkESEl1cDYNk8ufqVbp+dXhX93X5 QkTBSyyezk47+42+Pt7qDj6S28hadVT3xokYiWOx8c5Za4/N5Flxd+qnNuSF1N/XWontl/sp3 yHK+GqW1JStN8vG5wKLdndb5IL7HTCd51/tekx487Hnw59WnxeZMnnHLcrWnFv41/q95zOLD/ 7TrT2ylJix7Yf4pTYinOSDTUYi4qTgQAmuSUPWcCAAA= X-Env-Sender: andre.przywara@arm.com X-Msg-Ref: server-4.tower-31.messagelabs.com!1490983431!35188664!1 X-Originating-IP: [217.140.101.70] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 9.2.3; banners=-,-,- X-VirusChecked: Checked Received: (qmail 33692 invoked from network); 31 Mar 2017 18:03:51 -0000 Received: from foss.arm.com (HELO foss.arm.com) (217.140.101.70) by server-4.tower-31.messagelabs.com with SMTP; 31 Mar 2017 18:03:51 -0000 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 4CAFBB16; Fri, 31 Mar 2017 11:03:51 -0700 (PDT) Received: from e104803-lin.lan (unknown [10.1.207.46]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 486D23F59A; Fri, 31 Mar 2017 11:03:50 -0700 (PDT) From: Andre Przywara To: Julien Grall , Stefano Stabellini Date: Fri, 31 Mar 2017 19:05:17 +0100 Message-Id: <20170331180525.30038-19-andre.przywara@arm.com> X-Mailer: git-send-email 2.9.0 In-Reply-To: <20170331180525.30038-1-andre.przywara@arm.com> References: <20170331180525.30038-1-andre.przywara@arm.com> Cc: xen-devel@lists.xenproject.org, Shanker Donthineni , Vijay Kilari Subject: [Xen-devel] [PATCH v3 18/26] ARM: vITS: handle MAPD command X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP The MAPD command maps a device by associating a memory region for storing ITEs with a certain device ID. We store the given guest physical address in the device table, and, if this command comes from Dom0, tell the host ITS driver about this new mapping, so it can issue the corresponing host MAPD command and create the required tables. We don't map the device tables permanently, as their alignment requirement is only 256 Bytes, thus making mapping of several tables complicated. Instead we map the device tables on demand when we need them later. Signed-off-by: Andre Przywara --- xen/arch/arm/vgic-v3-its.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/xen/arch/arm/vgic-v3-its.c b/xen/arch/arm/vgic-v3-its.c index 8c2eaaa..36b44f2 100644 --- a/xen/arch/arm/vgic-v3-its.c +++ b/xen/arch/arm/vgic-v3-its.c @@ -42,6 +42,7 @@ #define VIRT_ITS_CMDBUF_VALID 3 struct virt_its { struct domain *d; + paddr_t doorbell_address; spinlock_t vcmd_lock; /* Protects the virtual command buffer. */ uint64_t cbaser; uint64_t cwriter; @@ -141,6 +142,27 @@ static struct vcpu *get_vcpu_from_collection(struct virt_its *its, int collid) #define DEV_TABLE_ENTRY(addr, bits) \ (((addr) & GENMASK_ULL(51, 8)) | (((bits) - 1) & GENMASK_ULL(7, 0))) +/* Set the address of an ITT for a given device ID. */ +static int its_set_itt_address(struct virt_its *its, uint32_t devid, + paddr_t itt_address, uint32_t nr_bits) +{ + paddr_t addr = get_baser_phys_addr(its->baser_dev); + uint64_t *itt; + + if ( devid >= its->max_devices ) + return -ENOENT; + + itt = map_one_guest_page(its->d, addr + devid * sizeof(uint64_t)); + if ( !itt ) + return -EFAULT; + + *itt = DEV_TABLE_ENTRY(itt_address, nr_bits); + + unmap_one_guest_page(itt); + + return 0; +} + /* * Lookup the address of the Interrupt Translation Table associated with * a device ID and return the address of the ITTE belonging to the event ID @@ -361,6 +383,44 @@ static int its_handle_mapc(struct virt_its *its, uint64_t *cmdptr) return 0; } +static int its_handle_mapd(struct virt_its *its, uint64_t *cmdptr) +{ + uint32_t devid = its_cmd_get_deviceid(cmdptr); + int size = its_cmd_get_size(cmdptr) + 1; + bool valid = its_cmd_get_validbit(cmdptr); + paddr_t itt_addr = its_cmd_mask_field(cmdptr, 2, 0, 52) & + GENMASK_ULL(51, 8); + int ret; + + /* + * There is no easy and clean way for Xen to know the ITS device ID of a + * particular (PCI) device, so we have to rely on the guest telling + * us about it. For *now* we are just using the device ID *Dom0* uses, + * because the driver there has the actual knowledge. + * Eventually this will be replaced with a dedicated hypercall to + * announce pass-through of devices. + */ + if ( is_hardware_domain(its->d) ) + { + /* Dom0's ITSes are mapped 1:1, so both address are the same. */ + ret = gicv3_its_map_guest_device(its->d, its->doorbell_address, devid, + its->doorbell_address, devid, + BIT(size), valid); + if ( ret ) + return ret; + } + + spin_lock(&its->its_lock); + if ( valid ) + ret = its_set_itt_address(its, devid, itt_addr, size); + else + ret = its_set_itt_address(its, devid, INVALID_PADDR, 1); + + spin_unlock(&its->its_lock); + + return ret; +} + #define ITS_CMD_BUFFER_SIZE(baser) ((((baser) & 0xff) + 1) << 12) static int vgic_its_handle_cmds(struct domain *d, struct virt_its *its, @@ -407,6 +467,9 @@ static int vgic_its_handle_cmds(struct domain *d, struct virt_its *its, case GITS_CMD_MAPC: ret = its_handle_mapc(its, cmdptr); break; + case GITS_CMD_MAPD: + ret = its_handle_mapd(its, cmdptr); + break; case GITS_CMD_SYNC: /* We handle ITS commands synchronously, so we ignore SYNC. */ break;