[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 2/3] x86/hvm: introduce functions for HVMOP_get/set_param allowance checks
Some parameters can only (validly) be set once. Some cannot be set by a guest for its own domain. Consolidate these checks, along with the XSM check, in a new hvm_allow_set_param() function for clarity. Also, introduce hvm_allow_get_param() for similar reasons. Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx> Cc: Keir Fraser <keir@xxxxxxx> Cc: Jan Beulich <jbeulich@xxxxxxxx> Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- xen/arch/x86/hvm/hvm.c | 141 +++++++++++++++++++++++++++--------------------- 1 file changed, 79 insertions(+), 62 deletions(-) diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index 87c47b1..23c604d 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -5640,6 +5640,57 @@ static int hvmop_set_evtchn_upcall_vector( return 0; } +static int hvm_allow_set_param(struct domain *d, + struct xen_hvm_param *a) +{ + uint64_t value = d->arch.hvm_domain.params[a->index]; + int rc = 0; + + rc = xsm_hvm_param(XSM_TARGET, d, HVMOP_set_param); + if ( rc ) + return rc; + + /* The following parameters cannot be set by the guest */ + switch (a->index) + { + case HVM_PARAM_VIRIDIAN: + case HVM_PARAM_IDENT_PT: + case HVM_PARAM_DM_DOMAIN: + case HVM_PARAM_ACPI_S_STATE: + case HVM_PARAM_MEMORY_EVENT_CR0: + case HVM_PARAM_MEMORY_EVENT_CR3: + case HVM_PARAM_MEMORY_EVENT_CR4: + case HVM_PARAM_MEMORY_EVENT_INT3: + case HVM_PARAM_MEMORY_EVENT_SINGLE_STEP: + case HVM_PARAM_MEMORY_EVENT_MSR: + case HVM_PARAM_IOREQ_SERVER_PFN: + case HVM_PARAM_NR_IOREQ_SERVER_PAGES: + if ( d == current->domain ) + rc = -EPERM; + break; + default: + break; + } + + if ( rc ) + return rc; + + /* The following parameters can only be changed once */ + switch (a->index) + { + case HVM_PARAM_VIRIDIAN: + case HVM_PARAM_IOREQ_SERVER_PFN: + case HVM_PARAM_NR_IOREQ_SERVER_PAGES: + if (value != 0 && a->value != value) + rc = -EEXIST; + break; + default: + break; + } + + return rc; +} + static int hvmop_set_param( XEN_GUEST_HANDLE_PARAM(xen_hvm_param_t) arg) { @@ -5666,7 +5717,7 @@ static int hvmop_set_param( && (a.index != HVM_PARAM_CALLBACK_IRQ) ) goto out; - rc = xsm_hvm_param(XSM_TARGET, d, HVMOP_set_param); + rc = hvm_allow_set_param(d, &a); if ( rc ) goto out; @@ -5681,31 +5732,11 @@ static int hvmop_set_param( rc = -EINVAL; break; case HVM_PARAM_VIRIDIAN: - /* This should only ever be set once by the tools and read by the guest. */ - rc = -EPERM; - if ( d == current->domain ) - break; - - if ( a.value != d->arch.hvm_domain.params[a.index] ) - { - rc = -EEXIST; - if ( d->arch.hvm_domain.params[a.index] != 0 ) - break; - + if ( (a.value & ~HVMPV_feature_mask) || + !(a.value & HVMPV_base_freq) ) rc = -EINVAL; - if ( (a.value & ~HVMPV_feature_mask) || - !(a.value & HVMPV_base_freq) ) - break; - } - - rc = 0; break; case HVM_PARAM_IDENT_PT: - /* Not reflexive, as we must domain_pause(). */ - rc = -EPERM; - if ( d == current->domain ) - break; - rc = -EINVAL; if ( d->arch.hvm_domain.params[a.index] != 0 ) break; @@ -5733,22 +5764,12 @@ static int hvmop_set_param( domctl_lock_release(); break; case HVM_PARAM_DM_DOMAIN: - /* Not reflexive, as we may need to domain_pause(). */ - rc = -EPERM; - if ( d == current->domain ) - break; - if ( a.value == DOMID_SELF ) a.value = current->domain->domain_id; rc = hvm_set_dm_domain(d, a.value); break; case HVM_PARAM_ACPI_S_STATE: - /* Not reflexive, as we must domain_pause(). */ - rc = -EPERM; - if ( current->domain == d ) - break; - rc = 0; if ( a.value == 3 ) hvm_s3_suspend(d); @@ -5761,20 +5782,9 @@ static int hvmop_set_param( case HVM_PARAM_ACPI_IOPORTS_LOCATION: rc = pmtimer_change_ioport(d, a.value); break; - case HVM_PARAM_MEMORY_EVENT_CR0: - case HVM_PARAM_MEMORY_EVENT_CR3: - case HVM_PARAM_MEMORY_EVENT_CR4: - if ( d == current->domain ) - rc = -EPERM; - break; case HVM_PARAM_MEMORY_EVENT_INT3: case HVM_PARAM_MEMORY_EVENT_SINGLE_STEP: case HVM_PARAM_MEMORY_EVENT_MSR: - if ( d == current->domain ) - { - rc = -EPERM; - break; - } if ( a.value & HVMPME_onchangeonly ) rc = -EINVAL; break; @@ -5807,22 +5817,12 @@ static int hvmop_set_param( rc = -EINVAL; break; case HVM_PARAM_IOREQ_SERVER_PFN: - if ( d == current->domain ) - { - rc = -EPERM; - break; - } d->arch.hvm_domain.ioreq_gmfn.base = a.value; break; case HVM_PARAM_NR_IOREQ_SERVER_PAGES: { unsigned int i; - if ( d == current->domain ) - { - rc = -EPERM; - break; - } if ( a.value == 0 || a.value > sizeof(d->arch.hvm_domain.ioreq_gmfn.mask) * 8 ) { @@ -5866,6 +5866,30 @@ static int hvmop_set_param( return rc; } +static int hvm_allow_get_param(struct domain *d, + struct xen_hvm_param *a) +{ + int rc = 0; + + rc = xsm_hvm_param(XSM_TARGET, d, HVMOP_get_param); + if ( rc ) + return rc; + + /* The following parameters cannot be read by the guest */ + switch (a->index) + { + case HVM_PARAM_IOREQ_SERVER_PFN: + case HVM_PARAM_NR_IOREQ_SERVER_PAGES: + if ( d == current->domain ) + rc = -EPERM; + break; + default: + break; + } + + return rc; +} + static int hvmop_get_param( XEN_GUEST_HANDLE_PARAM(xen_hvm_param_t) arg) { @@ -5891,7 +5915,7 @@ static int hvmop_get_param( && (a.index != HVM_PARAM_CALLBACK_IRQ) ) goto out; - rc = xsm_hvm_param(XSM_TARGET, d, HVMOP_get_param); + rc = hvm_allow_get_param(d, &a); if ( rc ) goto out; @@ -5900,13 +5924,6 @@ static int hvmop_get_param( case HVM_PARAM_ACPI_S_STATE: a.value = d->arch.hvm_domain.is_s3_suspended ? 3 : 0; break; - case HVM_PARAM_IOREQ_SERVER_PFN: - case HVM_PARAM_NR_IOREQ_SERVER_PAGES: - if ( d == current->domain ) - { - rc = -EPERM; - goto out; - } case HVM_PARAM_IOREQ_PFN: case HVM_PARAM_BUFIOREQ_PFN: case HVM_PARAM_BUFIOREQ_EVTCHN: { -- 1.7.10.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |