[PATCH 3/3] kvm, x86: introduce kvm_inject_x86_mce_on

2010-12-21 Thread Jin Dongming
Pass a table instead of multiple args.

Note:

kvm_inject_x86_mce(env, bank, status, mcg_status, addr, misc,
   abort_on_error);

is equal to:

struct kvm_x86_mce mce = {
.bank = bank,
.status = status,
.mcg_status = mcg_status,
.addr = addr,
.misc = misc,
};
kvm_inject_x86_mce_on(env, &mce, abort_on_error);

Signed-off-by: Hidetoshi Seto 
Signed-off-by: Jin Dongming 
---
 target-i386/kvm.c |   57 +---
 1 files changed, 36 insertions(+), 21 deletions(-)

diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index ce01e18..9a4bf98 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -263,6 +263,23 @@ static void kvm_do_inject_x86_mce(void *_data)
 }
 }
 
+static void kvm_inject_x86_mce_on(CPUState *env, struct kvm_x86_mce *mce,
+  int flag)
+{
+struct kvm_x86_mce_data data = {
+.env = env,
+.mce = mce,
+.abort_on_error = (flag & ABORT_ON_ERROR),
+};
+
+if (!env->mcg_cap) {
+fprintf(stderr, "MCE support is not enabled!\n");
+return;
+}
+
+run_on_cpu(env, kvm_do_inject_x86_mce, &data);
+}
+
 static void kvm_mce_broadcast_rest(CPUState *env);
 #endif
 
@@ -278,21 +295,12 @@ void kvm_inject_x86_mce(CPUState *cenv, int bank, 
uint64_t status,
 .addr = addr,
 .misc = misc,
 };
-struct kvm_x86_mce_data data = {
-.env = cenv,
-.mce = &mce,
-};
-
-if (!cenv->mcg_cap) {
-fprintf(stderr, "MCE support is not enabled!\n");
-return;
-}
 
 if (flag & MCE_BROADCAST) {
 kvm_mce_broadcast_rest(cenv);
 }
 
-run_on_cpu(cenv, kvm_do_inject_x86_mce, &data);
+kvm_inject_x86_mce_on(cenv, &mce, flag);
 #else
 if (flag & ABORT_ON_ERROR) {
 abort();
@@ -1708,6 +1716,13 @@ static void hardware_memory_error(void)
 #ifdef KVM_CAP_MCE
 static void kvm_mce_broadcast_rest(CPUState *env)
 {
+struct kvm_x86_mce mce = {
+.bank = 1,
+.status = MCI_STATUS_VAL | MCI_STATUS_UC,
+.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV,
+.addr = 0,
+.misc = 0,
+};
 CPUState *cenv;
 
 /* Broadcast MCA signal for processor version 06H_EH and above */
@@ -1716,9 +1731,7 @@ static void kvm_mce_broadcast_rest(CPUState *env)
 if (cenv == env) {
 continue;
 }
-kvm_inject_x86_mce(cenv, 1, MCI_STATUS_VAL | MCI_STATUS_UC,
-   MCG_STATUS_MCIP | MCG_STATUS_RIPV, 0, 0,
-   ABORT_ON_ERROR);
+kvm_inject_x86_mce_on(cenv, &mce, ABORT_ON_ERROR);
 }
 }
 }
@@ -1767,15 +1780,17 @@ static void kvm_mce_inj_srao_memscrub(CPUState *env, 
target_phys_addr_t paddr)
 
 static void kvm_mce_inj_srao_memscrub2(CPUState *env, target_phys_addr_t paddr)
 {
-uint64_t status;
-
-status = MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN
-| MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S
-| 0xc0;
-kvm_inject_x86_mce(env, 9, status,
-   MCG_STATUS_MCIP | MCG_STATUS_RIPV, paddr,
-   (MCM_ADDR_PHYS << 6) | 0xc, ABORT_ON_ERROR);
+struct kvm_x86_mce mce = {
+.bank = 9,
+.status = MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN
+  | MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S
+  | 0xc0,
+.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV,
+.addr = paddr,
+.misc = (MCM_ADDR_PHYS << 6) | 0xc,
+};
 
+kvm_inject_x86_mce_on(env, &mce, ABORT_ON_ERROR);
 kvm_mce_broadcast_rest(env);
 }
 
-- 
1.7.3.1


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/3] kvm, x86: kvm_mce_inj_* subroutins for templated error injections

2010-12-21 Thread Jin Dongming
Refactor codes for maintainability.

Signed-off-by: Hidetoshi Seto 
Signed-off-by: Jin Dongming 
---
 target-i386/kvm.c |  111 ++---
 1 files changed, 71 insertions(+), 40 deletions(-)

diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 5a699fc..ce01e18 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -1722,44 +1722,75 @@ static void kvm_mce_broadcast_rest(CPUState *env)
 }
 }
 }
+
+static void kvm_mce_inj_srar_dataload(CPUState *env, target_phys_addr_t paddr)
+{
+struct kvm_x86_mce mce = {
+.bank = 9,
+.status = MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN
+  | MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S
+  | MCI_STATUS_AR | 0x134,
+.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_EIPV,
+.addr = paddr,
+.misc = (MCM_ADDR_PHYS << 6) | 0xc,
+};
+int r;
+
+r = kvm_set_mce(env, &mce);
+if (r < 0) {
+fprintf(stderr, "kvm_set_mce: %s\n", strerror(errno));
+abort();
+}
+kvm_mce_broadcast_rest(env);
+}
+
+static void kvm_mce_inj_srao_memscrub(CPUState *env, target_phys_addr_t paddr)
+{
+struct kvm_x86_mce mce = {
+.bank = 9,
+.status = MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN
+  | MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S
+  | 0xc0,
+.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV,
+.addr = paddr,
+.misc = (MCM_ADDR_PHYS << 6) | 0xc,
+};
+int r;
+
+r = kvm_set_mce(env, &mce);
+if (r < 0) {
+fprintf(stderr, "kvm_set_mce: %s\n", strerror(errno));
+abort();
+}
+kvm_mce_broadcast_rest(env);
+}
+
+static void kvm_mce_inj_srao_memscrub2(CPUState *env, target_phys_addr_t paddr)
+{
+uint64_t status;
+
+status = MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN
+| MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S
+| 0xc0;
+kvm_inject_x86_mce(env, 9, status,
+   MCG_STATUS_MCIP | MCG_STATUS_RIPV, paddr,
+   (MCM_ADDR_PHYS << 6) | 0xc, ABORT_ON_ERROR);
+
+kvm_mce_broadcast_rest(env);
+}
+
 #endif
 
 int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr)
 {
 #if defined(KVM_CAP_MCE)
-struct kvm_x86_mce mce = {
-.bank = 9,
-};
 void *vaddr;
 ram_addr_t ram_addr;
 target_phys_addr_t paddr;
-int r;
 
 if ((env->mcg_cap & MCG_SER_P) && addr
 && (code == BUS_MCEERR_AR
 || code == BUS_MCEERR_AO)) {
-if (code == BUS_MCEERR_AR) {
-/* Fake an Intel architectural Data Load SRAR UCR */
-mce.status = MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN
-| MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S
-| MCI_STATUS_AR | 0x134;
-mce.misc = (MCM_ADDR_PHYS << 6) | 0xc;
-mce.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_EIPV;
-} else {
-/*
- * If there is an MCE excpetion being processed, ignore
- * this SRAO MCE
- */
-if (kvm_mce_in_progress(env)) {
-return 0;
-}
-/* Fake an Intel architectural Memory scrubbing UCR */
-mce.status = MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN
-| MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S
-| 0xc0;
-mce.misc = (MCM_ADDR_PHYS << 6) | 0xc;
-mce.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV;
-}
 vaddr = (void *)addr;
 if (qemu_ram_addr_from_host(vaddr, &ram_addr) ||
 !kvm_physical_memory_addr_from_ram(env->kvm_state, ram_addr, 
&paddr)) {
@@ -1772,13 +1803,20 @@ int kvm_on_sigbus_vcpu(CPUState *env, int code, void 
*addr)
 hardware_memory_error();
 }
 }
-mce.addr = paddr;
-r = kvm_set_mce(env, &mce);
-if (r < 0) {
-fprintf(stderr, "kvm_set_mce: %s\n", strerror(errno));
-abort();
+
+if (code == BUS_MCEERR_AR) {
+/* Fake an Intel architectural Data Load SRAR UCR */
+kvm_mce_inj_srar_dataload(env, paddr);
+} else {
+/*
+ * If there is an MCE excpetion being processed, ignore
+ * this SRAO MCE
+ */
+if (!kvm_mce_in_progress(env)) {
+/* Fake an Intel architectural Memory scrubbing UCR */
+kvm_mce_inj_srao_memscrub(env, paddr);
+}
 }
-kvm_mce_broadcast_rest(env);
 } else
 #endif
 {
@@ -1797,7 +1835,6 @@ int kvm_on_sigbus(int code, void *addr)
 {
 #if defined(KVM_CAP_MCE)
 if ((first_cpu->mcg_cap & MCG_SER_P) && addr && code == BUS_MCEERR_AO) {
-uint64_t status

[PATCH 1/3] kvm, x86: introduce kvm_mce_in_progress

2010-12-21 Thread Jin Dongming
Hi, Marcelo-san

I modified the patches sent before and made them work well
on origin/uq/master tree.

Resend the patches.

Best Regards,
Jin Dongming
---
Share same error handing, and rename this function after
MCIP (Machine Check In Progress) flag.

Signed-off-by: Hidetoshi Seto 
Signed-off-by: Jin Dongming 
---
 target-i386/kvm.c |   15 +--
 1 files changed, 5 insertions(+), 10 deletions(-)

diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 2115a58..5a699fc 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -219,7 +219,7 @@ static int kvm_get_msr(CPUState *env, struct kvm_msr_entry 
*msrs, int n)
 }
 
 /* FIXME: kill this and kvm_get_msr, use env->mcg_status instead */
-static int kvm_mce_in_exception(CPUState *env)
+static int kvm_mce_in_progress(CPUState *env)
 {
 struct kvm_msr_entry msr_mcg_status = {
 .index = MSR_MCG_STATUS,
@@ -228,7 +228,8 @@ static int kvm_mce_in_exception(CPUState *env)
 
 r = kvm_get_msr(env, &msr_mcg_status, 1);
 if (r == -1 || r == 0) {
-return -1;
+fprintf(stderr, "Failed to get MCE status\n");
+return 0;
 }
 return !!(msr_mcg_status.data & MCG_STATUS_MCIP);
 }
@@ -248,10 +249,7 @@ static void kvm_do_inject_x86_mce(void *_data)
 /* If there is an MCE exception being processed, ignore this SRAO MCE */
 if ((data->env->mcg_cap & MCG_SER_P) &&
 !(data->mce->status & MCI_STATUS_AR)) {
-r = kvm_mce_in_exception(data->env);
-if (r == -1) {
-fprintf(stderr, "Failed to get MCE status\n");
-} else if (r) {
+if (kvm_mce_in_progress(data->env)) {
 return;
 }
 }
@@ -1752,10 +1750,7 @@ int kvm_on_sigbus_vcpu(CPUState *env, int code, void 
*addr)
  * If there is an MCE excpetion being processed, ignore
  * this SRAO MCE
  */
-r = kvm_mce_in_exception(env);
-if (r == -1) {
-fprintf(stderr, "Failed to get MCE status\n");
-} else if (r) {
+if (kvm_mce_in_progress(env)) {
 return 0;
 }
 /* Fake an Intel architectural Memory scrubbing UCR */
-- 
1.7.3.1


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/3] kvm, x86: introduce kvm_inject_x86_mce_on

2010-12-20 Thread Jin Dongming
Hi, Marcelo-san

(2010/12/20 20:29), Marcelo Tosatti wrote:
> On Fri, Dec 10, 2010 at 05:25:20PM +0900, Jin Dongming wrote:
>> Pass a table instead of multiple args.
>>
>> Note:
>>
>> kvm_inject_x86_mce(env, bank, status, mcg_status, addr, misc,
>>abort_on_error);
>>
>> is equal to:
>>
>> struct kvm_x86_mce mce = {
>> .bank = bank,
>> .status = status,
>> .mcg_status = mcg_status,
>> .addr = addr,
>> .misc = misc,
>> };
>> kvm_inject_x86_mce_on(env, &mce, abort_on_error);
>>
>> Signed-off-by: Hidetoshi Seto 
>> Signed-off-by: Jin Dongming 
> 
> Looks good, can you please regenerate against qemu-kvm.git's uq/master
> branch?
OK. I will do it as soon as possible.

Best Regards,
Jin Dongming
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> 


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/3] kvm, x86: introduce kvm_inject_x86_mce_on

2010-12-10 Thread Jin Dongming
Pass a table instead of multiple args.

Note:

kvm_inject_x86_mce(env, bank, status, mcg_status, addr, misc,
   abort_on_error);

is equal to:

struct kvm_x86_mce mce = {
.bank = bank,
.status = status,
.mcg_status = mcg_status,
.addr = addr,
.misc = misc,
};
kvm_inject_x86_mce_on(env, &mce, abort_on_error);

Signed-off-by: Hidetoshi Seto 
Signed-off-by: Jin Dongming 
---
 target-i386/kvm.c |   58 
 1 files changed, 36 insertions(+), 22 deletions(-)

diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 1f3f369..b11337a 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -263,6 +263,23 @@ static void kvm_do_inject_x86_mce(void *_data)
 }
 }
 
+static void kvm_inject_x86_mce_on(CPUState *env, struct kvm_x86_mce *mce,
+  int flag)
+{
+struct kvm_x86_mce_data data = {
+.env = env,
+.mce = mce,
+.abort_on_error = (flag & ABORT_ON_ERROR),
+};
+
+if (!env->mcg_cap) {
+fprintf(stderr, "MCE support is not enabled!\n");
+return;
+}
+
+on_vcpu(env, kvm_do_inject_x86_mce, &data);
+}
+
 static void kvm_mce_broadcast_rest(CPUState *env);
 #endif
 
@@ -278,21 +295,11 @@ void kvm_inject_x86_mce(CPUState *cenv, int bank, 
uint64_t status,
 .addr = addr,
 .misc = misc,
 };
-struct kvm_x86_mce_data data = {
-.env = cenv,
-.mce = &mce,
-};
-
-if (!cenv->mcg_cap) {
-fprintf(stderr, "MCE support is not enabled!\n");
-return;
-}
-
 if (flag & MCE_BROADCAST) {
 kvm_mce_broadcast_rest(cenv);
 }
 
-on_vcpu(cenv, kvm_do_inject_x86_mce, &data);
+kvm_inject_x86_mce_on(cenv, &mce, flag);
 #else
 if (flag & ABORT_ON_ERROR) {
 abort();
@@ -1738,6 +1745,13 @@ static void hardware_memory_error(void)
 #ifdef KVM_CAP_MCE
 static void kvm_mce_broadcast_rest(CPUState *env)
 {
+struct kvm_x86_mce mce = {
+.bank = 1,
+.status = MCI_STATUS_VAL | MCI_STATUS_UC,
+.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV,
+.addr = 0,
+.misc = 0,
+};
 CPUState *cenv;
 
 /* Broadcast MCA signal for processor version 06H_EH and above */
@@ -1746,9 +1760,7 @@ static void kvm_mce_broadcast_rest(CPUState *env)
 if (cenv == env) {
 continue;
 }
-kvm_inject_x86_mce(cenv, 1, MCI_STATUS_VAL | MCI_STATUS_UC,
-   MCG_STATUS_MCIP | MCG_STATUS_RIPV, 0, 0,
-   ABORT_ON_ERROR);
+kvm_inject_x86_mce_on(cenv, &mce, ABORT_ON_ERROR);
 }
 }
 }
@@ -1797,15 +1809,17 @@ static void kvm_mce_inj_srao_memscrub(CPUState *env, 
target_phys_addr_t paddr)
 
 static void kvm_mce_inj_srao_memscrub2(CPUState *env, target_phys_addr_t paddr)
 {
-uint64_t status;
-
-status = MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN
-| MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S
-| 0xc0;
-kvm_inject_x86_mce(env, 9, status,
-   MCG_STATUS_MCIP | MCG_STATUS_RIPV, paddr,
-   (MCM_ADDR_PHYS << 6) | 0xc, ABORT_ON_ERROR);
+struct kvm_x86_mce mce = {
+.bank = 9,
+.status = MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN
+  | MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S
+  | 0xc0,
+.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV,
+.addr = paddr,
+.misc = (MCM_ADDR_PHYS << 6) | 0xc,
+};
 
+kvm_inject_x86_mce_on(env, &mce, ABORT_ON_ERROR);
 kvm_mce_broadcast_rest(env);
 }
 
-- 
1.7.1.1


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/3] kvm, x86: kvm_mce_inj_* subroutins for templated error injections

