xref: /openbmc/qemu/target/i386/whpx/whpx-accel-ops.c (revision d16cab541ab9217977e2a39abf3d79f914146741)
1b86f59c7SClaudio Fontana /*
2b86f59c7SClaudio Fontana  * QEMU Windows Hypervisor Platform accelerator (WHPX)
3b86f59c7SClaudio Fontana  *
4b86f59c7SClaudio Fontana  * Copyright Microsoft Corp. 2017
5b86f59c7SClaudio Fontana  *
6b86f59c7SClaudio Fontana  * This work is licensed under the terms of the GNU GPL, version 2 or later.
7b86f59c7SClaudio Fontana  * See the COPYING file in the top-level directory.
8b86f59c7SClaudio Fontana  *
9b86f59c7SClaudio Fontana  */
10b86f59c7SClaudio Fontana 
11b86f59c7SClaudio Fontana #include "qemu/osdep.h"
12b86f59c7SClaudio Fontana #include "sysemu/kvm_int.h"
13b86f59c7SClaudio Fontana #include "qemu/main-loop.h"
14b86f59c7SClaudio Fontana #include "sysemu/cpus.h"
15b86f59c7SClaudio Fontana #include "qemu/guest-random.h"
16b86f59c7SClaudio Fontana 
17b86f59c7SClaudio Fontana #include "sysemu/whpx.h"
18b86f59c7SClaudio Fontana #include "whpx-internal.h"
19b86f59c7SClaudio Fontana #include "whpx-accel-ops.h"
20b86f59c7SClaudio Fontana 
whpx_cpu_thread_fn(void * arg)21b86f59c7SClaudio Fontana static void *whpx_cpu_thread_fn(void *arg)
22b86f59c7SClaudio Fontana {
23b86f59c7SClaudio Fontana     CPUState *cpu = arg;
24b86f59c7SClaudio Fontana     int r;
25b86f59c7SClaudio Fontana 
26b86f59c7SClaudio Fontana     rcu_register_thread();
27b86f59c7SClaudio Fontana 
28195801d7SStefan Hajnoczi     bql_lock();
29b86f59c7SClaudio Fontana     qemu_thread_get_self(cpu->thread);
30b86f59c7SClaudio Fontana     cpu->thread_id = qemu_get_thread_id();
31b86f59c7SClaudio Fontana     current_cpu = cpu;
32b86f59c7SClaudio Fontana 
33b86f59c7SClaudio Fontana     r = whpx_init_vcpu(cpu);
34b86f59c7SClaudio Fontana     if (r < 0) {
35b86f59c7SClaudio Fontana         fprintf(stderr, "whpx_init_vcpu failed: %s\n", strerror(-r));
36b86f59c7SClaudio Fontana         exit(1);
37b86f59c7SClaudio Fontana     }
38b86f59c7SClaudio Fontana 
39b86f59c7SClaudio Fontana     /* signal CPU creation */
40b86f59c7SClaudio Fontana     cpu_thread_signal_created(cpu);
41b86f59c7SClaudio Fontana     qemu_guest_random_seed_thread_part2(cpu->random_seed);
42b86f59c7SClaudio Fontana 
43b86f59c7SClaudio Fontana     do {
44b86f59c7SClaudio Fontana         if (cpu_can_run(cpu)) {
45b86f59c7SClaudio Fontana             r = whpx_vcpu_exec(cpu);
46b86f59c7SClaudio Fontana             if (r == EXCP_DEBUG) {
47b86f59c7SClaudio Fontana                 cpu_handle_guest_debug(cpu);
48b86f59c7SClaudio Fontana             }
49b86f59c7SClaudio Fontana         }
50b86f59c7SClaudio Fontana         while (cpu_thread_is_idle(cpu)) {
51*7c754c78SStefan Hajnoczi             qemu_cond_wait_bql(cpu->halt_cond);
52b86f59c7SClaudio Fontana         }
53b86f59c7SClaudio Fontana         qemu_wait_io_event_common(cpu);
54b86f59c7SClaudio Fontana     } while (!cpu->unplug || cpu_can_run(cpu));
55b86f59c7SClaudio Fontana 
56b86f59c7SClaudio Fontana     whpx_destroy_vcpu(cpu);
57b86f59c7SClaudio Fontana     cpu_thread_signal_destroyed(cpu);
58195801d7SStefan Hajnoczi     bql_unlock();
59b86f59c7SClaudio Fontana     rcu_unregister_thread();
60b86f59c7SClaudio Fontana     return NULL;
61b86f59c7SClaudio Fontana }
62b86f59c7SClaudio Fontana 
whpx_start_vcpu_thread(CPUState * cpu)63b86f59c7SClaudio Fontana static void whpx_start_vcpu_thread(CPUState *cpu)
64b86f59c7SClaudio Fontana {
65b86f59c7SClaudio Fontana     char thread_name[VCPU_THREAD_NAME_SIZE];
66b86f59c7SClaudio Fontana 
67b86f59c7SClaudio Fontana     snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/WHPX",
68b86f59c7SClaudio Fontana              cpu->cpu_index);
69b86f59c7SClaudio Fontana     qemu_thread_create(cpu->thread, thread_name, whpx_cpu_thread_fn,
70b86f59c7SClaudio Fontana                        cpu, QEMU_THREAD_JOINABLE);
71b86f59c7SClaudio Fontana }
72b86f59c7SClaudio Fontana 
whpx_kick_vcpu_thread(CPUState * cpu)73b86f59c7SClaudio Fontana static void whpx_kick_vcpu_thread(CPUState *cpu)
74b86f59c7SClaudio Fontana {
75b86f59c7SClaudio Fontana     if (!qemu_cpu_is_self(cpu)) {
76b86f59c7SClaudio Fontana         whpx_vcpu_kick(cpu);
77b86f59c7SClaudio Fontana     }
78b86f59c7SClaudio Fontana }
79b86f59c7SClaudio Fontana 
whpx_vcpu_thread_is_idle(CPUState * cpu)80ad7d684dSPhilippe Mathieu-Daudé static bool whpx_vcpu_thread_is_idle(CPUState *cpu)
81ad7d684dSPhilippe Mathieu-Daudé {
82ad7d684dSPhilippe Mathieu-Daudé     return !whpx_apic_in_platform();
83ad7d684dSPhilippe Mathieu-Daudé }
84ad7d684dSPhilippe Mathieu-Daudé 
whpx_accel_ops_class_init(ObjectClass * oc,void * data)85b86f59c7SClaudio Fontana static void whpx_accel_ops_class_init(ObjectClass *oc, void *data)
86b86f59c7SClaudio Fontana {
87b86f59c7SClaudio Fontana     AccelOpsClass *ops = ACCEL_OPS_CLASS(oc);
88b86f59c7SClaudio Fontana 
89b86f59c7SClaudio Fontana     ops->create_vcpu_thread = whpx_start_vcpu_thread;
90b86f59c7SClaudio Fontana     ops->kick_vcpu_thread = whpx_kick_vcpu_thread;
91ad7d684dSPhilippe Mathieu-Daudé     ops->cpu_thread_is_idle = whpx_vcpu_thread_is_idle;
92b86f59c7SClaudio Fontana 
93b86f59c7SClaudio Fontana     ops->synchronize_post_reset = whpx_cpu_synchronize_post_reset;
94b86f59c7SClaudio Fontana     ops->synchronize_post_init = whpx_cpu_synchronize_post_init;
95b86f59c7SClaudio Fontana     ops->synchronize_state = whpx_cpu_synchronize_state;
96b86f59c7SClaudio Fontana     ops->synchronize_pre_loadvm = whpx_cpu_synchronize_pre_loadvm;
97d7482ffeSIvan Shcherbakov     ops->synchronize_pre_resume = whpx_cpu_synchronize_pre_resume;
98b86f59c7SClaudio Fontana }
99b86f59c7SClaudio Fontana 
100b86f59c7SClaudio Fontana static const TypeInfo whpx_accel_ops_type = {
101b86f59c7SClaudio Fontana     .name = ACCEL_OPS_NAME("whpx"),
102b86f59c7SClaudio Fontana 
103b86f59c7SClaudio Fontana     .parent = TYPE_ACCEL_OPS,
104b86f59c7SClaudio Fontana     .class_init = whpx_accel_ops_class_init,
105b86f59c7SClaudio Fontana     .abstract = true,
106b86f59c7SClaudio Fontana };
107b86f59c7SClaudio Fontana 
whpx_accel_ops_register_types(void)108b86f59c7SClaudio Fontana static void whpx_accel_ops_register_types(void)
109b86f59c7SClaudio Fontana {
110b86f59c7SClaudio Fontana     type_register_static(&whpx_accel_ops_type);
111b86f59c7SClaudio Fontana }
112b86f59c7SClaudio Fontana type_init(whpx_accel_ops_register_types);
113