* [Qemu-devel] [Patch V0] This patch adds some support required for KVM in order to support LMCE.
@ 2015-12-09 19:57 Ashok Raj
2015-12-09 19:57 ` [Qemu-devel] [Patch V0] x86, mce: Basic support to add LMCE support to QEMU Ashok Raj
0 siblings, 1 reply; 5+ messages in thread
From: Ashok Raj @ 2015-12-09 19:57 UTC (permalink / raw)
To: kvm
Cc: Tony Luck, Ashok Raj, Gleb Natapov, linux-kernel, qemu-devel,
Andi Kleen, Paolo Bonzini, Boris Petkov
- Add support for MSR_IA32_MCG_EXT_CTL
- Add MCG_LMCE_P to KVM_MCE_CAP_SUPPORTED
- Changes to IA32_FEATURE_CONTROL, allow this MSR to be defined just not for
nested VMM, but now its required for Local MCE.
Reviewed-by: Andi Kleen <andi.kleen@intel.com>
Reviewed-by: Tony Luck <tony.luck@intel.com>
Tested-by: Gong Chen <gong.chen@intel.com>
Signed-off-by: Ashok Raj <ashok.raj@intel.com>
---
arch/x86/include/asm/kvm_host.h | 1 +
arch/x86/kvm/vmx.c | 26 +++++++++++++++++++++-----
arch/x86/kvm/x86.c | 17 ++++++++++++++++-
3 files changed, 38 insertions(+), 6 deletions(-)
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 30cfd64..6940141 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -525,6 +525,7 @@ struct kvm_vcpu_arch {
u64 mcg_cap;
u64 mcg_status;
u64 mcg_ctl;
+ u64 mcg_ext_ctl;
u64 *mce_banks;
/* Cache MMIO info */
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 87acc52..c2ce9f4 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -2747,6 +2747,20 @@ static int vmx_get_vmx_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata)
return 0;
}
+bool can_feature_control_exist(struct kvm_vcpu *vcpu)
+{
+ /*
+ * There are some features that require BIOS enabling.
+ * In such cases BIOS is supposed to set this bit and indicate
+ * the feature is enabled and available to the OS.
+ * Local Machine Check Exception (LMCE) is one such feature.
+ */
+ if (vcpu->arch.mcg_cap & MCG_LMCE_P)
+ return true;
+
+ return (nested_vmx_allowed(vcpu));
+}
+
/*
* Reads an msr value (of 'msr_index') into 'pdata'.
* Returns 0 on success, non-0 otherwise.
@@ -2789,9 +2803,11 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
msr_info->data = vmcs_read64(GUEST_BNDCFGS);
break;
case MSR_IA32_FEATURE_CONTROL:
- if (!nested_vmx_allowed(vcpu))
+ if (can_feature_control_exist(vcpu))
+ msr_info->data =
+ to_vmx(vcpu)->nested.msr_ia32_feature_control;
+ else
return 1;
- msr_info->data = to_vmx(vcpu)->nested.msr_ia32_feature_control;
break;
case MSR_IA32_VMX_BASIC ... MSR_IA32_VMX_VMFUNC:
if (!nested_vmx_allowed(vcpu))
@@ -2882,9 +2898,9 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
ret = kvm_set_msr_common(vcpu, msr_info);
break;
case MSR_IA32_FEATURE_CONTROL:
- if (!nested_vmx_allowed(vcpu) ||
- (to_vmx(vcpu)->nested.msr_ia32_feature_control &
- FEATURE_CONTROL_LOCKED && !msr_info->host_initiated))
+ if ((can_feature_control_exist(vcpu) == false) ||
+ ((to_vmx(vcpu)->nested.msr_ia32_feature_control &
+ FEATURE_CONTROL_LOCKED) && !msr_info->host_initiated))
return 1;
vmx->nested.msr_ia32_feature_control = data;
if (msr_info->host_initiated && data == 0)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 00462bd..0da3871 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -70,7 +70,7 @@
#define MAX_IO_MSRS 256
#define KVM_MAX_MCE_BANKS 32
-#define KVM_MCE_CAP_SUPPORTED (MCG_CTL_P | MCG_SER_P)
+#define KVM_MCE_CAP_SUPPORTED (MCG_CTL_P | MCG_SER_P | MCG_LMCE_P)
#define emul_to_vcpu(ctxt) \
container_of(ctxt, struct kvm_vcpu, arch.emulate_ctxt)
@@ -974,6 +974,7 @@ static u32 emulated_msrs[] = {
MSR_IA32_MISC_ENABLE,
MSR_IA32_MCG_STATUS,
MSR_IA32_MCG_CTL,
+ MSR_IA32_MCG_EXT_CTL,
MSR_IA32_SMBASE,
};
@@ -1913,6 +1914,13 @@ static int set_msr_mce(struct kvm_vcpu *vcpu, u32 msr, u64 data)
return -1;
vcpu->arch.mcg_ctl = data;
break;
+ case MSR_IA32_MCG_EXT_CTL:
+ if (!(mcg_cap & MCG_LMCE_P))
+ return 1;
+ if (data != 0 && data != 0x1)
+ return -1;
+ vcpu->arch.mcg_ext_ctl = data;
+ break;
default:
if (msr >= MSR_IA32_MC0_CTL &&
msr < MSR_IA32_MCx_CTL(bank_num)) {
@@ -2170,6 +2178,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
case MSR_IA32_MCG_CTL:
case MSR_IA32_MCG_STATUS:
+ case MSR_IA32_MCG_EXT_CTL:
case MSR_IA32_MC0_CTL ... MSR_IA32_MCx_CTL(KVM_MAX_MCE_BANKS) - 1:
return set_msr_mce(vcpu, msr, data);
@@ -2266,6 +2275,11 @@ static int get_msr_mce(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
return 1;
data = vcpu->arch.mcg_ctl;
break;
+ case MSR_IA32_MCG_EXT_CTL:
+ if (!(mcg_cap & MCG_LMCE_P))
+ return 1;
+ data = vcpu->arch.mcg_ext_ctl;
+ break;
case MSR_IA32_MCG_STATUS:
data = vcpu->arch.mcg_status;
break;
@@ -2384,6 +2398,7 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
case MSR_IA32_P5_MC_TYPE:
case MSR_IA32_MCG_CAP:
case MSR_IA32_MCG_CTL:
+ case MSR_IA32_MCG_EXT_CTL:
case MSR_IA32_MCG_STATUS:
case MSR_IA32_MC0_CTL ... MSR_IA32_MCx_CTL(KVM_MAX_MCE_BANKS) - 1:
return get_msr_mce(vcpu, msr_info->index, &msr_info->data);
--
2.4.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [Qemu-devel] [Patch V0] x86, mce: Basic support to add LMCE support to QEMU
2015-12-09 19:57 [Qemu-devel] [Patch V0] This patch adds some support required for KVM in order to support LMCE Ashok Raj
@ 2015-12-09 19:57 ` Ashok Raj
2015-12-09 21:07 ` Paolo Bonzini
0 siblings, 1 reply; 5+ messages in thread
From: Ashok Raj @ 2015-12-09 19:57 UTC (permalink / raw)
To: qemu-devel
Cc: Tony Luck, Ashok Raj, Gleb Natapov, Andi Kleen, Paolo Bonzini,
Boris Petkov
This patch adds basic enumeration, control msr's required to support
Local Machine Check Exception Support (LMCE).
- Added Local Machine Check definitions, changed MCG_CAP
- Added support for IA32_FEATURE_CONTROL.
- When delivering MCE to guest, we deliver to just a single CPU
when guest OS has opted in to Local delivery.
Signed-off-by: Ashok Raj <ashok.raj@intel.com>
Tested-by: Gong Chen <gong.chen@intel.com>
---
target-i386/cpu.c | 8 ++++++++
target-i386/cpu.h | 8 ++++++--
target-i386/kvm.c | 39 ++++++++++++++++++++++++++++++++-------
3 files changed, 46 insertions(+), 9 deletions(-)
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 11e5e39..167669a 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2737,6 +2737,13 @@ static void mce_init(X86CPU *cpu)
}
}
+static void feature_control_init(X86CPU *cpu)
+{
+ CPUX86State *cenv = &cpu->env;
+
+ cenv->msr_ia32_feature_control = ((1<<20) | (1<<0));
+}
+
#ifndef CONFIG_USER_ONLY
static void x86_cpu_apic_create(X86CPU *cpu, Error **errp)
{
@@ -2858,6 +2865,7 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
#endif
mce_init(cpu);
+ feature_control_init(cpu);
#ifndef CONFIG_USER_ONLY
if (tcg_enabled()) {
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 84edfd0..a567d7a 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -282,8 +282,9 @@
#define MCG_CTL_P (1ULL<<8) /* MCG_CAP register available */
#define MCG_SER_P (1ULL<<24) /* MCA recovery/new status bits */
+#define MCG_LMCE_P (1ULL<<27) /* Local Machine Check Supported */
-#define MCE_CAP_DEF (MCG_CTL_P|MCG_SER_P)
+#define MCE_CAP_DEF (MCG_CTL_P|MCG_SER_P|MCG_LMCE_P)
#define MCE_BANKS_DEF 10
#define MCG_CAP_BANKS_MASK 0xff
@@ -291,6 +292,7 @@
#define MCG_STATUS_RIPV (1ULL<<0) /* restart ip valid */
#define MCG_STATUS_EIPV (1ULL<<1) /* ip points to correct instruction */
#define MCG_STATUS_MCIP (1ULL<<2) /* machine check in progress */
+#define MCG_STATUS_LMCE (1ULL<<3) /* Local MCE signaled */
#define MCI_STATUS_VAL (1ULL<<63) /* valid error */
#define MCI_STATUS_OVER (1ULL<<62) /* previous errors lost */
@@ -333,6 +335,7 @@
#define MSR_MCG_CAP 0x179
#define MSR_MCG_STATUS 0x17a
#define MSR_MCG_CTL 0x17b
+#define MSR_MCG_EXT_CTL 0x4d0
#define MSR_P6_EVNTSEL0 0x186
@@ -892,7 +895,6 @@ typedef struct CPUX86State {
uint64_t mcg_status;
uint64_t msr_ia32_misc_enable;
- uint64_t msr_ia32_feature_control;
uint64_t msr_fixed_ctr_ctrl;
uint64_t msr_global_ctrl;
@@ -977,8 +979,10 @@ typedef struct CPUX86State {
int64_t tsc_khz;
void *kvm_xsave_buf;
+ uint64_t msr_ia32_feature_control;
uint64_t mcg_cap;
uint64_t mcg_ctl;
+ uint64_t mcg_ext_ctl;
uint64_t mce_banks[MCE_BANKS_DEF*4];
uint64_t tsc_aux;
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 6dc9846..d787fd9 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -72,6 +72,7 @@ static bool has_msr_tsc_aux;
static bool has_msr_tsc_adjust;
static bool has_msr_tsc_deadline;
static bool has_msr_feature_control;
+static bool has_msr_ext_mcg_ctl;
static bool has_msr_async_pf_en;
static bool has_msr_pv_eoi_en;
static bool has_msr_misc_enable;
@@ -370,18 +371,31 @@ static void kvm_mce_inject(X86CPU *cpu, hwaddr paddr, int code)
uint64_t status = MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN |
MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S;
uint64_t mcg_status = MCG_STATUS_MCIP;
+ int flags = 0;
+ CPUState *cs = CPU(cpu);
+
+ /*
+ * We need to read back the value of MSREXT_MCG_CTL that was set by the
+ * guest kernel back into Qemu
+ */
+ cs->kvm_vcpu_dirty = false;
+ cpu_synchronize_state(cs);
+
+ flags = cpu_x86_support_mca_broadcast(env) ? MCE_INJECT_BROADCAST : 0;
if (code == BUS_MCEERR_AR) {
- status |= MCI_STATUS_AR | 0x134;
- mcg_status |= MCG_STATUS_EIPV;
+ status |= MCI_STATUS_AR | 0x134;
+ mcg_status |= MCG_STATUS_EIPV;
+ if (env->mcg_ext_ctl & 0x1) {
+ mcg_status |= MCG_STATUS_LMCE;
+ flags = 0; /* No Broadcast when LMCE is opted by guest */
+ }
} else {
status |= 0xc0;
mcg_status |= MCG_STATUS_RIPV;
}
cpu_x86_inject_mce(NULL, cpu, 9, status, mcg_status, paddr,
- (MCM_ADDR_PHYS << 6) | 0xc,
- cpu_x86_support_mca_broadcast(env) ?
- MCE_INJECT_BROADCAST : 0);
+ (MCM_ADDR_PHYS << 6) | 0xc, flags);
}
static void hardware_memory_error(void)
@@ -808,10 +822,14 @@ int kvm_arch_init_vcpu(CPUState *cs)
c = cpuid_find_entry(&cpuid_data.cpuid, 1, 0);
if (c) {
- has_msr_feature_control = !!(c->ecx & CPUID_EXT_VMX) ||
- !!(c->ecx & CPUID_EXT_SMX);
+ has_msr_feature_control = !!((c->ecx & CPUID_EXT_VMX) ||
+ !!(c->ecx & CPUID_EXT_SMX) ||
+ !!(env->mcg_cap & MCG_LMCE_P));
}
+ if (has_msr_feature_control && (env->mcg_cap & MCG_LMCE_P))
+ has_msr_ext_mcg_ctl = true;
+
c = cpuid_find_entry(&cpuid_data.cpuid, 0x80000007, 0);
if (c && (c->edx & 1<<8) && invtsc_mig_blocker == NULL) {
/* for migration */
@@ -1557,6 +1575,7 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
kvm_msr_entry_set(&msrs[n++], MSR_MCG_STATUS, env->mcg_status);
kvm_msr_entry_set(&msrs[n++], MSR_MCG_CTL, env->mcg_ctl);
+ kvm_msr_entry_set(&msrs[n++], MSR_MCG_EXT_CTL, env->mcg_ext_ctl);
for (i = 0; i < (env->mcg_cap & 0xff) * 4; i++) {
kvm_msr_entry_set(&msrs[n++], MSR_MC0_CTL + i, env->mce_banks[i]);
}
@@ -1811,6 +1830,9 @@ static int kvm_get_msrs(X86CPU *cpu)
if (has_msr_feature_control) {
msrs[n++].index = MSR_IA32_FEATURE_CONTROL;
}
+ if (has_msr_ext_mcg_ctl) {
+ msrs[n++].index = MSR_MCG_EXT_CTL;
+ }
if (has_msr_bndcfgs) {
msrs[n++].index = MSR_IA32_BNDCFGS;
}
@@ -1981,6 +2003,9 @@ static int kvm_get_msrs(X86CPU *cpu)
case MSR_IA32_FEATURE_CONTROL:
env->msr_ia32_feature_control = msrs[i].data;
break;
+ case MSR_MCG_EXT_CTL:
+ env->mcg_ext_ctl = msrs[i].data;
+ break;
case MSR_IA32_BNDCFGS:
env->msr_bndcfgs = msrs[i].data;
break;
--
2.4.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] [Patch V0] x86, mce: Basic support to add LMCE support to QEMU
2015-12-09 19:57 ` [Qemu-devel] [Patch V0] x86, mce: Basic support to add LMCE support to QEMU Ashok Raj
@ 2015-12-09 21:07 ` Paolo Bonzini
2015-12-09 23:05 ` Raj, Ashok
0 siblings, 1 reply; 5+ messages in thread
From: Paolo Bonzini @ 2015-12-09 21:07 UTC (permalink / raw)
To: Ashok Raj, qemu-devel
Cc: Gleb Natapov, Andi Kleen, Boris Petkov, Eduardo Habkost,
Tony Luck
On 09/12/2015 20:57, Ashok Raj wrote:
> + /*
> + * We need to read back the value of MSREXT_MCG_CTL that was set by the
> + * guest kernel back into Qemu
> + */
> + cs->kvm_vcpu_dirty = false;
> + cpu_synchronize_state(cs);
This should not be necessary. I've only skimmed the patches but, apart
from this, the patches look good. Eduardo knows more than me about
machine types and backwards compatibility to older kernels, however, and
I'm deferring to him on this aspect.
How was this tested? (In general, how do you test MCE? :))
Paolo
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] [Patch V0] x86, mce: Basic support to add LMCE support to QEMU
2015-12-09 23:05 ` Raj, Ashok
@ 2015-12-09 22:23 ` Paolo Bonzini
0 siblings, 0 replies; 5+ messages in thread
From: Paolo Bonzini @ 2015-12-09 22:23 UTC (permalink / raw)
To: Raj, Ashok
Cc: Tony Luck, Eduardo Habkost, Gleb Natapov, qemu-devel, Gong Chen,
Andi Kleen, Boris Petkov
On 10/12/2015 00:05, Raj, Ashok wrote:
>>> > > + /*
>>> > > + * We need to read back the value of MSREXT_MCG_CTL that was set by the
>>> > > + * guest kernel back into Qemu
>>> > > + */
>>> > > + cs->kvm_vcpu_dirty = false;
>>> > > + cpu_synchronize_state(cs);
> This wasn't in my original patch, but was found required.
>
> Will have Gong check this and report back.
The cpu_synchronize_state is okay, the other part shouldn't be necessary
though.
Paolo
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Qemu-devel] [Patch V0] x86, mce: Basic support to add LMCE support to QEMU
2015-12-09 21:07 ` Paolo Bonzini
@ 2015-12-09 23:05 ` Raj, Ashok
2015-12-09 22:23 ` Paolo Bonzini
0 siblings, 1 reply; 5+ messages in thread
From: Raj, Ashok @ 2015-12-09 23:05 UTC (permalink / raw)
To: Paolo Bonzini
Cc: Tony Luck, Eduardo Habkost, Gleb Natapov, qemu-devel, Gong Chen,
Andi Kleen, Boris Petkov, Ashok Raj
[-- Attachment #1: Type: text/plain, Size: 4263 bytes --]
On Wed, Dec 09, 2015 at 10:07:48PM +0100, Paolo Bonzini wrote:
>
>
> On 09/12/2015 20:57, Ashok Raj wrote:
> > + /*
> > + * We need to read back the value of MSREXT_MCG_CTL that was set by the
> > + * guest kernel back into Qemu
> > + */
> > + cs->kvm_vcpu_dirty = false;
> > + cpu_synchronize_state(cs);
This wasn't in my original patch, but was found required.
Will have Gong check this and report back.
>
> This should not be necessary. I've only skimmed the patches but, apart
> from this, the patches look good. Eduardo knows more than me about
> machine types and backwards compatibility to older kernels, however, and
> I'm deferring to him on this aspect.
>
> How was this tested? (In general, how do you test MCE? :))
We tested on a real hardware that supported error injection via EINJ.
One additional patch is required to support the testing to translate
from GPA to HPA. Probably we could include this as well to make it easy
and not have us maintain out of tree?
Here are logs from Gong's testing.. he has a pretty eloborate test to
test this. :-)
Look at the MCGCAP and MCGSTATUS in host and guest for the values
introduced by this change set.
===================================================================================================
dmesg on guest system:
[ 35.294009] mce: [Hardware Error]: Machine check events logged
[ 35.294009] mce: Uncorrected hardware memory error in user-access at 7451b000
[ 35.334006] MCE 0x7451b: Killing victim:1822 due to hardware memory corruption
[ 35.334515] MCE 0x7451b: dirty mlocked LRU page still referenced by 1 users
[ 35.334930] MCE 0x7451b: recovery action for dirty mlocked LRU page: Failed
[ 35.335372] mce: Memory error not recovered
------------------------------------------------------------------------------------------------------------------------
dmesg on host system:
[57629.858659] kvm: zapping shadow pages for mmio generation wraparound
[57629.859592] kvm: zapping shadow pages for mmio generation wraparound
[57637.023199] kvm [46095]: vcpu0 disabled perfctr wrmsr: 0xc2 data 0xffff
[57637.116429] kvm [46095]: vcpu0 unhandled rdmsr: 0x570
[57637.122112] kvm [46095]: vcpu1 unhandled rdmsr: 0x570
[57672.381651] mce: [Hardware Error]: Machine check events logged
[57672.388178] mce: Uncorrected hardware memory error in user-access at 1da71b000
[57672.396057] mce: [Hardware Error]: Machine check events logged
[57672.403345] MCE 0x1da71b: Killing qemu-system-x86:46095 due to hardware memory corruption
[57672.412499] MCE 0x1da71b: recovery action for dirty LRU page: Recovered
===================================================================================================
Mcelog on host system:
[root@BKD06SDP host]# mcelog
Hardware event. This is not a software error.
MCE 0
CPU 68 BANK 1 TSC 835ad3e00dfe
MISC 86 ADDR 1da71b000
TIME 1449669775 Wed Dec 9 09:02:55 2015
MCG status:RIPV EIPV MCIP
MCi status:
Uncorrected error
Error enabled
MCi_MISC register valid
MCi_ADDR register valid
SRAR
MCA: Data CACHE Level-0 Data-Read Error
STATUS bd80000000100134 MCGSTATUS 7
MCGCAP 7000c16 APICID f0 SOCKETID 3
CPUID Vendor Intel Family 6 Model 63
Hardware event. This is not a software error.
MCE 1
CPU 0 BANK 7
MISC 146588a86 ADDR 1da71b000
TIME 1449669775 Wed Dec 9 09:02:55 2015
MCG status:
MCi status:
Uncorrected error
MCi_MISC register valid
MCi_ADDR register valid
MCA: MEMORY CONTROLLER RD_CHANNEL2_ERR
Transaction: Memory read error
STATUS ac00000000010092 MCGSTATUS 0
MCGCAP 7000c16 APICID 0 SOCKETID 0
CPUID Vendor Intel Family 6 Model 63
[root@BKD06SDP host]#
----------------------------------------------------------------------------
GUEST system mcelog:
[root@localhost ~]# cat /var/log/mcelog
mcelog: mcelog server already running
mcelog: mcelog server already running
Hardware event. This is not a software error.
MCE 0
CPU 0 BANK 9 TSC 18ce71469a
RIP 33:401535
MISC 8c ADDR 7451b000
TIME 1449669775 Wed Dec 9 09:02:55 2015
MCG status:EIPV MCIP LMCE
MCi status:
Uncorrected error
Error enabled
MCi_MISC register valid
MCi_ADDR register valid
SRAR
MCA: Data CACHE Level-0 Data-Read Error
STATUS bd80000000000134 MCGSTATUS e
MCGCAP 900010a APICID 0 SOCKETID 0
CPUID Vendor Intel Family 6 Model 6
[-- Attachment #2: qemu-add-monitor.patch --]
[-- Type: text/plain, Size: 5076 bytes --]
Signed-off-by: Feng Liu <feng.liu@intel.com>
From: root <root@lmcesrv.bj.intel.com>
---
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;
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2015-12-09 22:23 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-12-09 19:57 [Qemu-devel] [Patch V0] This patch adds some support required for KVM in order to support LMCE Ashok Raj
2015-12-09 19:57 ` [Qemu-devel] [Patch V0] x86, mce: Basic support to add LMCE support to QEMU Ashok Raj
2015-12-09 21:07 ` Paolo Bonzini
2015-12-09 23:05 ` Raj, Ashok
2015-12-09 22:23 ` Paolo Bonzini
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).