Message ID | 1449776482-26070-2-git-send-email-ashok.raj@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Hi, Ashok Please add " original author by Huang Ying <ying.huang@intel.com>" at some place. Thanks. > -----Original Message----- > From: Raj, Ashok > Sent: Friday, December 11, 2015 3:41 AM > To: kvm@vger.kernel.org > Cc: Chen, Gong; Gleb Natapov; Paolo Bonzini; qemu-devel@nongnu.org; > linux-kernel@vger.kernel.org; Boris Petkov; Luck, Tony; Raj, Ashok; Kleen, > Andi > Subject: [Patch V2 2/2] x86, mce: Need to translate GPA to HPA to inject > error in guest. > > From: Gong Chen <gong.chen@intel.com> > > 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 <gong.chen@intel.com> > --- > 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; > -- > 2.4.3 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
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;