@@ -17,7 +17,7 @@ static unsigned long raw_copy_to_guest_helper(void *to, const void *from,
unsigned size = min(len, (unsigned)PAGE_SIZE - offset);
struct page_info *page;
- page = get_page_from_gva(current->domain, (vaddr_t) to, GV2M_WRITE);
+ page = get_page_from_gva(current, (vaddr_t) to, GV2M_WRITE);
if ( page == NULL )
return len;
@@ -64,7 +64,7 @@ unsigned long raw_clear_guest(void *to, unsigned len)
unsigned size = min(len, (unsigned)PAGE_SIZE - offset);
struct page_info *page;
- page = get_page_from_gva(current->domain, (vaddr_t) to, GV2M_WRITE);
+ page = get_page_from_gva(current, (vaddr_t) to, GV2M_WRITE);
if ( page == NULL )
return len;
@@ -96,7 +96,7 @@ unsigned long raw_copy_from_guest(void *to, const void __user *from, unsigned le
unsigned size = min(len, (unsigned)(PAGE_SIZE - offset));
struct page_info *page;
- page = get_page_from_gva(current->domain, (vaddr_t) from, GV2M_READ);
+ page = get_page_from_gva(current, (vaddr_t) from, GV2M_READ);
if ( page == NULL )
return len;
@@ -1829,10 +1829,11 @@ err:
return page;
}
-struct page_info *get_page_from_gva(struct domain *d, vaddr_t va,
+struct page_info *get_page_from_gva(struct vcpu *v, vaddr_t va,
unsigned long flags)
{
- struct p2m_domain *p2m = &d->arch.p2m;
+ struct domain *d = v->domain;
+ struct p2m_domain *p2m = altp2m_active(d) ? p2m_get_altp2m(v) : p2m_get_hostp2m(d);
struct page_info *page = NULL;
paddr_t maddr = 0;
int rc;
@@ -1844,17 +1845,23 @@ struct page_info *get_page_from_gva(struct domain *d, vaddr_t va,
unsigned long irq_flags;
local_irq_save(irq_flags);
- p2m_load_VTTBR(d);
+
+ if ( altp2m_active(d) )
+ p2m_load_altp2m_VTTBR(v);
+ else
+ p2m_load_VTTBR(d);
rc = gvirt_to_maddr(va, &maddr, flags);
- p2m_load_VTTBR(current->domain);
+ if ( altp2m_active(current->domain) )
+ p2m_load_altp2m_VTTBR(current);
+ else
+ p2m_load_VTTBR(current->domain);
+
local_irq_restore(irq_flags);
}
else
- {
rc = gvirt_to_maddr(va, &maddr, flags);
- }
if ( rc )
goto err;
@@ -957,7 +957,7 @@ static void show_guest_stack(struct vcpu *v, struct cpu_user_regs *regs)
return;
}
- page = get_page_from_gva(v->domain, sp, GV2M_READ);
+ page = get_page_from_gva(v, sp, GV2M_READ);
if ( page == NULL )
{
printk("Failed to convert stack to physical address\n");
@@ -281,7 +281,7 @@ static inline void *page_to_virt(const struct page_info *pg)
return mfn_to_virt(page_to_mfn(pg));
}
-struct page_info *get_page_from_gva(struct domain *d, vaddr_t va,
+struct page_info *get_page_from_gva(struct vcpu *v, vaddr_t va,
unsigned long flags);
/*
This commit adapts get_page_from_gva to consider the currently mapped altp2m view during address translation. We also adapt the function's prototype (provide "struct vcpu *" instead of "struct domain *"). This change is required, as the function indirectly calls the function gva_to_ma_par, which requires the mmu to use the current p2m mapping. So if the caller is interested in a page that must be claimed from a vCPU other than current, it must temporarily set the altp2m view that is used by the vCPU in question. Therefore, we need to provide the particular vCPU to this function. Signed-off-by: Sergej Proskurin <proskurin@sec.in.tum.de> --- Cc: Stefano Stabellini <sstabellini@kernel.org> Cc: Julien Grall <julien.grall@arm.com> --- xen/arch/arm/guestcopy.c | 6 +++--- xen/arch/arm/p2m.c | 19 +++++++++++++------ xen/arch/arm/traps.c | 2 +- xen/include/asm-arm/mm.h | 2 +- 4 files changed, 18 insertions(+), 11 deletions(-)