2010-12-10 Thread Jin Dongming
Refactor codes for maintainability.

Signed-off-by: Hidetoshi Seto 
Signed-off-by: Jin Dongming 
---
 target-i386/kvm.c |  111 ++---
 1 files changed, 71 insertions(+), 40 deletions(-)

diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index d7aae8b..1f3f369 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -1752,44 +1752,75 @@ static void kvm_mce_broadcast_rest(CPUState *env)
 }
 }
 }
+
+static void kvm_mce_inj_srar_dataload(CPUState *env, target_phys_addr_t paddr)
+{
+struct kvm_x86_mce mce = {
+.bank = 9,
+.status = MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN
+  | MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S
+  | MCI_STATUS_AR | 0x134,
+.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_EIPV,
+.addr = paddr,
+.misc = (MCM_ADDR_PHYS << 6) | 0xc,
+};
+int r;
+
+r = kvm_set_mce(env, &mce);
+if (r < 0) {
+fprintf(stderr, "kvm_set_mce: %s\n", strerror(errno));
+abort();
+}
+kvm_mce_broadcast_rest(env);
+}
+
+static void kvm_mce_inj_srao_memscrub(CPUState *env, target_phys_addr_t paddr)
+{
+struct kvm_x86_mce mce = {
+.bank = 9,
+.status = MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN
+  | MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S
+  | 0xc0,
+.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV,
+.addr = paddr,
+.misc = (MCM_ADDR_PHYS << 6) | 0xc,
+};
+int r;
+
+r = kvm_set_mce(env, &mce);
+if (r < 0) {
+fprintf(stderr, "kvm_set_mce: %s\n", strerror(errno));
+abort();
+}
+kvm_mce_broadcast_rest(env);
+}
+
+static void kvm_mce_inj_srao_memscrub2(CPUState *env, target_phys_addr_t paddr)
+{
+uint64_t status;
+
+status = MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN
+| MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S
+| 0xc0;
+kvm_inject_x86_mce(env, 9, status,
+   MCG_STATUS_MCIP | MCG_STATUS_RIPV, paddr,
+   (MCM_ADDR_PHYS << 6) | 0xc, ABORT_ON_ERROR);
+
+kvm_mce_broadcast_rest(env);
+}
+
 #endif
 
 int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr)
 {
 #if defined(KVM_CAP_MCE)
-struct kvm_x86_mce mce = {
-.bank = 9,
-};
 void *vaddr;
 ram_addr_t ram_addr;
 target_phys_addr_t paddr;
-int r;
 
 if ((env->mcg_cap & MCG_SER_P) && addr
 && (code == BUS_MCEERR_AR
 || code == BUS_MCEERR_AO)) {
-if (code == BUS_MCEERR_AR) {
-/* Fake an Intel architectural Data Load SRAR UCR */
-mce.status = MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN
-| MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S
-| MCI_STATUS_AR | 0x134;
-mce.misc = (MCM_ADDR_PHYS << 6) | 0xc;
-mce.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_EIPV;
-} else {
-/*
- * If there is an MCE excpetion being processed, ignore
- * this SRAO MCE
- */
-if (kvm_mce_in_progress(env)) {
-return 0;
-}
-/* Fake an Intel architectural Memory scrubbing UCR */
-mce.status = MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN
-| MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S
-| 0xc0;
-mce.misc = (MCM_ADDR_PHYS << 6) | 0xc;
-mce.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV;
-}
 vaddr = (void *)addr;
 if (qemu_ram_addr_from_host(vaddr, &ram_addr) ||
 !kvm_physical_memory_addr_from_ram(env->kvm_state, ram_addr, 
&paddr)) {
@@ -1802,13 +1833,20 @@ int kvm_on_sigbus_vcpu(CPUState *env, int code, void 
*addr)
 hardware_memory_error();
 }
 }
-mce.addr = paddr;
-r = kvm_set_mce(env, &mce);
-if (r < 0) {
-fprintf(stderr, "kvm_set_mce: %s\n", strerror(errno));
-abort();
+
+if (code == BUS_MCEERR_AR) {
+/* Fake an Intel architectural Data Load SRAR UCR */
+kvm_mce_inj_srar_dataload(env, paddr);
+} else {
+/*
+ * If there is an MCE excpetion being processed, ignore
+ * this SRAO MCE
+ */
+if (!kvm_mce_in_progress(env)) {
+/* Fake an Intel architectural Memory scrubbing UCR */
+kvm_mce_inj_srao_memscrub(env, paddr);
+}
 }
-kvm_mce_broadcast_rest(env);
 } else
 #endif
 {
@@ -1827,7 +1865,6 @@ int kvm_on_sigbus(int code, void *addr)
 {
 #if defined(KVM_CAP_MCE)
 if ((first_cpu->mcg_cap & MCG_SER_P) && addr && code == BUS_MCEERR_AO) {
-uint64_t status

[PATCH 1/3] kvm, x86: introduce kvm_mce_in_progress

2010-12-10 Thread Jin Dongming
Share same error handing, and rename this function after
MCIP (Machine Check In Progress) flag.

Signed-off-by: Hidetoshi Seto 
Signed-off-by: Jin Dongming 
---
 target-i386/kvm.c |   15 +--
 1 files changed, 5 insertions(+), 10 deletions(-)

diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index a7261c0..d7aae8b 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -219,7 +219,7 @@ static int kvm_get_msr(CPUState *env, struct kvm_msr_entry 
*msrs, int n)
 }
 
 /* FIXME: kill this and kvm_get_msr, use env->mcg_status instead */
-static int kvm_mce_in_exception(CPUState *env)
+static int kvm_mce_in_progress(CPUState *env)
 {
 struct kvm_msr_entry msr_mcg_status = {
 .index = MSR_MCG_STATUS,
@@ -228,7 +228,8 @@ static int kvm_mce_in_exception(CPUState *env)
 
 r = kvm_get_msr(env, &msr_mcg_status, 1);
 if (r == -1 || r == 0) {
-return -1;
+fprintf(stderr, "Failed to get MCE status\n");
+return 0;
 }
 return !!(msr_mcg_status.data & MCG_STATUS_MCIP);
 }
@@ -248,10 +249,7 @@ static void kvm_do_inject_x86_mce(void *_data)
 /* If there is an MCE exception being processed, ignore this SRAO MCE */
 if ((data->env->mcg_cap & MCG_SER_P) &&
 !(data->mce->status & MCI_STATUS_AR)) {
-r = kvm_mce_in_exception(data->env);
-if (r == -1) {
-fprintf(stderr, "Failed to get MCE status\n");
-} else if (r) {
+if (kvm_mce_in_progress(data->env)) {
 return;
 }
 }
@@ -1782,10 +1780,7 @@ int kvm_on_sigbus_vcpu(CPUState *env, int code, void 
*addr)
  * If there is an MCE excpetion being processed, ignore
  * this SRAO MCE
  */
-r = kvm_mce_in_exception(env);
-if (r == -1) {
-fprintf(stderr, "Failed to get MCE status\n");
-} else if (r) {
+if (kvm_mce_in_progress(env)) {
 return 0;
 }
 /* Fake an Intel architectural Memory scrubbing UCR */
-- 
1.7.1.1


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/3] Add function for checking mca broadcast of CPU.

2010-12-10 Thread Jin Dongming
Add function for checking whether current CPU support mca broadcast.

Signed-off-by: Jin Dongming 
---
 target-i386/cpu.h|1 +
 target-i386/helper.c |   33 +
 target-i386/kvm.c|6 +-
 3 files changed, 35 insertions(+), 5 deletions(-)

diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 1f1151d..f16860f 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -762,6 +762,7 @@ int cpu_x86_exec(CPUX86State *s);
 void cpu_x86_close(CPUX86State *s);
 void x86_cpu_list (FILE *f, fprintf_function cpu_fprintf, const char *optarg);
 void x86_cpudef_setup(void);
+int cpu_x86_support_mca_broadcast(CPUState *env);
 
 int cpu_get_pic_interrupt(CPUX86State *s);
 /* MSDOS compatibility mode FPU exception support */
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 985d532..b86a6c5 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -112,6 +112,32 @@ void cpu_x86_close(CPUX86State *env)
 qemu_free(env);
 }
 
+static void cpu_x86_version(CPUState *env, int *family, int *model)
+{
+int cpuver = env->cpuid_version;
+
+if (family == NULL || model == NULL) {
+return;
+}
+
+*family = (cpuver >> 8) & 0x0f;
+*model = ((cpuver >> 12) & 0xf0) + ((cpuver >> 4) & 0x0f);
+}
+
+/* Broadcast MCA signal for processor version 06H_EH and above */
+int cpu_x86_support_mca_broadcast(CPUState *env)
+{
+int family = 0;
+int model = 0;
+
+cpu_x86_version(env, &family, &model);
+if ((family == 6 && model >= 14) || family > 6) {
+return 1;
+}
+
+return 0;
+}
+
 /***/
 /* x86 debug */
 
@@ -1082,6 +1108,13 @@ void cpu_inject_x86_mce(CPUState *cenv, int bank, 
uint64_t status,
 return;
 }
 
+if (broadcast) {
+if (!cpu_x86_support_mca_broadcast(cenv)) {
+fprintf(stderr, "Current CPU does not support broadcast\n");
+return;
+}
+}
+
 if (kvm_enabled()) {
 if (broadcast) {
 flag |= MCE_BROADCAST;
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index d866dce..a7261c0 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -1741,13 +1741,9 @@ static void hardware_memory_error(void)
 static void kvm_mce_broadcast_rest(CPUState *env)
 {
 CPUState *cenv;
-int family, model, cpuver = env->cpuid_version;
-
-family = (cpuver >> 8) & 0xf;
-model = ((cpuver >> 12) & 0xf0) + ((cpuver >> 4) & 0xf);
 
 /* Broadcast MCA signal for processor version 06H_EH and above */
-if ((family == 6 && model >= 14) || family > 6) {
+if (cpu_x86_support_mca_broadcast(env)) {
 for (cenv = first_cpu; cenv != NULL; cenv = cenv->next_cpu) {
 if (cenv == env) {
 continue;
-- 
1.7.1.1


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/3] Add "broadcast" option for mce command.

2010-12-10 Thread Jin Dongming
When the following test case is injected with mce command, maybe user could not
get the expected result.
DATA
   command cpu bank status mcg_status  addr   misc
(qemu) mce 1   10xbd00 0x050x1234 0x8c

Expected Result
   panic type: "Fatal Machine check"

That is because each mce command can only inject the given cpu and could not
inject mce interrupt to other cpus. So user will get the following result:
panic type: "Fatal machine check on current CPU"

"broadcast" option is used for injecting dummy data into other cpus. Injecting
mce with this option the expected result could be gotten.

Usage:
Broadcast[on]
   command broadcast cpu bank status mcg_status  addr   misc
(qemu) mce -b1   10xbd00 0x050x1234 0x8c

Broadcast[off]
   command cpu bank status mcg_status  addr   misc
(qemu) mce 1   10xbd00 0x05    0x1234 0x8c

Signed-off-by: Jin Dongming 
---
 cpu-all.h |3 ++-
 hmp-commands.hx   |6 +++---
 monitor.c |7 +--
 target-i386/helper.c  |   20 ++--
 target-i386/kvm.c |   16 
 target-i386/kvm_x86.h |5 -
 6 files changed, 44 insertions(+), 13 deletions(-)

diff --git a/cpu-all.h b/cpu-all.h
index 30ae17d..4ce4e83 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -964,6 +964,7 @@ int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
 uint8_t *buf, int len, int is_write);
 
 void cpu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
-uint64_t mcg_status, uint64_t addr, uint64_t misc);
+uint64_t mcg_status, uint64_t addr, uint64_t misc,
+int broadcast);
 
 #endif /* CPU_ALL_H */
diff --git a/hmp-commands.hx b/hmp-commands.hx
index d989ddb..dea5e78 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1054,9 +1054,9 @@ ETEXI
 
 {
 .name   = "mce",
-.args_type  = "cpu_index:i,bank:i,status:l,mcg_status:l,addr:l,misc:l",
-.params = "cpu bank status mcgstatus addr misc",
-.help   = "inject a MCE on the given CPU",
+.args_type  = 
"broadcast:-b,cpu_index:i,bank:i,status:l,mcg_status:l,addr:l,misc:l",
+.params = "[-b] cpu bank status mcgstatus addr misc",
+.help   = "inject a MCE on the given CPU [and broadcast to other 
CPUs with -b option]",
 .mhandler.cmd = do_inject_mce,
 },
 
diff --git a/monitor.c b/monitor.c
index ba45fb5..acdce49 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2264,12 +2264,15 @@ static void do_inject_mce(Monitor *mon, const QDict 
*qdict)
 uint64_t mcg_status = qdict_get_int(qdict, "mcg_status");
 uint64_t addr = qdict_get_int(qdict, "addr");
 uint64_t misc = qdict_get_int(qdict, "misc");
+int broadcast = qdict_get_try_bool(qdict, "broadcast", 0);
 
-for (cenv = first_cpu; cenv != NULL; cenv = cenv->next_cpu)
+for (cenv = first_cpu; cenv != NULL; cenv = cenv->next_cpu) {
 if (cenv->cpu_index == cpu_index && cenv->mcg_cap) {
-cpu_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc);
+cpu_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc,
+   broadcast);
 break;
 }
+} 
 }
 #endif
 
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 9c07c38..985d532 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -1071,18 +1071,34 @@ static void qemu_inject_x86_mce(CPUState *cenv, int 
bank, uint64_t status,
 }
 
 void cpu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
-uint64_t mcg_status, uint64_t addr, uint64_t misc)
+uint64_t mcg_status, uint64_t addr, uint64_t misc,
+int broadcast)
 {
 unsigned bank_num = cenv->mcg_cap & 0xff;
+CPUState *env;
+int flag = 0;
 
 if (bank >= bank_num || !(status & MCI_STATUS_VAL)) {
 return;
 }
 
 if (kvm_enabled()) {
-kvm_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc, 0);
+if (broadcast) {
+flag |= MCE_BROADCAST;
+}
+
+kvm_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc, flag);
 } else {
 qemu_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc);
