@@ -1485,6 +1485,13 @@ static void do_trap_hypercall(struct cpu_user_regs *regs, register_t *nr,
regs->pc -= 4; /* re-execute 'hvc #XEN_HYPERCALL_TAG' */
}
+void arch_hypercall_tasklet_result(struct vcpu *v, long res)
+{
+ struct cpu_user_regs *regs = &v->arch.cpu_info->guest_cpu_user_regs;
+
+ HYPERCALL_RESULT_REG(regs) = res;
+}
+
static bool check_multicall_32bit_clean(struct multicall_entry *multi)
{
int i;
@@ -166,6 +166,13 @@ unsigned long hypercall_create_continuation(
#undef NEXT_ARG
+void arch_hypercall_tasklet_result(struct vcpu *v, long res)
+{
+ struct cpu_user_regs *regs = &v->arch.user_regs;
+
+ regs->rax = res;
+}
+
int hypercall_xlat_continuation(unsigned int *id, unsigned int nr,
unsigned int mask, ...)
{
@@ -1665,13 +1665,18 @@ static void continue_hypercall_tasklet_handler(unsigned long _info)
{
struct migrate_info *info = (struct migrate_info *)_info;
struct vcpu *v = info->vcpu;
+ long res = -EINVAL;
/* Wait for vcpu to sleep so that we can access its register state. */
vcpu_sleep_sync(v);
this_cpu(continue_info) = info;
- return_reg(v) = (info->cpu == smp_processor_id())
- ? info->func(info->data) : -EINVAL;
+
+ if ( likely(info->cpu == smp_processor_id()) )
+ res = info->func(info->data);
+
+ arch_hypercall_tasklet_result(v, res);
+
this_cpu(continue_info) = NULL;
if ( info->nest-- == 0 )
@@ -57,8 +57,6 @@ static inline bool guest_mode(const struct cpu_user_regs *r)
return (diff == 0);
}
-#define return_reg(v) ((v)->arch.cpu_info->guest_cpu_user_regs.r0)
-
register_t get_user_reg(struct cpu_user_regs *regs, int reg);
void set_user_reg(struct cpu_user_regs *regs, int reg, register_t val);
@@ -15,6 +15,4 @@
(diff == 0); \
})
-#define return_reg(v) ((v)->arch.user_regs.rax)
-
#endif /* __X86_REGS_H__ */
@@ -103,6 +103,12 @@ void domctl_lock_release(void);
int continue_hypercall_on_cpu(
unsigned int cpu, long (*func)(void *data), void *data);
+/*
+ * Companion to continue_hypercall_on_cpu(), to feed func()'s result back into
+ * vcpu regsiter state.
+ */
+void arch_hypercall_tasklet_result(struct vcpu *v, long res);
+
extern unsigned int xen_processor_pmbits;
extern bool_t opt_dom0_vcpus_pin;