All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: Gonglei <arei.gonglei@huawei.com>, qemu-devel@nongnu.org
Cc: peter.huangpeng@huawei.com, kevin@koconnor.net,
	ehabkost@redhat.com, rth@twiddle.net
Subject: Re: [Qemu-devel] [PATCH] rtc: introduce nmi disable bit handler for cmos
Date: Mon, 14 Dec 2015 10:56:41 +0100	[thread overview]
Message-ID: <566E9259.2010404@redhat.com> (raw)
In-Reply-To: <1449926146-14828-1-git-send-email-arei.gonglei@huawei.com>



On 12/12/2015 14:15, Gonglei wrote:
> The Non-Maskable Interrupt (NMI) Enable bit is 0x80 bit of
> Port 0x70 (and its aliases). This bit must be 0b to enable
> the hardware chipset to send a Non-Maskable Interrupt. When
> set to a 1b, NMI's are disabled. This bit is commonly accessed
> by applications, BIOS, and even the operating system since it is
> used to block NMI assertions when sensitive code is executing.
> 
> Currently, QEMU do no not handle the bit, means Qemu cannot
> block NMI occur, sometimes maybe cause a race between the CMOS
> read/write and the NMI handler. If you are setting the CMOS clock
> or reading CMOS RAM and an NMI occurs, Bad values could be written
> to or read from the CMOS RAM, or the NMI operation might not
> occur correctly.
> 
> This patch introduce nmi disable bit handler to fix the problem
> and make the emulated CMOS like the real hardware.

I think that this only works with -machine kernel_irqchip=off, however.
 You would have to add a new bit to struct kvm_vcpu_events, which could
for example replace nmi.pad.

>  Please refer to:
>    https://lists.gnu.org/archive/html/qemu-devel/2015-11/msg00616.html
>  
>  Note: We can't reproduce the problem, what a pity :(
>  I holp the patch can fix it. Please review, thanks!

The effect of the patch could be tested with kvm-unit-tests.

Thanks,

Paolo