+if (broadcast) {
+for (env = first_cpu; env != NULL; env = env->next_cpu) {
+if (cenv == env) {
+continue;
+}
+
+qemu_inject_x86_mce(env, 1, 0xa000, 0, 0, 0);
+}
+}
 }
 }
 #endif /* !CONFIG_USER_ONLY */
diff --git a/target

[PATCH 1/3] Clean up cpu_inject_x86_mce().

2010-12-10 Thread Jin Dongming
Hi, all

I am sorry for replying late.
I modified the patches as the comments of huang-san and Marcelo-san
and resend them.

Thanks.

Best Regards,
Jin Dongming
---
Clean up cpu_inject_x86_mce() for later patch.

Signed-off-by: Jin Dongming 
---
 target-i386/helper.c |   27 +--
 1 files changed, 17 insertions(+), 10 deletions(-)

diff --git a/target-i386/helper.c b/target-i386/helper.c
index d765cc6..9c07c38 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -1023,21 +1023,12 @@ static void breakpoint_handler(CPUState *env)
 /* This should come from sysemu.h - if we could include it here... */
 void qemu_system_reset_request(void);
 
-void cpu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
+static void qemu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
 uint64_t mcg_status, uint64_t addr, uint64_t misc)
 {
 uint64_t mcg_cap = cenv->mcg_cap;
-unsigned bank_num = mcg_cap & 0xff;
 uint64_t *banks = cenv->mce_banks;
 
-if (bank >= bank_num || !(status & MCI_STATUS_VAL))
-return;
-
-if (kvm_enabled()) {
-kvm_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc, 0);
-return;
-}
-
 /*
  * if MSR_MCG_CTL is not all 1s, the uncorrected error
  * reporting is disabled
@@ -1078,6 +1069,22 @@ void cpu_inject_x86_mce(CPUState *cenv, int bank, 
uint64_t status,
 } else
 banks[1] |= MCI_STATUS_OVER;
 }
+
+void cpu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
+uint64_t mcg_status, uint64_t addr, uint64_t misc)
+{
+unsigned bank_num = cenv->mcg_cap & 0xff;
+
+if (bank >= bank_num || !(status & MCI_STATUS_VAL)) {
+return;
+}
+
+if (kvm_enabled()) {
+kvm_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc, 0);
+} else {
+qemu_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc);
+}
+}
 #endif /* !CONFIG_USER_ONLY */
 
 static void mce_init(CPUX86State *cenv)
-- 
1.7.1.1


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/3] Check processor version for broadcast.

2010-11-30 Thread Jin Dongming
Hi, Huang-san

(2010/11/30 17:22), Huang Ying wrote:
> Hi, Dongming,
> 
> On Tue, 2010-11-30 at 16:15 +0800, Jin Dongming wrote:
>> Broadcast MCA signal is not supported by the CPUs whose version is
>> below 06H_EH.
>>
>> Signed-off-by: Jin Dongming 
>> ---
>>  target-i386/helper.c |   13 +
>>  1 files changed, 13 insertions(+), 0 deletions(-)
>>
>> diff --git a/target-i386/helper.c b/target-i386/helper.c
>> index 7e07ebd..437290b 100644
>> --- a/target-i386/helper.c
>> +++ b/target-i386/helper.c
>> @@ -1077,10 +1077,23 @@ void cpu_inject_x86_mce(CPUState *cenv, int bank, 
>> uint64_t status,
>>  unsigned bank_num = cenv->mcg_cap & 0xff;
>>  CPUState *env;
>>  int flag = 0;
>> +int family, model, cpuver = first_cpu->cpuid_version;
>>  
>>  if (bank >= bank_num || !(status & MCI_STATUS_VAL))
>>  return;
>>  
>> +if (broadcast) {
>> +family = (cpuver >> 8) & 0x0f;
>> +model = ((cpuver >> 12) & 0xf0) + ((cpuver >> 4) & 0x0f);
>> +
>> +if ((family == 6 && model >= 14) || family > 6)
>> +broadcast = 1;
>> +else {
>> +fprintf(stderr, "Current CPU does not support broadcast\n");
>> +return;
>> +}
>> +}
>> +
>>  if (kvm_enabled()) {
>>  if (broadcast)
>>  flag |= 0x02; /* bit 1: 1(broadcast); 0(not broadcast) */
> 
> Why not wrap this into a function? I think it may be used by other
> functions too.

I have other patchset for cleanup. So I will do it in that patchset.
Thank you!

Best Regards,
Jin Dongming
> 
> Best Regards,
> Huang Ying
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> 


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/3] Check processor version for broadcast.

2010-11-30 Thread Jin Dongming
Broadcast MCA signal is not supported by the CPUs whose version is
below 06H_EH.

Signed-off-by: Jin Dongming 
---
 target-i386/helper.c |   13 +
 1 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/target-i386/helper.c b/target-i386/helper.c
index 7e07ebd..437290b 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -1077,10 +1077,23 @@ void cpu_inject_x86_mce(CPUState *cenv, int bank, 
uint64_t status,
 unsigned bank_num = cenv->mcg_cap & 0xff;
 CPUState *env;
 int flag = 0;
+int family, model, cpuver = first_cpu->cpuid_version;
 
 if (bank >= bank_num || !(status & MCI_STATUS_VAL))
 return;
 
+if (broadcast) {
+family = (cpuver >> 8) & 0x0f;
+model = ((cpuver >> 12) & 0xf0) + ((cpuver >> 4) & 0x0f);
+
+if ((family == 6 && model >= 14) || family > 6)
+broadcast = 1;
+else {
+fprintf(stderr, "Current CPU does not support broadcast\n");
+return;
+}
+}
+
 if (kvm_enabled()) {
 if (broadcast)
 flag |= 0x02; /* bit 1: 1(broadcast); 0(not broadcast) */
-- 
1.7.1.1


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/3] Add "broadcast" option for mce command.

2010-11-30 Thread Jin Dongming
When the following test case is injected with mce command, maybe user could not
get the expected result.
DATA
   command cpu bank status mcg_status  addr   misc
(qemu) mce 1   10xbd00 0x050x1234 0x8c

Expected Result
   panic type: "Fatal Machine check"

That is because each mce command can only inject the given cpu and could not
inject mce interrupt to other cpus. So user will get the following result:
panic type: "Fatal machine check on current CPU"

"broadcast" option is used for injecting dummy data into other cpus. Injecting
mce with this option the expected result could be gotten.

Signed-off-by: Jin Dongming 
---
 cpu-all.h |3 ++-
 hmp-commands.hx   |6 +++---
 monitor.c |   18 --
 target-i386/helper.c  |   17 +++--
 target-i386/kvm.c |   12 ++--
 target-i386/kvm_x86.h |2 +-
 6 files changed, 47 insertions(+), 11 deletions(-)

diff --git a/cpu-all.h b/cpu-all.h
index 11edddc..a3b3cd8 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -967,6 +967,7 @@ int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
 uint8_t *buf, int len, int is_write);
 
 void cpu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
-uint64_t mcg_status, uint64_t addr, uint64_t misc);
+uint64_t mcg_status, uint64_t addr, uint64_t misc,
+int broadcast);
 
 #endif /* CPU_ALL_H */
diff --git a/hmp-commands.hx b/hmp-commands.hx
index ba6de28..44ad571 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1053,9 +1053,9 @@ ETEXI
 
 {
 .name   = "mce",
-.args_type  = "cpu_index:i,bank:i,status:l,mcg_status:l,addr:l,misc:l",
-.params = "cpu bank status mcgstatus addr misc",
-.help   = "inject a MCE on the given CPU",
+.args_type  = 
"cpu_index:i,bank:i,status:l,mcg_status:l,addr:l,misc:l,broadcast:s?",
+.params = "cpu bank status mcgstatus addr misc [broadcast|b]",
+.help   = "inject a MCE on the given CPU [and broadcast to other 
CPUs]",
 .mhandler.cmd = do_inject_mce,
 },
 
diff --git a/monitor.c b/monitor.c
index 66d6acd..e316eb6 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2263,12 +2263,26 @@ static void do_inject_mce(Monitor *mon, const QDict 
*qdict)
 uint64_t mcg_status = qdict_get_int(qdict, "mcg_status");
 uint64_t addr = qdict_get_int(qdict, "addr");
 uint64_t misc = qdict_get_int(qdict, "misc");
+const char *b = qdict_get_try_str(qdict, "broadcast");
+int broadcast = 0;
 
-for (cenv = first_cpu; cenv != NULL; cenv = cenv->next_cpu)
+if (b) {
+if (!strncmp(b, "broadcast", sizeof("broadcast")) ||
+!strncmp(b, "b", sizeof("b"))) {
+broadcast = 1;
+} else {
+monitor_printf(mon, "unexpected option: %s\n", b);
+return;
+}
+}
+
+for (cenv = first_cpu; cenv != NULL; cenv = cenv->next_cpu) {
 if (cenv->cpu_index == cpu_index && cenv->mcg_cap) {
-cpu_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc);
+cpu_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc,
+   broadcast);
 break;
 }
+} 
 }
 #endif
 
diff --git a/target-i386/helper.c b/target-i386/helper.c
index e384fdc..7e07ebd 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -1071,17 +1071,30 @@ static void qemu_inject_x86_mce(CPUState *cenv, int 
bank, uint64_t status,
 }
 
 void cpu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
-uint64_t mcg_status, uint64_t addr, uint64_t misc)
+uint64_t mcg_status, uint64_t addr, uint64_t misc,
+int broadcast)
 {
 unsigned bank_num = cenv->mcg_cap & 0xff;
+CPUState *env;
+int flag = 0;
 
 if (bank >= bank_num || !(status & MCI_STATUS_VAL))
 return;
 
 if (kvm_enabled()) {
-kvm_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc, 0);
+if (broadcast)
+flag |= 0x02; /* bit 1: 1(broadcast); 0(not broadcast) */
+kvm_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc, flag);
 } else {
 qemu_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc);
+if (broadcast) {
+for (env = first_cpu; env != NULL; env = env->next_cpu) {
+if (cenv == env)
+continue;
+
+qemu_inject_x86_mce(env, 1, 0xa000, 0, 0, 0);
+}
+}
 }
 }
 #endif /* !CONFIG_USER_ONLY */
diff --git a/target-i386/kvm.c b/target-i38

[PATCH 1/3] Clean up cpu_inject_x86_mce().

2010-11-30 Thread Jin Dongming
Clean up cpu_inject_x86_mce() for later patch.

Signed-off-by: Jin Dongming 
---
 target-i386/helper.c |   26 --
 1 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/target-i386/helper.c b/target-i386/helper.c
index f5c06a8..e384fdc 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -1023,21 +1023,12 @@ static void breakpoint_handler(CPUState *env)
 /* This should come from sysemu.h - if we could include it here... */
 void qemu_system_reset_request(void);
 
-void cpu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
+static void qemu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
 uint64_t mcg_status, uint64_t addr, uint64_t misc)
 {
 uint64_t mcg_cap = cenv->mcg_cap;
-unsigned bank_num = mcg_cap & 0xff;
 uint64_t *banks = cenv->mce_banks;
 
-if (bank >= bank_num || !(status & MCI_STATUS_VAL))
-return;
-
-if (kvm_enabled()) {
-kvm_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc, 0);
-return;
-}
-
 /*
  * if MSR_MCG_CTL is not all 1s, the uncorrected error
  * reporting is disabled
@@ -1078,6 +1069,21 @@ void cpu_inject_x86_mce(CPUState *cenv, int bank, 
uint64_t status,
 } else
 banks[1] |= MCI_STATUS_OVER;
 }
+
+void cpu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
+uint64_t mcg_status, uint64_t addr, uint64_t misc)
+{
+unsigned bank_num = cenv->mcg_cap & 0xff;
+
+if (bank >= bank_num || !(status & MCI_STATUS_VAL))
+return;
+
+if (kvm_enabled()) {
+kvm_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc, 0);
+} else {
+qemu_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc);
+}
+}
 #endif /* !CONFIG_USER_ONLY */
 
 static void mce_init(CPUX86State *cenv)
-- 
1.7.1.1


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/2] reset mce registers of the given VCPU or all VCPUs with mce command.

2010-11-25 Thread Jin Dongming
Hi, Huang-san

(2010/11/25 14:55), Huang Ying wrote:
> On Thu, 2010-11-25 at 09:20 +0800, Jin Dongming wrote:
>> --- a/monitor.c
>> +++ b/monitor.c
>> @@ -60,6 +60,7 @@
>>  #include "trace.h"
>>  #endif
>>  #include "qemu-kvm.h"
>> +#include "kvm_x86.h"
>>  
>>  //#define DEBUG
>>  //#define DEBUG_COMPLETION
>> @@ -2277,7 +2278,19 @@ static void do_inject_mce(Monitor *mon, const QDict 
>> *qdict)
>>  #endif
>>  
>>  for (cenv = first_cpu; cenv != NULL; cenv = cenv->next_cpu) {
>> -if (cenv->cpu_index == cpu_index && cenv->mcg_cap) {
>> +if (!cenv->mcg_cap)
>> +continue;
>> +
>> +#if defined(KVM_CAP_MCE)
>> +if (!status && !mcg_status) {
>> +if (cenv->cpu_index == cpu_index || broadcast)
>> +kvm_inject_x86_mce(cenv, 0, 0, 0, 0, 0, 0);
>> +
>> +continue;
>> +}
>> +#endif
>> +
>> +if (cenv->cpu_index == cpu_index) {
>>  cpu_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc);
>>  #if defined(KVM_CAP_MCE)
>>  if (broadcast)
> 
> Are you sure there is no test cases that require the Machine Check
> registers not cleared? I have had a test case before that injects
> another MCE when MCIP in MCGSTATUS is set to check whether system will
> go reset.
> 
> It may be better to clear MC registers in an explicit mode.
MC registers could be cleared in Guest OS with APL. So I will cancel this patch.

I will resend the patch for broadcast option.

Best Regards,
Jin Dongming
> 
> Best Regards,
> Huang Ying
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> 


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Add function for clearing the requested VCPUs' mce registers.

2010-11-25 Thread Jin Dongming
Hi, Huang-san

(2010/11/25 14:44), Huang Ying wrote:
> On Thu, 2010-11-25 at 13:30 +0800, Jin Dongming wrote:
>> Hi, Huang-san
>>
>> (2010/11/25 10:27), Huang Ying wrote:
>>> Hi, Dongming,
>>>
>>> On Thu, 2010-11-25 at 09:14 +0800, Jin Dongming wrote:
>>>> In some case of mce test, the injected data can be remained
>>>> in the registers and ca affect to the result of following test cases.
>>>> So add codes for clearing mce registers of given VCPU.
>>>>
>>>> mce registers of give VCPU could be cleared from kernel by calling
>>>> the function in this patch.  What need to be paid attention is that
>>>> the status and mcg_status of mce must be set with 0. If not, mce
>>>> registers will not be cleared.
>>>
>>> Why do you need this? To use "mce=3" in guest Linux MCE testing?
>> When I set fake_panic==1 on Guest OS and tested mce via qemu-monitor,
>> I got the wrong result sometimes. The reason why I got the wrong result
>> was that mce registers were not cleared. So I made this patch.
> 
> This can be done in QEMU via KVM_SET_MSRS too.
Yes, it could be done in Guest OS with APL. So I will cancel this patch.

Best Regards,
Jin Dongming
>  
>>> If it is, why not use full reboot? MCE registers are not cleared in real
>>> machine too. And it is not so pain to reboot the guest.
>> Though we know that mce registers could be cleared by rebooting the Guest
>> Machine and the reboot of Guest Machine could save much more time than
>> the reboot of Host Machine, it is still slower than setting
>> fake_panic==1 to mce test.
> 
> Best Regards,
> Huang Ying
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> 


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Add function for clearing the requested VCPUs' mce registers.

2010-11-24 Thread Jin Dongming
Hi, Huang-san

(2010/11/25 10:27), Huang Ying wrote:
> Hi, Dongming,
> 
> On Thu, 2010-11-25 at 09:14 +0800, Jin Dongming wrote:
>> In some case of mce test, the injected data can be remained
>> in the registers and ca affect to the result of following test cases.
>> So add codes for clearing mce registers of given VCPU.
>>
>> mce registers of give VCPU could be cleared from kernel by calling
>> the function in this patch.  What need to be paid attention is that
>> the status and mcg_status of mce must be set with 0. If not, mce
>> registers will not be cleared.
> 
> Why do you need this? To use "mce=3" in guest Linux MCE testing?
When I set fake_panic==1 on Guest OS and tested mce via qemu-monitor,
I got the wrong result sometimes. The reason why I got the wrong result
was that mce registers were not cleared. So I made this patch.


> 
> If it is, why not use full reboot? MCE registers are not cleared in real
> machine too. And it is not so pain to reboot the guest.
Though we know that mce registers could be cleared by rebooting the Guest
Machine and the reboot of Guest Machine could save much more time than
the reboot of Host Machine, it is still slower than setting
fake_panic==1 to mce test.

Best Regards,
Jin Dongming
> 
> Best Regards,
> Huang Ying
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> 


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/2] Add "broadcast" option for mce command.

2010-11-24 Thread Jin Dongming
Hi, Huang-san

(2010/11/25 10:33), Huang Ying wrote:
> On Thu, 2010-11-25 at 09:19 +0800, Jin Dongming wrote:
> [...]
> 
>> --- a/hmp-commands.hx
>> +++ b/hmp-commands.hx
>> @@ -1053,9 +1053,15 @@ ETEXI
>>  
>>  {
>>  .name   = "mce",
>> +#if defined(KVM_CAP_MCE)
>> +.args_type  = 
>> "cpu_index:i,bank:i,status:l,mcg_status:l,addr:l,misc:l,broadcast:s?",
>> +.params = "cpu bank status mcgstatus addr misc [broadcast|b]",
>> +.help   = "inject a MCE on the given CPU [and broadcast to 
>> other CPUs]",
>> +#else
>>  .args_type  = 
>> "cpu_index:i,bank:i,status:l,mcg_status:l,addr:l,misc:l",
>>  .params = "cpu bank status mcgstatus addr misc",
>>  .help   = "inject a MCE on the given CPU",
>> +#endif
> 
> Broadcast can not be used by QEMU-TCG?
I must say sorry, I don't know much about QEMU-TCG.

Because broadcast option used kvm_mce_broadcast_rest() in KVM_CAP_MCE,
so if KVM_CAP_MCE is disabled, broadcast option could not work well.

And I don't know how mce command is used in other virtual machine
without KVM module, so I add ifdef to make sure this patch does not give
any impact to other virtual machine without KVM module.

Best Regards,
Jin Dongming
> 
> [...]
> 
> Best Regards,
> Huang Ying
> 
> 
> 
> 


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] reset mce registers of the given VCPU or all VCPUs with mce command.

2010-11-24 Thread Jin Dongming
For saving test time, fake_panic will be set when mce test is done.
After setting fake_panic==1, injecting mce from qemu-monitor to test
mce of Guest OS, fatal mce data of last time will not be cleared.
And the result of this time is not right.

Before testing mce, mce registers could be reset with mce command now.
This operation could be sure the result more reliable.

The usage of resetting mce registers with mce command is like following:

   COMMAND CPU BANK STATUS MCG_STATUS ADDR MISC BROADCAST
given VCPU: (qemu) mce N   00  0  00-
all VCPUs:  (qemu) mce N   00  0  00broadcast/b

(Comment: "N" is the number of VCPU; "-" means no option.)

Signed-off-by: Jin Dongming 
---
 hmp-commands.hx |4 +++-
 monitor.c   |   15 ++-
 2 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 3a93837..3f1389d 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1056,7 +1056,9 @@ ETEXI
 #if defined(KVM_CAP_MCE)
 .args_type  = 
"cpu_index:i,bank:i,status:l,mcg_status:l,addr:l,misc:l,broadcast:s?",
 .params = "cpu bank status mcgstatus addr misc [broadcast|b]",
-.help   = "inject a MCE on the given CPU [and broadcast to other 
CPUs]",
+.help   = "\n1. inject a MCE on the given CPU [and broadcast to 
other CPUs] \
+   \n2. reset MCE registers on the given CPU with !status 
and !mcg_status \
+   \n   [and reset other CPUs with broadcast/b option]",
 #else
 .args_type  = "cpu_index:i,bank:i,status:l,mcg_status:l,addr:l,misc:l",
 .params = "cpu bank status mcgstatus addr misc",
diff --git a/monitor.c b/monitor.c
index 9d0a98e..419fafd 100644
--- a/monitor.c
+++ b/monitor.c
@@ -60,6 +60,7 @@
 #include "trace.h"
 #endif
 #include "qemu-kvm.h"
+#include "kvm_x86.h"
 
 //#define DEBUG
 //#define DEBUG_COMPLETION
@@ -2277,7 +2278,19 @@ static void do_inject_mce(Monitor *mon, const QDict 
*qdict)
 #endif
 
 for (cenv = first_cpu; cenv != NULL; cenv = cenv->next_cpu) {
-if (cenv->cpu_index == cpu_index && cenv->mcg_cap) {
+if (!cenv->mcg_cap)
+continue;
+
+#if defined(KVM_CAP_MCE)
+if (!status && !mcg_status) {
+if (cenv->cpu_index == cpu_index || broadcast)
+kvm_inject_x86_mce(cenv, 0, 0, 0, 0, 0, 0);
+
+continue;
+}
+#endif
+
+if (cenv->cpu_index == cpu_index) {
 cpu_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc);
 #if defined(KVM_CAP_MCE)
 if (broadcast)
-- 
1.7.1.1


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/2] Add "broadcast" option for mce command.

2010-11-24 Thread Jin Dongming
When the following test case is injected with mce command, maybe user could not
get the expected result.
DATA
   command cpu bank status mcg_status  addr   misc
(qemu) mce 1   10xbd00 0x050x1234 0x8c

Expected Result
   panic type: "Fatal Machine check"

That is because each mce command can only inject the given cpu and could not
inject mce interrupt to other cpus. So user will get the following result:
panic type: "Fatal machine check on current CPU"

"broadcast" option is used for injecting dummy data into other cpus. Injecting 
mce
with this option the expected result could be gotten.

Signed-off-by: Jin Dongming 
---
 hmp-commands.hx   |6 ++
 monitor.c |   19 ++-
 qemu-kvm.h|3 +++
 target-i386/kvm.c |2 +-
 4 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index ba6de28..3a93837 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1053,9 +1053,15 @@ ETEXI
 
 {
 .name   = "mce",
+#if defined(KVM_CAP_MCE)
+.args_type  = 
"cpu_index:i,bank:i,status:l,mcg_status:l,addr:l,misc:l,broadcast:s?",
+.params = "cpu bank status mcgstatus addr misc [broadcast|b]",
+.help   = "inject a MCE on the given CPU [and broadcast to other 
CPUs]",
+#else
 .args_type  = "cpu_index:i,bank:i,status:l,mcg_status:l,addr:l,misc:l",
 .params = "cpu bank status mcgstatus addr misc",
 .help   = "inject a MCE on the given CPU",
+#endif
 .mhandler.cmd = do_inject_mce,
 },
 
