From patchwork Wed Aug 9 08:20:35 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergej Proskurin X-Patchwork-Id: 9889833 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 1F32860384 for ; Wed, 9 Aug 2017 08:23:53 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0D82328A30 for ; Wed, 9 Aug 2017 08:23:53 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 01F5628A37; Wed, 9 Aug 2017 08:23:52 +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 406D928A30 for ; Wed, 9 Aug 2017 08:23:52 +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 1dfMF9-0006ZD-TQ; Wed, 09 Aug 2017 08:21:31 +0000 Received: from mail6.bemta6.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dfMF7-0006WK-WC for xen-devel@lists.xenproject.org; Wed, 09 Aug 2017 08:21:30 +0000 Received: from [85.158.143.35] by server-11.bemta-6.messagelabs.com id 92/F8-03612-906CA895; Wed, 09 Aug 2017 08:21:29 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrBLMWRWlGSWpSXmKPExsXSPJ+BQ5fjWFe kwalLuhbft0xmcmD0OPzhCksAYxRrZl5SfkUCa8a/2euYC+bYVPxbZt3A+Ea/i5GLQ0hgI6PE nT+z2CGcTYwSmx6vYuli5ORgEzCQmPJ6JSuILSKgJHFv1WQmkCJmgSZGiXuND9hAEsICPhLrv +9jBLFZBFQlGhc8A4vzCthILL3wAiwuISAvMbF3GpjNCRTfcQfCFhKwlph27BzzBEbuBYwMqx jVi1OLylKLdI30kooy0zNKchMzc3QNDcz0clOLixPTU3MSk4r1kvNzNzEC/csABDsYl/11OsQ oycGkJMq7SbszUogvKT+lMiOxOCO+qDQntfgQowwHh5IE748jXZFCgkWp6akVaZk5wECDSUtw 8CiJ8N4GSfMWFyTmFmemQ6ROMRpzLOjZ8IWJ49WE/9+YhFjy8vNSpcR5N4OUCoCUZpTmwQ2CR cAlRlkpYV5GoNOEeApSi3IzS1DlXzGKczAqCfOWHgWawpOZVwK37xXQKUxAp0T4doKcUpKIkJ JqYEzTPir4za5/R/l0n+otc12y7tjdevO1W26doaNVzjbFqYKfMv1vyu8wMTNlrjhR8O7gG69 0//veVyrMz757vvvlnQP6hjlmkrraYdWuv6ULdNOc+2pbXYy1l1x7+Y1n0W6BO0HCk3+EbJ22 n/HUPLn6lqf2MgXVt9W+/lip/evnE+3LFS8+NSixFGckGmoxFxUnAgDJ1vzAewIAAA== X-Env-Sender: proskurin@sec.in.tum.de X-Msg-Ref: server-8.tower-21.messagelabs.com!1502266888!76986871!1 X-Originating-IP: [131.159.0.8] X-SpamReason: No, hits=0.5 required=7.0 tests=BODY_RANDOM_LONG X-StarScan-Received: X-StarScan-Version: 9.4.45; banners=-,-,- X-VirusChecked: Checked Received: (qmail 12998 invoked from network); 9 Aug 2017 08:21:28 -0000 Received: from mail-out1.informatik.tu-muenchen.de (HELO mail-out1.informatik.tu-muenchen.de) (131.159.0.8) by server-8.tower-21.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 9 Aug 2017 08:21:28 -0000 Received: from files.sec.in.tum.de (files.sec.in.tum.de [131.159.50.1]) by services.sec.in.tum.de (Postfix) with ESMTP id 35AA010DD29F3; Wed, 9 Aug 2017 10:21:07 +0200 (CEST) Received: from thanatos.sec.in.tum.de (thanatos.sec.in.tum.de [131.159.50.57]) by files.sec.in.tum.de (Postfix) with ESMTP id 271351F048; Wed, 9 Aug 2017 10:21:07 +0200 (CEST) From: Sergej Proskurin To: xen-devel@lists.xenproject.org Date: Wed, 9 Aug 2017 10:20:35 +0200 Message-Id: <20170809082038.3236-11-proskurin@sec.in.tum.de> X-Mailer: git-send-email 2.13.3 In-Reply-To: <20170809082038.3236-1-proskurin@sec.in.tum.de> References: <20170809082038.3236-1-proskurin@sec.in.tum.de> Cc: Sergej Proskurin , Julien Grall , Stefano Stabellini Subject: [Xen-devel] [PATCH v8 10/13] arm/mem_access: Add software guest-page-table walk 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 function p2m_mem_access_check_and_get_page in mem_access.c translates a gva to an ipa by means of the hardware functionality of the ARM architecture. This is implemented in the function gva_to_ipa. If mem_access is active, hardware-based gva to ipa translation might fail, as gva_to_ipa uses the guest's translation tables, access to which might be restricted by the active VTTBR. To address this issue, in this commit we add a software-based guest-page-table walk, which will be used by the function p2m_mem_access_check_and_get_page perform the gva to ipa translation in software in one of the following commits. Note: The introduced function guest_walk_tables assumes that the domain, the gva of which is to be translated, is running on the currently active vCPU. To walk the guest's page tables on a different vCPU, the following registers would need to be loaded: TCR_EL1, TTBR0_EL1, TTBR1_EL1, and SCTLR_EL1. Signed-off-by: Sergej Proskurin Acked-by: Julien Grall --- Cc: Stefano Stabellini Cc: Julien Grall --- v2: Rename p2m_gva_to_ipa to p2m_walk_gpt and move it to p2m.c. Move the functionality responsible for walking long-descriptor based translation tables out of the function p2m_walk_gpt. Also move out the long-descriptor based translation out of this commit. Change function parameters in order to return access access rights to a requested gva. Cosmetic fixes. v3: Rename the introduced functions to guest_walk_(tables|sd|ld) and move the implementation to guest_copy.(c|h). Set permissions in guest_walk_tables also if the MMU is disabled. Change the function parameter of type "struct p2m_domain *" to "struct vcpu *" in the function guest_walk_tables. v4: Change the function parameter of type "struct p2m_domain *" to "struct vcpu *" in the functions guest_walk_(sd|ld) as well. v5: Merge two if-statements in guest_walk_tables to ease readability. Set perms to GV2M_READ as to avoid undefined permissions. Add Julien Grall's Acked-by. v6: Adjusted change-log of v5. Remove Julien Grall's Acked-by as we have changed the initialization of perms. This needs to be reviewed. Comment why we initialize perms with GV2M_READ by default. This is due to the fact that in the current implementation we assume a GVA to IPA translation with EL1 privileges. Since, valid mappings in the first stage address translation table are readable by default for EL1, we initialize perms with GV2M_READ and extend the permissions according to the particular page table walk. v7: Add Acked-by Julien Grall. --- xen/arch/arm/Makefile | 1 + xen/arch/arm/guest_walk.c | 99 ++++++++++++++++++++++++++++++++++++++++ xen/include/asm-arm/guest_walk.h | 19 ++++++++ 3 files changed, 119 insertions(+) create mode 100644 xen/arch/arm/guest_walk.c create mode 100644 xen/include/asm-arm/guest_walk.h diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile index 49e1fb2f84..282d2c2949 100644 --- a/xen/arch/arm/Makefile +++ b/xen/arch/arm/Makefile @@ -21,6 +21,7 @@ obj-$(CONFIG_HAS_GICV3) += gic-v3.o obj-$(CONFIG_HAS_ITS) += gic-v3-its.o obj-$(CONFIG_HAS_ITS) += gic-v3-lpi.o obj-y += guestcopy.o +obj-y += guest_walk.o obj-y += hvm.o obj-y += io.o obj-y += irq.o diff --git a/xen/arch/arm/guest_walk.c b/xen/arch/arm/guest_walk.c new file mode 100644 index 0000000000..78badc2949 --- /dev/null +++ b/xen/arch/arm/guest_walk.c @@ -0,0 +1,99 @@ +/* + * Guest page table walk + * Copyright (c) 2017 Sergej Proskurin + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; If not, see . + */ + +#include + +/* + * The function guest_walk_sd translates a given GVA into an IPA using the + * short-descriptor translation table format in software. This function assumes + * that the domain is running on the currently active vCPU. To walk the guest's + * page table on a different vCPU, the following registers would need to be + * loaded: TCR_EL1, TTBR0_EL1, TTBR1_EL1, and SCTLR_EL1. + */ +static int guest_walk_sd(const struct vcpu *v, + vaddr_t gva, paddr_t *ipa, + unsigned int *perms) +{ + /* Not implemented yet. */ + return -EFAULT; +} + +/* + * The function guest_walk_ld translates a given GVA into an IPA using the + * long-descriptor translation table format in software. This function assumes + * that the domain is running on the currently active vCPU. To walk the guest's + * page table on a different vCPU, the following registers would need to be + * loaded: TCR_EL1, TTBR0_EL1, TTBR1_EL1, and SCTLR_EL1. + */ +static int guest_walk_ld(const struct vcpu *v, + vaddr_t gva, paddr_t *ipa, + unsigned int *perms) +{ + /* Not implemented yet. */ + return -EFAULT; +} + +int guest_walk_tables(const struct vcpu *v, vaddr_t gva, + paddr_t *ipa, unsigned int *perms) +{ + uint32_t sctlr = READ_SYSREG(SCTLR_EL1); + register_t tcr = READ_SYSREG(TCR_EL1); + unsigned int _perms; + + /* We assume that the domain is running on the currently active domain. */ + if ( v != current ) + return -EFAULT; + + /* Allow perms to be NULL. */ + perms = perms ?: &_perms; + + /* + * Currently, we assume a GVA to IPA translation with EL1 privileges. + * Since, valid mappings in the first stage address translation table are + * readable by default for EL1, we initialize perms with GV2M_READ and + * extend the permissions as part of the particular page table walk. Please + * note that the current implementation does not consider further + * attributes that distinguish between EL0 and EL1 permissions (EL0 might + * not have permissions on the particular mapping). + */ + *perms = GV2M_READ; + + /* If the MMU is disabled, there is no need to translate the gva. */ + if ( !(sctlr & SCTLR_M) ) + { + *ipa = gva; + + /* Memory can be accessed without any restrictions. */ + *perms = GV2M_READ|GV2M_WRITE|GV2M_EXEC; + + return 0; + } + + if ( is_32bit_domain(v->domain) && !(tcr & TTBCR_EAE) ) + return guest_walk_sd(v, gva, ipa, perms); + else + return guest_walk_ld(v, gva, ipa, perms); +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/asm-arm/guest_walk.h b/xen/include/asm-arm/guest_walk.h new file mode 100644 index 0000000000..4ed8476e08 --- /dev/null +++ b/xen/include/asm-arm/guest_walk.h @@ -0,0 +1,19 @@ +#ifndef _XEN_GUEST_WALK_H +#define _XEN_GUEST_WALK_H + +/* Walk the guest's page tables in software. */ +int guest_walk_tables(const struct vcpu *v, + vaddr_t gva, + paddr_t *ipa, + unsigned int *perms); + +#endif /* _XEN_GUEST_WALK_H */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */