#include <linux/kvm_host.h>
 #include <linux/io.h>
 #include <linux/hugetlb.h>
+#include <linux/sched/signal.h>
 #include <trace/events/kvm.h>
 #include <asm/pgalloc.h>
 #include <asm/cacheflush.h>
        __coherent_cache_guest_page(vcpu, pfn, size);
 }
 
+static void kvm_send_hwpoison_signal(unsigned long address,
+                                    struct vm_area_struct *vma)
+{
+       siginfo_t info;
+
+       info.si_signo   = SIGBUS;
+       info.si_errno   = 0;
+       info.si_code    = BUS_MCEERR_AR;
+       info.si_addr    = (void __user *)address;
+
+       if (is_vm_hugetlb_page(vma))
+               info.si_addr_lsb = huge_page_shift(hstate_vma(vma));
+       else
+               info.si_addr_lsb = PAGE_SHIFT;
+
+       send_sig_info(SIGBUS, &info, current);
+}
+
 static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
                          struct kvm_memory_slot *memslot, unsigned long hva,
                          unsigned long fault_status)
        smp_rmb();
 
        pfn = gfn_to_pfn_prot(kvm, gfn, write_fault, &writable);
+       if (pfn == KVM_PFN_ERR_HWPOISON) {
+               kvm_send_hwpoison_signal(hva, vma);
+               return 0;
+       }
        if (is_error_noslot_pfn(pfn))
                return -EFAULT;