On 8 November 2018 at 10:29, Dongjiu Geng <gengdongjiu@xxxxxxxxxx> wrote: > Add SIGBUS signal handler. In this handler, it checks the SIGBUS type, > translates the host VA delivered by host to guest PA, then fill this PA > to guest APEI GHES memory, then notify guest according to the SIGBUS type. > There are two kinds of SIGBUS that QEMU needs to handle, which are > BUS_MCEERR_AO and BUS_MCEERR_AR. > > If guest accesses the poisoned memory, it generates Synchronous External > Abort(SEA). Then host kernel gets an APEI notification and call memory_failure() > to unmapped the affected page from the guest's stage 2, finally return > to guest. > > Guest continues to access PG_hwpoison page, it will trap to KVM as stage2 fault, > then a SIGBUS_MCEERR_AR synchronous signal is delivered to Qemu, Qemu record this > error into guest APEI GHES memory and notify guest using Synchronous-External-Abort(SEA). > > Suggested-by: James Morse <james.morse@xxxxxxx> > Signed-off-by: Dongjiu Geng <gengdongjiu@xxxxxxxxxx> > --- > Address James's comments to record CPER and notify guest for SIGBUS signal handling. > Shown some discussion in [1]. > > [1]: > https://lkml.org/lkml/2017/2/27/246 > https://lkml.org/lkml/2017/9/14/241 > https://lkml.org/lkml/2017/9/22/499 > --- > > +void kvm_arch_on_sigbus_vcpu(CPUState *c, int code, void *addr) > +{ > + ram_addr_t ram_addr; > + hwaddr paddr; > + > + assert(code == BUS_MCEERR_AR || code == BUS_MCEERR_AO); > + if (addr) { > + ram_addr = qemu_ram_addr_from_host(addr); > + if (ram_addr != RAM_ADDR_INVALID && > + kvm_physical_memory_addr_from_host(c->kvm_state, addr, &paddr)) { > + kvm_hwpoison_page_add(ram_addr); > + if (code == BUS_MCEERR_AR) { > + kvm_cpu_synchronize_state(c); > + if (ghes_record_errors(ACPI_HEST_NOTIFY_SEA, paddr)) { > + kvm_inject_arm_sea(c); > + } else { > + fprintf(stderr, "failed to record the error\n"); > + } Shouldn't there be something in here to say "only report this error to the guest if we are actually reporting RAS errors to the guest" ? > + } > + return; > + } > + fprintf(stderr, "Hardware memory error for memory used by " > + "QEMU itself instead of guest system!\n"); > + } > + > + if (code == BUS_MCEERR_AR) { > + fprintf(stderr, "Hardware memory error!\n"); > + exit(1); > + } > +} > + > /* C6.6.29 BRK instruction */ > static const uint32_t brk_insn = 0xd4200000; thanks -- PMM