]> xenbits.xensource.com Git - xen.git/commitdiff
relocate p2m_mem_access_resume to mem_access common
authorTamas K Lengyel <tklengyel@sec.in.tum.de>
Fri, 26 Sep 2014 14:25:31 +0000 (16:25 +0200)
committerJan Beulich <jbeulich@suse.com>
Fri, 26 Sep 2014 14:25:31 +0000 (16:25 +0200)
Relocate p2m_mem_access_resume to common and abstract the new
p2m_mem_event_emulate_check into the p2m layer to.

Signed-off-by: Tamas K Lengyel <tklengyel@sec.in.tum.de>
Acked-by: Tim Deegan <tim@xen.org>
xen/arch/x86/mm/p2m.c
xen/common/mem_access.c
xen/common/mem_event.c
xen/include/asm-arm/p2m.h
xen/include/asm-x86/p2m.h
xen/include/xen/mem_access.h

index 31d0d9e11af6dc69cef19afee83fff7caab9f37e..4822517379f2fedae4a5960eaa8285f53fc81eec 100644 (file)
@@ -1382,6 +1382,59 @@ static void p2m_mem_event_fill_regs(mem_event_request_t *req)
     req->x86_regs.cs_arbytes = seg.attr.bytes;
 }
 
+void p2m_mem_event_emulate_check(struct vcpu *v, const mem_event_response_t *rsp)
+{
+    /* Mark vcpu for skipping one instruction upon rescheduling. */
+    if ( rsp->flags & MEM_EVENT_FLAG_EMULATE )
+    {
+        xenmem_access_t access;
+        bool_t violation = 1;
+
+        if ( p2m_get_mem_access(v->domain, rsp->gfn, &access) == 0 )
+        {
+            switch ( access )
+            {
+            case XENMEM_access_n:
+            case XENMEM_access_n2rwx:
+            default:
+                violation = rsp->access_r || rsp->access_w || rsp->access_x;
+                break;
+
+            case XENMEM_access_r:
+                violation = rsp->access_w || rsp->access_x;
+                break;
+
+            case XENMEM_access_w:
+                violation = rsp->access_r || rsp->access_x;
+                break;
+
+            case XENMEM_access_x:
+                violation = rsp->access_r || rsp->access_w;
+                break;
+
+            case XENMEM_access_rx:
+            case XENMEM_access_rx2rw:
+                violation = rsp->access_w;
+                break;
+
+            case XENMEM_access_wx:
+                violation = rsp->access_r;
+                break;
+
+            case XENMEM_access_rw:
+                violation = rsp->access_x;
+                break;
+
+            case XENMEM_access_rwx:
+                violation = 0;
+                break;
+            }
+        }
+
+        v->arch.mem_event.emulate_flags = violation ? rsp->flags : 0;
+    }
+}
+
 bool_t p2m_mem_access_check(paddr_t gpa, unsigned long gla,
                             struct npfec npfec,
                             mem_event_request_t **req_ptr)
@@ -1509,80 +1562,6 @@ bool_t p2m_mem_access_check(paddr_t gpa, unsigned long gla,
     return (p2ma == p2m_access_n2rwx);
 }
 
