From patchwork Thu Dec 10 19:41:22 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ashok Raj X-Patchwork-Id: 7821451 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id A7417BEEE1 for ; Thu, 10 Dec 2015 18:46:56 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id AEC9E205CD for ; Thu, 10 Dec 2015 18:46:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id ACDCC20524 for ; Thu, 10 Dec 2015 18:46:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755470AbbLJSld (ORCPT ); Thu, 10 Dec 2015 13:41:33 -0500 Received: from mga03.intel.com ([134.134.136.65]:3461 "EHLO mga03.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755271AbbLJSlb (ORCPT ); Thu, 10 Dec 2015 13:41:31 -0500 Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga103.jf.intel.com with ESMTP; 10 Dec 2015 10:41:29 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,409,1444719600"; d="scan'208";a="11090180" Received: from otc-brkl-03.jf.intel.com ([10.54.39.10]) by fmsmga004.fm.intel.com with ESMTP; 10 Dec 2015 10:41:29 -0800 From: Ashok Raj To: kvm@vger.kernel.org Cc: Gong Chen , Gleb Natapov , Paolo Bonzini , qemu-devel@nongnu.org, linux-kernel@vger.kernel.org, Boris Petkov , Tony Luck , Ashok Raj , Andi Kleen Subject: [Patch V2 2/2] x86, mce: Need to translate GPA to HPA to inject error in guest. Date: Thu, 10 Dec 2015 14:41:22 -0500 Message-Id: <1449776482-26070-2-git-send-email-ashok.raj@intel.com> X-Mailer: git-send-email 2.4.3 In-Reply-To: <1449776482-26070-1-git-send-email-ashok.raj@intel.com> References: <1449776482-26070-1-git-send-email-ashok.raj@intel.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Gong Chen When we need to test error injection to a specific address using EINJ, there needs to be a way to translate GPA to HPA. This will allow host EINJ to inject error to test how guest behavior is when a bad address is consumed. This permits guest OS to perform its own recovery. Signed-off-by: Gong Chen --- Sorry about the spam :-(. Resending with proper Commit Message. Previous had a bogus From. Fixed that. before sending. hmp-commands.hx | 14 ++++++++++++++ include/exec/memory.h | 2 ++ kvm-all.c | 24 ++++++++++++++++++++++++ memory.c | 13 +++++++++++++ monitor.c | 16 ++++++++++++++++ 5 files changed, 69 insertions(+) mode change 100644 => 100755 include/exec/memory.h mode change 100644 => 100755 kvm-all.c mode change 100644 => 100755 memory.c mode change 100644 => 100755 monitor.c diff --git a/hmp-commands.hx b/hmp-commands.hx index bb52e4d..673c00e 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -444,6 +444,20 @@ Start gdbserver session (default @var{port}=1234) ETEXI { + .name = "x-gpa2hva", + .args_type = "fmt:/,addr:l", + .params = "/fmt addr", + .help = "translate guest physical 'addr' to host virtual address, only for debugging", + .mhandler.cmd = do_gpa2hva, + }, + +STEXI +@item x-gpa2hva @var{addr} +@findex x-gpa2hva +Translate guest physical @var{addr} to host virtual address, only for debugging. +ETEXI + + { .name = "x", .args_type = "fmt:/,addr:l", .params = "/fmt addr", diff --git a/include/exec/memory.h b/include/exec/memory.h old mode 100644 new mode 100755 index 0f07159..57d7bf8 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -222,6 +222,7 @@ struct MemoryListener { hwaddr addr, hwaddr len); void (*coalesced_mmio_del)(MemoryListener *listener, MemoryRegionSection *section, hwaddr addr, hwaddr len); + int (*translate_gpa2hva)(MemoryListener *listener, uint64_t paddr, uint64_t *vaddr); /* Lower = earlier (during add), later (during del) */ unsigned priority; AddressSpace *address_space_filter; @@ -1123,6 +1124,7 @@ void memory_global_dirty_log_start(void); void memory_global_dirty_log_stop(void); void mtree_info(fprintf_function mon_printf, void *f); +int memory_translate_gpa2hva(hwaddr paddr, uint64_t *vaddr); /** * memory_region_dispatch_read: perform a read directly to the specified diff --git a/kvm-all.c b/kvm-all.c old mode 100644 new mode 100755 index c648b81..cb029be --- a/kvm-all.c +++ b/kvm-all.c @@ -197,6 +197,29 @@ static KVMSlot *kvm_lookup_overlapping_slot(KVMMemoryListener *kml, return found; } + +static int kvm_translate_gpa2hva(MemoryListener *listener, uint64_t paddr, uint64_t *vaddr) +{ + KVMState *s = kvm_state; + KVMMemoryListener *kml = container_of(listener, KVMMemoryListener, listener); + KVMSlot *mem = NULL; + int i; + + for (i = 0; i < s->nr_slots; i++) { + mem = &kml->slots[i]; + if (paddr >= mem->start_addr && paddr < mem->start_addr + mem->memory_size) { + *vaddr = (uint64_t)mem->ram + paddr - mem->start_addr; + break; + } + } + + if (i == s->nr_slots) { + fprintf(stderr, "fail to find target physical addr(%ld) in KVM memory range\n", paddr); + return 1; + } + return 0; +} + int kvm_physical_memory_addr_from_host(KVMState *s, void *ram, hwaddr *phys_addr) { @@ -902,6 +925,7 @@ void kvm_memory_listener_register(KVMState *s, KVMMemoryListener *kml, kml->listener.log_start = kvm_log_start; kml->listener.log_stop = kvm_log_stop; kml->listener.log_sync = kvm_log_sync; + kml->listener.translate_gpa2hva = kvm_translate_gpa2hva; kml->listener.priority = 10; memory_listener_register(&kml->listener, as); diff --git a/memory.c b/memory.c old mode 100644 new mode 100755 index e193658..979dcf8 --- a/memory.c +++ b/memory.c @@ -2294,6 +2294,19 @@ static const TypeInfo memory_region_info = { .instance_finalize = memory_region_finalize, }; +int memory_translate_gpa2hva(hwaddr paddr, uint64_t *vaddr){ + MemoryListener *ml = NULL; + int ret = 1; + + QTAILQ_FOREACH(ml, &memory_listeners, link) { + if(ml->translate_gpa2hva) + ret = ml->translate_gpa2hva(ml, paddr, vaddr); + if(0 == ret) + break; + } + return ret; +} + static void memory_register_types(void) { type_register_static(&memory_region_info); diff --git a/monitor.c b/monitor.c old mode 100644 new mode 100755 index 9a35d72..408e1fa --- a/monitor.c +++ b/monitor.c @@ -76,6 +76,7 @@ #include "qapi-event.h" #include "qmp-introspect.h" #include "sysemu/block-backend.h" +#include "exec/memory.h" /* for hmp_info_irq/pic */ #if defined(TARGET_SPARC) @@ -1681,6 +1682,21 @@ static void hmp_acl_remove(Monitor *mon, const QDict *qdict) } } +static void do_gpa2hva(Monitor *mon, const QDict *qdict) +{ + uint64_t paddr; + uint64_t vaddr; + + paddr = qdict_get_int(qdict, "addr"); + if (memory_translate_gpa2hva(paddr, &vaddr)){ + monitor_printf(mon, "fail to translate gpa(0x%lx) to hva\n", paddr); + return; + } + + monitor_printf(mon, "0x%lx\n", (unsigned long)vaddr); + return; +} + void qmp_getfd(const char *fdname, Error **errp) { mon_fd_t *monfd;