[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH 14/18] arm/altp2m: Add HVMOP_altp2m_set_mem_access.



Hi,

On 04/07/16 12:45, Sergej Proskurin wrote:
--- a/xen/arch/arm/p2m.c
+++ b/xen/arch/arm/p2m.c
@@ -2085,6 +2085,159 @@ bool_t p2m_mem_access_check(paddr_t gpa, vaddr_t gla, 
const struct npfec npfec)

[...]

+static inline
+int p2m_set_altp2m_mem_access(struct domain *d, struct p2m_domain *hp2m,
+                              struct p2m_domain *ap2m, p2m_access_t a,
+                              gfn_t gfn)
+{
+    p2m_type_t p2mt;
+    xenmem_access_t xma_old;
+    paddr_t gpa = pfn_to_paddr(gfn_x(gfn));
+    paddr_t maddr, mask = 0;
+    unsigned int level;
+    unsigned long mattr;
+    int rc;
+
+    static const p2m_access_t memaccess[] = {
+#define ACCESS(ac) [XENMEM_access_##ac] = p2m_access_##ac
+        ACCESS(n),
+        ACCESS(r),
+        ACCESS(w),
+        ACCESS(rw),
+        ACCESS(x),
+        ACCESS(rx),
+        ACCESS(wx),
+        ACCESS(rwx),
+        ACCESS(rx2rw),
+        ACCESS(n2rwx),
+#undef ACCESS
+    };
+
+    /* Check if entry is part of the altp2m view. */
+    spin_lock(&ap2m->lock);
+    maddr = __p2m_lookup(ap2m, gpa, &p2mt);
+    spin_unlock(&ap2m->lock);
+
+    /* Check host p2m if no valid entry in ap2m. */
+    if ( maddr == INVALID_PADDR )
+    {
+        /* Check if entry is part of the host p2m view. */
+        spin_lock(&hp2m->lock);
+        maddr = __p2m_lookup(hp2m, gpa, &p2mt);
+        if ( maddr == INVALID_PADDR || p2mt != p2m_ram_rw )
+            goto out;
+
+        rc = __p2m_get_mem_access(hp2m, gfn, &xma_old);
+        if ( rc )
+            goto out;
+
+        rc = p2m_get_gfn_level_and_attr(hp2m, gpa, &level, &mattr);
+        if ( rc )
+            goto out;
+        spin_unlock(&hp2m->lock);
+
+        mask = level_masks[level];
+
+        /* If this is a superpage, copy that first. */
+        if ( level != 3 )
+        {
+            rc = apply_p2m_changes(d, ap2m, INSERT,
+                                   gpa & mask,
+                                   (gpa + level_sizes[level]) & mask,
+                                   maddr & mask, mattr, 0, p2mt,
+                                   memaccess[xma_old]);
+            if ( rc < 0 )
+                goto out;
+        }
+    }
+    else
+    {
+        spin_lock(&ap2m->lock);
+        rc = p2m_get_gfn_level_and_attr(ap2m, gpa, &level, &mattr);
+        spin_unlock(&ap2m->lock);
+        if ( rc )
+            goto out;
+    }
+
+    /* Set mem access attributes - currently supporting only one (4K) page. */
+    mask = level_masks[3];
+    return apply_p2m_changes(d, ap2m, INSERT,
+                             gpa & mask,
+                             (gpa + level_sizes[level]) & mask,
+                             maddr & mask, mattr, 0, p2mt, a);
+
+out:
+    if ( spin_is_locked(&hp2m->lock) )
+        spin_unlock(&hp2m->lock);

I have not spotted this before. spin_is_locked does not ensure that the lock was taken by this CPU. So you may unlock for another CPU.

+
+    return -ESRCH;
+}
+

Regards,

--
Julien Grall

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.