aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2008-07-10 15:30:39 +0100
committerKeir Fraser <keir.fraser@citrix.com>2008-07-10 15:30:39 +0100
commit51cf89ed5da0f2e865d976b8baee54ffcfdd25a6 (patch)
tree5aff263c47d685d439d8633218d5adf3f5a1e117
parent4d8aa29d6566ac33cb72a496fb073cdd3a52db25 (diff)
downloadxen-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.c30
-rw-r--r--tools/libxc/xenctrl.h9
-rw-r--r--xen/arch/x86/hvm/hvm.c59
-rw-r--r--xen/include/public/hvm/hvm_op.h21
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__ */