# HG changeset patch
# User Tim Deegan <Tim.Deegan@xxxxxxxxxx>
# Date 1305302439 -3600
# Node ID 72da3d3b68d68c9b5e834e9b707abf2e2c61bdc4
# Parent ba2902017f010e1a3a756f4053175d71027244e8
x86/mm/p2m: Move p2m code in HVMOP_[gs]et_mem_access into p2m.c
It uses p2m internals like the p2m lock and function pointers so belongs
behind the p2m interface.
Signed-off-by: Tim Deegan <Tim.Deegan@xxxxxxxxxx>
diff -r ba2902017f01 -r 72da3d3b68d6 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c Fri May 13 17:00:39 2011 +0100
+++ b/xen/arch/x86/hvm/hvm.c Fri May 13 17:00:39 2011 +0100
@@ -3786,21 +3786,6 @@ long do_hvm_op(unsigned long op, XEN_GUE
{
struct xen_hvm_set_mem_access a;
struct domain *d;
- struct p2m_domain *p2m;
- unsigned long pfn;
-
- p2m_access_t memaccess[] = {
- p2m_access_n,
- p2m_access_r,
- p2m_access_w,
- p2m_access_rw,
- p2m_access_x,
- p2m_access_rx,
- p2m_access_wx,
- p2m_access_rwx,
- p2m_access_rx2rw,
- 0, /* HVMMEM_access_default -- will get set below */
- };
if ( copy_from_guest(&a, arg, 1) )
return -EFAULT;
@@ -3813,42 +3798,13 @@ long do_hvm_op(unsigned long op, XEN_GUE
if ( !is_hvm_domain(d) )
goto param_fail5;
- p2m = p2m_get_hostp2m(d);
- memaccess[HVMMEM_access_default] = p2m->default_access;
-
- /* If request to set default access */
- if ( a.first_pfn == ~0ull )
- {
- rc = 0;
- p2m->default_access = memaccess[a.hvmmem_access];
- goto param_fail5;
- }
-
rc = -EINVAL;
if ( (a.first_pfn > domain_get_maximum_gpfn(d)) ||
((a.first_pfn + a.nr - 1) < a.first_pfn) ||
((a.first_pfn + a.nr - 1) > domain_get_maximum_gpfn(d)) )
goto param_fail5;
- if ( a.hvmmem_access >= ARRAY_SIZE(memaccess) )
- goto param_fail5;
-
- for ( pfn = a.first_pfn; pfn < a.first_pfn + a.nr; pfn++ )
- {
- p2m_type_t t;
- mfn_t mfn;
- int success;
-
- mfn = gfn_to_mfn_unshare(d, pfn, &t);
-
- p2m_lock(p2m);
- success = p2m->set_entry(p2m, pfn, mfn, 0, t,
memaccess[a.hvmmem_access]);
- p2m_unlock(p2m);
- if ( !success )
- goto param_fail5;
- }
-
- rc = 0;
+ rc = p2m_set_mem_access(d, a.first_pfn, a.nr, a.hvmmem_access);
param_fail5:
rcu_unlock_domain(d);
@@ -3859,23 +3815,7 @@ long do_hvm_op(unsigned long op, XEN_GUE
{
struct xen_hvm_get_mem_access a;
struct domain *d;
- struct p2m_domain *p2m;
- p2m_type_t t;
- p2m_access_t ac;
- mfn_t mfn;
-
- /* Interface access to internal p2m accesses */
- hvmmem_access_t memaccess[] = {
- HVMMEM_access_n,
- HVMMEM_access_r,
- HVMMEM_access_w,
- HVMMEM_access_rw,
- HVMMEM_access_x,
- HVMMEM_access_rx,
- HVMMEM_access_wx,
- HVMMEM_access_rwx,
- HVMMEM_access_rx2rw
- };
+ hvmmem_access_t access;
if ( copy_from_guest(&a, arg, 1) )
return -EFAULT;
@@ -3888,30 +3828,15 @@ long do_hvm_op(unsigned long op, XEN_GUE
if ( !is_hvm_domain(d) )
goto param_fail6;
- p2m = p2m_get_hostp2m(d);
-
- if ( a.pfn == ~0ull )
- {
- a.hvmmem_access = memaccess[p2m->default_access];
- }
- else {
- rc = -EINVAL;
- if ( (a.pfn > domain_get_maximum_gpfn(d)) )
- goto param_fail6;
-
- rc = -ESRCH;
- mfn = p2m->get_entry(p2m, a.pfn, &t, &ac, p2m_query);
-
- if ( mfn_x(mfn) == INVALID_MFN )
- goto param_fail6;
-
- rc = -ERANGE;
- if ( ac >= ARRAY_SIZE(memaccess) )
- goto param_fail6;
-
- a.hvmmem_access = memaccess[ac];
- }
-
+ rc = -EINVAL;
+ if ( (a.pfn > domain_get_maximum_gpfn(d)) && a.pfn != ~0ull )
+ goto param_fail6;
+
+ rc = p2m_get_mem_access(d, a.pfn, &access);
+ if ( rc != 0 )
+ goto param_fail6;
+
+ a.hvmmem_access = access;
rc = copy_to_guest(arg, &a, 1) ? -EFAULT : 0;
param_fail6:
diff -r ba2902017f01 -r 72da3d3b68d6 xen/arch/x86/mm/p2m.c
--- a/xen/arch/x86/mm/p2m.c Fri May 13 17:00:39 2011 +0100
+++ b/xen/arch/x86/mm/p2m.c Fri May 13 17:00:39 2011 +0100
@@ -923,6 +923,101 @@ void p2m_mem_access_resume(struct p2m_do
* was available */
mem_event_unpause_vcpus(d);
}
+
+
+/* Set access type for a region of pfns.
+ * If start_pfn == -1ul, sets the default access type */
+int p2m_set_mem_access(struct domain *d, unsigned long start_pfn,
+ uint32_t nr, hvmmem_access_t access)
+{
+ struct p2m_domain *p2m = p2m_get_hostp2m(d);
+ unsigned long pfn;
+ p2m_access_t a;
+ p2m_type_t t;
+ mfn_t mfn;
+ int rc = 0;
+
+ /* N.B. _not_ static: initializer depends on p2m->default_access */
+ p2m_access_t memaccess[] = {
+ p2m_access_n,
+ p2m_access_r,
+ p2m_access_w,
+ p2m_access_rw,
+ p2m_access_x,
+ p2m_access_rx,
+ p2m_access_wx,
+ p2m_access_rwx,
+ p2m_access_rx2rw,
+ p2m->default_access,
+ };
+
+ if ( access >= HVMMEM_access_default || access < 0 )
+ return -EINVAL;
+
+ a = memaccess[access];
+
+ /* If request to set default access */
+ if ( start_pfn == ~0ull )
+ {
+ p2m->default_access = a;
+ return 0;
+ }
+
+ p2m_lock(p2m);
+ for ( pfn = start_pfn; pfn < start_pfn + nr; pfn++ )
+ {
+ mfn = gfn_to_mfn_query(d, pfn, &t);
+ if ( p2m->set_entry(p2m, pfn, mfn, 0, t, a) == 0 )
+ {
+ rc = -ENOMEM;
+ break;
+ }
+ }
+ p2m_unlock(p2m);
+ return rc;
+}
+
+/* Get access type for a pfn
+ * If pfn == -1ul, gets the default access type */
+int p2m_get_mem_access(struct domain *d, unsigned long pfn,
+ hvmmem_access_t *access)
+{
+ struct p2m_domain *p2m = p2m_get_hostp2m(d);
+ p2m_type_t t;
+ p2m_access_t a;
+ mfn_t mfn;
+
+ static const hvmmem_access_t memaccess[] = {
+ HVMMEM_access_n,
+ HVMMEM_access_r,
+ HVMMEM_access_w,
+ HVMMEM_access_rw,
+ HVMMEM_access_x,
+ HVMMEM_access_rx,
+ HVMMEM_access_wx,
+ HVMMEM_access_rwx,
+ HVMMEM_access_rx2rw
+ };
+
+ /* If request to get default access */
+ if ( pfn == ~0ull )
+ {
+ *access = memaccess[p2m->default_access];
+ return 0;
+ }
+
+ mfn = p2m->get_entry(p2m, pfn, &t, &a, p2m_query);
+ if ( mfn_x(mfn) == INVALID_MFN )
+ return -ESRCH;
+
+ if ( a >= ARRAY_SIZE(memaccess) || a < 0 )
+ return -ERANGE;
+
+ *access = memaccess[a];
+ return 0;
+}
+
+
#endif /* __x86_64__ */
static struct p2m_domain *
diff -r ba2902017f01 -r 72da3d3b68d6 xen/include/asm-x86/p2m.h
--- a/xen/include/asm-x86/p2m.h Fri May 13 17:00:39 2011 +0100
+++ b/xen/include/asm-x86/p2m.h Fri May 13 17:00:39 2011 +0100
@@ -553,6 +553,17 @@ void p2m_mem_access_check(unsigned long
bool_t access_r, bool_t access_w, bool_t access_x);
/* Resumes the running of the VCPU, restarting the last instruction */
void p2m_mem_access_resume(struct p2m_domain *p2m);
+
+/* Set access type for a region of pfns.
+ * If start_pfn == -1ul, sets the default access type */
+int p2m_set_mem_access(struct domain *d, unsigned long start_pfn,
+ uint32_t nr, hvmmem_access_t access);
+
+/* Get access type for a pfn
+ * If pfn == -1ul, gets the default access type */
+int p2m_get_mem_access(struct domain *d, unsigned long pfn,
+ hvmmem_access_t *access);
+
#else
static inline void p2m_mem_access_check(unsigned long gpa, bool_t gla_valid,
unsigned long gla, bool_t access_r,
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|