aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorHuang Ying <ying.huang@intel.com>2010-10-08 04:24:15 -0400
committerAvi Kivity <avi@redhat.com>2010-10-24 04:53:15 -0400
commit77db5cbd29b7cb0e0fb4fd146e7f7ac2831a025a (patch)
tree1ea1aa2e677ed92f4ce2ec62920a6d7239b005aa /arch/x86
parent5854dbca9b235f8cdd414a0961018763d2d5bf77 (diff)
KVM: MCE: Send SRAR SIGBUS directly
Originally, SRAR SIGBUS is sent to QEMU-KVM via touching the poisoned page. But commit 96054569190bdec375fe824e48ca1f4e3b53dd36 prevents the signal from being sent. So now the signal is sent via force_sig_info_fault directly. [marcelo: use send_sig_info instead] Reported-by: Dean Nelson <dnelson@redhat.com> Signed-off-by: Huang Ying <ying.huang@intel.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/kvm/mmu.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index eb65b9c5ea40..908ea5464a51 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -2251,22 +2251,24 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write,
2251 return pt_write; 2251 return pt_write;
2252} 2252}
2253 2253
2254static void kvm_send_hwpoison_signal(struct kvm *kvm, gfn_t gfn) 2254static void kvm_send_hwpoison_signal(unsigned long address, struct task_struct *tsk)
2255{ 2255{
2256 char buf[1]; 2256 siginfo_t info;
2257 void __user *hva; 2257
2258 int r; 2258 info.si_signo = SIGBUS;
2259 info.si_errno = 0;
2260 info.si_code = BUS_MCEERR_AR;
2261 info.si_addr = (void __user *)address;
2262 info.si_addr_lsb = PAGE_SHIFT;
2259 2263
2260 /* Touch the page, so send SIGBUS */ 2264 send_sig_info(SIGBUS, &info, tsk);
2261 hva = (void __user *)gfn_to_hva(kvm, gfn);
2262 r = copy_from_user(buf, hva, 1);
2263} 2265}
2264 2266
2265static int kvm_handle_bad_page(struct kvm *kvm, gfn_t gfn, pfn_t pfn) 2267static int kvm_handle_bad_page(struct kvm *kvm, gfn_t gfn, pfn_t pfn)
2266{ 2268{
2267 kvm_release_pfn_clean(pfn); 2269 kvm_release_pfn_clean(pfn);
2268 if (is_hwpoison_pfn(pfn)) { 2270 if (is_hwpoison_pfn(pfn)) {
2269 kvm_send_hwpoison_signal(kvm, gfn); 2271 kvm_send_hwpoison_signal(gfn_to_hva(kvm, gfn), current);
2270 return 0; 2272 return 0;
2271 } else if (is_fault_pfn(pfn)) 2273 } else if (is_fault_pfn(pfn))
2272 return -EFAULT; 2274 return -EFAULT;