From nobody Thu Nov 6 01:12:42 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1538298847767691.2281015827788; Sun, 30 Sep 2018 02:14:07 -0700 (PDT) Received: from localhost ([::1]:54571 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g6Xni-00082v-9q for importer@patchew.org; Sun, 30 Sep 2018 05:14:06 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41904) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g6WsI-0003BV-Bv for qemu-devel@nongnu.org; Sun, 30 Sep 2018 04:14:47 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g6WsB-0001GY-H9 for qemu-devel@nongnu.org; Sun, 30 Sep 2018 04:14:43 -0400 Received: from mail-wr1-x42a.google.com ([2a00:1450:4864:20::42a]:46945) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1g6WsA-00011J-Qv for qemu-devel@nongnu.org; Sun, 30 Sep 2018 04:14:39 -0400 Received: by mail-wr1-x42a.google.com with SMTP id z3-v6so10452763wrr.13 for ; Sun, 30 Sep 2018 01:14:18 -0700 (PDT) Received: from 640k.lan (94-36-187-248.adsl-ull.clienti.tiscali.it. [94.36.187.248]) by smtp.gmail.com with ESMTPSA id u76-v6sm11369194wmd.10.2018.09.30.01.14.15 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 30 Sep 2018 01:14:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:subject:date:message-id:in-reply-to:references; bh=aVI0vNSrYleKMPeDtvTEEZqeH83kzoX533J0ptW6dkw=; b=JLTEV+h3gA8gJeU5Lk2H8Cf5Pzalke7t9Woj1l8LI7Kchz7EjzN7wB7nTTOx972poD yAFKckX6rv46ziTigDDeSgeiSJM0nu6XIdHq3isj61beZkNUakG342y1aMNRs5eh5mK6 N3SG44lSxoax8gqLm4/3NgHtJdAPu7UpsrSYKcJvXQSDgrTOgJ8wpyawGna7oTXGfPJ8 i83ytE2ega1e9Cyz3QGCvnD67veR7rvZlqzq7lb/FYG6lOrmIgl1irFk2c+qpIVrk7Ls x0oDvgJF1N1OrnUuCQa/Z4HWBOz0AncOjWFQcOBl6AIcWqqisRAqXMmLWm6c2u84slvc 0vGQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:subject:date:message-id :in-reply-to:references; bh=aVI0vNSrYleKMPeDtvTEEZqeH83kzoX533J0ptW6dkw=; b=feN6sVIz4+1jg6Hvxd6/ExbHlSI3wWkiFkbj7luP07joNKUOkuKlL7rdzmYZmr7Zm2 AXJ0ls6CmX1mYqjm7XhCaaY5YIiMR7xGReQtRLH3hlvrs4rHmB1kLgTwJX1u8guSMa2C Axi6NlKbVXLH6TEIc0WyxfERI3s4Dj3xq/x61j1XCSXBrPXqXeFZCoTCG5nrAtz2zt2Q c/0UCfxFFbMMIGocjSq45MQi93N8iq4yeMQXLuEm27xSZAV9ka6QDRsM89ieKrODSWzZ Eke6stPabVOYOFtCl9nP0EWzC0/JMaW7sguO9u2azcRlLDKmh4njEOjVbm5J57A3hNwa tp1A== X-Gm-Message-State: ABuFfoi+lVMwydOtblwlFg6GNeJ8NH7SKqiKhs0ese+aOIAXrV+CImSp hXgUy+FUIYP34u03vVVCGJGf2eJF X-Google-Smtp-Source: ACcGV60PE3DBSAGzJFP6jrrVePn0R1ryO9xJXXOkh0jE7m1p14nVgcHtV8JphG+RmPiXoA4j04bzIA== X-Received: by 2002:adf:9206:: with SMTP id 6-v6mr448184wrj.275.1538295256816; Sun, 30 Sep 2018 01:14:16 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Sun, 30 Sep 2018 10:12:53 +0200 Message-Id: <1538295197-23704-56-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1538295197-23704-1-git-send-email-pbonzini@redhat.com> References: <1538295197-23704-1-git-send-email-pbonzini@redhat.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::42a Subject: [Qemu-devel] [PULL 55/79] target/i386: unify masking of interrupts X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDMRC_1 RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Interrupt handling depends on various flags in env->hflags or env->hflags2, and the exact detail were not exactly replicated between x86_cpu_has_work and x86_cpu_exec_interrupt. Create a new function that extracts the highest-priority non-masked interrupt, and use it in both functions. Signed-off-by: Paolo Bonzini --- target/i386/cpu.c | 51 ++++++++++++++++++----- target/i386/cpu.h | 1 + target/i386/seg_helper.c | 106 ++++++++++++++++++++++---------------------= ---- 3 files changed, 91 insertions(+), 67 deletions(-) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index f24295e..c88876d 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -5429,20 +5429,51 @@ static void x86_cpu_synchronize_from_tb(CPUState *c= s, TranslationBlock *tb) cpu->env.eip =3D tb->pc - tb->cs_base; } =20 -static bool x86_cpu_has_work(CPUState *cs) +int x86_cpu_pending_interrupt(CPUState *cs, int interrupt_request) { X86CPU *cpu =3D X86_CPU(cs); CPUX86State *env =3D &cpu->env; =20 - return ((cs->interrupt_request & (CPU_INTERRUPT_HARD | - CPU_INTERRUPT_POLL)) && - (env->eflags & IF_MASK)) || - (cs->interrupt_request & (CPU_INTERRUPT_NMI | - CPU_INTERRUPT_INIT | - CPU_INTERRUPT_SIPI | - CPU_INTERRUPT_MCE)) || - ((cs->interrupt_request & CPU_INTERRUPT_SMI) && - !(env->hflags & HF_SMM_MASK)); +#if !defined(CONFIG_USER_ONLY) + if (interrupt_request & CPU_INTERRUPT_POLL) { + return CPU_INTERRUPT_POLL; + } +#endif + if (interrupt_request & CPU_INTERRUPT_SIPI) { + return CPU_INTERRUPT_SIPI; + } + + if (env->hflags2 & HF2_GIF_MASK) { + if ((interrupt_request & CPU_INTERRUPT_SMI) && + !(env->hflags & HF_SMM_MASK)) { + return CPU_INTERRUPT_SMI; + } else if ((interrupt_request & CPU_INTERRUPT_NMI) && + !(env->hflags2 & HF2_NMI_MASK)) { + return CPU_INTERRUPT_NMI; + } else if (interrupt_request & CPU_INTERRUPT_MCE) { + return CPU_INTERRUPT_MCE; + } else if ((interrupt_request & CPU_INTERRUPT_HARD) && + (((env->hflags2 & HF2_VINTR_MASK) && + (env->hflags2 & HF2_HIF_MASK)) || + (!(env->hflags2 & HF2_VINTR_MASK) && + (env->eflags & IF_MASK && + !(env->hflags & HF_INHIBIT_IRQ_MASK))))) { + return CPU_INTERRUPT_HARD; +#if !defined(CONFIG_USER_ONLY) + } else if ((interrupt_request & CPU_INTERRUPT_VIRQ) && + (env->eflags & IF_MASK) && + !(env->hflags & HF_INHIBIT_IRQ_MASK)) { + return CPU_INTERRUPT_VIRQ; +#endif + } + } + + return 0; +} + +static bool x86_cpu_has_work(CPUState *cs) +{ + return x86_cpu_pending_interrupt(cs, cs->interrupt_request) !=3D 0; } =20 static void x86_disas_set_info(CPUState *cs, disassemble_info *info) diff --git a/target/i386/cpu.h b/target/i386/cpu.h index b572a8e..227a5d9 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -1485,6 +1485,7 @@ extern struct VMStateDescription vmstate_x86_cpu; */ void x86_cpu_do_interrupt(CPUState *cpu); bool x86_cpu_exec_interrupt(CPUState *cpu, int int_req); +int x86_cpu_pending_interrupt(CPUState *cs, int interrupt_request); =20 int x86_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cpu, int cpuid, void *opaque); diff --git a/target/i386/seg_helper.c b/target/i386/seg_helper.c index d1cbc6e..ba9cc68 100644 --- a/target/i386/seg_helper.c +++ b/target/i386/seg_helper.c @@ -1319,74 +1319,66 @@ bool x86_cpu_exec_interrupt(CPUState *cs, int inter= rupt_request) { X86CPU *cpu =3D X86_CPU(cs); CPUX86State *env =3D &cpu->env; - bool ret =3D false; + int intno; =20 + interrupt_request =3D x86_cpu_pending_interrupt(cs, interrupt_request); + if (!interrupt_request) { + return false; + } + + /* Don't process multiple interrupt requests in a single call. + * This is required to make icount-driven execution deterministic. + */ + switch (interrupt_request) { #if !defined(CONFIG_USER_ONLY) - if (interrupt_request & CPU_INTERRUPT_POLL) { + case CPU_INTERRUPT_POLL: cs->interrupt_request &=3D ~CPU_INTERRUPT_POLL; apic_poll_irq(cpu->apic_state); - /* Don't process multiple interrupt requests in a single call. - This is required to make icount-driven execution deterministic.= */ - return true; - } + break; #endif - if (interrupt_request & CPU_INTERRUPT_SIPI) { + case CPU_INTERRUPT_SIPI: do_cpu_sipi(cpu); - ret =3D true; - } else if (env->hflags2 & HF2_GIF_MASK) { - if ((interrupt_request & CPU_INTERRUPT_SMI) && - !(env->hflags & HF_SMM_MASK)) { - cpu_svm_check_intercept_param(env, SVM_EXIT_SMI, 0, 0); - cs->interrupt_request &=3D ~CPU_INTERRUPT_SMI; - do_smm_enter(cpu); - ret =3D true; - } else if ((interrupt_request & CPU_INTERRUPT_NMI) && - !(env->hflags2 & HF2_NMI_MASK)) { - cpu_svm_check_intercept_param(env, SVM_EXIT_NMI, 0, 0); - cs->interrupt_request &=3D ~CPU_INTERRUPT_NMI; - env->hflags2 |=3D HF2_NMI_MASK; - do_interrupt_x86_hardirq(env, EXCP02_NMI, 1); - ret =3D true; - } else if (interrupt_request & CPU_INTERRUPT_MCE) { - cs->interrupt_request &=3D ~CPU_INTERRUPT_MCE; - do_interrupt_x86_hardirq(env, EXCP12_MCHK, 0); - ret =3D true; - } else if ((interrupt_request & CPU_INTERRUPT_HARD) && - (((env->hflags2 & HF2_VINTR_MASK) && - (env->hflags2 & HF2_HIF_MASK)) || - (!(env->hflags2 & HF2_VINTR_MASK) && - (env->eflags & IF_MASK && - !(env->hflags & HF_INHIBIT_IRQ_MASK))))) { - int intno; - cpu_svm_check_intercept_param(env, SVM_EXIT_INTR, 0, 0); - cs->interrupt_request &=3D ~(CPU_INTERRUPT_HARD | - CPU_INTERRUPT_VIRQ); - intno =3D cpu_get_pic_interrupt(env); - qemu_log_mask(CPU_LOG_TB_IN_ASM, - "Servicing hardware INT=3D0x%02x\n", intno); - do_interrupt_x86_hardirq(env, intno, 1); - /* ensure that no TB jump will be modified as - the program flow was changed */ - ret =3D true; + break; + case CPU_INTERRUPT_SMI: + cpu_svm_check_intercept_param(env, SVM_EXIT_SMI, 0, 0); + cs->interrupt_request &=3D ~CPU_INTERRUPT_SMI; + do_smm_enter(cpu); + break; + case CPU_INTERRUPT_NMI: + cpu_svm_check_intercept_param(env, SVM_EXIT_NMI, 0, 0); + cs->interrupt_request &=3D ~CPU_INTERRUPT_NMI; + env->hflags2 |=3D HF2_NMI_MASK; + do_interrupt_x86_hardirq(env, EXCP02_NMI, 1); + break; + case CPU_INTERRUPT_MCE: + cs->interrupt_request &=3D ~CPU_INTERRUPT_MCE; + do_interrupt_x86_hardirq(env, EXCP12_MCHK, 0); + break; + case CPU_INTERRUPT_HARD: + cpu_svm_check_intercept_param(env, SVM_EXIT_INTR, 0, 0); + cs->interrupt_request &=3D ~(CPU_INTERRUPT_HARD | + CPU_INTERRUPT_VIRQ); + intno =3D cpu_get_pic_interrupt(env); + qemu_log_mask(CPU_LOG_TB_IN_ASM, + "Servicing hardware INT=3D0x%02x\n", intno); + do_interrupt_x86_hardirq(env, intno, 1); + break; #if !defined(CONFIG_USER_ONLY) - } else if ((interrupt_request & CPU_INTERRUPT_VIRQ) && - (env->eflags & IF_MASK) && - !(env->hflags & HF_INHIBIT_IRQ_MASK)) { - int intno; - /* FIXME: this should respect TPR */ - cpu_svm_check_intercept_param(env, SVM_EXIT_VINTR, 0, 0); - intno =3D x86_ldl_phys(cs, env->vm_vmcb + case CPU_INTERRUPT_VIRQ: + /* FIXME: this should respect TPR */ + cpu_svm_check_intercept_param(env, SVM_EXIT_VINTR, 0, 0); + intno =3D x86_ldl_phys(cs, env->vm_vmcb + offsetof(struct vmcb, control.int_vector)); - qemu_log_mask(CPU_LOG_TB_IN_ASM, - "Servicing virtual hardware INT=3D0x%02x\n", int= no); - do_interrupt_x86_hardirq(env, intno, 1); - cs->interrupt_request &=3D ~CPU_INTERRUPT_VIRQ; - ret =3D true; + qemu_log_mask(CPU_LOG_TB_IN_ASM, + "Servicing virtual hardware INT=3D0x%02x\n", intno); + do_interrupt_x86_hardirq(env, intno, 1); + cs->interrupt_request &=3D ~CPU_INTERRUPT_VIRQ; + break; #endif - } } =20 - return ret; + /* Ensure that no TB jump will be modified as the program flow was cha= nged. */ + return true; } =20 void helper_lldt(CPUX86State *env, int selector) --=20 1.8.3.1