-void p2m_mem_access_resume(struct domain *d)
-{
-    mem_event_response_t rsp;
-
-    /* Pull all responses off the ring */
-    while( mem_event_get_response(d, &d->mem_event->access, &rsp) )
-    {
-        struct vcpu *v;
-
-        if ( rsp.flags & MEM_EVENT_FLAG_DUMMY )
-            continue;
-
-        /* Validate the vcpu_id in the response. */
-        if ( (rsp.vcpu_id >= d->max_vcpus) || !d->vcpu[rsp.vcpu_id] )
-            continue;
-
-        v = d->vcpu[rsp.vcpu_id];
-
-        /* Mark vcpu for skipping one instruction upon rescheduling. */
-        if ( rsp.flags & MEM_EVENT_FLAG_EMULATE )
-        {
-            xenmem_access_t access;
-            bool_t violation = 1;
-
-            if ( p2m_get_mem_access(d, rsp.gfn, &access) == 0 )
-            {
-                switch ( access )
-                {
-                case XENMEM_access_n:
-                case XENMEM_access_n2rwx:
-                default:
-                    violation = rsp.access_r || rsp.access_w || rsp.access_x;
-                    break;
-
-                case XENMEM_access_r:
-                    violation = rsp.access_w || rsp.access_x;
-                    break;
-
-                case XENMEM_access_w:
-                    violation = rsp.access_r || rsp.access_x;
-                    break;
-
-                case XENMEM_access_x:
-                    violation = rsp.access_r || rsp.access_w;
-                    break;
-
-                case XENMEM_access_rx:
-                case XENMEM_access_rx2rw:
-                    violation = rsp.access_w;
-                    break;
-
-                case XENMEM_access_wx:
-                    violation = rsp.access_r;
-                    break;
-
-                case XENMEM_access_rw:
-                    violation = rsp.access_x;
-                    break;
-
-                case XENMEM_access_rwx:
-                    violation = 0;
-                    break;
-                }
-            }
-
-            v->arch.mem_event.emulate_flags = violation ? rsp.flags : 0;
-        }
-
-        /* Unpause domain */
-        if ( rsp.flags & MEM_EVENT_FLAG_VCPU_PAUSED )
-            mem_event_vcpu_unpause(v);
-    }
-}
-
 /* Set access type for a region of pfns.
  * If start_pfn == -1ul, sets the default access type */
 long p2m_set_mem_access(struct domain *d, unsigned long pfn, uint32_t nr,
index 9a8c1a9eaa440b56edd79cfb2df0db80519401e2..64e5301467ec829df0ad140103706373f48c805d 100644 (file)
 #include <asm/p2m.h>
 #include <xsm/xsm.h>
 
+void mem_access_resume(struct domain *d)
+{
+    mem_event_response_t rsp;
+
+    /* Pull all responses off the ring. */
+    while ( mem_event_get_response(d, &d->mem_event->access, &rsp) )
+    {
+        struct vcpu *v;
+
+        if ( rsp.flags & MEM_EVENT_FLAG_DUMMY )
+            continue;
+
+        /* Validate the vcpu_id in the response. */
+        if ( (rsp.vcpu_id >= d->max_vcpus) || !d->vcpu[rsp.vcpu_id] )
+            continue;
+
+        v = d->vcpu[rsp.vcpu_id];
+
+        p2m_mem_event_emulate_check(v, &rsp);
+
+        /* Unpause domain. */
+        if ( rsp.flags & MEM_EVENT_FLAG_VCPU_PAUSED )
+            mem_event_vcpu_unpause(v);
+    }
+}
+
 int mem_access_memop(unsigned long cmd,
                      XEN_GUEST_HANDLE_PARAM(xen_mem_access_op_t) arg)
 {
@@ -58,7 +84,7 @@ int mem_access_memop(unsigned long cmd,
     switch ( mao.op )
     {
     case XENMEM_access_op_resume:
-        p2m_mem_access_resume(d);
+        mem_access_resume(d);
         rc = 0;
         break;
 
index 1e337694d166683d884d652eaed6109c720eac21..a179cbcb3ae9d3c893f6ef3514d1731f82d682a6 100644 (file)
@@ -440,7 +440,7 @@ static void mem_paging_notification(struct vcpu *v, unsigned int port)
 static void mem_access_notification(struct vcpu *v, unsigned int port)
 {
     if ( likely(v->domain->mem_event->access.ring_page != NULL) )
-        p2m_mem_access_resume(v->domain);
+        mem_access_resume(v->domain);
 }
 #endif
 
index faf14d3364b4bd77a58f1fb817534fc1f12b2307..38e32e632b2ddce33377a54b28dcca63dbc0e0fb 100644 (file)
@@ -66,6 +66,13 @@ typedef enum {
     p2m_max_real_type,  /* Types after this won't be store in the p2m */
 } p2m_type_t;
 
+static inline
+void p2m_mem_event_emulate_check(struct vcpu *v,
+                                 const mem_event_response_t *rsp)
+{
+    /* Not supported on ARM. */
+};
+
 #define p2m_is_foreign(_t)  ((_t) == p2m_map_foreign)
 #define p2m_is_ram(_t)      ((_t) == p2m_ram_rw || (_t) == p2m_ram_ro)
 
index 42c04b203a6bdd973002c1df6f9b3caca26ae2b2..5c16fb112e9fc5ecd657a56e1bac9535e2359eb4 100644 (file)
@@ -573,8 +573,6 @@ void p2m_mem_paging_resume(struct domain *d);
 bool_t p2m_mem_access_check(paddr_t gpa, unsigned long gla,
                             struct npfec npfec,
                             mem_event_request_t **req_ptr);
-/* Resumes the running of the VCPU, restarting the last instruction */
-void p2m_mem_access_resume(struct domain *d);
 
 /* Set access type for a region of pfns.
  * If start_pfn == -1ul, sets the default access type */
@@ -586,6 +584,11 @@ long p2m_set_mem_access(struct domain *d, unsigned long start_pfn, uint32_t nr,
 int p2m_get_mem_access(struct domain *d, unsigned long pfn,
                        xenmem_access_t *access);
 
+/* Check for emulation and mark vcpu for skipping one instruction
+ * upon rescheduling if required. */
+void p2m_mem_event_emulate_check(struct vcpu *v,
+                                 const mem_event_response_t *rsp);
+
 /* 
  * Internal functions, only called by other p2m code
  */
index 19d1a2d19f0f38b66dcf5cfcce2b83360efe4732..6ceb2a407b226e86ea618829edd9c3f9e06d7f37 100644 (file)
@@ -31,6 +31,9 @@ int mem_access_memop(unsigned long cmd,
                      XEN_GUEST_HANDLE_PARAM(xen_mem_access_op_t) arg);
 int mem_access_send_req(struct domain *d, mem_event_request_t *req);
 
+/* Resumes the running of the VCPU, restarting the last instruction */
+void mem_access_resume(struct domain *d);
+
 #else
 
 static inline
@@ -46,6 +49,8 @@ int mem_access_send_req(struct domain *d, mem_event_request_t *req)
     return -ENOSYS;
 }
 
+static inline void mem_access_resume(struct domain *d) {}
+
 #endif /* HAS_MEM_ACCESS */
 
 #endif /* _XEN_ASM_MEM_ACCESS_H */