[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v4 2/3] arm: export platform_op XENPF_settime64
Call update_domain_wallclock_time at domain initialization. Set time_offset_seconds to the number of seconds between physical boot and domain initialization: it is going to be used to get/set the wallclock time. Add time_offset_seconds to system_time when before calling do_settime, so that system_time actually accounts for all the time in nsec between machine boot and when the wallclock was set. Expose xsm_platform_op to ARM. Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx> CC: dgdegra@xxxxxxxxxxxxx --- Changes in v4: - remove spurious change to ticks_to_ns - move flask_platform_op out of ifdef CONFIG_X86 - move set_to_dummy_if_null out of ifdef CONFIG_X86 for platform_op - dropped previous ack from Daniel Changes in v3: - move update_domain_wallclock_time() call to arch_domain_create - move setting time_offset_seconds to domain_vtimer_init - use spin_trylock(&xenpf_lock) loop in do_platform_op Changes in v2: - drop XENPF_settime32 - set time_offset_seconds - modify xen/xsm/flask/hooks.c --- xen/arch/arm/Makefile | 1 + xen/arch/arm/domain.c | 2 + xen/arch/arm/platform_hypercall.c | 70 +++++++++++++++++++ xen/arch/arm/traps.c | 1 + xen/arch/arm/vtimer.c | 3 + xen/include/xsm/dummy.h | 12 ++-- xen/include/xsm/xsm.h | 13 ++-- xen/xsm/dummy.c | 2 +- xen/xsm/flask/hooks.c | 140 ++++++++++++++++++------------------- 9 files changed, 161 insertions(+), 83 deletions(-) create mode 100644 xen/arch/arm/platform_hypercall.c diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile index 1ef39f7..240aa29 100644 --- a/xen/arch/arm/Makefile +++ b/xen/arch/arm/Makefile @@ -23,6 +23,7 @@ obj-y += percpu.o obj-y += guestcopy.o obj-y += physdev.o obj-y += platform.o +obj-y += platform_hypercall.o obj-y += setup.o obj-y += bootfdt.o obj-y += time.o diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c index b2bfc7d..b17f6cf 100644 --- a/xen/arch/arm/domain.c +++ b/xen/arch/arm/domain.c @@ -598,6 +598,8 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags, if ( (rc = domain_vtimer_init(d, config)) != 0 ) goto fail; + update_domain_wallclock_time(d); + /* * The hardware domain will get a PPI later in * arch/arm/domain_build.c depending on the diff --git a/xen/arch/arm/platform_hypercall.c b/xen/arch/arm/platform_hypercall.c new file mode 100644 index 0000000..b708711 --- /dev/null +++ b/xen/arch/arm/platform_hypercall.c @@ -0,0 +1,70 @@ +/****************************************************************************** + * platform_hypercall.c + * + * Hardware platform operations. Intended for use by domain-0 kernel. + * + * Copyright (c) 2015, Citrix + */ + +#include <xen/config.h> +#include <xen/types.h> +#include <xen/sched.h> +#include <xen/guest_access.h> +#include <xen/spinlock.h> +#include <public/platform.h> +#include <xsm/xsm.h> +#include <asm/current.h> +#include <asm/event.h> + +DEFINE_SPINLOCK(xenpf_lock); + +long do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op) +{ + long ret; + struct xen_platform_op curop, *op = &curop; + struct domain *d; + + if ( copy_from_guest(op, u_xenpf_op, 1) ) + return -EFAULT; + + if ( op->interface_version != XENPF_INTERFACE_VERSION ) + return -EACCES; + + d = rcu_lock_current_domain(); + if ( d == NULL ) + return -ESRCH; + + ret = xsm_platform_op(XSM_PRIV, op->cmd); + if ( ret ) + return ret; + + /* + * Trylock here avoids deadlock with an existing platform critical section + * which might (for some current or future reason) want to synchronise + * with this vcpu. + */ + while ( !spin_trylock(&xenpf_lock) ) + if ( hypercall_preempt_check() ) + return hypercall_create_continuation( + __HYPERVISOR_platform_op, "h", u_xenpf_op); + + switch ( op->cmd ) + { + case XENPF_settime64: + if ( likely(!op->u.settime64.mbz) ) + do_settime(op->u.settime64.secs, + op->u.settime64.nsecs, + op->u.settime64.system_time + SECONDS(d->time_offset_seconds)); + else + ret = -EINVAL; + break; + + default: + ret = -ENOSYS; + break; + } + + spin_unlock(&xenpf_lock); + rcu_unlock_domain(d); + return ret; +} diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c index 9d2bd6a..c49bd3f 100644 --- a/xen/arch/arm/traps.c +++ b/xen/arch/arm/traps.c @@ -1233,6 +1233,7 @@ static arm_hypercall_t arm_hypercall_table[] = { HYPERCALL(hvm_op, 2), HYPERCALL(grant_table_op, 3), HYPERCALL(multicall, 2), + HYPERCALL(platform_op, 1), HYPERCALL_ARM(vcpu_op, 3), }; diff --git a/xen/arch/arm/vtimer.c b/xen/arch/arm/vtimer.c index 1418092..c8e2a12 100644 --- a/xen/arch/arm/vtimer.c +++ b/xen/arch/arm/vtimer.c @@ -22,6 +22,7 @@ #include <xen/timer.h> #include <xen/sched.h> #include <xen/perfc.h> +#include <asm/div64.h> #include <asm/irq.h> #include <asm/time.h> #include <asm/gic.h> @@ -64,6 +65,8 @@ int domain_vtimer_init(struct domain *d, struct xen_arch_domainconfig *config) { d->arch.phys_timer_base.offset = NOW(); d->arch.virt_timer_base.offset = READ_SYSREG64(CNTPCT_EL0); + d->time_offset_seconds = ticks_to_ns(d->arch.virt_timer_base.offset - boot_count); + do_div(d->time_offset_seconds, 1000000000); config->clock_frequency = timer_dt_clock_frequency; diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h index 9fe372c..e43f2a1 100644 --- a/xen/include/xsm/dummy.h +++ b/xen/include/xsm/dummy.h @@ -584,6 +584,12 @@ static XSM_INLINE int xsm_mem_sharing(XSM_DEFAULT_ARG struct domain *d) } #endif +static XSM_INLINE int xsm_platform_op(XSM_DEFAULT_ARG uint32_t op) +{ + XSM_ASSERT_ACTION(XSM_PRIV); + return xsm_default_action(action, current->domain, NULL); +} + #ifdef CONFIG_X86 static XSM_INLINE int xsm_do_mca(XSM_DEFAULT_VOID) { @@ -639,12 +645,6 @@ static XSM_INLINE int xsm_apic(XSM_DEFAULT_ARG struct domain *d, int cmd) return xsm_default_action(action, d, NULL); } -static XSM_INLINE int xsm_platform_op(XSM_DEFAULT_ARG uint32_t op) -{ - XSM_ASSERT_ACTION(XSM_PRIV); - return xsm_default_action(action, current->domain, NULL); -} - static XSM_INLINE int xsm_machine_memory_map(XSM_DEFAULT_VOID) { XSM_ASSERT_ACTION(XSM_PRIV); diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h index ba3caed..f48cf60 100644 --- a/xen/include/xsm/xsm.h +++ b/xen/include/xsm/xsm.h @@ -164,6 +164,8 @@ struct xsm_operations { int (*mem_sharing) (struct domain *d); #endif + int (*platform_op) (uint32_t cmd); + #ifdef CONFIG_X86 int (*do_mca) (void); int (*shadow_control) (struct domain *d, uint32_t op); @@ -175,7 +177,6 @@ struct xsm_operations { int (*mem_sharing_op) (struct domain *d, struct domain *cd, int op); int (*apic) (struct domain *d, int cmd); int (*memtype) (uint32_t access); - int (*platform_op) (uint32_t cmd); int (*machine_memory_map) (void); int (*domain_memory_map) (struct domain *d); #define XSM_MMU_UPDATE_READ 1 @@ -624,6 +625,11 @@ static inline int xsm_mem_sharing (xsm_default_t def, struct domain *d) } #endif +static inline int xsm_platform_op (xsm_default_t def, uint32_t op) +{ + return xsm_ops->platform_op(op); +} + #ifdef CONFIG_X86 static inline int xsm_do_mca(xsm_default_t def) { @@ -675,11 +681,6 @@ static inline int xsm_memtype (xsm_default_t def, uint32_t access) return xsm_ops->memtype(access); } -static inline int xsm_platform_op (xsm_default_t def, uint32_t op) -{ - return xsm_ops->platform_op(op); -} - static inline int xsm_machine_memory_map(xsm_default_t def) { return xsm_ops->machine_memory_map(); diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c index 72eba40..618a96e 100644 --- a/xen/xsm/dummy.c +++ b/xen/xsm/dummy.c @@ -141,6 +141,7 @@ void xsm_fixup_ops (struct xsm_operations *ops) set_to_dummy_if_null(ops, mem_sharing); #endif + set_to_dummy_if_null(ops, platform_op); #ifdef CONFIG_X86 set_to_dummy_if_null(ops, do_mca); set_to_dummy_if_null(ops, shadow_control); @@ -151,7 +152,6 @@ void xsm_fixup_ops (struct xsm_operations *ops) set_to_dummy_if_null(ops, hvm_ioreq_server); set_to_dummy_if_null(ops, mem_sharing_op); set_to_dummy_if_null(ops, apic); - set_to_dummy_if_null(ops, platform_op); set_to_dummy_if_null(ops, machine_memory_map); set_to_dummy_if_null(ops, domain_memory_map); set_to_dummy_if_null(ops, mmu_update); diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c index fafb1a4..48f5aef 100644 --- a/xen/xsm/flask/hooks.c +++ b/xen/xsm/flask/hooks.c @@ -1332,6 +1332,75 @@ static int flask_deassign_dtdevice(struct domain *d, const char *dtpath) } #endif /* HAS_PASSTHROUGH && HAS_DEVICE_TREE */ +static int flask_platform_op(uint32_t op) +{ + switch ( op ) + { +#ifdef CONFIG_X86 + /* These operations have their own XSM hooks */ + case XENPF_cpu_online: + case XENPF_cpu_offline: + case XENPF_cpu_hotadd: + case XENPF_mem_hotadd: + return 0; +#endif + + case XENPF_settime32: + case XENPF_settime64: + return domain_has_xen(current->domain, XEN__SETTIME); + + case XENPF_add_memtype: + return domain_has_xen(current->domain, XEN__MTRR_ADD); + + case XENPF_del_memtype: + return domain_has_xen(current->domain, XEN__MTRR_DEL); + + case XENPF_read_memtype: + return domain_has_xen(current->domain, XEN__MTRR_READ); + + case XENPF_microcode_update: + return domain_has_xen(current->domain, XEN__MICROCODE); + + case XENPF_platform_quirk: + return domain_has_xen(current->domain, XEN__QUIRK); + + case XENPF_firmware_info: + return domain_has_xen(current->domain, XEN__FIRMWARE); + + case XENPF_efi_runtime_call: + return domain_has_xen(current->domain, XEN__FIRMWARE); + + case XENPF_enter_acpi_sleep: + return domain_has_xen(current->domain, XEN__SLEEP); + + case XENPF_change_freq: + return domain_has_xen(current->domain, XEN__FREQUENCY); + + case XENPF_getidletime: + return domain_has_xen(current->domain, XEN__GETIDLE); + + case XENPF_set_processor_pminfo: + case XENPF_core_parking: + return domain_has_xen(current->domain, XEN__PM_OP); + + case XENPF_get_cpu_version: + case XENPF_get_cpuinfo: + return domain_has_xen(current->domain, XEN__GETCPUINFO); + + case XENPF_resource_op: + return avc_current_has_perm(SECINITSID_XEN, SECCLASS_XEN2, + XEN2__RESOURCE_OP, NULL); + + case XENPF_get_symbol: + return avc_has_perm(domain_sid(current->domain), SECINITSID_XEN, + SECCLASS_XEN2, XEN2__GET_SYMBOL, NULL); + + default: + printk("flask_platform_op: Unknown op %d\n", op); + return -EPERM; + } +} + #ifdef CONFIG_X86 static int flask_do_mca(void) { @@ -1470,75 +1539,6 @@ static int flask_apic(struct domain *d, int cmd) return domain_has_xen(d, perm); } -static int flask_platform_op(uint32_t op) -{ - switch ( op ) - { -#ifdef CONFIG_X86 - /* These operations have their own XSM hooks */ - case XENPF_cpu_online: - case XENPF_cpu_offline: - case XENPF_cpu_hotadd: - case XENPF_mem_hotadd: - return 0; -#endif - - case XENPF_settime32: - case XENPF_settime64: - return domain_has_xen(current->domain, XEN__SETTIME); - - case XENPF_add_memtype: - return domain_has_xen(current->domain, XEN__MTRR_ADD); - - case XENPF_del_memtype: - return domain_has_xen(current->domain, XEN__MTRR_DEL); - - case XENPF_read_memtype: - return domain_has_xen(current->domain, XEN__MTRR_READ); - - case XENPF_microcode_update: - return domain_has_xen(current->domain, XEN__MICROCODE); - - case XENPF_platform_quirk: - return domain_has_xen(current->domain, XEN__QUIRK); - - case XENPF_firmware_info: - return domain_has_xen(current->domain, XEN__FIRMWARE); - - case XENPF_efi_runtime_call: - return domain_has_xen(current->domain, XEN__FIRMWARE); - - case XENPF_enter_acpi_sleep: - return domain_has_xen(current->domain, XEN__SLEEP); - - case XENPF_change_freq: - return domain_has_xen(current->domain, XEN__FREQUENCY); - - case XENPF_getidletime: - return domain_has_xen(current->domain, XEN__GETIDLE); - - case XENPF_set_processor_pminfo: - case XENPF_core_parking: - return domain_has_xen(current->domain, XEN__PM_OP); - - case XENPF_get_cpu_version: - case XENPF_get_cpuinfo: - return domain_has_xen(current->domain, XEN__GETCPUINFO); - - case XENPF_resource_op: - return avc_current_has_perm(SECINITSID_XEN, SECCLASS_XEN2, - XEN2__RESOURCE_OP, NULL); - - case XENPF_get_symbol: - return avc_has_perm(domain_sid(current->domain), SECINITSID_XEN, - SECCLASS_XEN2, XEN2__GET_SYMBOL, NULL); - - default: - printk("flask_platform_op: Unknown op %d\n", op); - return -EPERM; - } -} - static int flask_machine_memory_map(void) { return avc_current_has_perm(SECINITSID_XEN, SECCLASS_MMU, MMU__MEMORYMAP, NULL); @@ -1735,6 +1735,7 @@ static struct xsm_operations flask_ops = { .deassign_dtdevice = flask_deassign_dtdevice, #endif + .platform_op = flask_platform_op, #ifdef CONFIG_X86 .do_mca = flask_do_mca, .shadow_control = flask_shadow_control, @@ -1745,7 +1746,6 @@ static struct xsm_operations flask_ops = { .hvm_ioreq_server = flask_hvm_ioreq_server, .mem_sharing_op = flask_mem_sharing_op, .apic = flask_apic, - .platform_op = flask_platform_op, .machine_memory_map = flask_machine_memory_map, .domain_memory_map = flask_domain_memory_map, .mmu_update = flask_mmu_update, -- 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 |