diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2008-07-10 15:30:39 +0100 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2008-07-10 15:30:39 +0100 |
commit | 51cf89ed5da0f2e865d976b8baee54ffcfdd25a6 (patch) | |
tree | 5aff263c47d685d439d8633218d5adf3f5a1e117 | |
parent | 4d8aa29d6566ac33cb72a496fb073cdd3a52db25 (diff) | |
download | xen-51cf89ed5da0f2e865d976b8baee54ffcfdd25a6.tar.gz xen-51cf89ed5da0f2e865d976b8baee54ffcfdd25a6.tar.bz2 xen-51cf89ed5da0f2e865d976b8baee54ffcfdd25a6.zip |
x86 hvm: New hvm_op "set_mem_type" which allows marking ram page
ranges as ro, rw, or mmio_dm.
Signed-off-by: Trolle Selander <trolle.selander@eu.citrix.com>
-rw-r--r-- | tools/libxc/xc_misc.c | 30 | ||||
-rw-r--r-- | tools/libxc/xenctrl.h | 9 | ||||
-rw-r--r-- | xen/arch/x86/hvm/hvm.c | 59 | ||||
-rw-r--r-- | xen/include/public/hvm/hvm_op.h | 21 |
4 files changed, 119 insertions, 0 deletions
diff --git a/tools/libxc/xc_misc.c b/tools/libxc/xc_misc.c index 0fe5272eab..7fa1607896 100644 --- a/tools/libxc/xc_misc.c +++ b/tools/libxc/xc_misc.c @@ -295,6 +295,36 @@ int xc_hvm_modified_memory( return rc; } +int xc_hvm_set_mem_type( + int xc_handle, domid_t dom, hvmmem_type_t mem_type, uint64_t first_pfn, uint64_t nr) +{ + DECLARE_HYPERCALL; + struct xen_hvm_set_mem_type arg; + int rc; + + hypercall.op = __HYPERVISOR_hvm_op; + hypercall.arg[0] = HVMOP_set_mem_type; + hypercall.arg[1] = (unsigned long)&arg; + + arg.domid = dom; + arg.hvmmem_type = mem_type; + arg.first_pfn = first_pfn; + arg.nr = nr; + + if ( (rc = lock_pages(&arg, sizeof(arg))) != 0 ) + { + PERROR("Could not lock memory"); + return rc; + } + + rc = do_xen_hypercall(xc_handle, &hypercall); + + unlock_pages(&arg, sizeof(arg)); + + return rc; +} + + void *xc_map_foreign_pages(int xc_handle, uint32_t dom, int prot, const xen_pfn_t *arr, int num) { diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h index 040f67dc9b..b70c3b8193 100644 --- a/tools/libxc/xenctrl.h +++ b/tools/libxc/xenctrl.h @@ -27,6 +27,7 @@ #include <xen/event_channel.h> #include <xen/sched.h> #include <xen/memory.h> +#include <xen/hvm/params.h> #include <xen/xsm/acm.h> #include <xen/xsm/acm_ops.h> #include <xen/xsm/flask_op.h> @@ -942,6 +943,14 @@ int xc_hvm_track_dirty_vram( int xc_hvm_modified_memory( int xc_handle, domid_t dom, uint64_t first_pfn, uint64_t nr); +/* + * Set a range of memory to a specific type. + * Allowed types are HVMMEM_ram_rw, HVMMEM_ram_ro, HVMMEM_mmio_dm + */ +int xc_hvm_set_mem_type( + int xc_handle, domid_t dom, hvmmem_type_t memtype, uint64_t first_pfn, uint64_t nr); + + typedef enum { XC_ERROR_NONE = 0, XC_INTERNAL_ERROR = 1, diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index 509b5e35d4..04e9da6e0e 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -2611,6 +2611,65 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE(void) arg) break; } + case HVMOP_set_mem_type: + { + struct xen_hvm_set_mem_type a; + struct domain *d; + unsigned long pfn; + + /* Interface types to internal p2m types */ + p2m_type_t memtype[] = { + p2m_ram_rw, /* HVMMEM_ram_rw */ + p2m_ram_ro, /* HVMMEM_ram_ro */ + p2m_mmio_dm /* HVMMEM_mmio_dm */ + }; + + if ( copy_from_guest(&a, arg, 1) ) + return -EFAULT; + + if ( a.domid == DOMID_SELF ) + { + d = rcu_lock_current_domain(); + } + else + { + if ( (d = rcu_lock_domain_by_id(a.domid)) == NULL ) + return -ESRCH; + if ( !IS_PRIV_FOR(current->domain, d) ) + { + rc = -EPERM; + goto param_fail4; + } + } + + rc = -EINVAL; + if ( !is_hvm_domain(d) ) + goto param_fail4; + + 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_fail4; + + if ( a.hvmmem_type >= ARRAY_SIZE(memtype) ) + goto param_fail4; + + rc = 0; + + for ( pfn = a.first_pfn; pfn < a.first_pfn + a.nr; pfn++ ) + { + p2m_type_t t; + mfn_t mfn; + mfn = gfn_to_mfn(d, pfn, &t); + p2m_change_type(d, pfn, t, memtype[a.hvmmem_type]); + } + + param_fail4: + rcu_unlock_domain(d); + break; + } + default: { gdprintk(XENLOG_WARNING, "Bad HVM op %ld.\n", op); diff --git a/xen/include/public/hvm/hvm_op.h b/xen/include/public/hvm/hvm_op.h index a06d941683..f0ada2d758 100644 --- a/xen/include/public/hvm/hvm_op.h +++ b/xen/include/public/hvm/hvm_op.h @@ -105,6 +105,27 @@ struct xen_hvm_modified_memory { typedef struct xen_hvm_modified_memory xen_hvm_modified_memory_t; DEFINE_XEN_GUEST_HANDLE(xen_hvm_modified_memory_t); +#define HVMOP_set_mem_type 8 +typedef enum { + HVMMEM_ram_rw, /* Normal read/write guest RAM */ + HVMMEM_ram_ro, /* Read-only; writes are discarded */ + HVMMEM_mmio_dm, /* Reads and write go to the device model */ +} hvmmem_type_t; +/* Notify that a region of memory is to be treated in a specific way. */ +struct xen_hvm_set_mem_type { + /* Domain to be updated. */ + domid_t domid; + /* Memory type */ + hvmmem_type_t hvmmem_type; + /* First pfn. */ + uint64_aligned_t first_pfn; + /* Number of pages. */ + uint64_aligned_t nr; +}; +typedef struct xen_hvm_set_mem_type xen_hvm_set_mem_type_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_set_mem_type_t); + + #endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */ #endif /* __XEN_PUBLIC_HVM_HVM_OP_H__ */ |