From patchwork Fri Apr 7 17:33:00 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 9670029 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 A354E60364 for ; Fri, 7 Apr 2017 17:33:46 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 96535262FF for ; Fri, 7 Apr 2017 17:33:46 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8B33328497; Fri, 7 Apr 2017 17:33:46 +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 0B943262FF for ; Fri, 7 Apr 2017 17:33:46 +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 1cwXjh-0006Xq-Kp; Fri, 07 Apr 2017 17:31:49 +0000 Received: from mail6.bemta6.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cwXjg-0006Ue-Ob for xen-devel@lists.xenproject.org; Fri, 07 Apr 2017 17:31:48 +0000 Received: from [85.158.143.35] by server-10.bemta-6.messagelabs.com id C2/9D-13192-40DC7E85; Fri, 07 Apr 2017 17:31:48 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrGLMWRWlGSWpSXmKPExsVysyfVTZf57PM IgxXTdS2+b5nM5MDocfjDFZYAxijWzLyk/IoE1owjM9cxFVyUr/jxeSpLA+Nx8S5GLg4hgU2M Epe3nWCHcJYzSkz6NZuli5GTg01AV2LHzdfMILaIQKjEnJ+PwGxmgUqJfx82MYHYwgIWEk8/T AWLswioSry5swrM5hWwljh7aA4jiC0hICfRcP4+WJwTKP71+xYwW0jASmLFxouMExi5FzAyrG JUL04tKkst0jXUSyrKTM8oyU3MzNE1NDDTy00tLk5MT81JTCrWS87P3cQI9C8DEOxg3Pnc6RC jJAeTkiivgs+TCCG+pPyUyozE4oz4otKc1OJDjDIcHEoSvItOP48QEixKTU+tSMvMAQYaTFqC g0dJhHcmSJq3uCAxtzgzHSJ1ilFRSpy3ESQhAJLIKM2Da4MF9yVGWSlhXkagQ4R4ClKLcjNLU OVfMYpzMCoJ884BmcKTmVcCN/0V0GImoMU+t56CLC5JREhJNTDmdn6UZF5m2KUWVi0zz5ZRRf OhdvDH6Sk2L+emr8mffavkv57Op9en2dh5H+0K/2prqrDngfHersMZl6//XVrGNOdRwrPz/pK VLbZlN1YYbr/zb9KB5z/414bucujOyC5l+Xe7++H9au5G/mDBfSe/FbLaTXXImZGhUbLsFWOu b26kCpPm5M1KLMUZiYZazEXFiQCsLmvqaQIAAA== X-Env-Sender: andre.przywara@arm.com X-Msg-Ref: server-11.tower-21.messagelabs.com!1491586307!62694714!1 X-Originating-IP: [217.140.101.70] X-SpamReason: No, hits=0.5 required=7.0 tests=BODY_RANDOM_LONG X-StarScan-Received: X-StarScan-Version: 9.4.12; banners=-,-,- X-VirusChecked: Checked Received: (qmail 47055 invoked from network); 7 Apr 2017 17:31:47 -0000 Received: from foss.arm.com (HELO foss.arm.com) (217.140.101.70) by server-11.tower-21.messagelabs.com with SMTP; 7 Apr 2017 17:31:47 -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 D1D94B16; Fri, 7 Apr 2017 10:31:46 -0700 (PDT) Received: from e104803-lin.lan (unknown [10.1.207.46]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id CCFA23F3E1; Fri, 7 Apr 2017 10:31:45 -0700 (PDT) From: Andre Przywara To: Stefano Stabellini , Julien Grall Date: Fri, 7 Apr 2017 18:33:00 +0100 Message-Id: <20170407173307.9788-30-andre.przywara@arm.com> X-Mailer: git-send-email 2.9.0 In-Reply-To: <20170407173307.9788-1-andre.przywara@arm.com> References: <20170407173307.9788-1-andre.przywara@arm.com> Cc: xen-devel@lists.xenproject.org, Vijay Kilari , Shanker Donthineni Subject: [Xen-devel] [PATCH v6 29/36] 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 corresponding host MAPD command and create the required tables. We simply use our existing guest memory access function to find the right ITT entry and store the mapping there. Signed-off-by: Andre Przywara --- xen/arch/arm/vgic-v3-its.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/xen/arch/arm/vgic-v3-its.c b/xen/arch/arm/vgic-v3-its.c index 72e2885..37c932b 100644 --- a/xen/arch/arm/vgic-v3-its.c +++ b/xen/arch/arm/vgic-v3-its.c @@ -42,6 +42,7 @@ */ struct virt_its { struct domain *d; + paddr_t doorbell_address; unsigned int devid_bits; unsigned int intid_bits; spinlock_t vcmd_lock; /* Protects the virtual command buffer, which */ @@ -148,6 +149,20 @@ static struct vcpu *get_vcpu_from_collection(struct virt_its *its, #define DEV_TABLE_ENTRY(addr, bits) \ (((addr) & GENMASK(51, 8)) | (((bits) - 1) & GENMASK(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_entry = DEV_TABLE_ENTRY(itt_address, nr_bits); + + if ( devid >= its->max_devices ) + return -ENOENT; + + return vgic_access_guest_memory(its->d, addr + devid * sizeof(uint64_t), + &itt_entry, sizeof(itt_entry), true); +} + /* * 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 @@ -389,6 +404,47 @@ 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) +{ + /* size and devid get validated by the functions called below. */ + uint32_t devid = its_cmd_get_deviceid(cmdptr); + unsigned int size = its_cmd_get_size(cmdptr) + 1; + bool valid = its_cmd_get_validbit(cmdptr); + paddr_t itt_addr = its_cmd_get_ittaddr(cmdptr); + 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 addresses are the same. + * Also the device IDs are equal. + */ + 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) /* @@ -427,6 +483,9 @@ static int vgic_its_handle_cmds(struct domain *d, struct virt_its *its) case GITS_CMD_MAPC: ret = its_handle_mapc(its, command); break; + case GITS_CMD_MAPD: + ret = its_handle_mapd(its, command); + break; case GITS_CMD_SYNC: /* We handle ITS commands synchronously, so we ignore SYNC. */ break;