diff options
-rw-r--r-- | arch/x86/kvm/mmu.c | 18 |
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 | ||
2254 | static void kvm_send_hwpoison_signal(struct kvm *kvm, gfn_t gfn) | 2254 | static 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 | ||
2265 | static int kvm_handle_bad_page(struct kvm *kvm, gfn_t gfn, pfn_t pfn) | 2267 | static 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; |