|
[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 |