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>
This commit is contained in:
Keir Fraser committed 2008-07-10 15:30:39 +01:00
1 parent 4d8aa29d65
commit 51cf89ed5d
4 files changed
+119

No files matched your search

+30
View File
@@ -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)
{
+9
View File
@@ -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,
+59
View File
@@ -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);
+21
View File
@@ -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__ */
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.