@@ -690,12 +690,15 @@ static int whpx_handle_portio(CPUState *cpu,
static int whpx_handle_halt(CPUState *cpu)
{
struct CPUX86State *env = (CPUArchState *)(cpu->env_ptr);
+ int interrupt_request;
int ret = 0;
qemu_mutex_lock_iothread();
- if (!((cpu->interrupt_request & CPU_INTERRUPT_HARD) &&
+ interrupt_request = atomic_read(&cpu->interrupt_request);
+
+ if (!((interrupt_request & CPU_INTERRUPT_HARD) &&
(env->eflags & IF_MASK)) &&
- !(cpu->interrupt_request & CPU_INTERRUPT_NMI)) {
+ !(interrupt_request & CPU_INTERRUPT_NMI)) {
cpu->exception_index = EXCP_HLT;
cpu->halted = true;
ret = 1;
@@ -718,6 +721,7 @@ static void whpx_vcpu_pre_run(CPUState *cpu)
UINT32 reg_count = 0;
WHV_REGISTER_VALUE reg_values[3];
WHV_REGISTER_NAME reg_names[3];
+ int interrupt_request;
memset(&new_int, 0, sizeof(new_int));
memset(reg_values, 0, sizeof(reg_values));
@@ -725,16 +729,17 @@ static void whpx_vcpu_pre_run(CPUState *cpu)
qemu_mutex_lock_iothread();
/* Inject NMI */
+ interrupt_request = atomic_read(&cpu->interrupt_request);
if (!vcpu->interruption_pending &&
- cpu->interrupt_request & (CPU_INTERRUPT_NMI | CPU_INTERRUPT_SMI)) {
- if (cpu->interrupt_request & CPU_INTERRUPT_NMI) {
+ interrupt_request & (CPU_INTERRUPT_NMI | CPU_INTERRUPT_SMI)) {
+ if (interrupt_request & CPU_INTERRUPT_NMI) {
cpu_reset_interrupt(cpu, CPU_INTERRUPT_NMI);
vcpu->interruptable = false;
new_int.InterruptionType = WHvX64PendingNmi;
new_int.InterruptionPending = 1;
new_int.InterruptionVector = 2;
}
- if (cpu->interrupt_request & CPU_INTERRUPT_SMI) {
+ if (interrupt_request & CPU_INTERRUPT_SMI) {
cpu_reset_interrupt(cpu, CPU_INTERRUPT_SMI);
}
}
@@ -743,12 +748,13 @@ static void whpx_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)) {
- if ((cpu->interrupt_request & CPU_INTERRUPT_INIT) &&
+ interrupt_request = atomic_read(&cpu->interrupt_request);
+ if (interrupt_request & (CPU_INTERRUPT_INIT | CPU_INTERRUPT_TPR)) {
+ if ((interrupt_request & CPU_INTERRUPT_INIT) &&
!(env->hflags & HF_SMM_MASK)) {
cpu->exit_request = 1;
}
- if (cpu->interrupt_request & CPU_INTERRUPT_TPR) {
+ if (interrupt_request & CPU_INTERRUPT_TPR) {
cpu->exit_request = 1;
}
}
@@ -757,7 +763,7 @@ static void whpx_vcpu_pre_run(CPUState *cpu)
if (!vcpu->interruption_pending &&
vcpu->interruptable && (env->eflags & IF_MASK)) {
assert(!new_int.InterruptionPending);
- if (cpu->interrupt_request & CPU_INTERRUPT_HARD) {
+ if (interrupt_request & CPU_INTERRUPT_HARD) {
cpu_reset_interrupt(cpu, CPU_INTERRUPT_HARD);
irq = cpu_get_pic_interrupt(env);
if (irq >= 0) {
@@ -787,7 +793,7 @@ static void whpx_vcpu_pre_run(CPUState *cpu)
/* Update the state of the interrupt delivery notification */
if (!vcpu->window_registered &&
- cpu->interrupt_request & CPU_INTERRUPT_HARD) {
+ atomic_read(&cpu->interrupt_request) & CPU_INTERRUPT_HARD) {
reg_values[reg_count].DeliverabilityNotifications.InterruptNotification
= 1;
vcpu->window_registered = 1;
@@ -840,8 +846,9 @@ static void whpx_vcpu_process_async_events(CPUState *cpu)
struct CPUX86State *env = (CPUArchState *)(cpu->env_ptr);
X86CPU *x86_cpu = X86_CPU(cpu);
struct whpx_vcpu *vcpu = get_whpx_vcpu(cpu);
+ int interrupt_request;
- if ((cpu->interrupt_request & CPU_INTERRUPT_INIT) &&
+ if ((atomic_read(&cpu->interrupt_request) & CPU_INTERRUPT_INIT) &&
!(env->hflags & HF_SMM_MASK)) {
do_cpu_init(x86_cpu);
@@ -849,25 +856,26 @@ static void whpx_vcpu_process_async_events(CPUState *cpu)
vcpu->interruptable = true;
}
- if (cpu->interrupt_request & CPU_INTERRUPT_POLL) {
+ if (atomic_read(&cpu->interrupt_request) & CPU_INTERRUPT_POLL) {
cpu_reset_interrupt(cpu, CPU_INTERRUPT_POLL);
apic_poll_irq(x86_cpu->apic_state);
}
- if (((cpu->interrupt_request & CPU_INTERRUPT_HARD) &&
+ interrupt_request = atomic_read(&cpu->interrupt_request);
+ if (((interrupt_request & CPU_INTERRUPT_HARD) &&
(env->eflags & IF_MASK)) ||
- (cpu->interrupt_request & CPU_INTERRUPT_NMI)) {
+ (interrupt_request & CPU_INTERRUPT_NMI)) {
cpu->halted = false;
}
- if (cpu->interrupt_request & CPU_INTERRUPT_SIPI) {
+ if (interrupt_request & CPU_INTERRUPT_SIPI) {
if (!cpu->vcpu_dirty) {
whpx_get_registers(cpu);
}
do_cpu_sipi(x86_cpu);
}
- if (cpu->interrupt_request & CPU_INTERRUPT_TPR) {
+ if (atomic_read(&cpu->interrupt_request) & CPU_INTERRUPT_TPR) {
cpu_reset_interrupt(cpu, CPU_INTERRUPT_TPR);
if (!cpu->vcpu_dirty) {
whpx_get_registers(cpu);
@@ -1350,7 +1358,7 @@ static void whpx_memory_init(void)
static void whpx_handle_interrupt(CPUState *cpu, int mask)
{
- cpu->interrupt_request |= mask;
+ atomic_or(&cpu->interrupt_request, mask);
if (!qemu_cpu_is_self(cpu)) {
qemu_cpu_kick(cpu);
I am not familiar with whpx, so I opted for the safe (and slow) route of performing probably many unnecessary atomic_reads. Cc: Richard Henderson <rth@twiddle.net> Cc: Eduardo Habkost <ehabkost@redhat.com> Signed-off-by: Emilio G. Cota <cota@braap.org> --- target/i386/whpx-all.c | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-)