From: William Roche <william.roche@xxxxxxxxxx> When an entire large page is impacted by an error (hugetlbfs case), report better the size and location of this large memory hole, so give a warning message when this page is first hit: Memory error: Loosing a large page (size: X) at QEMU addr Y and GUEST addr Z Signed-off-by: William Roche <william.roche@xxxxxxxxxx> --- accel/kvm/kvm-all.c | 9 ++++++++- include/sysemu/kvm_int.h | 4 +++- target/arm/kvm.c | 2 +- target/i386/kvm/kvm.c | 2 +- 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index 6dd06f5edf..a572437115 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -1284,7 +1284,7 @@ static void kvm_unpoison_all(void *param) } } -void kvm_hwpoison_page_add(ram_addr_t ram_addr) +void kvm_hwpoison_page_add(ram_addr_t ram_addr, void *ha, hwaddr gpa) { HWPoisonPage *page; size_t sz = qemu_ram_pagesize_from_addr(ram_addr); @@ -1301,6 +1301,13 @@ void kvm_hwpoison_page_add(ram_addr_t ram_addr) page->ram_addr = ram_addr; page->page_size = sz; QLIST_INSERT_HEAD(&hwpoison_page_list, page, list); + + if (sz > TARGET_PAGE_SIZE) { + gpa = ROUND_DOWN(gpa, sz); + ha = (void *)ROUND_DOWN((uint64_t)ha, sz); + warn_report("Memory error: Loosing a large page (size: %zu) " + "at QEMU addr %p and GUEST addr 0x%" HWADDR_PRIx, sz, ha, gpa); + } } bool kvm_hwpoisoned_mem(void) diff --git a/include/sysemu/kvm_int.h b/include/sysemu/kvm_int.h index a1e72763da..ee34f1d225 100644 --- a/include/sysemu/kvm_int.h +++ b/include/sysemu/kvm_int.h @@ -178,10 +178,12 @@ void kvm_set_max_memslot_size(hwaddr max_slot_size); * * Parameters: * @ram_addr: the address in the RAM for the poisoned page + * @hva: host virtual address aka QEMU addr + * @gpa: guest physical address aka GUEST addr * * Add a poisoned page to the list * * Return: None. */ -void kvm_hwpoison_page_add(ram_addr_t ram_addr); +void kvm_hwpoison_page_add(ram_addr_t ram_addr, void *hva, hwaddr gpa); #endif diff --git a/target/arm/kvm.c b/target/arm/kvm.c index f1f1b5b375..aae66dba41 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -2359,7 +2359,7 @@ void kvm_arch_on_sigbus_vcpu(CPUState *c, int code, void *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); + kvm_hwpoison_page_add(ram_addr, addr, paddr); /* * If this is a BUS_MCEERR_AR, we know we have been called * synchronously from the vCPU thread, so we can easily diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c index fd9f198892..fd7cd7008e 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c @@ -753,7 +753,7 @@ void kvm_arch_on_sigbus_vcpu(CPUState *c, int code, void *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); + kvm_hwpoison_page_add(ram_addr, addr, paddr); kvm_mce_inject(cpu, paddr, code); /* -- 2.43.5