Lines Matching +full:cs +full:- +full:out
8 * See the COPYING file in the top-level directory.
14 #include "qemu/main-loop.h"
15 #include "qemu/error-report.h"
20 #include "exec/address-spaces.h"
21 #include "xen-emu.h"
26 #include "hw/i386/apic-msidef.h"
43 #include "xen-compat.h"
47 static int vcpuop_stop_singleshot_timer(CPUState *cs);
55 static bool kvm_gva_to_gpa(CPUState *cs, uint64_t gva, uint64_t *gpa, in kvm_gva_to_gpa() argument
63 *len = TARGET_PAGE_SIZE - (gva & ~TARGET_PAGE_MASK); in kvm_gva_to_gpa()
66 if (kvm_vcpu_ioctl(cs, KVM_TRANSLATE, &tr) || !tr.valid || in kvm_gva_to_gpa()
74 static int kvm_gva_rw(CPUState *cs, uint64_t gva, void *_buf, size_t sz, in kvm_gva_rw() argument
82 if (!kvm_gva_to_gpa(cs, gva, &gpa, &len, is_write)) { in kvm_gva_rw()
83 return -EFAULT; in kvm_gva_rw()
92 sz -= len; in kvm_gva_rw()
99 static inline int kvm_copy_from_gva(CPUState *cs, uint64_t gva, void *buf, in kvm_copy_from_gva() argument
102 return kvm_gva_rw(cs, gva, buf, sz, false); in kvm_copy_from_gva()
105 static inline int kvm_copy_to_gva(CPUState *cs, uint64_t gva, void *buf, in kvm_copy_to_gva() argument
108 return kvm_gva_rw(cs, gva, buf, sz, true); in kvm_copy_to_gva()
124 return -ENOSYS; in kvm_xen_init()
130 .u.xen_version = s->xen_version, in kvm_xen_init()
140 strerror(-ret)); in kvm_xen_init()
145 if (s->xen_caps) { in kvm_xen_init()
151 * of vCPU0 to deassert the IRQ when ->evtchn_upcall_pending is cleared. in kvm_xen_init()
155 * it nicely in the kernel: check vcpu_info[0]->evtchn_upcall_pending at in kvm_xen_init()
158 * But the in-kernel irqchip is deprecated, so we're unlikely to add in kvm_xen_init()
172 error_report("kvm: Xen support requires kernel-irqchip=split"); in kvm_xen_init()
173 return -EINVAL; in kvm_xen_init()
176 s->xen_caps = xen_caps; in kvm_xen_init()
188 int kvm_xen_init_vcpu(CPUState *cs) in kvm_xen_init_vcpu() argument
190 X86CPU *cpu = X86_CPU(cs); in kvm_xen_init_vcpu()
191 CPUX86State *env = &cpu->env; in kvm_xen_init_vcpu()
199 * their KVM vCPUs out of order, it doesn't necessarily match in kvm_xen_init_vcpu()
205 .u.vcpu_id = cs->cpu_index, in kvm_xen_init_vcpu()
207 err = kvm_vcpu_ioctl(cs, KVM_XEN_VCPU_SET_ATTR, &va); in kvm_xen_init_vcpu()
210 strerror(-err)); in kvm_xen_init_vcpu()
215 env->xen_vcpu_info_gpa = INVALID_GPA; in kvm_xen_init_vcpu()
216 env->xen_vcpu_info_default_gpa = INVALID_GPA; in kvm_xen_init_vcpu()
217 env->xen_vcpu_time_info_gpa = INVALID_GPA; in kvm_xen_init_vcpu()
218 env->xen_vcpu_runstate_gpa = INVALID_GPA; in kvm_xen_init_vcpu()
220 qemu_mutex_init(&env->xen_timers_lock); in kvm_xen_init_vcpu()
221 env->xen_singleshot_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, in kvm_xen_init_vcpu()
224 if (!env->xen_singleshot_timer) { in kvm_xen_init_vcpu()
225 return -ENOMEM; in kvm_xen_init_vcpu()
227 env->xen_singleshot_timer->opaque = cs; in kvm_xen_init_vcpu()
229 env->xen_periodic_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, in kvm_xen_init_vcpu()
232 if (!env->xen_periodic_timer) { in kvm_xen_init_vcpu()
233 return -ENOMEM; in kvm_xen_init_vcpu()
235 env->xen_periodic_timer->opaque = cs; in kvm_xen_init_vcpu()
242 return kvm_state->xen_caps; in kvm_xen_get_caps()
280 exit->u.hcall.result = err; in kvm_xen_hcall_xen_version()
284 static int kvm_xen_set_vcpu_attr(CPUState *cs, uint16_t type, uint64_t gpa) in kvm_xen_set_vcpu_attr() argument
291 trace_kvm_xen_set_vcpu_attr(cs->cpu_index, type, gpa); in kvm_xen_set_vcpu_attr()
293 return kvm_vcpu_ioctl(cs, KVM_XEN_VCPU_SET_ATTR, &xhsi); in kvm_xen_set_vcpu_attr()
296 static int kvm_xen_set_vcpu_callback_vector(CPUState *cs) in kvm_xen_set_vcpu_callback_vector() argument
298 uint8_t vector = X86_CPU(cs)->env.xen_vcpu_callback_vector; in kvm_xen_set_vcpu_callback_vector()
304 trace_kvm_xen_set_vcpu_callback(cs->cpu_index, vector); in kvm_xen_set_vcpu_callback_vector()
306 return kvm_vcpu_ioctl(cs, KVM_XEN_VCPU_SET_ATTR, &xva); in kvm_xen_set_vcpu_callback_vector()
309 static void do_set_vcpu_callback_vector(CPUState *cs, run_on_cpu_data data) in do_set_vcpu_callback_vector() argument
311 X86CPU *cpu = X86_CPU(cs); in do_set_vcpu_callback_vector()
312 CPUX86State *env = &cpu->env; in do_set_vcpu_callback_vector()
314 env->xen_vcpu_callback_vector = data.host_int; in do_set_vcpu_callback_vector()
317 kvm_xen_set_vcpu_callback_vector(cs); in do_set_vcpu_callback_vector()
321 static int set_vcpu_info(CPUState *cs, uint64_t gpa) in set_vcpu_info() argument
323 X86CPU *cpu = X86_CPU(cs); in set_vcpu_info()
324 CPUX86State *env = &cpu->env; in set_vcpu_info()
329 ret = kvm_xen_set_vcpu_attr(cs, KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO, gpa); in set_vcpu_info()
331 goto out; in set_vcpu_info()
336 if (mrs.mr && mrs.mr->ram_block && in set_vcpu_info()
338 vcpu_info_hva = qemu_map_ram_ptr(mrs.mr->ram_block, in set_vcpu_info()
346 ret = -EINVAL; in set_vcpu_info()
349 out: in set_vcpu_info()
350 if (env->xen_vcpu_info_mr) { in set_vcpu_info()
351 memory_region_unref(env->xen_vcpu_info_mr); in set_vcpu_info()
353 env->xen_vcpu_info_hva = vcpu_info_hva; in set_vcpu_info()
354 env->xen_vcpu_info_mr = mrs.mr; in set_vcpu_info()
358 static void do_set_vcpu_info_default_gpa(CPUState *cs, run_on_cpu_data data) in do_set_vcpu_info_default_gpa() argument
360 X86CPU *cpu = X86_CPU(cs); in do_set_vcpu_info_default_gpa()
361 CPUX86State *env = &cpu->env; in do_set_vcpu_info_default_gpa()
363 env->xen_vcpu_info_default_gpa = data.host_ulong; in do_set_vcpu_info_default_gpa()
366 if (env->xen_vcpu_info_gpa == INVALID_GPA) { in do_set_vcpu_info_default_gpa()
367 set_vcpu_info(cs, env->xen_vcpu_info_default_gpa); in do_set_vcpu_info_default_gpa()
371 static void do_set_vcpu_info_gpa(CPUState *cs, run_on_cpu_data data) in do_set_vcpu_info_gpa() argument
373 X86CPU *cpu = X86_CPU(cs); in do_set_vcpu_info_gpa()
374 CPUX86State *env = &cpu->env; in do_set_vcpu_info_gpa()
376 env->xen_vcpu_info_gpa = data.host_ulong; in do_set_vcpu_info_gpa()
378 set_vcpu_info(cs, env->xen_vcpu_info_gpa); in do_set_vcpu_info_gpa()
383 CPUState *cs = qemu_get_cpu(vcpu_id); in kvm_xen_get_vcpu_info_hva() local
384 if (!cs) { in kvm_xen_get_vcpu_info_hva()
388 return X86_CPU(cs)->env.xen_vcpu_info_hva; in kvm_xen_get_vcpu_info_hva()
391 void kvm_xen_maybe_deassert_callback(CPUState *cs) in kvm_xen_maybe_deassert_callback() argument
393 CPUX86State *env = &X86_CPU(cs)->env; in kvm_xen_maybe_deassert_callback()
394 struct vcpu_info *vi = env->xen_vcpu_info_hva; in kvm_xen_maybe_deassert_callback()
400 if (!vi->evtchn_upcall_pending) { in kvm_xen_maybe_deassert_callback()
407 if (!vi->evtchn_upcall_pending) { in kvm_xen_maybe_deassert_callback()
408 X86_CPU(cs)->env.xen_callback_asserted = false; in kvm_xen_maybe_deassert_callback()
417 CPUState *cs = qemu_get_cpu(0); in kvm_xen_set_callback_asserted() local
419 if (cs) { in kvm_xen_set_callback_asserted()
420 X86_CPU(cs)->env.xen_callback_asserted = true; in kvm_xen_set_callback_asserted()
426 CPUState *cs = qemu_get_cpu(0); in kvm_xen_has_vcpu_callback_vector() local
428 return cs && !!X86_CPU(cs)->env.xen_vcpu_callback_vector; in kvm_xen_has_vcpu_callback_vector()
433 CPUState *cs = qemu_get_cpu(vcpu_id); in kvm_xen_inject_vcpu_callback_vector() local
436 if (!cs) { in kvm_xen_inject_vcpu_callback_vector()
440 vector = X86_CPU(cs)->env.xen_vcpu_callback_vector; in kvm_xen_inject_vcpu_callback_vector()
443 * The per-vCPU callback vector injected via lapic. Just in kvm_xen_inject_vcpu_callback_vector()
448 (X86_CPU(cs)->apic_id << MSI_ADDR_DEST_ID_SHIFT), in kvm_xen_inject_vcpu_callback_vector()
460 * so all we have to do is kick it out. in kvm_xen_inject_vcpu_callback_vector()
462 qemu_cpu_kick(cs); in kvm_xen_inject_vcpu_callback_vector()
475 static int kvm_xen_set_vcpu_timer(CPUState *cs) in kvm_xen_set_vcpu_timer() argument
477 X86CPU *cpu = X86_CPU(cs); in kvm_xen_set_vcpu_timer()
478 CPUX86State *env = &cpu->env; in kvm_xen_set_vcpu_timer()
482 .u.timer.port = env->xen_virq[VIRQ_TIMER], in kvm_xen_set_vcpu_timer()
484 .u.timer.expires_ns = env->xen_singleshot_timer_ns, in kvm_xen_set_vcpu_timer()
487 return kvm_vcpu_ioctl(cs, KVM_XEN_VCPU_SET_ATTR, &va); in kvm_xen_set_vcpu_timer()
490 static void do_set_vcpu_timer_virq(CPUState *cs, run_on_cpu_data data) in do_set_vcpu_timer_virq() argument
492 QEMU_LOCK_GUARD(&X86_CPU(cs)->env.xen_timers_lock); in do_set_vcpu_timer_virq()
493 kvm_xen_set_vcpu_timer(cs); in do_set_vcpu_timer_virq()
498 CPUState *cs = qemu_get_cpu(vcpu_id); in kvm_xen_set_vcpu_virq() local
500 if (!cs) { in kvm_xen_set_vcpu_virq()
501 return -ENOENT; in kvm_xen_set_vcpu_virq()
508 return -EINVAL; in kvm_xen_set_vcpu_virq()
511 if (port && X86_CPU(cs)->env.xen_virq[virq]) { in kvm_xen_set_vcpu_virq()
512 return -EEXIST; in kvm_xen_set_vcpu_virq()
515 X86_CPU(cs)->env.xen_virq[virq] = port; in kvm_xen_set_vcpu_virq()
517 async_run_on_cpu(cs, do_set_vcpu_timer_virq, in kvm_xen_set_vcpu_virq()
523 static void do_set_vcpu_time_info_gpa(CPUState *cs, run_on_cpu_data data) in do_set_vcpu_time_info_gpa() argument
525 X86CPU *cpu = X86_CPU(cs); in do_set_vcpu_time_info_gpa()
526 CPUX86State *env = &cpu->env; in do_set_vcpu_time_info_gpa()
528 env->xen_vcpu_time_info_gpa = data.host_ulong; in do_set_vcpu_time_info_gpa()
530 kvm_xen_set_vcpu_attr(cs, KVM_XEN_VCPU_ATTR_TYPE_VCPU_TIME_INFO, in do_set_vcpu_time_info_gpa()
531 env->xen_vcpu_time_info_gpa); in do_set_vcpu_time_info_gpa()
534 static void do_set_vcpu_runstate_gpa(CPUState *cs, run_on_cpu_data data) in do_set_vcpu_runstate_gpa() argument
536 X86CPU *cpu = X86_CPU(cs); in do_set_vcpu_runstate_gpa()
537 CPUX86State *env = &cpu->env; in do_set_vcpu_runstate_gpa()
539 env->xen_vcpu_runstate_gpa = data.host_ulong; in do_set_vcpu_runstate_gpa()
541 kvm_xen_set_vcpu_attr(cs, KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADDR, in do_set_vcpu_runstate_gpa()
542 env->xen_vcpu_runstate_gpa); in do_set_vcpu_runstate_gpa()
545 static void do_vcpu_soft_reset(CPUState *cs, run_on_cpu_data data) in do_vcpu_soft_reset() argument
547 X86CPU *cpu = X86_CPU(cs); in do_vcpu_soft_reset()
548 CPUX86State *env = &cpu->env; in do_vcpu_soft_reset()
550 env->xen_vcpu_info_gpa = INVALID_GPA; in do_vcpu_soft_reset()
551 env->xen_vcpu_info_default_gpa = INVALID_GPA; in do_vcpu_soft_reset()
552 env->xen_vcpu_time_info_gpa = INVALID_GPA; in do_vcpu_soft_reset()
553 env->xen_vcpu_runstate_gpa = INVALID_GPA; in do_vcpu_soft_reset()
554 env->xen_vcpu_callback_vector = 0; in do_vcpu_soft_reset()
555 memset(env->xen_virq, 0, sizeof(env->xen_virq)); in do_vcpu_soft_reset()
557 set_vcpu_info(cs, INVALID_GPA); in do_vcpu_soft_reset()
558 kvm_xen_set_vcpu_attr(cs, KVM_XEN_VCPU_ATTR_TYPE_VCPU_TIME_INFO, in do_vcpu_soft_reset()
560 kvm_xen_set_vcpu_attr(cs, KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADDR, in do_vcpu_soft_reset()
563 kvm_xen_set_vcpu_callback_vector(cs); in do_vcpu_soft_reset()
565 QEMU_LOCK_GUARD(&X86_CPU(cs)->env.xen_timers_lock); in do_vcpu_soft_reset()
566 env->xen_singleshot_timer_ns = 0; in do_vcpu_soft_reset()
567 kvm_xen_set_vcpu_timer(cs); in do_vcpu_soft_reset()
569 vcpuop_stop_singleshot_timer(cs); in do_vcpu_soft_reset()
585 * KVM-specific. in xen_set_shared_info()
611 return -EINVAL; in add_to_physmap_one()
620 return -ENOTSUP; in add_to_physmap_one()
624 return -EPERM; in add_to_physmap_one()
627 return -EINVAL; in add_to_physmap_one()
635 CPUState *cs = CPU(cpu); in do_add_to_physmap() local
637 if (hypercall_compat32(exit->u.hcall.longmode)) { in do_add_to_physmap()
641 if (kvm_copy_from_gva(cs, arg, &xatp32, sizeof(xatp32))) { in do_add_to_physmap()
642 return -EFAULT; in do_add_to_physmap()
650 if (kvm_copy_from_gva(cs, arg, &xatp, sizeof(xatp))) { in do_add_to_physmap()
651 return -EFAULT; in do_add_to_physmap()
656 return -ESRCH; in do_add_to_physmap()
667 CPUState *cs = CPU(cpu); in do_add_to_physmap_batch() local
670 if (hypercall_compat32(exit->u.hcall.longmode)) { in do_add_to_physmap_batch()
674 if (kvm_copy_from_gva(cs, arg, &xatpb32, sizeof(xatpb32))) { in do_add_to_physmap_batch()
675 return -EFAULT; in do_add_to_physmap_batch()
686 if (kvm_copy_from_gva(cs, arg, &xatpb, sizeof(xatpb))) { in do_add_to_physmap_batch()
687 return -EFAULT; in do_add_to_physmap_batch()
696 return -ESRCH; in do_add_to_physmap_batch()
701 return -EINVAL; in do_add_to_physmap_batch()
704 while (xatpb.size--) { in do_add_to_physmap_batch()
709 /* For 32-bit compat this only copies the low 32 bits of each */ in do_add_to_physmap_batch()
710 if (kvm_copy_from_gva(cs, idxs_gva, &idx, op_sz) || in do_add_to_physmap_batch()
711 kvm_copy_from_gva(cs, gpfns_gva, &gpfn, op_sz)) { in do_add_to_physmap_batch()
712 return -EFAULT; in do_add_to_physmap_batch()
719 if (kvm_copy_to_gva(cs, errs_gva, &err, sizeof(err))) { in do_add_to_physmap_batch()
720 return -EFAULT; in do_add_to_physmap_batch()
745 exit->u.hcall.result = err; in kvm_xen_hcall_memory_op()
752 CPUState *cs = CPU(cpu); in handle_set_param() local
759 if (kvm_copy_from_gva(cs, arg, &hp, sizeof(hp))) { in handle_set_param()
760 err = -EFAULT; in handle_set_param()
761 goto out; in handle_set_param()
765 err = -ESRCH; in handle_set_param()
766 goto out; in handle_set_param()
774 xen_set_long_mode(exit->u.hcall.longmode); in handle_set_param()
780 out: in handle_set_param()
781 exit->u.hcall.result = err; in handle_set_param()
788 CPUState *cs = CPU(cpu); in handle_get_param() local
795 if (kvm_copy_from_gva(cs, arg, &hp, sizeof(hp))) { in handle_get_param()
796 err = -EFAULT; in handle_get_param()
797 goto out; in handle_get_param()
801 err = -ESRCH; in handle_get_param()
802 goto out; in handle_get_param()
815 err = -EINVAL; in handle_get_param()
821 err = -EINVAL; in handle_get_param()
828 if (!err && kvm_copy_to_gva(cs, arg, &hp, sizeof(hp))) { in handle_get_param()
829 err = -EFAULT; in handle_get_param()
831 out: in handle_get_param()
832 exit->u.hcall.result = err; in handle_get_param()
846 return -EFAULT; in kvm_xen_hcall_evtchn_upcall_vector()
850 return -EINVAL; in kvm_xen_hcall_evtchn_upcall_vector()
855 return -EINVAL; in kvm_xen_hcall_evtchn_upcall_vector()
866 int ret = -ENOSYS; in kvm_xen_hcall_hvm_op()
873 ret = -ENOSYS; in kvm_xen_hcall_hvm_op()
886 exit->u.hcall.result = ret; in kvm_xen_hcall_hvm_op()
890 static int vcpuop_register_vcpu_info(CPUState *cs, CPUState *target, in vcpuop_register_vcpu_info() argument
901 return -ENOENT; in vcpuop_register_vcpu_info()
904 if (kvm_copy_from_gva(cs, arg, &rvi, sizeof(rvi))) { in vcpuop_register_vcpu_info()
905 return -EFAULT; in vcpuop_register_vcpu_info()
908 if (rvi.offset > TARGET_PAGE_SIZE - sizeof(struct vcpu_info)) { in vcpuop_register_vcpu_info()
909 return -EINVAL; in vcpuop_register_vcpu_info()
917 static int vcpuop_register_vcpu_time_info(CPUState *cs, CPUState *target, in vcpuop_register_vcpu_time_info() argument
929 return -ENOENT; in vcpuop_register_vcpu_time_info()
932 if (kvm_copy_from_gva(cs, arg, &tma, sizeof(tma))) { in vcpuop_register_vcpu_time_info()
933 return -EFAULT; in vcpuop_register_vcpu_time_info()
943 if (!kvm_gva_to_gpa(cs, tma.addr.p, &gpa, &len, false) || in vcpuop_register_vcpu_time_info()
945 return -EFAULT; in vcpuop_register_vcpu_time_info()
953 static int vcpuop_register_runstate_info(CPUState *cs, CPUState *target, in vcpuop_register_runstate_info() argument
965 return -ENOENT; in vcpuop_register_runstate_info()
968 if (kvm_copy_from_gva(cs, arg, &rma, sizeof(rma))) { in vcpuop_register_runstate_info()
969 return -EFAULT; in vcpuop_register_runstate_info()
973 if (!kvm_gva_to_gpa(cs, rma.addr.p, &gpa, &len, false)) { in vcpuop_register_runstate_info()
974 return -EFAULT; in vcpuop_register_runstate_info()
999 CPUX86State *env = &X86_CPU(cpu)->env; in xen_vcpu_singleshot_timer_event()
1000 uint16_t port = env->xen_virq[VIRQ_TIMER]; in xen_vcpu_singleshot_timer_event()
1006 qemu_mutex_lock(&env->xen_timers_lock); in xen_vcpu_singleshot_timer_event()
1007 env->xen_singleshot_timer_ns = 0; in xen_vcpu_singleshot_timer_event()
1008 qemu_mutex_unlock(&env->xen_timers_lock); in xen_vcpu_singleshot_timer_event()
1014 CPUX86State *env = &X86_CPU(cpu)->env; in xen_vcpu_periodic_timer_event()
1015 uint16_t port = env->xen_virq[VIRQ_TIMER]; in xen_vcpu_periodic_timer_event()
1022 qemu_mutex_lock(&env->xen_timers_lock); in xen_vcpu_periodic_timer_event()
1025 timer_mod_ns(env->xen_periodic_timer, in xen_vcpu_periodic_timer_event()
1026 qemu_now + env->xen_periodic_timer_period); in xen_vcpu_periodic_timer_event()
1028 qemu_mutex_unlock(&env->xen_timers_lock); in xen_vcpu_periodic_timer_event()
1033 CPUX86State *tenv = &X86_CPU(target)->env; in do_set_periodic_timer()
1036 timer_del(tenv->xen_periodic_timer); in do_set_periodic_timer()
1038 qemu_mutex_lock(&tenv->xen_timers_lock); in do_set_periodic_timer()
1041 timer_mod_ns(tenv->xen_periodic_timer, qemu_now + period_ns); in do_set_periodic_timer()
1042 tenv->xen_periodic_timer_period = period_ns; in do_set_periodic_timer()
1044 qemu_mutex_unlock(&tenv->xen_timers_lock); in do_set_periodic_timer()
1054 static int vcpuop_set_periodic_timer(CPUState *cs, CPUState *target, in vcpuop_set_periodic_timer() argument
1060 if (kvm_copy_from_gva(cs, arg, &spt, sizeof(spt))) { in vcpuop_set_periodic_timer()
1061 return -EFAULT; in vcpuop_set_periodic_timer()
1065 return -EINVAL; in vcpuop_set_periodic_timer()
1073 CPUX86State *tenv = &X86_CPU(target)->env; in vcpuop_stop_periodic_timer()
1075 qemu_mutex_lock(&tenv->xen_timers_lock); in vcpuop_stop_periodic_timer()
1077 timer_del(tenv->xen_periodic_timer); in vcpuop_stop_periodic_timer()
1078 tenv->xen_periodic_timer_period = 0; in vcpuop_stop_periodic_timer()
1080 qemu_mutex_unlock(&tenv->xen_timers_lock); in vcpuop_stop_periodic_timer()
1088 static int do_set_singleshot_timer(CPUState *cs, uint64_t timeout_abs, in do_set_singleshot_timer() argument
1091 CPUX86State *env = &X86_CPU(cs)->env; in do_set_singleshot_timer()
1094 int64_t delta = timeout_abs - now; in do_set_singleshot_timer()
1111 timer_mod_ns(env->xen_singleshot_timer, qemu_now + delta); in do_set_singleshot_timer()
1112 env->xen_singleshot_timer_ns = now + delta; in do_set_singleshot_timer()
1116 static int vcpuop_set_singleshot_timer(CPUState *cs, uint64_t arg) in vcpuop_set_singleshot_timer() argument
1121 * The struct is a uint64_t followed by a uint32_t. On 32-bit that in vcpuop_set_singleshot_timer()
1122 * makes it 12 bytes. On 64-bit it gets padded to 16. The parts in vcpuop_set_singleshot_timer()
1125 * to copy the full 16 bytes from 64-bit guests, and return -EFAULT in vcpuop_set_singleshot_timer()
1132 if (kvm_copy_from_gva(cs, arg, &sst, 12)) { in vcpuop_set_singleshot_timer()
1133 return -EFAULT; in vcpuop_set_singleshot_timer()
1136 QEMU_LOCK_GUARD(&X86_CPU(cs)->env.xen_timers_lock); in vcpuop_set_singleshot_timer()
1143 return do_set_singleshot_timer(cs, sst.timeout_abs_ns, false); in vcpuop_set_singleshot_timer()
1146 static int vcpuop_stop_singleshot_timer(CPUState *cs) in vcpuop_stop_singleshot_timer() argument
1148 CPUX86State *env = &X86_CPU(cs)->env; in vcpuop_stop_singleshot_timer()
1150 qemu_mutex_lock(&env->xen_timers_lock); in vcpuop_stop_singleshot_timer()
1152 timer_del(env->xen_singleshot_timer); in vcpuop_stop_singleshot_timer()
1153 env->xen_singleshot_timer_ns = 0; in vcpuop_stop_singleshot_timer()
1155 qemu_mutex_unlock(&env->xen_timers_lock); in vcpuop_stop_singleshot_timer()
1167 QEMU_LOCK_GUARD(&X86_CPU(cpu)->env.xen_timers_lock); in kvm_xen_hcall_set_timer_op()
1170 exit->u.hcall.result = err; in kvm_xen_hcall_set_timer_op()
1177 CPUState *cs = CPU(cpu); in kvm_xen_hcall_vcpu_op() local
1178 CPUState *dest = cs->cpu_index == vcpu_id ? cs : qemu_get_cpu(vcpu_id); in kvm_xen_hcall_vcpu_op()
1182 err = -ENOENT; in kvm_xen_hcall_vcpu_op()
1183 goto out; in kvm_xen_hcall_vcpu_op()
1188 err = vcpuop_register_runstate_info(cs, dest, arg); in kvm_xen_hcall_vcpu_op()
1191 err = vcpuop_register_vcpu_time_info(cs, dest, arg); in kvm_xen_hcall_vcpu_op()
1194 err = vcpuop_register_vcpu_info(cs, dest, arg); in kvm_xen_hcall_vcpu_op()
1197 if (cs->cpu_index == vcpu_id) { in kvm_xen_hcall_vcpu_op()
1200 err = -EINVAL; in kvm_xen_hcall_vcpu_op()
1205 if (cs->cpu_index == vcpu_id) { in kvm_xen_hcall_vcpu_op()
1208 err = -EINVAL; in kvm_xen_hcall_vcpu_op()
1212 err = vcpuop_set_periodic_timer(cs, dest, arg); in kvm_xen_hcall_vcpu_op()
1223 out: in kvm_xen_hcall_vcpu_op()
1224 exit->u.hcall.result = err; in kvm_xen_hcall_vcpu_op()
1231 CPUState *cs = CPU(cpu); in kvm_xen_hcall_evtchn_op() local
1232 int err = -ENOSYS; in kvm_xen_hcall_evtchn_op()
1239 err = -ENOSYS; in kvm_xen_hcall_evtchn_op()
1246 if (kvm_copy_from_gva(cs, arg, &status, sizeof(status))) { in kvm_xen_hcall_evtchn_op()
1247 err = -EFAULT; in kvm_xen_hcall_evtchn_op()
1252 if (!err && kvm_copy_to_gva(cs, arg, &status, sizeof(status))) { in kvm_xen_hcall_evtchn_op()
1253 err = -EFAULT; in kvm_xen_hcall_evtchn_op()
1261 if (kvm_copy_from_gva(cs, arg, &close, sizeof(close))) { in kvm_xen_hcall_evtchn_op()
1262 err = -EFAULT; in kvm_xen_hcall_evtchn_op()
1273 if (kvm_copy_from_gva(cs, arg, &unmask, sizeof(unmask))) { in kvm_xen_hcall_evtchn_op()
1274 err = -EFAULT; in kvm_xen_hcall_evtchn_op()
1285 if (kvm_copy_from_gva(cs, arg, &virq, sizeof(virq))) { in kvm_xen_hcall_evtchn_op()
1286 err = -EFAULT; in kvm_xen_hcall_evtchn_op()
1291 if (!err && kvm_copy_to_gva(cs, arg, &virq, sizeof(virq))) { in kvm_xen_hcall_evtchn_op()
1292 err = -EFAULT; in kvm_xen_hcall_evtchn_op()
1300 if (kvm_copy_from_gva(cs, arg, &pirq, sizeof(pirq))) { in kvm_xen_hcall_evtchn_op()
1301 err = -EFAULT; in kvm_xen_hcall_evtchn_op()
1306 if (!err && kvm_copy_to_gva(cs, arg, &pirq, sizeof(pirq))) { in kvm_xen_hcall_evtchn_op()
1307 err = -EFAULT; in kvm_xen_hcall_evtchn_op()
1315 if (kvm_copy_from_gva(cs, arg, &ipi, sizeof(ipi))) { in kvm_xen_hcall_evtchn_op()
1316 err = -EFAULT; in kvm_xen_hcall_evtchn_op()
1321 if (!err && kvm_copy_to_gva(cs, arg, &ipi, sizeof(ipi))) { in kvm_xen_hcall_evtchn_op()
1322 err = -EFAULT; in kvm_xen_hcall_evtchn_op()
1330 if (kvm_copy_from_gva(cs, arg, &send, sizeof(send))) { in kvm_xen_hcall_evtchn_op()
1331 err = -EFAULT; in kvm_xen_hcall_evtchn_op()
1342 if (kvm_copy_from_gva(cs, arg, &alloc, sizeof(alloc))) { in kvm_xen_hcall_evtchn_op()
1343 err = -EFAULT; in kvm_xen_hcall_evtchn_op()
1348 if (!err && kvm_copy_to_gva(cs, arg, &alloc, sizeof(alloc))) { in kvm_xen_hcall_evtchn_op()
1349 err = -EFAULT; in kvm_xen_hcall_evtchn_op()
1357 if (kvm_copy_from_gva(cs, arg, &interdomain, sizeof(interdomain))) { in kvm_xen_hcall_evtchn_op()
1358 err = -EFAULT; in kvm_xen_hcall_evtchn_op()
1364 kvm_copy_to_gva(cs, arg, &interdomain, sizeof(interdomain))) { in kvm_xen_hcall_evtchn_op()
1365 err = -EFAULT; in kvm_xen_hcall_evtchn_op()
1373 if (kvm_copy_from_gva(cs, arg, &vcpu, sizeof(vcpu))) { in kvm_xen_hcall_evtchn_op()
1374 err = -EFAULT; in kvm_xen_hcall_evtchn_op()
1385 if (kvm_copy_from_gva(cs, arg, &reset, sizeof(reset))) { in kvm_xen_hcall_evtchn_op()
1386 err = -EFAULT; in kvm_xen_hcall_evtchn_op()
1397 exit->u.hcall.result = err; in kvm_xen_hcall_evtchn_op()
1452 static int schedop_shutdown(CPUState *cs, uint64_t arg) in schedop_shutdown() argument
1460 if (kvm_copy_from_gva(cs, arg, &shutdown, sizeof(shutdown))) { in schedop_shutdown()
1461 return -EFAULT; in schedop_shutdown()
1466 cpu_dump_state(cs, stderr, CPU_DUMP_CODE); in schedop_shutdown()
1485 ret = -EINVAL; in schedop_shutdown()
1495 CPUState *cs = CPU(cpu); in kvm_xen_hcall_sched_op() local
1496 int err = -ENOSYS; in kvm_xen_hcall_sched_op()
1500 err = schedop_shutdown(cs, arg); in kvm_xen_hcall_sched_op()
1520 exit->u.hcall.result = err; in kvm_xen_hcall_sched_op()
1527 CPUState *cs = CPU(cpu); in kvm_xen_hcall_gnttab_op() local
1535 if (kvm_copy_from_gva(cs, arg, &set, sizeof(set))) { in kvm_xen_hcall_gnttab_op()
1536 err = -EFAULT; in kvm_xen_hcall_gnttab_op()
1541 if (!err && kvm_copy_to_gva(cs, arg, &set, sizeof(set))) { in kvm_xen_hcall_gnttab_op()
1542 err = -EFAULT; in kvm_xen_hcall_gnttab_op()
1550 if (kvm_copy_from_gva(cs, arg, &get, sizeof(get))) { in kvm_xen_hcall_gnttab_op()
1551 err = -EFAULT; in kvm_xen_hcall_gnttab_op()
1556 if (!err && kvm_copy_to_gva(cs, arg, &get, sizeof(get))) { in kvm_xen_hcall_gnttab_op()
1557 err = -EFAULT; in kvm_xen_hcall_gnttab_op()
1565 if (kvm_copy_from_gva(cs, arg, &size, sizeof(size))) { in kvm_xen_hcall_gnttab_op()
1566 err = -EFAULT; in kvm_xen_hcall_gnttab_op()
1571 if (!err && kvm_copy_to_gva(cs, arg, &size, sizeof(size))) { in kvm_xen_hcall_gnttab_op()
1572 err = -EFAULT; in kvm_xen_hcall_gnttab_op()
1584 /* Xen explicitly returns -ENOSYS to HVM guests for all others */ in kvm_xen_hcall_gnttab_op()
1585 err = -ENOSYS; in kvm_xen_hcall_gnttab_op()
1589 exit->u.hcall.result = err; in kvm_xen_hcall_gnttab_op()
1596 CPUState *cs = CPU(cpu); in kvm_xen_hcall_physdev_op() local
1603 if (hypercall_compat32(exit->u.hcall.longmode)) { in kvm_xen_hcall_physdev_op()
1606 if (kvm_copy_from_gva(cs, arg, map32, sizeof(*map32))) { in kvm_xen_hcall_physdev_op()
1607 return -EFAULT; in kvm_xen_hcall_physdev_op()
1613 * it 64-bit aligned in the 64-bit version. in kvm_xen_hcall_physdev_op()
1618 memmove(&map.table_base, &map32->table_base, sizeof(map.table_base)); in kvm_xen_hcall_physdev_op()
1620 if (kvm_copy_from_gva(cs, arg, &map, sizeof(map))) { in kvm_xen_hcall_physdev_op()
1621 err = -EFAULT; in kvm_xen_hcall_physdev_op()
1630 if (!err && kvm_copy_to_gva(cs, arg, &map, in kvm_xen_hcall_physdev_op()
1632 err = -EFAULT; in kvm_xen_hcall_physdev_op()
1640 if (kvm_copy_from_gva(cs, arg, &unmap, sizeof(unmap))) { in kvm_xen_hcall_physdev_op()
1641 err = -EFAULT; in kvm_xen_hcall_physdev_op()
1646 if (!err && kvm_copy_to_gva(cs, arg, &unmap, sizeof(unmap))) { in kvm_xen_hcall_physdev_op()
1647 err = -EFAULT; in kvm_xen_hcall_physdev_op()
1655 if (kvm_copy_from_gva(cs, arg, &eoi, sizeof(eoi))) { in kvm_xen_hcall_physdev_op()
1656 err = -EFAULT; in kvm_xen_hcall_physdev_op()
1661 if (!err && kvm_copy_to_gva(cs, arg, &eoi, sizeof(eoi))) { in kvm_xen_hcall_physdev_op()
1662 err = -EFAULT; in kvm_xen_hcall_physdev_op()
1670 if (kvm_copy_from_gva(cs, arg, &query, sizeof(query))) { in kvm_xen_hcall_physdev_op()
1671 err = -EFAULT; in kvm_xen_hcall_physdev_op()
1676 if (!err && kvm_copy_to_gva(cs, arg, &query, sizeof(query))) { in kvm_xen_hcall_physdev_op()
1677 err = -EFAULT; in kvm_xen_hcall_physdev_op()
1685 if (kvm_copy_from_gva(cs, arg, &get, sizeof(get))) { in kvm_xen_hcall_physdev_op()
1686 err = -EFAULT; in kvm_xen_hcall_physdev_op()
1691 if (!err && kvm_copy_to_gva(cs, arg, &get, sizeof(get))) { in kvm_xen_hcall_physdev_op()
1692 err = -EFAULT; in kvm_xen_hcall_physdev_op()
1697 err = -ENOSYS; in kvm_xen_hcall_physdev_op()
1704 exit->u.hcall.result = err; in kvm_xen_hcall_physdev_op()
1710 uint16_t code = exit->u.hcall.input; in do_kvm_xen_handle_exit()
1712 if (exit->u.hcall.cpl > 0) { in do_kvm_xen_handle_exit()
1713 exit->u.hcall.result = -EPERM; in do_kvm_xen_handle_exit()
1719 if (exit->u.hcall.longmode) { in do_kvm_xen_handle_exit()
1721 exit->u.hcall.params[0]); in do_kvm_xen_handle_exit()
1723 /* In 32-bit mode, the 64-bit timer value is in two args. */ in do_kvm_xen_handle_exit()
1724 uint64_t val = ((uint64_t)exit->u.hcall.params[1]) << 32 | in do_kvm_xen_handle_exit()
1725 (uint32_t)exit->u.hcall.params[0]; in do_kvm_xen_handle_exit()
1729 return kvm_xen_hcall_gnttab_op(exit, cpu, exit->u.hcall.params[0], in do_kvm_xen_handle_exit()
1730 exit->u.hcall.params[1], in do_kvm_xen_handle_exit()
1731 exit->u.hcall.params[2]); in do_kvm_xen_handle_exit()
1733 return kvm_xen_hcall_sched_op(exit, cpu, exit->u.hcall.params[0], in do_kvm_xen_handle_exit()
1734 exit->u.hcall.params[1]); in do_kvm_xen_handle_exit()
1736 return kvm_xen_hcall_evtchn_op(exit, cpu, exit->u.hcall.params[0], in do_kvm_xen_handle_exit()
1737 exit->u.hcall.params[1]); in do_kvm_xen_handle_exit()
1740 exit->u.hcall.params[0], in do_kvm_xen_handle_exit()
1741 exit->u.hcall.params[1], in do_kvm_xen_handle_exit()
1742 exit->u.hcall.params[2]); in do_kvm_xen_handle_exit()
1744 return kvm_xen_hcall_hvm_op(exit, cpu, exit->u.hcall.params[0], in do_kvm_xen_handle_exit()
1745 exit->u.hcall.params[1]); in do_kvm_xen_handle_exit()
1747 return kvm_xen_hcall_memory_op(exit, cpu, exit->u.hcall.params[0], in do_kvm_xen_handle_exit()
1748 exit->u.hcall.params[1]); in do_kvm_xen_handle_exit()
1750 return kvm_xen_hcall_physdev_op(exit, cpu, exit->u.hcall.params[0], in do_kvm_xen_handle_exit()
1751 exit->u.hcall.params[1]); in do_kvm_xen_handle_exit()
1753 return kvm_xen_hcall_xen_version(exit, cpu, exit->u.hcall.params[0], in do_kvm_xen_handle_exit()
1754 exit->u.hcall.params[1]); in do_kvm_xen_handle_exit()
1762 if (exit->type != KVM_EXIT_XEN_HCALL) { in kvm_xen_handle_exit()
1763 return -1; in kvm_xen_handle_exit()
1772 if (exit->u.hcall.longmode != xen_is_long_mode()) { in kvm_xen_handle_exit()
1779 * -ENOSYS. This case is for hypercalls which are unexpected. in kvm_xen_handle_exit()
1781 exit->u.hcall.result = -ENOSYS; in kvm_xen_handle_exit()
1784 (uint64_t)exit->u.hcall.input, in kvm_xen_handle_exit()
1785 (uint64_t)exit->u.hcall.params[0], in kvm_xen_handle_exit()
1786 (uint64_t)exit->u.hcall.params[1], in kvm_xen_handle_exit()
1787 (uint64_t)exit->u.hcall.params[2]); in kvm_xen_handle_exit()
1790 trace_kvm_xen_hypercall(CPU(cpu)->cpu_index, exit->u.hcall.cpl, in kvm_xen_handle_exit()
1791 exit->u.hcall.input, exit->u.hcall.params[0], in kvm_xen_handle_exit()
1792 exit->u.hcall.params[1], exit->u.hcall.params[2], in kvm_xen_handle_exit()
1793 exit->u.hcall.result); in kvm_xen_handle_exit()
1800 return s->xen_gnttab_max_frames; in kvm_xen_get_gnttab_max_frames()
1806 return s->xen_evtchn_max_pirq; in kvm_xen_get_evtchn_max_pirq()
1809 int kvm_put_xen_state(CPUState *cs) in kvm_put_xen_state() argument
1811 X86CPU *cpu = X86_CPU(cs); in kvm_put_xen_state()
1812 CPUX86State *env = &cpu->env; in kvm_put_xen_state()
1816 gpa = env->xen_vcpu_info_gpa; in kvm_put_xen_state()
1818 gpa = env->xen_vcpu_info_default_gpa; in kvm_put_xen_state()
1822 ret = set_vcpu_info(cs, gpa); in kvm_put_xen_state()
1828 gpa = env->xen_vcpu_time_info_gpa; in kvm_put_xen_state()
1830 ret = kvm_xen_set_vcpu_attr(cs, KVM_XEN_VCPU_ATTR_TYPE_VCPU_TIME_INFO, in kvm_put_xen_state()
1837 gpa = env->xen_vcpu_runstate_gpa; in kvm_put_xen_state()
1839 ret = kvm_xen_set_vcpu_attr(cs, KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADDR, in kvm_put_xen_state()
1846 if (env->xen_periodic_timer_period) { in kvm_put_xen_state()
1847 ret = do_set_periodic_timer(cs, env->xen_periodic_timer_period); in kvm_put_xen_state()
1858 QEMU_LOCK_GUARD(&env->xen_timers_lock); in kvm_put_xen_state()
1859 if (env->xen_singleshot_timer_ns) { in kvm_put_xen_state()
1860 ret = do_set_singleshot_timer(cs, env->xen_singleshot_timer_ns, in kvm_put_xen_state()
1869 if (env->xen_vcpu_callback_vector) { in kvm_put_xen_state()
1870 ret = kvm_xen_set_vcpu_callback_vector(cs); in kvm_put_xen_state()
1876 if (env->xen_virq[VIRQ_TIMER]) { in kvm_put_xen_state()
1877 do_set_vcpu_timer_virq(cs, in kvm_put_xen_state()
1878 RUN_ON_CPU_HOST_INT(env->xen_virq[VIRQ_TIMER])); in kvm_put_xen_state()
1883 int kvm_get_xen_state(CPUState *cs) in kvm_get_xen_state() argument
1885 X86CPU *cpu = X86_CPU(cs); in kvm_get_xen_state()
1886 CPUX86State *env = &cpu->env; in kvm_get_xen_state()
1896 gpa = env->xen_vcpu_info_gpa; in kvm_get_xen_state()
1898 gpa = env->xen_vcpu_info_default_gpa; in kvm_get_xen_state()
1916 * If the kernel is accelerating timers, read out the current value of the in kvm_get_xen_state()
1919 if (env->xen_virq[VIRQ_TIMER]) { in kvm_get_xen_state()
1923 ret = kvm_vcpu_ioctl(cs, KVM_XEN_VCPU_GET_ATTR, &va); in kvm_get_xen_state()
1931 * timer for this vCPU after the value has been read out. But that's in kvm_get_xen_state()
1935 QEMU_LOCK_GUARD(&X86_CPU(cs)->env.xen_timers_lock); in kvm_get_xen_state()
1936 env->xen_singleshot_timer_ns = va.u.timer.expires_ns; in kvm_get_xen_state()