From nobody Tue May 7 13:52:40 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1489512118385263.8754749469799; Tue, 14 Mar 2017 10:21:58 -0700 (PDT) Received: from localhost ([::1]:60892 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cnq8u-00089E-4n for importer@patchew.org; Tue, 14 Mar 2017 13:21:52 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57140) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cnq7y-00087k-Gv for qemu-devel@nongnu.org; Tue, 14 Mar 2017 13:20:56 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cnq7t-0003fA-IS for qemu-devel@nongnu.org; Tue, 14 Mar 2017 13:20:54 -0400 Received: from mail-wm0-x244.google.com ([2a00:1450:400c:c09::244]:33143) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1cnq7t-0003eY-9O for qemu-devel@nongnu.org; Tue, 14 Mar 2017 13:20:49 -0400 Received: by mail-wm0-x244.google.com with SMTP id n11so887130wma.0 for ; Tue, 14 Mar 2017 10:20:48 -0700 (PDT) Received: from 640k.lan (94-39-132-181.adsl-ull.clienti.tiscali.it. [94.39.132.181]) by smtp.gmail.com with ESMTPSA id x133sm16256053wme.22.2017.03.14.10.20.46 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 14 Mar 2017 10:20:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id; bh=fhp0jdS3JUhtpQvzRfv2AAjNdsrqRFG3Qm+bYM9U2iM=; b=fV+MHz1C0BLAch3AP86Hqc+D6OLSmLOwwegvTHLFPyYxxuCZ/A+WEfW5VnyMLdVzE8 V9+H54oA/tY+GRE3MS2RC3Vm1xnHK1oCZ+wlV0wWHyyEumi1yTdt9vim5u3HRTgPXCiy Ibgf4e+YFJ9Q/pNa1GbdyopazJsOMbJ6ussgyLxgizVByUvg5ymij5FNLyz2wCcPBZGU wXseLwowz/eIzI5skueR4dbYkZXMpIKY7/OXAL5CbEFrKB45l1unjXESj5fYS/y/L+3s eb+hSLH1jLjgGCcoAEMmTG7lApHP/pDGES8lxPqLIKqicQ6U8u7ocJKI5tPs8lzixxiI wDkg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id; bh=fhp0jdS3JUhtpQvzRfv2AAjNdsrqRFG3Qm+bYM9U2iM=; b=skNpZnGV8MArrNOqM3OogWXVCE3xzQP1Fo2+Zg/6FFywKCeRfvC5yq6N2BxrWgU2cp 66/TXuUFAIJtzifLmemA5GC94sPsw1EPqrF47+XfkTdu3D5djgwPAknrFcxho+fetX8u SWjC4plFSeOd7jj30j1zNY5JG6CuFW0cJMvHRCr95jimED64F61kehCnL/lLgMDq03FC VrQ/a6phy6jwuohv1zN90i6MIQcRRfRgrLYp1XweI/73Q6+Y99/MvutWLDsUQYc/uMnc Ad1qndk8hyxb/kJHtILQ592hVLPaYvNzz8vdWVSi4AadngiTZd3GSwqyDQetTAmUqxBc eq1w== X-Gm-Message-State: AFeK/H3KlwD09UmFwy8NbCTzJ7bUYoK4HA33UN6OgfVDo6fqI2/ntcbPkmOSBFizzqUswg== X-Received: by 10.28.136.68 with SMTP id k65mr16482542wmd.48.1489512047848; Tue, 14 Mar 2017 10:20:47 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Tue, 14 Mar 2017 18:20:45 +0100 Message-Id: <1489512045-49206-1-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.8.3.1 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2a00:1450:400c:c09::244 Subject: [Qemu-devel] [PATCH for 2.9?] hmp: gpa2hva and gpa2hpa hostaddr command X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: dgilbert@redhat.com, armbru@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" These commands are useful when testing machine-check passthrough. gpa2hva is useful to inject a MADV_HWPOISON madvise from gdb, while gpa2hpa is useful to inject an error with the mce-inject kernel module. Signed-off-by: Paolo Bonzini --- Technically a feature, but on the other hand it is pretty much impossible to test without it, and the people testing the feature are using it as an out-of-tree patch. Opinions? hmp-commands.hx | 32 ++++++++++++++++++ monitor.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++= ++++ 2 files changed, 135 insertions(+) diff --git a/hmp-commands.hx b/hmp-commands.hx index 8819281..0aca984 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -526,6 +526,38 @@ Dump 80 16 bit values at the start of the video memory. ETEXI =20 { + .name =3D "gpa2hva", + .args_type =3D "addr:l", + .params =3D "addr", + .help =3D "print the host virtual address corresponding to a= guest physical address", + .cmd =3D hmp_gpa2hva, + }, + +STEXI +@item gpa2hva @var{addr} +@findex gpa2hva +Print the host virtual address at which the guest's physical address @var{= addr} +is mapped. +ETEXI + +#ifdef CONFIG_LINUX + { + .name =3D "gpa2hpa", + .args_type =3D "addr:l", + .params =3D "addr", + .help =3D "print the host physical address corresponding to = a guest physical address", + .cmd =3D hmp_gpa2hpa, + }, +#endif + +STEXI +@item gpa2hpa @var{addr} +@findex gpa2hpa +Print the host physical address at which the guest's physical address @var= {addr} +is mapped. +ETEXI + + { .name =3D "p|print", .args_type =3D "fmt:/,val:l", .params =3D "/fmt expr", diff --git a/monitor.c b/monitor.c index be282ec..1ac8c5f 100644 --- a/monitor.c +++ b/monitor.c @@ -1421,6 +1421,109 @@ static void hmp_physical_memory_dump(Monitor *mon, = const QDict *qdict) memory_dump(mon, count, format, size, addr, 1); } =20 +static void *gpa2hva(MemoryRegion **p_mr, hwaddr addr, Error **errp) +{ + MemoryRegionSection mrs =3D memory_region_find(get_system_memory(), + addr, 1); + + if (!mrs.mr) { + error_setg(errp, "No memory is mapped at address 0x%" HWADDR_PRIx,= addr); + return NULL; + } + + if (!memory_region_is_ram(mrs.mr) && !memory_region_is_romd(mrs.mr)) { + error_setg(errp, "Memory at address 0x%" HWADDR_PRIx "is not RAM",= addr); + memory_region_unref(mrs.mr); + return NULL; + } + + *p_mr =3D mrs.mr; + return qemu_map_ram_ptr(mrs.mr->ram_block, mrs.offset_within_region); +} + +static void hmp_gpa2hva(Monitor *mon, const QDict *qdict) +{ + hwaddr addr =3D qdict_get_int(qdict, "addr"); + Error *local_err =3D NULL; + MemoryRegion *mr; + void *ptr; + + ptr =3D gpa2hva(&mr, addr, &local_err); + if (local_err) { + error_report_err(local_err); + return; + } + + monitor_printf(mon, "Host virtual address for 0x%" HWADDR_PRIx + " (%s) is %p\n", + addr, mr->name, ptr); + + memory_region_unref(mr); +} + +#ifdef CONFIG_LINUX +static uint64_t vtop(void *ptr, Error **errp) +{ + uint64_t pinfo; + uint64_t ret =3D -1; + uintptr_t addr =3D (uintptr_t) ptr; + uintptr_t pagesize =3D getpagesize(); + off_t offset =3D addr / pagesize * sizeof (pinfo); + char pagemapname[64]; + int fd; + + sprintf(pagemapname, "/proc/%d/pagemap", getpid()); + fd =3D open(pagemapname, O_RDONLY); + if (fd =3D=3D -1) { + error_setg_errno(errp, errno, "Cannot open %s", pagemapname); + return -1; + } + + /* Force copy-on-write if necessary. */ + atomic_add((uint8_t *)ptr, 0); + + if (pread(fd, &pinfo, sizeof(pinfo), offset) !=3D sizeof(pinfo)) { + error_setg_errno(errp, errno, "Cannot read from %s", pagemapname); + goto out; + } + if ((pinfo & (1ull << 63)) =3D=3D 0) { + error_setg(errp, "Page not present"); + goto out; + } + ret =3D ((pinfo & 0x007fffffffffffffull) << 12) | (addr & (pagesize - = 1)); + +out: + close(fd); + return ret; +} + +static void hmp_gpa2hpa(Monitor *mon, const QDict *qdict) +{ + hwaddr addr =3D qdict_get_int(qdict, "addr"); + Error *local_err =3D NULL; + MemoryRegion *mr; + void *ptr; + uint64_t physaddr; + + ptr =3D gpa2hva(&mr, addr, &local_err); + if (local_err) { + error_report_err(local_err); + return; + } + + physaddr =3D vtop(ptr, &local_err); + if (local_err) { + error_report_err(local_err); + } else { + monitor_printf(mon, "Host physical address for 0x%" HWADDR_PRIx + " (%s) is 0x%" PRIx64 "\n", + addr, mr->name, (uint64_t) physaddr); + } + + memory_region_unref(mr); +} +#endif + static void do_print(Monitor *mon, const QDict *qdict) { int format =3D qdict_get_int(qdict, "format"); --=20 1.8.3.1