>  hw/i386/kvm/apic.c                  |  4 +++-
>  hw/timer/mc146818rtc.c              | 11 +++++++++++
>  include/hw/timer/mc146818rtc_regs.h |  3 +++
>  include/sysemu/sysemu.h             |  1 +
>  target-i386/kvm.c                   |  4 ++--
>  vl.c                                |  1 +
>  6 files changed, 21 insertions(+), 3 deletions(-)
> 
> diff --git a/hw/i386/kvm/apic.c b/hw/i386/kvm/apic.c
> index 5b47056..deea49f 100644
> --- a/hw/i386/kvm/apic.c
> +++ b/hw/i386/kvm/apic.c
> @@ -12,6 +12,7 @@
>  #include "hw/i386/apic_internal.h"
>  #include "hw/pci/msi.h"
>  #include "sysemu/kvm.h"
> +#include "sysemu/sysemu.h"
>  
>  static inline void kvm_apic_set_reg(struct kvm_lapic_state *kapic,
>                                      int reg_id, uint32_t val)
> @@ -132,7 +133,8 @@ static void do_inject_external_nmi(void *data)
>      cpu_synchronize_state(cpu);
>  
>      lvt = s->lvt[APIC_LVT_LINT1];
> -    if (!(lvt & APIC_LVT_MASKED) && ((lvt >> 8) & 7) == APIC_DM_NMI) {
> +    if (!nmi_disabled && (lvt & APIC_LVT_MASKED)
> +        && ((lvt >> 8) & 7) == APIC_DM_NMI) {
>          ret = kvm_vcpu_ioctl(cpu, KVM_NMI);
>          if (ret < 0) {
>              fprintf(stderr, "KVM: injection failed, NMI lost (%s)\n",
> diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c
> index a9f0efd..aaa8b4e 100644
> --- a/hw/timer/mc146818rtc.c
> +++ b/hw/timer/mc146818rtc.c
> @@ -389,6 +389,17 @@ static void cmos_ioport_write(void *opaque, hwaddr addr,
>      RTCState *s = opaque;
>  
>      if ((addr & 1) == 0) {
> +        /*
> +         * The Non-Maskable Interrupt (NMI) Enable bit is 0x80 bit of
> +         * Port 0x70 (and its aliases). This bit must be 0b to enable
> +         * the hardware chipset to send a Non-Maskable Interrupt. When
> +         * set to a 1b, NMI's are disabled. This bit is commonly accessed
> +         * by applications, BIOS, and even the operating system since it is
> +         * used to block NMI assertions when sensitive code is executing.
> +         */
> +        nmi_disabled = !!(data & NMI_DISABLE_BIT);
> +        CMOS_DPRINTF("cmos: nmi_disabled=%s\n",
> +                     nmi_disabled ? "true" : "false");
>          s->cmos_index = data & 0x7f;
>      } else {
>          CMOS_DPRINTF("cmos: write index=0x%02x val=0x%02" PRIx64 "\n",
> diff --git a/include/hw/timer/mc146818rtc_regs.h b/include/hw/timer/mc146818rtc_regs.h
> index ccdee42..175249f 100644
> --- a/include/hw/timer/mc146818rtc_regs.h
> +++ b/include/hw/timer/mc146818rtc_regs.h
> @@ -64,4 +64,7 @@
>  #define REG_C_AF   0x20
>  #define REG_C_MASK 0x70
>  
> +/* PORT_CMOS_INDEX nmi disable bit */
> +#define NMI_DISABLE_BIT 0x80
> +
>  #endif
> diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
> index 3bb8897..a5b2342 100644
> --- a/include/sysemu/sysemu.h
> +++ b/include/sysemu/sysemu.h
> @@ -177,6 +177,7 @@ extern uint8_t qemu_extra_params_fw[2];
>  extern QEMUClockType rtc_clock;
>  extern const char *mem_path;
>  extern int mem_prealloc;
> +extern bool nmi_disabled;
>  
>  #define MAX_NODES 128
>  #define NUMA_NODE_UNASSIGNED MAX_NODES
> diff --git a/target-i386/kvm.c b/target-i386/kvm.c
> index 6dc9846..abbd65b 100644
> --- a/target-i386/kvm.c
> +++ b/target-i386/kvm.c
> @@ -2456,9 +2456,9 @@ void kvm_arch_pre_run(CPUState *cpu, struct kvm_run *run)
>      CPUX86State *env = &x86_cpu->env;
>      int ret;
>  
> -    /* Inject NMI */
> +    /* Inject NMI Or SMI */
>      if (cpu->interrupt_request & (CPU_INTERRUPT_NMI | CPU_INTERRUPT_SMI)) {
> -        if (cpu->interrupt_request & CPU_INTERRUPT_NMI) {
> +        if (!nmi_disabled && (cpu->interrupt_request & CPU_INTERRUPT_NMI)) {
>              qemu_mutex_lock_iothread();
>              cpu->interrupt_request &= ~CPU_INTERRUPT_NMI;
>              qemu_mutex_unlock_iothread();
> diff --git a/vl.c b/vl.c
> index 4211ff1..ff5b06f 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -185,6 +185,7 @@ bool boot_strict;
>  uint8_t *boot_splash_filedata;
>  size_t boot_splash_filedata_size;
>  uint8_t qemu_extra_params_fw[2];
> +bool nmi_disabled;
>  
>  int icount_align_option;
>  
> 

  reply	other threads:[~2015-12-14  9:56 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-12-12 13:15 [Qemu-devel] [PATCH] rtc: introduce nmi disable bit handler for cmos Gonglei
2015-12-14  9:56 ` Paolo Bonzini [this message]
2015-12-14 12:49   ` Gonglei (Arei)
2015-12-14 12:51     ` Paolo Bonzini
2015-12-14 13:27       ` Gonglei (Arei)
2015-12-14 13:37         ` Paolo Bonzini
2015-12-15  0:58           ` Gonglei (Arei)
2015-12-15  9:34           ` Gonglei (Arei)
2015-12-15 10:43             ` Paolo Bonzini
2015-12-15 18:53               ` Radim Krcmar
2015-12-16  8:26                 ` Gonglei (Arei)
2015-12-16  8:51                 ` Paolo Bonzini
2015-12-16 10:28                   ` Gonglei (Arei)
2015-12-16 12:14                     ` Paolo Bonzini
2015-12-17  7:17                       ` Gonglei (Arei)
2015-12-17  8:37                         ` Paolo Bonzini
2015-12-17  9:04                           ` Gonglei (Arei)
2015-12-14 18:16 ` Eduardo Habkost
2015-12-15  1:00   ` Gonglei (Arei)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=566E9259.2010404@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=arei.gonglei@huawei.com \
    --cc=ehabkost@redhat.com \
    --cc=kevin@koconnor.net \
    --cc=peter.huangpeng@huawei.com \
    --cc=qemu-devel@nongnu.org \
    --cc=rth@twiddle.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.