[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v15 10/19] pvh: PVH access to hypercalls
Hypercalls where we now have unrestricted access: * memory_op * console_io * vcpu_op * mmuext_op We also restrict PVH domain access to HVMOP_*_param to reading and writing HVM_PARAM_CALLBACK_IRQ. Most hvm_op functions require "is_hvm_domain()" and will default to -EINVAL; exceptions are HVMOP_get_time and HVMOP_xentrace. Finally, we restrict setting IOPL permissions for a PVH domain. Signed-off-by: George Dunlap <george.dunlap@xxxxxxxxxxxxx> Signed-off-by: Mukesh Rathor <mukesh.rathor@xxxxxxxxxx> Acked-by: Tim Deegan <tim@xxxxxxx> --- v15: - Remove unnecessary comment v14: - Get rid of (now) spurious null check for hvm_domain.params v13: - Minor code tweaks, as suggested during review - return -ENOSYS for set_iopl and set_iobitmap calls - Allow HVMOP_set_param for HVM_PARAM_CALLBACK_IRQ. We still don't allow other values to be written. CC: Jan Beulich <jbeulich@xxxxxxxx> CC: Tim Deegan <tim@xxxxxxx> CC: Keir Fraser <keir@xxxxxxx> --- xen/arch/x86/hvm/hvm.c | 44 ++++++++++++++++++++++++++++++++++++-------- xen/arch/x86/physdev.c | 10 ++++++++++ xen/common/kernel.c | 13 +++++++++++-- 3 files changed, 57 insertions(+), 10 deletions(-) diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index 6992106..3f245ba 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -3414,6 +3414,24 @@ static hvm_hypercall_t *const hvm_hypercall32_table[NR_hypercalls] = { HYPERCALL(tmem_op) }; +/* PVH 32bitfixme. */ +static hvm_hypercall_t *const pvh_hypercall64_table[NR_hypercalls] = { + HYPERCALL(platform_op), + HYPERCALL(memory_op), + HYPERCALL(xen_version), + HYPERCALL(console_io), + [ __HYPERVISOR_grant_table_op ] = (hvm_hypercall_t *)hvm_grant_table_op, + HYPERCALL(vcpu_op), + HYPERCALL(mmuext_op), + HYPERCALL(xsm_op), + HYPERCALL(sched_op), + HYPERCALL(event_channel_op), + [ __HYPERVISOR_physdev_op ] = (hvm_hypercall_t *)hvm_physdev_op, + HYPERCALL(hvm_op), + HYPERCALL(sysctl), + HYPERCALL(domctl) +}; + int hvm_do_hypercall(struct cpu_user_regs *regs) { struct vcpu *curr = current; @@ -3440,7 +3458,9 @@ int hvm_do_hypercall(struct cpu_user_regs *regs) if ( (eax & 0x80000000) && is_viridian_domain(curr->domain) ) return viridian_hypercall(regs); - if ( (eax >= NR_hypercalls) || !hvm_hypercall32_table[eax] ) + if ( (eax >= NR_hypercalls) || + (is_pvh_vcpu(curr) ? !pvh_hypercall64_table[eax] + : !hvm_hypercall32_table[eax]) ) { regs->eax = -ENOSYS; return HVM_HCALL_completed; @@ -3455,16 +3475,20 @@ int hvm_do_hypercall(struct cpu_user_regs *regs) regs->r10, regs->r8, regs->r9); curr->arch.hvm_vcpu.hcall_64bit = 1; - regs->rax = hvm_hypercall64_table[eax](regs->rdi, - regs->rsi, - regs->rdx, - regs->r10, - regs->r8, - regs->r9); + if ( is_pvh_vcpu(curr) ) + regs->rax = pvh_hypercall64_table[eax](regs->rdi, regs->rsi, + regs->rdx, regs->r10, + regs->r8, regs->r9); + else + regs->rax = hvm_hypercall64_table[eax](regs->rdi, regs->rsi, + regs->rdx, regs->r10, + regs->r8, regs->r9); curr->arch.hvm_vcpu.hcall_64bit = 0; } else { + ASSERT(!is_pvh_vcpu(curr)); /* PVH 32bitfixme. */ + HVM_DBG_LOG(DBG_LEVEL_HCALL, "hcall%u(%x, %x, %x, %x, %x, %x)", eax, (uint32_t)regs->ebx, (uint32_t)regs->ecx, (uint32_t)regs->edx, (uint32_t)regs->esi, @@ -3889,7 +3913,11 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void) arg) return -ESRCH; rc = -EINVAL; - if ( !is_hvm_domain(d) ) + if ( !has_hvm_container_domain(d) ) + goto param_fail; + + if ( is_pvh_domain(d) + && (a.index != HVM_PARAM_CALLBACK_IRQ) ) goto param_fail; rc = xsm_hvm_param(XSM_TARGET, d, op); diff --git a/xen/arch/x86/physdev.c b/xen/arch/x86/physdev.c index dab6213..7d787dc 100644 --- a/xen/arch/x86/physdev.c +++ b/xen/arch/x86/physdev.c @@ -519,6 +519,11 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg) case PHYSDEVOP_set_iopl: { struct physdev_set_iopl set_iopl; + + ret = -ENOSYS; + if ( is_pvh_vcpu(current) ) + break; + ret = -EFAULT; if ( copy_from_guest(&set_iopl, arg, 1) != 0 ) break; @@ -532,6 +537,11 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg) case PHYSDEVOP_set_iobitmap: { struct physdev_set_iobitmap set_iobitmap; + + ret = -ENOSYS; + if ( is_pvh_vcpu(current) ) + break; + ret = -EFAULT; if ( copy_from_guest(&set_iobitmap, arg, 1) != 0 ) break; diff --git a/xen/common/kernel.c b/xen/common/kernel.c index 97d9050..cc1f743 100644 --- a/xen/common/kernel.c +++ b/xen/common/kernel.c @@ -306,14 +306,23 @@ DO(xen_version)(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg) if ( current->domain == dom0 ) fi.submap |= 1U << XENFEAT_dom0; #ifdef CONFIG_X86 - if ( is_pv_vcpu(current) ) + switch(d->guest_type) { + case guest_type_pv: fi.submap |= (1U << XENFEAT_mmu_pt_update_preserve_ad) | (1U << XENFEAT_highmem_assist) | (1U << XENFEAT_gnttab_map_avail_bits); - else + break; + case guest_type_pvh: + fi.submap |= (1U << XENFEAT_hvm_safe_pvclock) | + (1U << XENFEAT_supervisor_mode_kernel) | + (1U << XENFEAT_hvm_callback_vector); + break; + case guest_type_hvm: fi.submap |= (1U << XENFEAT_hvm_safe_pvclock) | (1U << XENFEAT_hvm_callback_vector) | (1U << XENFEAT_hvm_pirqs); + break; + } #endif break; default: -- 1.7.9.5 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |