diff options
-rw-r--r-- | xen/common/compat/memory.c | 14 | ||||
-rw-r--r-- | xen/common/memory.c | 37 | ||||
-rw-r--r-- | xen/include/asm-ia64/mm.h | 1 | ||||
-rw-r--r-- | xen/include/public/memory.h | 16 | ||||
-rw-r--r-- | xen/include/xlat.lst | 1 | ||||
-rw-r--r-- | xen/include/xsm/xsm.h | 6 | ||||
-rw-r--r-- | xen/xsm/dummy.c | 6 | ||||
-rw-r--r-- | xen/xsm/flask/hooks.c | 6 |
8 files changed, 87 insertions, 0 deletions
diff --git a/xen/common/compat/memory.c b/xen/common/compat/memory.c index 2402984f1e..e7257cc53e 100644 --- a/xen/common/compat/memory.c +++ b/xen/common/compat/memory.c @@ -25,6 +25,7 @@ int compat_memory_op(unsigned int cmd, XEN_GUEST_HANDLE(void) compat) XEN_GUEST_HANDLE(void) hnd; struct xen_memory_reservation *rsrv; struct xen_memory_exchange *xchg; + struct xen_remove_from_physmap *xrfp; } nat; union { struct compat_memory_reservation rsrv; @@ -179,6 +180,18 @@ int compat_memory_op(unsigned int cmd, XEN_GUEST_HANDLE(void) compat) nat.hnd = compat; break; + case XENMEM_remove_from_physmap: + { + struct compat_remove_from_physmap cmp; + + if ( copy_from_guest(&cmp, compat, 1) ) + return -EFAULT; + + XLAT_remove_from_physmap(nat.xrfp, &cmp); + + break; + } + default: return compat_arch_memory_op(cmd, compat); } @@ -284,6 +297,7 @@ int compat_memory_op(unsigned int cmd, XEN_GUEST_HANDLE(void) compat) case XENMEM_current_reservation: case XENMEM_maximum_reservation: case XENMEM_maximum_gpfn: + case XENMEM_remove_from_physmap: break; default: diff --git a/xen/common/memory.c b/xen/common/memory.c index 8d45439745..53886cea3b 100644 --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -659,6 +659,43 @@ long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE(void) arg) break; + case XENMEM_remove_from_physmap: + { + struct xen_remove_from_physmap xrfp; + unsigned long mfn; + struct domain *d; + + if ( copy_from_guest(&xrfp, arg, 1) ) + return -EFAULT; + + rc = rcu_lock_target_domain_by_id(xrfp.domid, &d); + if ( rc != 0 ) + return rc; + + if ( xsm_remove_from_physmap(current->domain, d) ) + { + rcu_unlock_domain(d); + return -EPERM; + } + + domain_lock(d); + + mfn = get_gfn_untyped(d, xrfp.gpfn); + + if ( mfn_valid(mfn) ) + guest_physmap_remove_page(d, xrfp.gpfn, mfn, PAGE_ORDER_4K); + else + rc = -ENOENT; + + put_gfn(d, xrfp.gpfn); + + domain_unlock(d); + + rcu_unlock_domain(d); + + break; + } + default: rc = arch_memory_op(op, arg); break; diff --git a/xen/include/asm-ia64/mm.h b/xen/include/asm-ia64/mm.h index d09c363df3..a2bfc026e6 100644 --- a/xen/include/asm-ia64/mm.h +++ b/xen/include/asm-ia64/mm.h @@ -550,6 +550,7 @@ extern u64 translate_domain_pte(u64 pteval, u64 address, u64 itir__, #define gmfn_to_mfn(_d, gpfn) \ gmfn_to_mfn_foreign((_d), (gpfn)) +#define get_gfn_untyped(d, gpfn) gmfn_to_mfn(d, gpfn) #define put_gfn(d, g) ((void)0) #define __gpfn_invalid(_d, gpfn) \ diff --git a/xen/include/public/memory.h b/xen/include/public/memory.h index 3bc2f25cdc..9d9aabcfdb 100644 --- a/xen/include/public/memory.h +++ b/xen/include/public/memory.h @@ -229,6 +229,22 @@ struct xen_add_to_physmap { typedef struct xen_add_to_physmap xen_add_to_physmap_t; DEFINE_XEN_GUEST_HANDLE(xen_add_to_physmap_t); +/* + * Unmaps the page appearing at a particular GPFN from the specified guest's + * pseudophysical address space. + * arg == addr of xen_remove_from_physmap_t. + */ +#define XENMEM_remove_from_physmap 15 +struct xen_remove_from_physmap { + /* Which domain to change the mapping for. */ + domid_t domid; + + /* GPFN of the current mapping of the page. */ + xen_pfn_t gpfn; +}; +typedef struct xen_remove_from_physmap xen_remove_from_physmap_t; +DEFINE_XEN_GUEST_HANDLE(xen_remove_from_physmap_t); + /*** REMOVED ***/ /*#define XENMEM_translate_gpfn_list 8*/ diff --git a/xen/include/xlat.lst b/xen/include/xlat.lst index f6021550df..3d4f1e328f 100644 --- a/xen/include/xlat.lst +++ b/xen/include/xlat.lst @@ -60,6 +60,7 @@ ! memory_map memory.h ! memory_reservation memory.h ! pod_target memory.h +! remove_from_physmap memory.h ? physdev_eoi physdev.h ? physdev_get_free_pirq physdev.h ? physdev_irq physdev.h diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h index df6cec22f3..566c8080f7 100644 --- a/xen/include/xsm/xsm.h +++ b/xen/include/xsm/xsm.h @@ -169,6 +169,7 @@ struct xsm_operations { int (*update_va_mapping) (struct domain *d, struct domain *f, l1_pgentry_t pte); int (*add_to_physmap) (struct domain *d1, struct domain *d2); + int (*remove_from_physmap) (struct domain *d1, struct domain *d2); int (*sendtrigger) (struct domain *d); int (*bind_pt_irq) (struct domain *d, struct xen_domctl_bind_pt_irq *bind); int (*unbind_pt_irq) (struct domain *d); @@ -738,6 +739,11 @@ static inline int xsm_add_to_physmap(struct domain *d1, struct domain *d2) return xsm_call(add_to_physmap(d1, d2)); } +static inline int xsm_remove_from_physmap(struct domain *d1, struct domain *d2) +{ + return xsm_call(remove_from_physmap(d1, d2)); +} + static inline int xsm_sendtrigger(struct domain *d) { return xsm_call(sendtrigger(d)); diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c index 4bbfbffb14..65daa4e775 100644 --- a/xen/xsm/dummy.c +++ b/xen/xsm/dummy.c @@ -529,6 +529,11 @@ static int dummy_add_to_physmap (struct domain *d1, struct domain *d2) return 0; } +static int dummy_remove_from_physmap (struct domain *d1, struct domain *d2) +{ + return 0; +} + static int dummy_sendtrigger (struct domain *d) { return 0; @@ -690,6 +695,7 @@ void xsm_fixup_ops (struct xsm_operations *ops) set_to_dummy_if_null(ops, mmu_machphys_update); set_to_dummy_if_null(ops, update_va_mapping); set_to_dummy_if_null(ops, add_to_physmap); + set_to_dummy_if_null(ops, remove_from_physmap); set_to_dummy_if_null(ops, sendtrigger); set_to_dummy_if_null(ops, bind_pt_irq); set_to_dummy_if_null(ops, pin_mem_cacheattr); diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c index 0d35767821..a2020a9f60 100644 --- a/xen/xsm/flask/hooks.c +++ b/xen/xsm/flask/hooks.c @@ -1283,6 +1283,11 @@ static int flask_add_to_physmap(struct domain *d1, struct domain *d2) return domain_has_perm(d1, d2, SECCLASS_MMU, MMU__PHYSMAP); } +static int flask_remove_from_physmap(struct domain *d1, struct domain *d2) +{ + return domain_has_perm(d1, d2, SECCLASS_MMU, MMU__PHYSMAP); +} + static int flask_sendtrigger(struct domain *d) { return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, DOMAIN__TRIGGER); @@ -1550,6 +1555,7 @@ static struct xsm_operations flask_ops = { .mmu_machphys_update = flask_mmu_machphys_update, .update_va_mapping = flask_update_va_mapping, .add_to_physmap = flask_add_to_physmap, + .remove_from_physmap = flask_remove_from_physmap, .sendtrigger = flask_sendtrigger, .get_device_group = flask_get_device_group, .test_assign_device = flask_test_assign_device, |