diff --git a/monitor.c b/monitor.c
index 66d6acd..9d0a98e 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2263,12 +2263,29 @@ static void do_inject_mce(Monitor *mon, const QDict 
*qdict)
 uint64_t mcg_status = qdict_get_int(qdict, "mcg_status");
 uint64_t addr = qdict_get_int(qdict, "addr");
 uint64_t misc = qdict_get_int(qdict, "misc");
+#if defined(KVM_CAP_MCE)
+const char *b = qdict_get_try_str(qdict, "broadcast");
+int broadcast = 0;
 
-for (cenv = first_cpu; cenv != NULL; cenv = cenv->next_cpu)
+if (b) {
+if (!strncmp(b, "broadcast", sizeof("broadcast")) ||
+!strncmp(b, "b", sizeof("b"))) {
+broadcast = 1;
+} else
+monitor_printf(mon, "Don't do broadcast: option invalid: %s\n", b);
+}
+#endif
+
+for (cenv = first_cpu; cenv != NULL; cenv = cenv->next_cpu) {
 if (cenv->cpu_index == cpu_index && cenv->mcg_cap) {
 cpu_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc);
+#if defined(KVM_CAP_MCE)
+if (broadcast)
+kvm_mce_broadcast_rest(cenv);
+#endif
 break;
 }
+} 
 }
 #endif
 
diff --git a/qemu-kvm.h b/qemu-kvm.h
index 0f3fb50..b3986cc 100644
--- a/qemu-kvm.h
+++ b/qemu-kvm.h
@@ -98,6 +98,9 @@ int try_push_interrupts(kvm_context_t kvm);
 
 #if defined(__x86_64__) || defined(__i386__)
 struct kvm_x86_mce;
+#if defined KVM_CAP_MCE
+extern void kvm_mce_broadcast_rest(CPUState *env);
+#endif
 #endif
 
 /*!
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index b7b2430..e3ebbb2 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -1705,7 +1705,7 @@ static void hardware_memory_error(void)
 }
 
 #ifdef KVM_CAP_MCE
-static void kvm_mce_broadcast_rest(CPUState *env)
+void kvm_mce_broadcast_rest(CPUState *env)
 {
 CPUState *cenv;
 int family, model, cpuver = env->cpuid_version;
-- 
1.7.1.1


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] Add function for clearing the requested VCPUs' mce registers.

2010-11-24 Thread Jin Dongming
In some case of mce test, the injected data can be remained
in the registers and ca affect to the result of following test cases.
So add codes for clearing mce registers of given VCPU.

mce registers of give VCPU could be cleared from kernel by calling
the function in this patch.  What need to be paid attention is that
the status and mcg_status of mce must be set with 0. If not, mce
registers will not be cleared.

Signed-off-by: Jin Dongming 
---
 arch/x86/kvm/x86.c |   28 +++-
 1 files changed, 27 insertions(+), 1 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 3a09c62..9c2cdfc 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2246,6 +2246,25 @@ out:
return r;
 }
 
+static void kvm_vcpu_x86_clear_mce(struct kvm_vcpu *vcpu,
+ struct kvm_x86_mce *mce)
+{
+   u64 *banks = vcpu->arch.mce_banks;
+   u64 mcg_cap = vcpu->arch.mcg_cap;
+
+   unsigned bank_num = mcg_cap & 0xff;
+   int i = 0;
+
+   for (i = 0; i < bank_num; i++) {
+   banks[1] = 0;
+   banks[2] = 0;
+   banks[3] = 0;
+   banks += 4;
+   }
+
+   vcpu->arch.mcg_status = 0;
+}
+
 static int kvm_vcpu_ioctl_x86_set_mce(struct kvm_vcpu *vcpu,
  struct kvm_x86_mce *mce)
 {
@@ -2253,8 +2272,15 @@ static int kvm_vcpu_ioctl_x86_set_mce(struct kvm_vcpu 
*vcpu,
unsigned bank_num = mcg_cap & 0xff;
u64 *banks = vcpu->arch.mce_banks;
 
-   if (mce->bank >= bank_num || !(mce->status & MCI_STATUS_VAL))
+   if (mce->bank >= bank_num)
return -EINVAL;
+   if (!(mce->status & MCI_STATUS_VAL)) {
+   if (!mce->status && !mce->mcg_status) {
+   kvm_vcpu_x86_clear_mce(vcpu, mce);
+   return 0;
+   }
+   return -EINVAL;
+   }
/*
 * if IA32_MCG_CTL is not all 1s, the uncorrected error
 * reporting is disabled
-- 
1.7.1.1


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 11/11] kvm, x86: broadcast mce depending on the cpu version

2010-10-14 Thread Jin Dongming
There is no reason why SRAO event received by the main thread
is the only one that being broadcasted.

According to the x86 ASDM vol.3A 15.10.4.1,
MCE signal is broadcast on processor version 06H_EH or later.

This change is required to handle SRAR in the guest.

Signed-off-by: Hidetoshi Seto 
Tested-by: Jin Dongming 
---
 qemu-kvm.c |   63 +--
 1 files changed, 31 insertions(+), 32 deletions(-)

diff --git a/qemu-kvm.c b/qemu-kvm.c
index d2b2459..846f0b6 100644
--- a/qemu-kvm.c
+++ b/qemu-kvm.c
@@ -1149,6 +1149,34 @@ static int kvm_mce_in_progress(CPUState *env)
 return !!(msr_mcg_status.data & MCG_STATUS_MCIP);
 }
 
+static void kvm_mce_inj_broadcast(CPUState *env, struct kvm_x86_mce *mce)
+{
+struct kvm_x86_mce mce_sub = {
+.bank = 1,
+.status = MCI_STATUS_VAL | MCI_STATUS_UC,
+.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV,
+.addr = 0,
+.misc = 0,
+};
+CPUState *cenv;
+int family, model, cpuver = env->cpuid_version;
+
+family = (cpuver >> 8) & 0xf;
+model = ((cpuver >> 12) & 0xf0) + ((cpuver >> 4) & 0xf);
+
+kvm_inject_x86_mce_on(env, mce, 1);
+
+/* Broadcast MCA signal for processor version 06H_EH and above */
+if ((family == 6 && model >= 14) || family > 6) {
+for (cenv = first_cpu; cenv != NULL; cenv = cenv->next_cpu) {
+if (cenv == env) {
+continue;
+}
+kvm_inject_x86_mce_on(cenv, &mce_sub, 1);
+}
+}
+}
+
 static void kvm_do_set_mce(CPUState *env, struct kvm_x86_mce *mce,
int abort_on_error)
 {
@@ -1175,7 +1203,7 @@ static void kvm_mce_inj_srar_dataload(CPUState *env, 
target_phys_addr_t paddr)
 .misc = (MCM_ADDR_PHYS << 6) | 0xc,
 };
 
-kvm_do_set_mce(env, &mce, 1);
+kvm_mce_inj_broadcast(env, &mce);
 }
 
 static void kvm_mce_inj_srao_memscrub(CPUState *env, target_phys_addr_t paddr)
@@ -1190,32 +1218,7 @@ static void kvm_mce_inj_srao_memscrub(CPUState *env, 
target_phys_addr_t paddr)
 .misc = (MCM_ADDR_PHYS << 6) | 0xc,
 };
 
-kvm_do_set_mce(env, &mce, 1);
-}
-
-static void kvm_mce_inj_srao_broadcast(target_phys_addr_t paddr)
-{
-struct kvm_x86_mce mce_srao_memscrub = {
-.bank = 9,
-.status = MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN
-  | MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S
-  | 0xc0,
-.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV,
-.addr = paddr,
-.misc = (MCM_ADDR_PHYS << 6) | 0xc,
-};
-struct kvm_x86_mce mce_dummy = {
-.bank = 1,
-.status = MCI_STATUS_VAL | MCI_STATUS_UC,
-.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV,
-.addr = 0,
-.misc = 0,
-};
-CPUState *cenv;
-
-kvm_inject_x86_mce_on(first_cpu, &mce_srao_memscrub, 1);
-for (cenv = first_cpu->next_cpu; cenv != NULL; cenv = cenv->next_cpu)
-kvm_inject_x86_mce_on(cenv, &mce_dummy, 1);
+kvm_mce_inj_broadcast(env, &mce);
 }
 #endif
 
@@ -1255,11 +1258,7 @@ static void kvm_handle_sigbus(CPUState *env, int code, 
void *vaddr)
 kvm_mce_inj_srar_dataload(target_env, paddr);
 } else {
 /* Fake an Intel architectural Memory scrubbing UCR */
-if (env) {
-kvm_mce_inj_srao_memscrub(target_env, paddr);
-} else {
-kvm_mce_inj_srao_broadcast(paddr);
-}
+kvm_mce_inj_srao_memscrub(target_env, paddr);
 }
 return;
 }
-- 
1.7.1.1


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 10/11] kvm, x86: unify sigbus handling, post2

2010-10-14 Thread Jin Dongming
Cleanup to finish unification.

Signed-off-by: Hidetoshi Seto 
Tested-by: Jin Dongming 
---
 qemu-kvm.c |   41 -
 1 files changed, 12 insertions(+), 29 deletions(-)

