From nobody Tue Feb 10 22:18:35 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; 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; dmarc=fail(p=none dis=none) header.from=virtuozzo.com Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1526574380783917.8371175044413; Thu, 17 May 2018 09:26:20 -0700 (PDT) Received: from localhost ([::1]:35369 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fJLjI-000826-48 for importer@patchew.org; Thu, 17 May 2018 12:26:12 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34456) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fJLhX-0006aY-Iy for qemu-devel@nongnu.org; Thu, 17 May 2018 12:24:26 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fJLhT-0007Ip-TT for qemu-devel@nongnu.org; Thu, 17 May 2018 12:24:23 -0400 Received: from mail-eopbgr50097.outbound.protection.outlook.com ([40.107.5.97]:20608 helo=EUR03-VE1-obe.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fJLhT-0007FD-Hd for qemu-devel@nongnu.org; Thu, 17 May 2018 12:24:19 -0400 Received: from localhost.localdomain (93.175.11.132) by VI1PR08MB2862.eurprd08.prod.outlook.com (2603:10a6:802:1f::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.755.16; Thu, 17 May 2018 16:24:15 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=virtuozzo.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Or69Emdt3DR4yBVhKRyX4bEMlc4Psp79jSe+IOGCE7Y=; b=I/ikLCa+M3QEHsnTX2Lwrg+U66b9Nsk11mqxOKJyiIgIlRxCXt/UOTcbEJjHaTmRgrCVbDz028QQVgg4MiCpCOtDOwPCPaNrCN0idzUDoaWVYg8qNhP1OTIWNtNG46hmNf1DgBzE+yIoM3/cUleafV89msivUMH4i5gwPhhiEFA= From: Viktor Prutyanov To: qemu-devel@nongnu.org Date: Thu, 17 May 2018 19:23:39 +0300 Message-ID: <20180517162342.4330-2-viktor.prutyanov@virtuozzo.com> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180517162342.4330-1-viktor.prutyanov@virtuozzo.com> References: <20180517162342.4330-1-viktor.prutyanov@virtuozzo.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Originating-IP: [93.175.11.132] X-ClientProxiedBy: AM0PR06CA0027.eurprd06.prod.outlook.com (2603:10a6:208:ab::40) To VI1PR08MB2862.eurprd08.prod.outlook.com (2603:10a6:802:1f::10) X-MS-PublicTrafficType: Email X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(5600026)(4534165)(4627221)(201703031133081)(201702281549075)(2017052603328)(7153060)(7193020); SRVR:VI1PR08MB2862; X-Microsoft-Exchange-Diagnostics: 1; VI1PR08MB2862; 3:XE5FugXJJufxC0IYyoeXVQC/RQoWBYOn2Ye3TNQBlmBzlS5R5ma1i4A0CAGpbHJv4jZqB/C+VmBeDTsnNZiNp2JZqs35LH/A8lO3OKPVTlPSYrydjXq30+y4R9OcX4YA6IUj4JerPWZDU5wlF74mMnyumDjv8k0ncGWDirqnetmHTtJaGc2cO7Nt1MZ5tRlwn75W9WYNTg6vp1pVWq2ZFWEGJTvr793E2lJeOCkxeUbpnUY5zrXXOi4PDL3NF9F+; 25:TVAXd1ushYmN+U66UvyR+w/bYr5nzGr4fLZMrwQE68VN7rU+aMaY0BhxeJaFpAU5fX2ddGsGoNh/Mw466qgcNrgOEaWz3RcMph8ZCH5+M8Ny0nQZ8UmFmRqvlHtxjxQGkE5d1/gaoVzWPQChOEdi+QvxB67qph8VvgU/AiqHvhs286qO8va19NPIuzFgf67LFqNmePiJDC1sI4F22F074m+N9LczErYU5gebeAmvMu4K+VV6JcmaNyn4Ah4thpQuLAdup5se36F66cS3S4HxMXF8Gv/FPYY0BgLq42Zif2W5BZNEQfnnRGsi991p2CwcXKEi2RSM0u03GbCJSGRdMg==; 31:APu0Rt0y8YyfIkEhstzodVJ3OyIsx21pYYTKhrWyBF3yzWc6h9Pi/FOezmBPlQt2bilvgqh2L9+8GWFBE14EgGiXTmZt79r0x/TV5GhlOqwIq70/bhpgo0rTheeMVVlWps/4LCkK64gReFa0XO/rjtKzgCn6v/JdgEIcn9jp6lLnntreZ5dbLKkGr8kHKAjqPCBviFiFdpm1vK/x/ChTu/gQkO57hGV0HFvufUkUJj0= X-MS-TrafficTypeDiagnostic: VI1PR08MB2862: X-Microsoft-Exchange-Diagnostics: 1; VI1PR08MB2862; 20:smKxmRqzqlD1tqXufYysTIhKasi7YV2i47GzCLDBXbkddfrI5maIwJ8M1r/oaeCJ0jM52/XtcNpbo9kRsqHEVzQJ3llv1ntDxLGiF0Q/MNyPelmRrOB8LAZjPj8QZgCaSc9bm5bSJoaoJLUYg97CRBuM8oiUIpH92HbLZSgqRGNGniLLtnx4UiglvEvae03s6LJDLFsJoufVKEmP+LH9P4mpSBxg79oPbvORaJ0tRPJ9f+t7uyEIUGe+nMiMpKvlKkro8eug+NOOb68H7pcq63tLgI1FD8oGMYrRJIJtXUyUVnG8uGO0Nv8ss7NBehPB0PLaNL8i1AgfvEzFPYjH7i1XaRhweDPVqOZbtBKRL2vdUf9Z6hejo+IEyAChWb3lTasMXOgLEBQ4lkAOr48oNOLquDTZj/DuGEN0mZwgm24OTGNsStZDHKWPfLPFZxkclt3FXQE3/jy7Bt+dZq/ce8Tw2GK/Xl9ief2H1Bwc/OlJWZuIavWPXuzccSwvdNCD; 4:zaj0NertTJiBU8WFUgcUrGHUR/YAgkVH8/khFPgXJY2T4EiVk/R3RCIuQaIhhojb2TErDR8sc8q/xmzoNh3HoAg35rRecrGkjvNCYGqANSXBZZXcAUO7/MetRoFCF1LTVay3pNc1cQaFsQqvnEh1AcbJcDc1thc1G3rouLQFCqyoPOPWCWosYZqKEFllfNEqX4vakKHEoDKgF47TDiodJy+Olchh4MzQQLvZxODBcY7tilgNqnYeYYe9A/Y7vqd+tLdJzPr3loA3oxGBPrK4GcbhcnpNnScwE3JfRU4phCfjPovWgQ3lDMr4LlQpKG8DWbT6Mr9balpnIgxX0BX31g== X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(6846125436962)(166708455590820); X-MS-Exchange-SenderADCheck: 1 X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040522)(2401047)(5005006)(8121501046)(93006095)(93001095)(3231254)(944501410)(52105095)(10201501046)(3002001)(149027)(150027)(6041310)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123564045)(20161123562045)(20161123558120)(20161123560045)(6072148)(201708071742011)(7699016); SRVR:VI1PR08MB2862; BCL:0; PCL:0; RULEID:; SRVR:VI1PR08MB2862; X-Forefront-PRVS: 067553F396 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(6069001)(366004)(396003)(39850400004)(346002)(39380400002)(376002)(377424004)(189003)(199004)(2870700001)(8676002)(47776003)(956004)(2616005)(81166006)(81156014)(59450400001)(6486002)(6666003)(6916009)(7736002)(486006)(446003)(44832011)(6116002)(3846002)(1076002)(97736004)(11346002)(36756003)(76176011)(476003)(25786009)(53936002)(6306002)(6512007)(478600001)(86362001)(107886003)(2351001)(106356001)(2361001)(386003)(966005)(66066001)(2906002)(5660300001)(316002)(68736007)(8936002)(23676004)(52116002)(50466002)(186003)(305945005)(6506007)(50226002)(26005)(6346003)(16526019)(575784001)(4326008)(105586002)(19627235001); DIR:OUT; SFP:1102; SCL:1; SRVR:VI1PR08MB2862; H:localhost.localdomain; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; 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; Received-SPF: None (protection.outlook.com: virtuozzo.com does not designate permitted sender hosts) Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=viktor.prutyanov@virtuozzo.com; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; VI1PR08MB2862; 23:75Rw4CtEkSnaPyoNWTHOlZFhAde2Siqmm5w9jgWQ6?= =?us-ascii?Q?JOcNO4mcD37ACJLJkAsRgDY3b05k4umUUSz3kCwHdZXeH2/SPLbM9vx/7+7e?= =?us-ascii?Q?+1V2E9WTbjf63kEt35KDOEZJ3T3B/f2LsQf+Sw/Mv9JVA+CjG/apoh7B93A/?= =?us-ascii?Q?yKI2ERLnGPzPVYJemWrz5oiU+HhGuwtOqqxTAuzhHgY9RmrDJTNE7LqkKhn2?= =?us-ascii?Q?nMDSMd/8d+F9w6POnQ4DX9CKHlrKXvCNHOp0SN5/iVuomp8RzxvX9QKj4b8I?= =?us-ascii?Q?TIKWsCfsnyv+/lCV6dErpgt9OCzziUo9jr9lsiGCKDAXfq8V/WolxVoctbCR?= =?us-ascii?Q?9j48uoaeRXXWZPq0ezyjnDPjXvIReHs7jArD95eFsayZmgLdb+hIMTvusxL8?= =?us-ascii?Q?rDhS3Viy/REd+5ti5Fm603DSkZggduwXEI9vn/dm/5NySehYFGq1KRxiUgXv?= =?us-ascii?Q?wzOIrDC6eBX3+/wXPfShfXP4qtuDO706oKsB9PRWAuOG9Xe10CyKuDGbQUGh?= =?us-ascii?Q?zOC7FpCosTvoCTAW+x0UB267xR6VD/8QY0y/ypDjCE2t8JZTgFo991eIcpGy?= =?us-ascii?Q?YtkqFO8cD26Z9VfHUZEQzwoecqN43DM0TJK7ZxWe0MoxhRuFiiVmvlkYy/AJ?= =?us-ascii?Q?fmlG/v7TrUv+tbHaW4Jw4uFQrGyjDTmoeaIQNSAMLnfOFw/pIC+c+ZNdQzWm?= =?us-ascii?Q?TMMOT/OgrUgA/PBFaHwkASPT/X5PnfNDvDH88A11kZqIrRpW8GlYCSJwEjFo?= =?us-ascii?Q?3kTrsv+sEWNcC+NbbGu+mXUmCRF4R5kjXci7C9RbzGbJhYtZAj3DcjXMVj5/?= =?us-ascii?Q?Ugw4Gxy+2vuyzzkd8EuuI9ol9eHObPUa8HZ6sLZQ0iV2HKymw3TdoVj8vGPe?= =?us-ascii?Q?tWw1kqwGkK5IhFRWJc7Fucrkkov2zI7X5a/hAX9ajG4tkJk8zSs6mfO7bl/6?= =?us-ascii?Q?6TRN9hDt4AVK18maKnQ5tLBgAebEsCRSbqfsL1kKD7KpBhQSV5OH84ZZuwvx?= =?us-ascii?Q?rnHXOPI4kvbEm2jFlIZ1JnsU6owV77m0Z61Yy0nIopvreNmbENOT5jeVcZ92?= =?us-ascii?Q?XZ5oxtWrkbMXYYKfVerxCteAqyCJSzzJo0ri1Z5WUWarDNF57wxXLuISAI1h?= =?us-ascii?Q?nl0udNAcLgnl022bbnDjyqJ7L6VLD5CU74bIIh1vgJbteCJWe+kTwGx9Pqef?= =?us-ascii?Q?mQRaj/Diw7EFZLqw7TdHaqAlrchaIra6E02AFvNRksS0F4XTqkgytqtuszPc?= =?us-ascii?Q?We4JT/ejJVYiiFTxntvgVGENR3xYjXrAozmXeEo0S6Zjb/iu814fFGXtvLwt?= =?us-ascii?Q?1A/aFb4hPI5OIwwFDZduh7BEh1j/nmOLf1FQ9AwZk+v0o1v+Abf62TqbRmWv?= =?us-ascii?Q?X8FyfOf6fHeEGvXiDjBhspRsYzOpqNJd8WzRdDeZEZ9zuTw/Gcm/dWrgDtnU?= =?us-ascii?Q?HV0MQv/4B6UENiIdyM38TuWbQ1vwq0=3D?= X-Microsoft-Antispam-Message-Info: 4O5UE1Zm5VOdFLfOfySudDqv1mLfc8LA9RXYGxG6LT/Gh0bND4Fwrk8NWj/H6Gfr2lpA7dNkaKTmZdpwl8khTQz4HOvxNzh5Y4zwNxtJL7l+lzk3cieRgyUlskQZ1CLvvI6nMOg/iCsMs9AL8Zh2rTJmyCOptFHZKQD2IXjzbpHW5C8Z3L6wGbnRzO0x1Can X-Microsoft-Exchange-Diagnostics: 1; VI1PR08MB2862; 6:uQFg+9WEhYBXeswcrtUk9uoes5XRGQrxRWWOtE/HFq+qbogTW96WEtjRkeCVk3XmlMF/SgcIJcA6vkEzX4ZB13lK7+P9wulwAmdB5ZzsqA8R3Ja2yXJSHvQrX/mrttP5jrsjxTZ5oUvINnUk4/S2BQh9R+Dy3EOJCIeK9Vo91lpMsih1PaQDGRm2ZQxNpCjJgqrBH5Oo8akji7dQd/Jpalk1wJ+SggsQ2CgRAve3POnTFj1Jg69sX4wv2SnJfx4oncZn9uCwhu4Qo9DoQuIujQK/fw2NWlTrMXHosT+Zdyn71km2loDlvywNygVeBoU27+tY82JJW4R9wFOnKXIrajMWnrB/PRxV7uCMy/TvWrO+VAo/Z/kdz0FCVb5dGkT6sLHd8AIqxm5CGRTFQe641eq64SmAPzLOcl8GG4zl1SvlNeMsa1DhkAq91MEL8BK08ZlNz7ntPYDyPjpQxrPUYQ==; 5:IXOfe+ntOldwIspZszuaAizTTfYw6bz20b2uD0As4nvJpv4kDtmocjEzrwBMOtPS/fXLxQ9rlNi/uV0gmvxielsgqlZgERIM8cv/mV974n75gK9FEizSK1MQtXkTpm5hLK4CJOrdMIZoSQ7aXLpMyQkGosFGz/W7YlovFDnb+5s=; 24:jaQIjRUwd1cYeSgODJ3VxAOZENN0avoR+zxOgu6XYEtgMdmCpAPbEK2lHAUypiG6bSIqXew3cp2f7mK9QnkkF9xO0VzpOlOWHke0ihUBsIg= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; VI1PR08MB2862; 7:QPvK0jIDqoxK6npHkWaeohH9HatH5TFx47g1oWbvG4KdGXzU/8edvtQ+chwvpSRtN4igHqlPbZuFSdWixsGqLDKb5hb8KmPmm0cO1YzCD/2CSBLPE0UthPFsGYJKv8NJGZq0WV9rs1GJ5xZYP9xgxxKmApDIxys3ios7lOaBdiYknkAHExrBIbG151UlHQ11r9UP5a56cnukN7+xkdN4bAWxsotjQ4Zbwr51vqAqxNfn42O9uZiOdaxbkI+QOJ1P; 20:O96XS/k5x/ZQM4dH4XKyirCGfApkpyR0FL3oigyk/y11QCGrv1jU/ibpYrVi0r2cMJjQVRhEWONb+IztJb2F/855v3qG14e6QVWdGLI4uWaXa6D+/EO/I7jh0xTgfplINrzuElCtQQ93lgf63gg1IctyEL6lIsJzA7NCnkv4jfc= X-MS-Office365-Filtering-Correlation-Id: 070b56fe-643e-4fd3-bbdf-08d5bc12a238 X-OriginatorOrg: virtuozzo.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 May 2018 16:24:15.3915 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 070b56fe-643e-4fd3-bbdf-08d5bc12a238 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 0bc7f26d-0264-416e-a6fc-8352af79c58f X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1PR08MB2862 X-detected-operating-system: by eggs.gnu.org: Windows 7 or 8 [fuzzy] X-Received-From: 40.107.5.97 Subject: [Qemu-devel] [PATCH 1/4] dump: add Windows dump format to dump-guest-memory 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: marcandre.lureau@redhat.com, Viktor Prutyanov , rkagan@virtuozzo.com, armbru@redhat.com, dgilbert@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" This patch adds Windows crashdumping feature. Now QEMU can produce ELF-dump containing Windows crashdump header, which can help to convert to a valid WinDbg-understandable crashdump file, or immediately create such file. The crashdump will be obtained by joining physical memory dump and 8K header exposed through vmcoreinfo/fw_cfg device by guest driver at BSOD time. Opti= on '-w' was added to dump-guest-memory command. At the moment, only x64 configuration is supported. Suitable driver can be found at https://github.com/virtio-win/kvm-guest-drivers-windows/tree/master/fwcfg64 Signed-off-by: Viktor Prutyanov Reviewed-by: Marc-Andr=C3=A9 Lureau --- This patch is unchanged from the one posted separately on 2018-05-01 with message-id: <20180501132031.13270-1-viktor.prutyanov@virtuozzo.com> Makefile.target | 1 + dump.c | 24 ++++++- hmp-commands.hx | 13 ++-- hmp.c | 9 ++- qapi/misc.json | 5 +- win_dump.c | 209 ++++++++++++++++++++++++++++++++++++++++++++++++++++= ++++ win_dump.h | 87 +++++++++++++++++++++++ 7 files changed, 339 insertions(+), 9 deletions(-) create mode 100644 win_dump.c create mode 100644 win_dump.h diff --git a/Makefile.target b/Makefile.target index d0ec77a307..6ae2609597 100644 --- a/Makefile.target +++ b/Makefile.target @@ -138,6 +138,7 @@ obj-y +=3D hw/ obj-y +=3D memory.o obj-y +=3D memory_mapping.o obj-y +=3D dump.o +obj-y +=3D win_dump.o obj-y +=3D migration/ram.o LIBS :=3D $(libs_softmmu) $(LIBS) =20 diff --git a/dump.c b/dump.c index b54cd42b21..04467b353e 100644 --- a/dump.c +++ b/dump.c @@ -29,6 +29,10 @@ #include "qemu/error-report.h" #include "hw/misc/vmcoreinfo.h" =20 +#ifdef TARGET_X86_64 +#include "win_dump.h" +#endif + #include #ifdef CONFIG_LZO #include @@ -1866,7 +1870,11 @@ static void dump_process(DumpState *s, Error **errp) Error *local_err =3D NULL; DumpQueryResult *result =3D NULL; =20 - if (s->has_format && s->format !=3D DUMP_GUEST_MEMORY_FORMAT_ELF) { + if (s->has_format && s->format =3D=3D DUMP_GUEST_MEMORY_FORMAT_WIN_DMP= ) { +#ifdef TARGET_X86_64 + create_win_dump(s, &local_err); +#endif + } else if (s->has_format && s->format !=3D DUMP_GUEST_MEMORY_FORMAT_EL= F) { create_kdump_vmcore(s, &local_err); } else { create_vmcore(s, &local_err); @@ -1970,6 +1978,13 @@ void qmp_dump_guest_memory(bool paging, const char *= file, } #endif =20 +#ifndef TARGET_X86_64 + if (has_format && format =3D=3D DUMP_GUEST_MEMORY_FORMAT_WIN_DMP) { + error_setg(errp, "Windows dump is only available for x86-64"); + return; + } +#endif + #if !defined(WIN32) if (strstart(file, "fd:", &p)) { fd =3D monitor_get_fd(cur_mon, p, errp); @@ -2044,5 +2059,12 @@ DumpGuestMemoryCapability *qmp_query_dump_guest_memo= ry_capability(Error **errp) item->value =3D DUMP_GUEST_MEMORY_FORMAT_KDUMP_SNAPPY; #endif =20 + /* Windows dump is available only if target is x86_64 */ +#ifdef TARGET_X86_64 + item->next =3D g_malloc0(sizeof(DumpGuestMemoryFormatList)); + item =3D item->next; + item->value =3D DUMP_GUEST_MEMORY_FORMAT_WIN_DMP; +#endif + return cap; } diff --git a/hmp-commands.hx b/hmp-commands.hx index 227f7eee88..fc1f7401f7 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1088,30 +1088,33 @@ ETEXI =20 { .name =3D "dump-guest-memory", - .args_type =3D "paging:-p,detach:-d,zlib:-z,lzo:-l,snappy:-s,file= name:F,begin:i?,length:i?", - .params =3D "[-p] [-d] [-z|-l|-s] filename [begin length]", + .args_type =3D "paging:-p,detach:-d,windmp:-w,zlib:-z,lzo:-l,snap= py:-s,filename:F,begin:i?,length:i?", + .params =3D "[-p] [-d] [-z|-l|-s|-w] filename [begin length]", .help =3D "dump guest memory into file 'filename'.\n\t\t\t" "-p: do paging to get guest's memory mapping.\n\t\t\= t" "-d: return immediately (do not wait for completion)= .\n\t\t\t" "-z: dump in kdump-compressed format, with zlib comp= ression.\n\t\t\t" "-l: dump in kdump-compressed format, with lzo compr= ession.\n\t\t\t" "-s: dump in kdump-compressed format, with snappy co= mpression.\n\t\t\t" + "-w: dump in Windows crashdump format (can be used i= nstead of ELF-dump converting),\n\t\t\t" + " for Windows x64 guests with vmcoreinfo driver o= nly.\n\t\t\t" "begin: the starting physical address.\n\t\t\t" "length: the memory size, in bytes.", .cmd =3D hmp_dump_guest_memory, }, =20 - STEXI @item dump-guest-memory [-p] @var{filename} @var{begin} @var{length} -@item dump-guest-memory [-z|-l|-s] @var{filename} +@item dump-guest-memory [-z|-l|-s|-w] @var{filename} @findex dump-guest-memory Dump guest memory to @var{protocol}. The file can be processed with crash = or -gdb. Without -z|-l|-s, the dump format is ELF. +gdb. Without -z|-l|-s|-w, the dump format is ELF. -p: do paging to get guest's memory mapping. -z: dump in kdump-compressed format, with zlib compression. -l: dump in kdump-compressed format, with lzo compression. -s: dump in kdump-compressed format, with snappy compression. + -w: dump in Windows crashdump format (can be used instead of ELF-d= ump converting), + for Windows x64 guests with vmcoreinfo driver only filename: dump file name. begin: the starting physical address. It's optional, and should be specified together with length. diff --git a/hmp.c b/hmp.c index bdb340605c..c0c7ff0982 100644 --- a/hmp.c +++ b/hmp.c @@ -1976,6 +1976,7 @@ void hmp_device_del(Monitor *mon, const QDict *qdict) void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict) { Error *err =3D NULL; + bool win_dmp =3D qdict_get_try_bool(qdict, "windmp", false); bool paging =3D qdict_get_try_bool(qdict, "paging", false); bool zlib =3D qdict_get_try_bool(qdict, "zlib", false); bool lzo =3D qdict_get_try_bool(qdict, "lzo", false); @@ -1990,12 +1991,16 @@ void hmp_dump_guest_memory(Monitor *mon, const QDic= t *qdict) enum DumpGuestMemoryFormat dump_format =3D DUMP_GUEST_MEMORY_FORMAT_EL= F; char *prot; =20 - if (zlib + lzo + snappy > 1) { - error_setg(&err, "only one of '-z|-l|-s' can be set"); + if (zlib + lzo + snappy + win_dmp > 1) { + error_setg(&err, "only one of '-z|-l|-s|-w' can be set"); hmp_handle_error(mon, &err); return; } =20 + if (win_dmp) { + dump_format =3D DUMP_GUEST_MEMORY_FORMAT_WIN_DMP; + } + if (zlib) { dump_format =3D DUMP_GUEST_MEMORY_FORMAT_KDUMP_ZLIB; } diff --git a/qapi/misc.json b/qapi/misc.json index f5988cc0b5..5d02d07298 100644 --- a/qapi/misc.json +++ b/qapi/misc.json @@ -1679,10 +1679,13 @@ # # @kdump-snappy: kdump-compressed format with snappy-compressed # +# @win-dmp: Windows full crashdump format, +# can be used instead of ELF converting (since 2.13) +# # Since: 2.0 ## { 'enum': 'DumpGuestMemoryFormat', - 'data': [ 'elf', 'kdump-zlib', 'kdump-lzo', 'kdump-snappy' ] } + 'data': [ 'elf', 'kdump-zlib', 'kdump-lzo', 'kdump-snappy', 'win-dmp' ] } =20 ## # @dump-guest-memory: diff --git a/win_dump.c b/win_dump.c new file mode 100644 index 0000000000..58255c12ee --- /dev/null +++ b/win_dump.c @@ -0,0 +1,209 @@ +/* + * Windows crashdump + * + * Copyright (c) 2018 Virtuozzo International GmbH + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + * + */ + +#include "qemu/osdep.h" +#include "qemu/cutils.h" +#include "elf.h" +#include "cpu.h" +#include "exec/hwaddr.h" +#include "monitor/monitor.h" +#include "sysemu/kvm.h" +#include "sysemu/dump.h" +#include "sysemu/sysemu.h" +#include "sysemu/memory_mapping.h" +#include "sysemu/cpus.h" +#include "qapi/error.h" +#include "qapi/qmp/qerror.h" +#include "qemu/error-report.h" +#include "hw/misc/vmcoreinfo.h" +#include "win_dump.h" + +static size_t write_run(WinDumpPhyMemRun64 *run, int fd, Error **errp) +{ + void *buf; + uint64_t addr =3D run->BasePage << TARGET_PAGE_BITS; + uint64_t size =3D run->PageCount << TARGET_PAGE_BITS; + uint64_t len =3D size; + + buf =3D cpu_physical_memory_map(addr, &len, false); + if (!buf) { + error_setg(errp, "win-dump: failed to map run"); + return 0; + } + if (len !=3D size) { + error_setg(errp, "win-dump: failed to map entire run"); + len =3D 0; + goto out_unmap; + } + + len =3D qemu_write_full(fd, buf, len); + if (len !=3D size) { + error_setg(errp, QERR_IO_ERROR); + } + +out_unmap: + cpu_physical_memory_unmap(buf, addr, false, len); + + return len; +} + +static void write_runs(DumpState *s, WinDumpHeader64 *h, Error **errp) +{ + WinDumpPhyMemDesc64 *desc =3D &h->PhysicalMemoryBlock; + WinDumpPhyMemRun64 *run =3D desc->Run; + Error *local_err =3D NULL; + int i; + + for (i =3D 0; i < desc->NumberOfRuns; i++) { + s->written_size +=3D write_run(run + i, s->fd, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + } +} + +static void patch_mm_pfn_database(WinDumpHeader64 *h, Error **errp) +{ + if (cpu_memory_rw_debug(first_cpu, + h->KdDebuggerDataBlock + KDBG_MM_PFN_DATABASE_OFFSET64, + (uint8_t *)&h->PfnDatabase, sizeof(h->PfnDatabase), 0)) { + error_setg(errp, "win-dump: failed to read MmPfnDatabase"); + return; + } +} + +static void patch_bugcheck_data(WinDumpHeader64 *h, Error **errp) +{ + uint64_t KiBugcheckData; + + if (cpu_memory_rw_debug(first_cpu, + h->KdDebuggerDataBlock + KDBG_KI_BUGCHECK_DATA_OFFSET64, + (uint8_t *)&KiBugcheckData, sizeof(KiBugcheckData), 0)) { + error_setg(errp, "win-dump: failed to read KiBugcheckData"); + return; + } + + if (cpu_memory_rw_debug(first_cpu, + KiBugcheckData, + h->BugcheckData, sizeof(h->BugcheckData), 0)) { + error_setg(errp, "win-dump: failed to read bugcheck data"); + return; + } +} + +/* + * This routine tries to correct mistakes in crashdump header. + */ +static void patch_header(WinDumpHeader64 *h) +{ + Error *local_err =3D NULL; + + h->RequiredDumpSpace =3D sizeof(WinDumpHeader64) + + (h->PhysicalMemoryBlock.NumberOfPages << TARGET_PAGE_BITS); + h->PhysicalMemoryBlock.unused =3D 0; + h->unused1 =3D 0; + + /* + * We assume h->DirectoryBase and current CR3 are the same when we acc= ess + * memory by virtual address. In other words, we suppose current conte= xt + * is system context. It is definetely true in case of BSOD. + */ + + patch_mm_pfn_database(h, &local_err); + if (local_err) { + warn_report_err(local_err); + local_err =3D NULL; + } + patch_bugcheck_data(h, &local_err); + if (local_err) { + warn_report_err(local_err); + } +} + +static void check_header(WinDumpHeader64 *h, Error **errp) +{ + const char Signature[] =3D "PAGE"; + const char ValidDump[] =3D "DU64"; + + if (memcmp(h->Signature, Signature, sizeof(h->Signature))) { + error_setg(errp, "win-dump: invalid header, expected '%.4s'," + " got '%.4s'", Signature, h->Signature); + return; + } + + if (memcmp(h->ValidDump, ValidDump, sizeof(h->ValidDump))) { + error_setg(errp, "win-dump: invalid header, expected '%.4s'," + " got '%.4s'", ValidDump, h->ValidDump); + return; + } +} + +static void check_kdbg(WinDumpHeader64 *h, Error **errp) +{ + const char OwnerTag[] =3D "KDBG"; + char read_OwnerTag[4]; + + if (cpu_memory_rw_debug(first_cpu, + h->KdDebuggerDataBlock + KDBG_OWNER_TAG_OFFSET64, + (uint8_t *)&read_OwnerTag, sizeof(read_OwnerTag), 0)) { + error_setg(errp, "win-dump: failed to read OwnerTag"); + return; + } + + if (memcmp(read_OwnerTag, OwnerTag, sizeof(read_OwnerTag))) { + error_setg(errp, "win-dump: invalid KDBG OwnerTag," + " expected '%.4s', got '%.4s'," + " KdDebuggerDataBlock seems to be encrypted", + OwnerTag, read_OwnerTag); + return; + } +} + +void create_win_dump(DumpState *s, Error **errp) +{ + WinDumpHeader64 *h =3D (WinDumpHeader64 *)(s->guest_note + + VMCOREINFO_ELF_NOTE_HDR_SIZE); + Error *local_err =3D NULL; + + if (s->guest_note_size !=3D sizeof(WinDumpHeader64) + + VMCOREINFO_ELF_NOTE_HDR_SIZE) { + error_setg(errp, "win-dump: invalid vmcoreinfo note size"); + return; + } + + check_header(h, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + + check_kdbg(h, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + + patch_header(h); + + s->total_size =3D h->RequiredDumpSpace; + + s->written_size =3D qemu_write_full(s->fd, h, sizeof(*h)); + if (s->written_size !=3D sizeof(*h)) { + error_setg(errp, QERR_IO_ERROR); + return; + } + + write_runs(s, h, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } +} diff --git a/win_dump.h b/win_dump.h new file mode 100644 index 0000000000..281241881e --- /dev/null +++ b/win_dump.h @@ -0,0 +1,87 @@ +/* + * Windows crashdump + * + * Copyright (c) 2018 Virtuozzo International GmbH + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + * + */ + +typedef struct WinDumpPhyMemRun64 { + uint64_t BasePage; + uint64_t PageCount; +} QEMU_PACKED WinDumpPhyMemRun64; + +typedef struct WinDumpPhyMemDesc64 { + uint32_t NumberOfRuns; + uint32_t unused; + uint64_t NumberOfPages; + WinDumpPhyMemRun64 Run[43]; +} QEMU_PACKED WinDumpPhyMemDesc64; + +typedef struct WinDumpExceptionRecord { + uint32_t ExceptionCode; + uint32_t ExceptionFlags; + uint64_t ExceptionRecord; + uint64_t ExceptionAddress; + uint32_t NumberParameters; + uint32_t unused; + uint64_t ExceptionInformation[15]; +} QEMU_PACKED WinDumpExceptionRecord; + +typedef struct WinDumpHeader64 { + char Signature[4]; + char ValidDump[4]; + uint32_t MajorVersion; + uint32_t MinorVersion; + uint64_t DirectoryTableBase; + uint64_t PfnDatabase; + uint64_t PsLoadedModuleList; + uint64_t PsActiveProcessHead; + uint32_t MachineImageType; + uint32_t NumberProcessors; + union { + struct { + uint32_t BugcheckCode; + uint32_t unused0; + uint64_t BugcheckParameter1; + uint64_t BugcheckParameter2; + uint64_t BugcheckParameter3; + uint64_t BugcheckParameter4; + }; + uint8_t BugcheckData[40]; + }; + uint8_t VersionUser[32]; + uint64_t KdDebuggerDataBlock; + union { + WinDumpPhyMemDesc64 PhysicalMemoryBlock; + uint8_t PhysicalMemoryBlockBuffer[704]; + }; + union { + uint8_t ContextBuffer[3000]; + }; + WinDumpExceptionRecord Exception; + uint32_t DumpType; + uint32_t unused1; + uint64_t RequiredDumpSpace; + uint64_t SystemTime; + char Comment[128]; + uint64_t SystemUpTime; + uint32_t MiniDumpFields; + uint32_t SecondaryDataState; + uint32_t ProductType; + uint32_t SuiteMask; + uint32_t WriterStatus; + uint8_t unused2; + uint8_t KdSecondaryVersion; + uint8_t reserved[4018]; +} QEMU_PACKED WinDumpHeader64; + +void create_win_dump(DumpState *s, Error **errp); + +#define KDBG_OWNER_TAG_OFFSET64 0x10 +#define KDBG_KI_BUGCHECK_DATA_OFFSET64 0x88 +#define KDBG_MM_PFN_DATABASE_OFFSET64 0xC0 + +#define VMCOREINFO_ELF_NOTE_HDR_SIZE 24 --=20 2.14.3