[Xen-devel,03/22] xen/arm: p2m: Restrict usage of get_page_from_gva to the current vCPU

Message ID 1469031064-23344-4-git-send-email-julien.grall@arm.com
State New
Headers show

Commit Message

Julien Grall July 20, 2016, 4:10 p.m.
The function get_page_from_gva translates a guest virtual address to a
machine address. The translation involves the register VTTBR_EL2,
TTBR0_EL1, TTBR1_EL1 and SCTLR_EL1.

Currently, only the first register is context switch is the current
domain is not the same. This will result to use the wrong TTBR*_EL1 and
SCTLR_EL1 for the translation.

To fix the code properly, we would have to context switch all the
registers mentioned above when the vCPU in parameter is not the current
one. Similar things would need to be done in the callee
p2m_mem_check_and_get_page.

Given that the only caller of this function with the vCPU that may not
be current is a guest debugging function (show_guest_stack), restrict
the usage to the current vCPU for the time being.

A proper fix will be send separately.

Signed-off-by: Julien Grall <julien.grall@arm.com>

---
    This patch is candidate to be backported up to Xen 4.5.
---
 xen/arch/arm/p2m.c | 24 ++++++++----------------
 1 file changed, 8 insertions(+), 16 deletions(-)

Patch

diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
index 1111d6f..64d84cc 100644
--- a/xen/arch/arm/p2m.c
+++ b/xen/arch/arm/p2m.c
@@ -1530,24 +1530,16 @@  struct page_info *get_page_from_gva(struct vcpu *v, vaddr_t va,
     paddr_t maddr = 0;
     int rc;
 
-    spin_lock(&p2m->lock);
-
-    if ( unlikely(d != current->domain) )
-    {
-        unsigned long irq_flags;
-
-        local_irq_save(irq_flags);
-        p2m_load_VTTBR(d);
+    /*
+     * XXX: To support a different vCPU, we would need to load the
+     * VTTBR_EL2, TTBR0_EL1, TTBR1_EL1 and SCTLR_EL1
+     */
+    if ( v != current )
+        return NULL;
 
-        rc = gvirt_to_maddr(va, &maddr, flags);
+    spin_lock(&p2m->lock);
 
-        p2m_load_VTTBR(current->domain);
-        local_irq_restore(irq_flags);
-    }
-    else
-    {
-        rc = gvirt_to_maddr(va, &maddr, flags);
-    }
+    rc = gvirt_to_maddr(va, &maddr, flags);
 
     if ( rc )
         goto err;