mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
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:
1 parent
4d8aa29d65
commit
51cf89ed5d
4 files changed
+119
No files matched your search
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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__ */
|
||||