aboutsummaryrefslogtreecommitdiff
path: root/target/i386/nvmm/nvmm-all.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/i386/nvmm/nvmm-all.c')
-rw-r--r--target/i386/nvmm/nvmm-all.c111
1 files changed, 65 insertions, 46 deletions
diff --git a/target/i386/nvmm/nvmm-all.c b/target/i386/nvmm/nvmm-all.c
index 04e5f7e..2e442ba 100644
--- a/target/i386/nvmm/nvmm-all.c
+++ b/target/i386/nvmm/nvmm-all.c
@@ -9,16 +9,20 @@
#include "qemu/osdep.h"
#include "cpu.h"
-#include "exec/address-spaces.h"
-#include "exec/ioport.h"
+#include "system/address-spaces.h"
+#include "system/ioport.h"
#include "qemu/accel.h"
+#include "accel/accel-ops.h"
#include "system/nvmm.h"
#include "system/cpus.h"
+#include "system/memory.h"
#include "system/runstate.h"
#include "qemu/main-loop.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
#include "qemu/queue.h"
+#include "accel/accel-cpu-target.h"
+#include "host-cpu.h"
#include "migration/blocker.h"
#include "strings.h"
@@ -30,7 +34,6 @@ struct AccelCPUState {
struct nvmm_vcpu vcpu;
uint8_t tpr;
bool stop;
- bool dirty;
/* Window-exiting for INTs/NMIs. */
bool int_window_exit;
@@ -47,7 +50,7 @@ struct qemu_machine {
/* -------------------------------------------------------------------------- */
-static bool nvmm_allowed;
+bool nvmm_allowed;
static struct qemu_machine qemu_mach;
static struct nvmm_machine *
@@ -411,22 +414,22 @@ nvmm_vcpu_pre_run(CPUState *cpu)
* Force the VCPU out of its inner loop to process any INIT requests
* or commit pending TPR access.
*/
- if (cpu->interrupt_request & (CPU_INTERRUPT_INIT | CPU_INTERRUPT_TPR)) {
- cpu->exit_request = 1;
+ if (cpu_test_interrupt(cpu, CPU_INTERRUPT_INIT | CPU_INTERRUPT_TPR)) {
+ qatomic_set(&cpu->exit_request, true);
}
- if (!has_event && (cpu->interrupt_request & CPU_INTERRUPT_NMI)) {
+ if (!has_event && cpu_test_interrupt(cpu, CPU_INTERRUPT_NMI)) {
if (nvmm_can_take_nmi(cpu)) {
- cpu->interrupt_request &= ~CPU_INTERRUPT_NMI;
+ cpu_reset_interrupt(cpu, CPU_INTERRUPT_NMI);
event->type = NVMM_VCPU_EVENT_INTR;
event->vector = 2;
has_event = true;
}
}
- if (!has_event && (cpu->interrupt_request & CPU_INTERRUPT_HARD)) {
+ if (!has_event && cpu_test_interrupt(cpu, CPU_INTERRUPT_HARD)) {
if (nvmm_can_take_int(cpu)) {
- cpu->interrupt_request &= ~CPU_INTERRUPT_HARD;
+ cpu_reset_interrupt(cpu, CPU_INTERRUPT_HARD);
event->type = NVMM_VCPU_EVENT_INTR;
event->vector = cpu_get_pic_interrupt(env);
has_event = true;
@@ -434,8 +437,8 @@ nvmm_vcpu_pre_run(CPUState *cpu)
}
/* Don't want SMIs. */
- if (cpu->interrupt_request & CPU_INTERRUPT_SMI) {
- cpu->interrupt_request &= ~CPU_INTERRUPT_SMI;
+ if (cpu_test_interrupt(cpu, CPU_INTERRUPT_SMI)) {
+ cpu_reset_interrupt(cpu, CPU_INTERRUPT_SMI);
}
if (sync_tpr) {
@@ -508,16 +511,18 @@ nvmm_io_callback(struct nvmm_io *io)
}
/* Needed, otherwise infinite loop. */
- current_cpu->accel->dirty = false;
+ current_cpu->vcpu_dirty = false;
}
static void
nvmm_mem_callback(struct nvmm_mem *mem)
{
- cpu_physical_memory_rw(mem->gpa, mem->data, mem->size, mem->write);
+ /* TODO: Get CPUState via mem->vcpu? */
+ address_space_rw(&address_space_memory, mem->gpa, MEMTXATTRS_UNSPECIFIED,
+ mem->data, mem->size, mem->write);
/* Needed, otherwise infinite loop. */
- current_cpu->accel->dirty = false;
+ current_cpu->vcpu_dirty = false;
}
static struct nvmm_assist_callbacks nvmm_callbacks = {
@@ -649,9 +654,9 @@ nvmm_handle_halted(struct nvmm_machine *mach, CPUState *cpu,
bql_lock();
- if (!((cpu->interrupt_request & CPU_INTERRUPT_HARD) &&
+ if (!(cpu_test_interrupt(cpu, CPU_INTERRUPT_HARD) &&
(cpu_env(cpu)->eflags & IF_MASK)) &&
- !(cpu->interrupt_request & CPU_INTERRUPT_NMI)) {
+ !cpu_test_interrupt(cpu, CPU_INTERRUPT_NMI)) {
cpu->exception_index = EXCP_HLT;
cpu->halted = true;
ret = 1;
@@ -689,26 +694,26 @@ nvmm_vcpu_loop(CPUState *cpu)
* Some asynchronous events must be handled outside of the inner
* VCPU loop. They are handled here.
*/
- if (cpu->interrupt_request & CPU_INTERRUPT_INIT) {
+ if (cpu_test_interrupt(cpu, CPU_INTERRUPT_INIT)) {
nvmm_cpu_synchronize_state(cpu);
do_cpu_init(x86_cpu);
/* set int/nmi windows back to the reset state */
}
- if (cpu->interrupt_request & CPU_INTERRUPT_POLL) {
- cpu->interrupt_request &= ~CPU_INTERRUPT_POLL;
+ if (cpu_test_interrupt(cpu, CPU_INTERRUPT_POLL)) {
+ cpu_reset_interrupt(cpu, CPU_INTERRUPT_POLL);
apic_poll_irq(x86_cpu->apic_state);
}
- if (((cpu->interrupt_request & CPU_INTERRUPT_HARD) &&
+ if ((cpu_test_interrupt(cpu, CPU_INTERRUPT_HARD) &&
(env->eflags & IF_MASK)) ||
- (cpu->interrupt_request & CPU_INTERRUPT_NMI)) {
+ cpu_test_interrupt(cpu, CPU_INTERRUPT_NMI)) {
cpu->halted = false;
}
- if (cpu->interrupt_request & CPU_INTERRUPT_SIPI) {
+ if (cpu_test_interrupt(cpu, CPU_INTERRUPT_SIPI)) {
nvmm_cpu_synchronize_state(cpu);
do_cpu_sipi(x86_cpu);
}
- if (cpu->interrupt_request & CPU_INTERRUPT_TPR) {
- cpu->interrupt_request &= ~CPU_INTERRUPT_TPR;
+ if (cpu_test_interrupt(cpu, CPU_INTERRUPT_TPR)) {
+ cpu_reset_interrupt(cpu, CPU_INTERRUPT_TPR);
nvmm_cpu_synchronize_state(cpu);
apic_handle_tpr_access_report(x86_cpu->apic_state, env->eip,
env->tpr_access_type);
@@ -727,9 +732,9 @@ nvmm_vcpu_loop(CPUState *cpu)
* Inner VCPU loop.
*/
do {
- if (cpu->accel->dirty) {
+ if (cpu->vcpu_dirty) {
nvmm_set_registers(cpu);
- cpu->accel->dirty = false;
+ cpu->vcpu_dirty = false;
}
if (qcpu->stop) {
@@ -741,7 +746,8 @@ nvmm_vcpu_loop(CPUState *cpu)
nvmm_vcpu_pre_run(cpu);
- if (qatomic_read(&cpu->exit_request)) {
+ /* Corresponding store-release is in cpu_exit. */
+ if (qatomic_load_acquire(&cpu->exit_request)) {
#if NVMM_USER_VERSION >= 2
nvmm_vcpu_stop(vcpu);
#else
@@ -749,8 +755,6 @@ nvmm_vcpu_loop(CPUState *cpu)
#endif
}
- /* Read exit_request before the kernel reads the immediate exit flag */
- smp_rmb();
ret = nvmm_vcpu_run(mach, vcpu);
if (ret == -1) {
error_report("NVMM: Failed to exec a virtual processor,"
@@ -816,8 +820,6 @@ nvmm_vcpu_loop(CPUState *cpu)
cpu_exec_end(cpu);
bql_lock();
- qatomic_set(&cpu->exit_request, false);
-
return ret < 0;
}
@@ -827,32 +829,32 @@ static void
do_nvmm_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data arg)
{
nvmm_get_registers(cpu);
- cpu->accel->dirty = true;
+ cpu->vcpu_dirty = true;
}
static void
do_nvmm_cpu_synchronize_post_reset(CPUState *cpu, run_on_cpu_data arg)
{
nvmm_set_registers(cpu);
- cpu->accel->dirty = false;
+ cpu->vcpu_dirty = false;
}
static void
do_nvmm_cpu_synchronize_post_init(CPUState *cpu, run_on_cpu_data arg)
{
nvmm_set_registers(cpu);
- cpu->accel->dirty = false;
+ cpu->vcpu_dirty = false;
}
static void
do_nvmm_cpu_synchronize_pre_loadvm(CPUState *cpu, run_on_cpu_data arg)
{
- cpu->accel->dirty = true;
+ cpu->vcpu_dirty = true;
}
void nvmm_cpu_synchronize_state(CPUState *cpu)
{
- if (!cpu->accel->dirty) {
+ if (!cpu->vcpu_dirty) {
run_on_cpu(cpu, do_nvmm_cpu_synchronize_state, RUN_ON_CPU_NULL);
}
}
@@ -982,7 +984,7 @@ nvmm_init_vcpu(CPUState *cpu)
}
}
- qcpu->dirty = true;
+ qcpu->vcpu_dirty = true;
cpu->accel = qcpu;
return 0;
@@ -1153,7 +1155,7 @@ static struct RAMBlockNotifier nvmm_ram_notifier = {
/* -------------------------------------------------------------------------- */
static int
-nvmm_accel_init(MachineState *ms)
+nvmm_accel_init(AccelState *as, MachineState *ms)
{
int ret, err;
@@ -1193,14 +1195,8 @@ nvmm_accel_init(MachineState *ms)
return 0;
}
-int
-nvmm_enabled(void)
-{
- return nvmm_allowed;
-}
-
static void
-nvmm_accel_class_init(ObjectClass *oc, void *data)
+nvmm_accel_class_init(ObjectClass *oc, const void *data)
{
AccelClass *ac = ACCEL_CLASS(oc);
ac->name = "NVMM";
@@ -1214,10 +1210,33 @@ static const TypeInfo nvmm_accel_type = {
.class_init = nvmm_accel_class_init,
};
+static void nvmm_cpu_instance_init(CPUState *cs)
+{
+ X86CPU *cpu = X86_CPU(cs);
+
+ host_cpu_instance_init(cpu);
+}
+
+static void nvmm_cpu_accel_class_init(ObjectClass *oc, const void *data)
+{
+ AccelCPUClass *acc = ACCEL_CPU_CLASS(oc);
+
+ acc->cpu_instance_init = nvmm_cpu_instance_init;
+}
+
+static const TypeInfo nvmm_cpu_accel_type = {
+ .name = ACCEL_CPU_NAME("nvmm"),
+
+ .parent = TYPE_ACCEL_CPU,
+ .class_init = nvmm_cpu_accel_class_init,
+ .abstract = true,
+};
+
static void
nvmm_type_init(void)
{
type_register_static(&nvmm_accel_type);
+ type_register_static(&nvmm_cpu_accel_type);
}
type_init(nvmm_type_init);