diff --git a/qemu-kvm.c b/qemu-kvm.c
index d96394b..d2b2459 100644
--- a/qemu-kvm.c
+++ b/qemu-kvm.c
@@ -1222,45 +1222,24 @@ static void 
kvm_mce_inj_srao_broadcast(target_phys_addr_t paddr)
 static void kvm_handle_sigbus(CPUState *env, int code, void *vaddr)
 {
 #if defined(KVM_CAP_MCE) && defined(TARGET_I386)
-/* env == NULL: when main thread received a SIGBUS */
-if (!env && vaddr && (code == BUS_MCEERR_AR || code == BUS_MCEERR_AO)) {
+if (vaddr && (code == BUS_MCEERR_AO || code == BUS_MCEERR_AR)) {
 ram_addr_t ram_addr;
 target_phys_addr_t paddr;
+CPUState *target_env;
 
 /* Give up MCE forwarding if immediate action required on main thread 
*/
-if (code == BUS_MCEERR_AR) {
+if (!env && code == BUS_MCEERR_AR) {
 goto out;
 }
 
 /* Check if recoverable MCE support is enabled */
-if (!(first_cpu->mcg_cap & MCG_SER_P)){
-goto out;
-}
-
-if (do_qemu_ram_addr_from_host(vaddr, &ram_addr) ||
-!kvm_physical_memory_addr_from_ram(kvm_state, ram_addr, &paddr)) {
-fprintf(stderr, "Hardware memory error for memory used by "
-"QEMU itself instead of guest system!: %llx\n",
-(unsigned long long)vaddr);
-return;
-}
-/* Broadcast SRAO UCR to all vcpu threads */
-kvm_mce_inj_srao_broadcast(paddr);
-return;
-}
-
-/* env != NULL: when vcpu thread received a SIGBUS */
-if (env && vaddr && (code == BUS_MCEERR_AR || code == BUS_MCEERR_AO)) {
-ram_addr_t ram_addr;
-unsigned long paddr;
-
-/* Check if recoverable MCE support is enabled */
-if (!(env->mcg_cap & MCG_SER_P)){
+target_env = env ? env : first_cpu;
+if (!target_env || !(target_env->mcg_cap & MCG_SER_P)) {
 goto out;
 }
 
 /* If there is an MCE exception being processed, ignore this SRAO MCE 
*/
-if (code == BUS_MCEERR_AO && kvm_mce_in_progress(env)) {
+if (env && code == BUS_MCEERR_AO && kvm_mce_in_progress(env)) {
 return;
 }
 
@@ -1273,10 +1252,14 @@ static void kvm_handle_sigbus(CPUState *env, int code, 
void *vaddr)
 }
 if (code == BUS_MCEERR_AR) {
 /* Fake an Intel architectural Data Load SRAR UCR */
-kvm_mce_inj_srar_dataload(env, paddr);
+kvm_mce_inj_srar_dataload(target_env, paddr);
 } else {
 /* Fake an Intel architectural Memory scrubbing UCR */
-kvm_mce_inj_srao_memscrub(env, paddr);
+if (env) {
+kvm_mce_inj_srao_memscrub(target_env, paddr);
+} else {
+kvm_mce_inj_srao_broadcast(paddr);
+}
 }
 return;
 }
-- 
1.7.1.1


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 09/11] kvm, x86: unify sigbus handling, post1

2010-10-14 Thread Jin Dongming
Explicitly duplicate blocks for next cleanup.

Signed-off-by: Hidetoshi Seto 
Tested-by: Jin Dongming 
---
 qemu-kvm.c |   56 +---
 1 files changed, 33 insertions(+), 23 deletions(-)

diff --git a/qemu-kvm.c b/qemu-kvm.c
index 16bc006..d96394b 100644
--- a/qemu-kvm.c
+++ b/qemu-kvm.c
@@ -1223,12 +1223,20 @@ static void kvm_handle_sigbus(CPUState *env, int code, 
void *vaddr)
 {
 #if defined(KVM_CAP_MCE) && defined(TARGET_I386)
 /* env == NULL: when main thread received a SIGBUS */
-if (!env && (first_cpu->mcg_cap & MCG_SER_P) && vaddr
-&& code == BUS_MCEERR_AO) {
+if (!env && vaddr && (code == BUS_MCEERR_AR || code == BUS_MCEERR_AO)) {
 ram_addr_t ram_addr;
 target_phys_addr_t paddr;
 
-/* Hope we are lucky for AO MCE */
+/* Give up MCE forwarding if immediate action required on main thread 
*/
+if (code == BUS_MCEERR_AR) {
+goto out;
+}
+
+/* Check if recoverable MCE support is enabled */
+if (!(first_cpu->mcg_cap & MCG_SER_P)){
+goto out;
+}
+
 if (do_qemu_ram_addr_from_host(vaddr, &ram_addr) ||
 !kvm_physical_memory_addr_from_ram(kvm_state, ram_addr, &paddr)) {
 fprintf(stderr, "Hardware memory error for memory used by "
@@ -1236,19 +1244,22 @@ static void kvm_handle_sigbus(CPUState *env, int code, 
void *vaddr)
 (unsigned long long)vaddr);
 return;
 }
+/* Broadcast SRAO UCR to all vcpu threads */
 kvm_mce_inj_srao_broadcast(paddr);
 return;
 }
 
 /* env != NULL: when vcpu thread received a SIGBUS */
-if (env && (env->mcg_cap & MCG_SER_P) && vaddr
-&& (code == BUS_MCEERR_AR || code == BUS_MCEERR_AO)) {
+if (env && vaddr && (code == BUS_MCEERR_AR || code == BUS_MCEERR_AO)) {
 ram_addr_t ram_addr;
 unsigned long paddr;
 
-/*
- * If there is an MCE excpetion being processed, ignore this SRAO MCE
- */
+/* Check if recoverable MCE support is enabled */
+if (!(env->mcg_cap & MCG_SER_P)){
+goto out;
+}
+
+/* If there is an MCE exception being processed, ignore this SRAO MCE 
*/
 if (code == BUS_MCEERR_AO && kvm_mce_in_progress(env)) {
 return;
 }
@@ -1256,13 +1267,9 @@ static void kvm_handle_sigbus(CPUState *env, int code, 
void *vaddr)
 if (do_qemu_ram_addr_from_host(vaddr, &ram_addr) ||
 !kvm_physical_memory_addr_from_ram(kvm_state, ram_addr, &paddr)) {
 fprintf(stderr, "Hardware memory error for memory used by "
-"QEMU itself instaed of guest system!\n");
-/* Hope we are lucky for AO MCE */
-if (code == BUS_MCEERR_AO) {
-return;
-} else {
-hardware_memory_error();
-}
+"QEMU itself instead of guest system!: %llx\n",
+(unsigned long long)vaddr);
+goto out;
 }
 if (code == BUS_MCEERR_AR) {
 /* Fake an Intel architectural Data Load SRAR UCR */
@@ -1273,15 +1280,18 @@ static void kvm_handle_sigbus(CPUState *env, int code, 
void *vaddr)
 }
 return;
 }
+out:
 #endif
-{
-if (code == BUS_MCEERR_AO) {
-return;
-} else if (code == BUS_MCEERR_AR) {
-hardware_memory_error();
-} else {
-sigbus_reraise();
-}
+/* Hope we are lucky for AO MCE */
+if (code == BUS_MCEERR_AO) {
+return;
+}
+
+/* Abort in either way */
+if (code == BUS_MCEERR_AR) {
+hardware_memory_error();
+} else {
+sigbus_reraise();
 }
 }
 
-- 
1.7.1.1


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 08/11] kvm, x86: unify sigbus handling

2010-10-14 Thread Jin Dongming
Now kvm_handle_sigbus can handle both cases of SIGBUS.

Note that env is NULL when main thread receives SIGBUS via
signalfd, otherwise env points vcpu thread that receives SIGBUS.

Signed-off-by: Hidetoshi Seto 
Tested-by: Jin Dongming 
---
 qemu-kvm.c |   94 +++-
 1 files changed, 42 insertions(+), 52 deletions(-)

diff --git a/qemu-kvm.c b/qemu-kvm.c
index b58181a..16bc006 100644
--- a/qemu-kvm.c
+++ b/qemu-kvm.c
@@ -1219,10 +1219,12 @@ static void 
kvm_mce_inj_srao_broadcast(target_phys_addr_t paddr)
 }
 #endif
 
-static void kvm_handle_sigbus(int code, void *vaddr)
+static void kvm_handle_sigbus(CPUState *env, int code, void *vaddr)
 {
 #if defined(KVM_CAP_MCE) && defined(TARGET_I386)
-if ((first_cpu->mcg_cap & MCG_SER_P) && vaddr && code == BUS_MCEERR_AO) {
+/* env == NULL: when main thread received a SIGBUS */
+if (!env && (first_cpu->mcg_cap & MCG_SER_P) && vaddr
+&& code == BUS_MCEERR_AO) {
 ram_addr_t ram_addr;
 target_phys_addr_t paddr;
 
@@ -1235,7 +1237,42 @@ static void kvm_handle_sigbus(int code, void *vaddr)
 return;
 }
 kvm_mce_inj_srao_broadcast(paddr);
-} else
+return;
+}
+
+/* env != NULL: when vcpu thread received a SIGBUS */
+if (env && (env->mcg_cap & MCG_SER_P) && vaddr
+&& (code == BUS_MCEERR_AR || code == BUS_MCEERR_AO)) {
+ram_addr_t ram_addr;
+unsigned long paddr;
+
+/*
+ * If there is an MCE excpetion being processed, ignore this SRAO MCE
+ */
+if (code == BUS_MCEERR_AO && kvm_mce_in_progress(env)) {
+return;
+}
+
+if (do_qemu_ram_addr_from_host(vaddr, &ram_addr) ||
+!kvm_physical_memory_addr_from_ram(kvm_state, ram_addr, &paddr)) {
+fprintf(stderr, "Hardware memory error for memory used by "
+"QEMU itself instaed of guest system!\n");
+/* Hope we are lucky for AO MCE */
+if (code == BUS_MCEERR_AO) {
+return;
+} else {
+hardware_memory_error();
+}
+}
+if (code == BUS_MCEERR_AR) {
+/* Fake an Intel architectural Data Load SRAR UCR */
+kvm_mce_inj_srar_dataload(env, paddr);
+} else {
+/* Fake an Intel architectural Memory scrubbing UCR */
+kvm_mce_inj_srao_memscrub(env, paddr);
+}
+return;
+}
 #endif
 {
 if (code == BUS_MCEERR_AO) {
@@ -1250,7 +1287,7 @@ static void kvm_handle_sigbus(int code, void *vaddr)
 
 static void sigbus_handler(int n, struct qemu_signalfd_siginfo *ssi, void *ctx)
 {
-kvm_handle_sigbus(ssi->ssi_code, (void *)(intptr_t)ssi->ssi_addr);
+kvm_handle_sigbus(NULL, ssi->ssi_code, (void *)(intptr_t)ssi->ssi_addr);
 }
 
 static void on_vcpu(CPUState *env, void (*func)(void *data), void *data)
@@ -1378,53 +1415,6 @@ static void flush_queued_work(CPUState *env)
 pthread_cond_broadcast(&qemu_work_cond);
 }
 
-static void kvm_on_sigbus(CPUState *env, int code, void *vaddr)
-{
-#if defined(KVM_CAP_MCE) && defined(TARGET_I386)
-ram_addr_t ram_addr;
-target_phys_addr_t paddr;
-
-if ((env->mcg_cap & MCG_SER_P) && vaddr
-&& (code == BUS_MCEERR_AR || code == BUS_MCEERR_AO)) {
-
-/*
- * If there is an MCE excpetion being processed, ignore this SRAO MCE
- */
-if (code == BUS_MCEERR_AO && kvm_mce_in_progress(env)) }
-return;
-}
-
-if (do_qemu_ram_addr_from_host(vaddr, &ram_addr) ||
-!kvm_physical_memory_addr_from_ram(kvm_state, ram_addr, &paddr)) {
-fprintf(stderr, "Hardware memory error for memory used by "
-"QEMU itself instead of guest system!\n");
-/* Hope we are lucky for AO MCE */
-if (code == BUS_MCEERR_AO) {
-return;
-} else {
-hardware_memory_error();
-}
-}
-if (code == BUS_MCEERR_AR) {
-/* Fake an Intel architectural Data Load SRAR UCR */
-kvm_mce_inj_srar_dataload(env, paddr);
-} else {
-/* Fake an Intel architectural Memory scrubbing UCR */
-kvm_mce_inj_srao_memscrub(env, paddr);
-}
-} else
-#endif
-{
-if (code == BUS_MCEERR_AO) {
-return;
-} else if (code == BUS_MCEERR_AR) {
-hardware_memory_error();
-} else {
-sigbus_reraise();
-}
-}
-}
-
 static void kvm_main_loop_wait(CPUState *env, int timeout)
 {
 struct timespec ts;
@@ -1454,7 +1444,7 @@ static void kvm_main_loop_wait(CPUState *env, int timeout)
 
 switch (r) {

[PATCH 07/11] kvm, x86: unify sigbus handling, prep

2010-10-14 Thread Jin Dongming
There are 2 similar functions to handle SIGBUS:
  sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo,
 void *ctx)
  kvm_on_sigbus(CPUState *env, siginfo_t *siginfo)

The former is used when main thread receives SIGBUS via signalfd,
while latter is used when vcpu thread receives SIGBUS.
These 2 take different siginfo, but in both case required parameters
are common, the code and the addr in the info.

Restruct functions to take the code and the addr explicitly.

Signed-off-by: Hidetoshi Seto 
Tested-by: Jin Dongming 
---
 qemu-kvm.c |   41 -
 1 files changed, 20 insertions(+), 21 deletions(-)

diff --git a/qemu-kvm.c b/qemu-kvm.c
index 89ae524..b58181a 100644
--- a/qemu-kvm.c
+++ b/qemu-kvm.c
@@ -1219,32 +1219,28 @@ static void 
kvm_mce_inj_srao_broadcast(target_phys_addr_t paddr)
 }
 #endif
 
-static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo,
-   void *ctx)
+static void kvm_handle_sigbus(int code, void *vaddr)
 {
 #if defined(KVM_CAP_MCE) && defined(TARGET_I386)
-if ((first_cpu->mcg_cap & MCG_SER_P) && siginfo->ssi_addr
-&& siginfo->ssi_code == BUS_MCEERR_AO) {
-void *vaddr;
+if ((first_cpu->mcg_cap & MCG_SER_P) && vaddr && code == BUS_MCEERR_AO) {
 ram_addr_t ram_addr;
 target_phys_addr_t paddr;
 
 /* Hope we are lucky for AO MCE */
-vaddr = (void *)(intptr_t)siginfo->ssi_addr;
 if (do_qemu_ram_addr_from_host(vaddr, &ram_addr) ||
 !kvm_physical_memory_addr_from_ram(kvm_state, ram_addr, &paddr)) {
 fprintf(stderr, "Hardware memory error for memory used by "
 "QEMU itself instead of guest system!: %llx\n",
-(unsigned long long)siginfo->ssi_addr);
+(unsigned long long)vaddr);
 return;
 }
 kvm_mce_inj_srao_broadcast(paddr);
 } else
 #endif
 {
-if (siginfo->ssi_code == BUS_MCEERR_AO) {
+if (code == BUS_MCEERR_AO) {
 return;
-} else if (siginfo->ssi_code == BUS_MCEERR_AR) {
+} else if (code == BUS_MCEERR_AR) {
 hardware_memory_error();
 } else {
 sigbus_reraise();
@@ -1252,6 +1248,11 @@ static void sigbus_handler(int n, struct 
qemu_signalfd_siginfo *siginfo,
 }
 }
 
+static void sigbus_handler(int n, struct qemu_signalfd_siginfo *ssi, void *ctx)
+{
+kvm_handle_sigbus(ssi->ssi_code, (void *)(intptr_t)ssi->ssi_addr);
+}
+
 static void on_vcpu(CPUState *env, void (*func)(void *data), void *data)
 {
 struct qemu_work_item wi;
@@ -1377,36 +1378,34 @@ static void flush_queued_work(CPUState *env)
 pthread_cond_broadcast(&qemu_work_cond);
 }
 
-static void kvm_on_sigbus(CPUState *env, siginfo_t *siginfo)
+static void kvm_on_sigbus(CPUState *env, int code, void *vaddr)
 {
 #if defined(KVM_CAP_MCE) && defined(TARGET_I386)
-void *vaddr;
 ram_addr_t ram_addr;
 target_phys_addr_t paddr;
 
-if ((env->mcg_cap & MCG_SER_P) && siginfo->si_addr
-&& (siginfo->si_code == BUS_MCEERR_AR
-|| siginfo->si_code == BUS_MCEERR_AO)) {
+if ((env->mcg_cap & MCG_SER_P) && vaddr
+&& (code == BUS_MCEERR_AR || code == BUS_MCEERR_AO)) {
 
 /*
  * If there is an MCE excpetion being processed, ignore this SRAO MCE
  */
-if (siginfo->si_code == BUS_MCEERR_AO && kvm_mce_in_progress(env)) {
+if (code == BUS_MCEERR_AO && kvm_mce_in_progress(env)) }
 return;
 }
-vaddr = (void *)siginfo->si_addr;
+
 if (do_qemu_ram_addr_from_host(vaddr, &ram_addr) ||
 !kvm_physical_memory_addr_from_ram(kvm_state, ram_addr, &paddr)) {
 fprintf(stderr, "Hardware memory error for memory used by "
 "QEMU itself instead of guest system!\n");
 /* Hope we are lucky for AO MCE */
-if (siginfo->si_code == BUS_MCEERR_AO) {
+if (code == BUS_MCEERR_AO) {
 return;
 } else {
 hardware_memory_error();
 }
 }
-if (siginfo->si_code == BUS_MCEERR_AR) {
+if (code == BUS_MCEERR_AR) {
 /* Fake an Intel architectural Data Load SRAR UCR */
 kvm_mce_inj_srar_dataload(env, paddr);
 } else {
@@ -1416,9 +1415,9 @@ static void kvm_on_sigbus(CPUState *env, siginfo_t 
*siginfo)
 } else
 #endif
 {
-if (siginfo->si_code == BUS_MCEERR_AO) {
+if (code == BUS_MCEERR_AO) {
 return;
-} else if (siginfo->si_code == BUS_MCEERR_AR) {
+} else if (code == BUS_MCEERR_AR) {
 hardware_memory_error();
 } els

[PATCH 06/11] kvm, x86: use target_phys_addr_t

2010-10-14 Thread Jin Dongming
Signed-off-by: Hidetoshi Seto 
Tested-by: Jin Dongming 
---
 qemu-kvm.c |   14 +++---
 1 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/qemu-kvm.c b/qemu-kvm.c
index 0ba42fc..89ae524 100644
--- a/qemu-kvm.c
+++ b/qemu-kvm.c
@@ -1163,7 +1163,7 @@ static void kvm_do_set_mce(CPUState *env, struct 
kvm_x86_mce *mce,
 }
 }
 
-static void kvm_mce_inj_srar_dataload(CPUState *env, unsigned long paddr)
+static void kvm_mce_inj_srar_dataload(CPUState *env, target_phys_addr_t paddr)
 {
 struct kvm_x86_mce mce = {
 .bank = 9,
@@ -1178,7 +1178,7 @@ static void kvm_mce_inj_srar_dataload(CPUState *env, 
unsigned long paddr)
 kvm_do_set_mce(env, &mce, 1);
 }
 
-static void kvm_mce_inj_srao_memscrub(CPUState *env, unsigned long paddr)
+static void kvm_mce_inj_srao_memscrub(CPUState *env, target_phys_addr_t paddr)
 {
 struct kvm_x86_mce mce = {
 .bank = 9,
@@ -1193,7 +1193,7 @@ static void kvm_mce_inj_srao_memscrub(CPUState *env, 
unsigned long paddr)
 kvm_do_set_mce(env, &mce, 1);
 }
 
-static void kvm_mce_inj_srao_broadcast(unsigned long paddr)
+static void kvm_mce_inj_srao_broadcast(target_phys_addr_t paddr)
 {
 struct kvm_x86_mce mce_srao_memscrub = {
 .bank = 9,
@@ -1227,12 +1227,12 @@ static void sigbus_handler(int n, struct 
qemu_signalfd_siginfo *siginfo,
 && siginfo->ssi_code == BUS_MCEERR_AO) {
 void *vaddr;
 ram_addr_t ram_addr;
-unsigned long paddr;
+target_phys_addr_t paddr;
 
 /* Hope we are lucky for AO MCE */
 vaddr = (void *)(intptr_t)siginfo->ssi_addr;
 if (do_qemu_ram_addr_from_host(vaddr, &ram_addr) ||
-!kvm_physical_memory_addr_from_ram(kvm_state, ram_addr, 
(target_phys_addr_t *)&paddr)) {
+!kvm_physical_memory_addr_from_ram(kvm_state, ram_addr, &paddr)) {
 fprintf(stderr, "Hardware memory error for memory used by "
 "QEMU itself instead of guest system!: %llx\n",
 (unsigned long long)siginfo->ssi_addr);
@@ -1382,7 +1382,7 @@ static void kvm_on_sigbus(CPUState *env, siginfo_t 
*siginfo)
 #if defined(KVM_CAP_MCE) && defined(TARGET_I386)
 void *vaddr;
 ram_addr_t ram_addr;
-unsigned long paddr;
+target_phys_addr_t paddr;
 
 if ((env->mcg_cap & MCG_SER_P) && siginfo->si_addr
 && (siginfo->si_code == BUS_MCEERR_AR
@@ -1396,7 +1396,7 @@ static void kvm_on_sigbus(CPUState *env, siginfo_t 
*siginfo)
 }
 vaddr = (void *)siginfo->si_addr;
 if (do_qemu_ram_addr_from_host(vaddr, &ram_addr) ||
-!kvm_physical_memory_addr_from_ram(kvm_state, ram_addr, 
(target_phys_addr_t *)&paddr)) {
+!kvm_physical_memory_addr_from_ram(kvm_state, ram_addr, &paddr)) {
 fprintf(stderr, "Hardware memory error for memory used by "
 "QEMU itself instead of guest system!\n");
 /* Hope we are lucky for AO MCE */
-- 
1.7.1.1


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 05/11] kvm, x86: introduce kvm_inject_x86_mce_on

2010-10-14 Thread Jin Dongming
Pass a table instead of multiple args.

Note:

kvm_inject_x86_mce(env, bank, status, mcg_status, addr, misc,
   abort_on_error);

is equal to:

struct kvm_x86_mce mce = {
.bank = bank,
.status = status,
.mcg_status = mcg_status,
.addr = addr,
.misc = misc,
};
kvm_inject_x86_mce_on(env, &mce, abort_on_error);

Signed-off-by: Hidetoshi Seto 
Tested-by: Jin Dongming 
---
 qemu-kvm.c |   56 ++--
 1 files changed, 38 insertions(+), 18 deletions(-)

diff --git a/qemu-kvm.c b/qemu-kvm.c
index 9f248f0..0ba42fc 100644
--- a/qemu-kvm.c
+++ b/qemu-kvm.c
@@ -1131,6 +1131,9 @@ static void sigbus_reraise(void)
 }
 
 #if defined(KVM_CAP_MCE) && defined(TARGET_I386)
+static void kvm_inject_x86_mce_on(CPUState *env, struct kvm_x86_mce *mce,
+  int abort_on_error);
+
 static int kvm_mce_in_progress(CPUState *env)
 {
 struct kvm_msr_entry msr_mcg_status = {
@@ -1192,17 +1195,27 @@ static void kvm_mce_inj_srao_memscrub(CPUState *env, 
unsigned long paddr)
 
 static void kvm_mce_inj_srao_broadcast(unsigned long paddr)
 {
+struct kvm_x86_mce mce_srao_memscrub = {
+.bank = 9,
+.status = MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN
+  | MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S
+  | 0xc0,
+.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV,
+.addr = paddr,
+.misc = (MCM_ADDR_PHYS << 6) | 0xc,
+};
+struct kvm_x86_mce mce_dummy = {
+.bank = 1,
+.status = MCI_STATUS_VAL | MCI_STATUS_UC,
+.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV,
+.addr = 0,
+.misc = 0,
+};
 CPUState *cenv;
 
-kvm_inject_x86_mce(first_cpu, 9,
-   MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN
-   | MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S
-   | 0xc0,
-   MCG_STATUS_MCIP | MCG_STATUS_RIPV, paddr,
-   (MCM_ADDR_PHYS << 6) | 0xc, 1);
+kvm_inject_x86_mce_on(first_cpu, &mce_srao_memscrub, 1);
 for (cenv = first_cpu->next_cpu; cenv != NULL; cenv = cenv->next_cpu)
-kvm_inject_x86_mce(cenv, 1, MCI_STATUS_VAL | MCI_STATUS_UC,
-   MCG_STATUS_MCIP | MCG_STATUS_RIPV, 0, 0, 1);
+kvm_inject_x86_mce_on(cenv, &mce_dummy, 1);
 }
 #endif
 
@@ -1941,6 +1954,22 @@ static void kvm_do_inject_x86_mce(void *_data)
 
 kvm_do_set_mce(data->env, data->mce, data->abort_on_error);
 }
+
+static void kvm_inject_x86_mce_on(CPUState *env, struct kvm_x86_mce *mce,
+  int abort_on_error)
+{
+struct kvm_x86_mce_data data = {
+.env = env,
+.mce = mce,
+.abort_on_error = abort_on_error,
+};
+
+if (!env->mcg_cap) {
+perror("MCE support is not enabled!");
+return;
+}
+on_vcpu(env, kvm_do_inject_x86_mce, &data);
+}
 #endif
 
 void kvm_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
@@ -1955,17 +1984,8 @@ void kvm_inject_x86_mce(CPUState *cenv, int bank, 
uint64_t status,
 .addr = addr,
 .misc = misc,
 };
-struct kvm_x86_mce_data data = {
-.env = cenv,
-.mce = &mce,
-.abort_on_error = abort_on_error,
-};
 
-if (!cenv->mcg_cap) {
-fprintf(stderr, "MCE support is not enabled!\n");
-return;
-}
-on_vcpu(cenv, kvm_do_inject_x86_mce, &data);
+kvm_inject_x86_mce_on(cenv, &mce, abort_on_error);
 #else
 if (abort_on_error) {
 abort();
-- 
1.7.1.1


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 04/11] kvm, x86: kvm_mce_inj_* subroutins for templated error injections

2010-10-14 Thread Jin Dongming
Refactor codes for maintainability.

Signed-off-by: Hidetoshi Seto 
Tested-by: Jin Dongming 
---
 qemu-kvm.c |   96 ---
 1 files changed, 58 insertions(+), 38 deletions(-)

diff --git a/qemu-kvm.c b/qemu-kvm.c
index a71c07c..9f248f0 100644
--- a/qemu-kvm.c
+++ b/qemu-kvm.c
@@ -1159,6 +1159,51 @@ static void kvm_do_set_mce(CPUState *env, struct 
kvm_x86_mce *mce,
 }
 }
 }
+
+static void kvm_mce_inj_srar_dataload(CPUState *env, unsigned long paddr)
+{
+struct kvm_x86_mce mce = {
+.bank = 9,
+.status = MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN
+  | MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S
+  | MCI_STATUS_AR | 0x134,
+.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_EIPV,
+.addr = paddr,
+.misc = (MCM_ADDR_PHYS << 6) | 0xc,
+};
+
+kvm_do_set_mce(env, &mce, 1);
+}
+
+static void kvm_mce_inj_srao_memscrub(CPUState *env, unsigned long paddr)
+{
+struct kvm_x86_mce mce = {
+.bank = 9,
+.status = MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN
+  | MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S
+  | 0xc0,
+.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV,
+.addr = paddr,
+.misc = (MCM_ADDR_PHYS << 6) | 0xc,
+};
+
+kvm_do_set_mce(env, &mce, 1);
+}
+
+static void kvm_mce_inj_srao_broadcast(unsigned long paddr)
+{
+CPUState *cenv;
+
+kvm_inject_x86_mce(first_cpu, 9,
+   MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN
+   | MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S
+   | 0xc0,
+   MCG_STATUS_MCIP | MCG_STATUS_RIPV, paddr,
+   (MCM_ADDR_PHYS << 6) | 0xc, 1);
+for (cenv = first_cpu->next_cpu; cenv != NULL; cenv = cenv->next_cpu)
+kvm_inject_x86_mce(cenv, 1, MCI_STATUS_VAL | MCI_STATUS_UC,
+   MCG_STATUS_MCIP | MCG_STATUS_RIPV, 0, 0, 1);
+}
 #endif
 
 static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo,
@@ -1167,11 +1212,9 @@ static void sigbus_handler(int n, struct 
qemu_signalfd_siginfo *siginfo,
 #if defined(KVM_CAP_MCE) && defined(TARGET_I386)
 if ((first_cpu->mcg_cap & MCG_SER_P) && siginfo->ssi_addr
 && siginfo->ssi_code == BUS_MCEERR_AO) {
-uint64_t status;
 void *vaddr;
 ram_addr_t ram_addr;
 unsigned long paddr;
-CPUState *cenv;
 
 /* Hope we are lucky for AO MCE */
 vaddr = (void *)(intptr_t)siginfo->ssi_addr;
@@ -1182,16 +1225,7 @@ static void sigbus_handler(int n, struct 
qemu_signalfd_siginfo *siginfo,
 (unsigned long long)siginfo->ssi_addr);
 return;
 }
-status = MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN
-| MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S
-| 0xc0;
-kvm_inject_x86_mce(first_cpu, 9, status,
-   MCG_STATUS_MCIP | MCG_STATUS_RIPV, paddr,
-   (MCM_ADDR_PHYS << 6) | 0xc, 1);
-for (cenv = first_cpu->next_cpu; cenv != NULL; cenv = cenv->next_cpu) {
-kvm_inject_x86_mce(cenv, 1, MCI_STATUS_VAL | MCI_STATUS_UC,
-   MCG_STATUS_MCIP | MCG_STATUS_RIPV, 0, 0, 1);
-}
+kvm_mce_inj_srao_broadcast(paddr);
 } else
 #endif
 {
@@ -1333,9 +1367,6 @@ static void flush_queued_work(CPUState *env)
 static void kvm_on_sigbus(CPUState *env, siginfo_t *siginfo)
 {
 #if defined(KVM_CAP_MCE) && defined(TARGET_I386)
-struct kvm_x86_mce mce = {
-.bank = 9,
-};
 void *vaddr;
 ram_addr_t ram_addr;
 unsigned long paddr;
@@ -1343,28 +1374,12 @@ static void kvm_on_sigbus(CPUState *env, siginfo_t 
*siginfo)
 if ((env->mcg_cap & MCG_SER_P) && siginfo->si_addr
 && (siginfo->si_code == BUS_MCEERR_AR
 || siginfo->si_code == BUS_MCEERR_AO)) {
-if (siginfo->si_code == BUS_MCEERR_AR) {
-/* Fake an Intel architectural Data Load SRAR UCR */
-mce.status = MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN
-| MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S
-| MCI_STATUS_AR | 0x134;
-mce.misc = (MCM_ADDR_PHYS << 6) | 0xc;
-mce.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_EIPV;
-} else {
-/*
- * If there is an MCE excpetion being processed, ignore
- * this SRAO MCE
- */
-if (kvm_mce_in_progress(env)) {
-return;
-}
 
-/* Fake an Intel architectural Memory scrubbing UCR */
-mce.status = MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN
-| MCI_STATUS_MISCV | 

[PATCH 03/11] kvm, x86: introduce kvm_mce_in_progress

2010-10-14 Thread Jin Dongming
Share same error handing, and put it in #ifdef MCE && i386.
Rename this function after MCIP (Machine Check In Progress) flag.

Signed-off-by: Hidetoshi Seto 
Tested-by: Jin Dongming 
---
 qemu-kvm.c |   47 ---
 1 files changed, 20 insertions(+), 27 deletions(-)

diff --git a/qemu-kvm.c b/qemu-kvm.c
index 1338e99..a71c07c 100644
--- a/qemu-kvm.c
+++ b/qemu-kvm.c
@@ -1131,6 +1131,21 @@ static void sigbus_reraise(void)
 }
 
 #if defined(KVM_CAP_MCE) && defined(TARGET_I386)
+static int kvm_mce_in_progress(CPUState *env)
+{
+struct kvm_msr_entry msr_mcg_status = {
+.index = MSR_MCG_STATUS,
+};
+int r;
+
+r = kvm_get_msrs(env, &msr_mcg_status, 1);
+if (r == -1 || r == 0) {
+perror("Failed to get MCE status");
+return 0;
+}
+return !!(msr_mcg_status.data & MCG_STATUS_MCIP);
+}
+
 static void kvm_do_set_mce(CPUState *env, struct kvm_x86_mce *mce,
int abort_on_error)
 {
@@ -1315,20 +1330,6 @@ static void flush_queued_work(CPUState *env)
 pthread_cond_broadcast(&qemu_work_cond);
 }
 
-static int kvm_mce_in_exception(CPUState *env)
-{
-struct kvm_msr_entry msr_mcg_status = {
-.index = MSR_MCG_STATUS,
-};
-int r;
-
-r = kvm_get_msrs(env, &msr_mcg_status, 1);
-if (r == -1 || r == 0) {
-return -1;
-}
-return !!(msr_mcg_status.data & MCG_STATUS_MCIP);
-}
-
 static void kvm_on_sigbus(CPUState *env, siginfo_t *siginfo)
 {
 #if defined(KVM_CAP_MCE) && defined(TARGET_I386)
@@ -1338,7 +1339,6 @@ static void kvm_on_sigbus(CPUState *env, siginfo_t 
*siginfo)
 void *vaddr;
 ram_addr_t ram_addr;
 unsigned long paddr;
-int r;
 
 if ((env->mcg_cap & MCG_SER_P) && siginfo->si_addr
 && (siginfo->si_code == BUS_MCEERR_AR
@@ -1355,12 +1355,10 @@ static void kvm_on_sigbus(CPUState *env, siginfo_t 
*siginfo)
  * If there is an MCE excpetion being processed, ignore
  * this SRAO MCE
  */
-r = kvm_mce_in_exception(env);
-if (r == -1) {
-fprintf(stderr, "Failed to get MCE status\n");
-} else if (r) {
+if (kvm_mce_in_progress(env)) {
 return;
 }
+
 /* Fake an Intel architectural Memory scrubbing UCR */
 mce.status = MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN
 | MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S
@@ -1913,17 +1911,12 @@ struct kvm_x86_mce_data {
 static void kvm_do_inject_x86_mce(void *_data)
 {
 struct kvm_x86_mce_data *data = _data;
-int r;
 
 /* If there is an MCE exception being processed, ignore this SRAO MCE */
 if ((data->env->mcg_cap & MCG_SER_P) &&
-!(data->mce->status & MCI_STATUS_AR)) {
-r = kvm_mce_in_exception(data->env);
-if (r == -1) {
-fprintf(stderr, "Failed to get MCE status\n");
-} else if (r) {
-return;
-}
+!(data->mce->status & MCI_STATUS_AR) &&
+kvm_mce_in_progress(data->env)) {
+return;
 }
 
 kvm_do_set_mce(data->env, data->mce, data->abort_on_error);
-- 
1.7.1.1


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 02/11] kvm, x86: introduce kvm_do_set_mce

2010-10-14 Thread Jin Dongming
Share the same error handling.

Signed-off-by: Hidetoshi Seto 
Tested-by: Jin Dongming 
---
 qemu-kvm.c |   31 +++
 1 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/qemu-kvm.c b/qemu-kvm.c
index 6f62973..1338e99 100644
--- a/qemu-kvm.c
+++ b/qemu-kvm.c
@@ -1130,6 +1130,22 @@ static void sigbus_reraise(void)
 abort();
 }
 
+#if defined(KVM_CAP_MCE) && defined(TARGET_I386)
+static void kvm_do_set_mce(CPUState *env, struct kvm_x86_mce *mce,
+   int abort_on_error)
+{
+int r;
+
+r = kvm_set_mce(env, mce);
+if (r < 0) {
+perror("kvm_set_mce FAILED");
+if (abort_on_error) {
+abort();
+}
+}
+}
+#endif
+
 static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo,
void *ctx)
 {
@@ -1365,11 +1381,7 @@ static void kvm_on_sigbus(CPUState *env, siginfo_t 
*siginfo)
 }
 }
 mce.addr = paddr;
-r = kvm_set_mce(env, &mce);
-if (r < 0) {
-fprintf(stderr, "kvm_set_mce: %s\n", strerror(errno));
-abort();
-}
+kvm_do_set_mce(env, &mce, 1);
 } else
 #endif
 {
@@ -1913,13 +1925,8 @@ static void kvm_do_inject_x86_mce(void *_data)
 return;
 }
 }
-r = kvm_set_mce(data->env, data->mce);
-if (r < 0) {
-perror("kvm_set_mce FAILED");
-if (data->abort_on_error) {
-abort();
-}
-}
+
+kvm_do_set_mce(data->env, data->mce, data->abort_on_error);
 }
 #endif
 
-- 
1.7.1.1

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 01/11] kvm, x86: ignore SRAO only when MCG_SER_P is available

2010-10-14 Thread Jin Dongming
And restruct this block to call kvm_mce_in_exception() only when it is
required.

Signed-off-by: Hidetoshi Seto 
Tested-by: Jin Dongming 
---
 qemu-kvm.c |   15 +--
 1 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/qemu-kvm.c b/qemu-kvm.c
index e78d850..6f62973 100644
--- a/qemu-kvm.c
+++ b/qemu-kvm.c
@@ -1903,12 +1903,15 @@ static void kvm_do_inject_x86_mce(void *_data)
 struct kvm_x86_mce_data *data = _data;
 int r;
 
-/* If there is an MCE excpetion being processed, ignore this SRAO MCE */
-r = kvm_mce_in_exception(data->env);
-if (r == -1) {
-fprintf(stderr, "Failed to get MCE status\n");
-} else if (r && !(data->mce->status & MCI_STATUS_AR)) {
-return;
+/* If there is an MCE exception being processed, ignore this SRAO MCE */
+if ((data->env->mcg_cap & MCG_SER_P) &&
+!(data->mce->status & MCI_STATUS_AR)) {
+r = kvm_mce_in_exception(data->env);
+if (r == -1) {
+fprintf(stderr, "Failed to get MCE status\n");
+} else if (r) {
+return;
+}
 }
 r = kvm_set_mce(data->env, data->mce);
 if (r < 0) {
-- 
1.7.1.1

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 00/11] Descriptions for patches of qemu mce.

2010-10-14 Thread Jin Dongming
These patches do the following changes.
1. Clean up:
 - Making the similar parts as one shared function.
 - modularizing the functions of SRAO and SRAR data setting.
2. Unify sigbus handling:
 -  kvm_handle_sigbus can handle both cases of SIGBUS listed as 
following.
 A) Received by Main thread
 B) Received by VCPU threads
3. Change broadcast:
 - Broadcasting SRAR same as SRAO.
 - Broadcasting SRAO received by VCPU threads same as it by Main Thread.
 - Broadcasting mce depending on the cpu version
   according to the x86 ASDM vol.3A 15.10.4.1.

=
  [PATCH 01/11]kvm, x86: ignore SRAO only when MCG_SER_P is available
  [PATCH 02/11]kvm, x86: introduce kvm_do_set_mce
  [PATCH 03/11]kvm, x86: introduce kvm_mce_in_progress
  [PATCH 04/11]kvm, x86: kvm_mce_inj_* subroutins for templated error injections
  [PATCH 05/11]kvm, x86: introduce kvm_inject_x86_mce_on
  [PATCH 06/11]kvm, x86: use target_phys_addr_t
  [PATCH 07/11]kvm, x86: unify sigbus handling, prep
  [PATCH 08/11]kvm, x86: unify sigbus handling
  [PATCH 09/11]kvm, x86: unify sigbus handling, post1
  [PATCH 10/11]kvm, x86: unify sigbus handling, post2
  [PATCH 11/11]kvm, x86: broadcast mce depending on the cpu version

 qemu-kvm.c |  300 
 1 files changed, 162 insertions(+), 138 deletions(-)


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] KVM: IOAPIC: only access APIC registers one dword at a time

2010-07-02 Thread Jin Dongming
Hi, Xiao Guangrong

Xiao Guangrong wrote:
> The IOAPIC spec says:
> 
> When accessing these registers, accesses must be done one dword at a time.
> For example, software should never access byte 2 from the Data register before
> accessing bytes 0 and 1. The hardware will not attempt to recover from a bad
> programming model in this case.

I could understand what you described on the above, but I don't think it is 
the best method to fix it. Could you consider a nice one?

>
> So, this patch removes other width access
> 
> Signed-off-by: Xiao Guangrong 
> ---
>  virt/kvm/ioapic.c |   10 +++---
>  1 files changed, 3 insertions(+), 7 deletions(-)
> 
> diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c
> index 1149c60..f96816f 100644
> --- a/virt/kvm/ioapic.c
> +++ b/virt/kvm/ioapic.c
> @@ -306,14 +306,10 @@ static int ioapic_mmio_read(struct kvm_io_device *this, 
> gpa_t addr, int len,
>   spin_unlock(&ioapic->lock);
>  
>   switch (len) {
> - case 8:
> - *(u64 *) val = result;
> - break;
> - case 1:
> - case 2:
>   case 4:
> - memcpy(val, (char *)&result, len);

Here the parameter len is not used for reading data from ioapic register, 
before switch case
the value of ioapic register has been read by ioapic_read_indirect().


> + *(u32 *) val = result;
>   break;
> +
>   default:
>   printk(KERN_WARNING "ioapic: wrong length %d\n", len);

And I think here is not good to print warning message. Maybe it is better to do
such kind of checking at the first of this function before 
ioapic_read_indirect().

>   }
> @@ -332,7 +328,7 @@ static int ioapic_mmio_write(struct kvm_io_device *this, 
> gpa_t addr, int len,
>(void*)addr, len, val);
>   ASSERT(!(addr & 0xf));  /* check alignment */
>  
> - if (len == 4 || len == 8)
> + if (len == 4)
>   data = *(u32 *) val;
>   else {
>   printk(KERN_WARNING "ioapic: Unsupported size %d\n", len);

So I hope you could read the source code again. I think you can use a better 
method to fix it.

Best Regards,
Jin Dongming

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html