[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v7 11/14] arm/mem_access: Add software guest-page-table walk
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 <proskurin@xxxxxxxxxxxxx> Acked-by: Julien Grall <julien.grall@xxxxxxx> --- Cc: Stefano Stabellini <sstabellini@xxxxxxxxxx> Cc: Julien Grall <julien.grall@xxxxxxx> --- 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 <proskurin@xxxxxxxxxxxxx> + * + * 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 <http://www.gnu.org/licenses/>. + */ + +#include <xen/sched.h> + +/* + * 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: + */ -- 2.13.2 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |