Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1604220 > unrolled thread
| Started by | Dongjiu Geng <gengdongjiu@huawei.com> |
|---|---|
| First post | 2017-03-20 08:50 +0100 |
| Last post | 2017-03-21 07:10 +0100 |
| Articles | 15 — 6 participants |
Back to article view | Back to linux.kernel
[PATCH] kvm: pass the virtual SEI syndrome to guest OS Dongjiu Geng <gengdongjiu@huawei.com> - 2017-03-20 08:50 +0100
Re: [PATCH] kvm: pass the virtual SEI syndrome to guest OS Marc Zyngier <marc.zyngier@arm.com> - 2017-03-20 12:30 +0100
Re: [PATCH] kvm: pass the virtual SEI syndrome to guest OS gengdongjiu <gengdongjiu@huawei.com> - 2017-03-20 13:40 +0100
Re: [PATCH] kvm: pass the virtual SEI syndrome to guest OS Marc Zyngier <marc.zyngier@arm.com> - 2017-03-20 15:00 +0100
Re: [PATCH] kvm: pass the virtual SEI syndrome to guest OS James Morse <james.morse@arm.com> - 2017-03-20 16:20 +0100
Re: [PATCH] kvm: pass the virtual SEI syndrome to guest OS gengdongjiu <gengdongjiu@huawei.com> - 2017-03-21 07:40 +0100
Re: [PATCH] kvm: pass the virtual SEI syndrome to guest OS Christoffer Dall <cdall@linaro.org> - 2017-03-21 12:50 +0100
Re: [PATCH] kvm: pass the virtual SEI syndrome to guest OS James Morse <james.morse@arm.com> - 2017-03-21 20:20 +0100
Re: [PATCH] kvm: pass the virtual SEI syndrome to guest OS Christoffer Dall <cdall@linaro.org> - 2017-03-21 21:00 +0100
Re: [PATCH] kvm: pass the virtual SEI syndrome to guest OS Peter Maydell <peter.maydell@linaro.org> - 2017-03-21 23:20 +0100
Re: [PATCH] kvm: pass the virtual SEI syndrome to guest OS Marc Zyngier <marc.zyngier@arm.com> - 2017-03-22 12:20 +0100
Re: [PATCH] kvm: pass the virtual SEI syndrome to guest OS James Morse <james.morse@arm.com> - 2017-03-21 14:20 +0100
Re: [PATCH] kvm: pass the virtual SEI syndrome to guest OS gengdongjiu <gengdongjiu@huawei.com> - 2017-03-22 14:50 +0100
Re: [PATCH] kvm: pass the virtual SEI syndrome to guest OS James Morse <james.morse@arm.com> - 2017-03-22 20:00 +0100
Re: [PATCH] kvm: pass the virtual SEI syndrome to guest OS gengdongjiu <gengdongjiu@huawei.com> - 2017-03-21 07:10 +0100
| From | Dongjiu Geng <gengdongjiu@huawei.com> |
|---|---|
| Date | 2017-03-20 08:50 +0100 |
| Subject | [PATCH] kvm: pass the virtual SEI syndrome to guest OS |
| Message-ID | <tn0eJ-1w7-1@gated-at.bofh.it> |
In the RAS implementation, hardware pass the virtual SEI
syndrome information through the VSESR_EL2, so set the virtual
SEI syndrome using physical SEI syndrome el2_elr to pass to
the guest OS
Signed-off-by: Dongjiu Geng <gengdongjiu@huawei.com>
Signed-off-by: Quanming wu <wuquanming@huawei.com>
---
arch/arm64/Kconfig | 8 ++++++++
arch/arm64/include/asm/esr.h | 1 +
arch/arm64/include/asm/kvm_emulate.h | 12 ++++++++++++
arch/arm64/include/asm/kvm_host.h | 4 ++++
arch/arm64/kvm/hyp/switch.c | 15 ++++++++++++++-
arch/arm64/kvm/inject_fault.c | 10 ++++++++++
6 files changed, 49 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 8c7c244247b6..ea62170a3b75 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -908,6 +908,14 @@ endmenu
menu "ARMv8.2 architectural features"
+config HAS_RAS_EXTENSION
+ bool "Support arm64 RAS extension"
+ default n
+ help
+ Reliability, Availability, Serviceability(RAS; part of the ARMv8.2 Extensions).
+
+ Selecting this option OS will try to recover the error that RAS hardware node detected.
+
config ARM64_UAO
bool "Enable support for User Access Override (UAO)"
default y
diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
index d14c478976d0..e38d32b2bdad 100644
--- a/arch/arm64/include/asm/esr.h
+++ b/arch/arm64/include/asm/esr.h
@@ -111,6 +111,7 @@
#define ESR_ELx_COND_MASK (UL(0xF) << ESR_ELx_COND_SHIFT)
#define ESR_ELx_WFx_ISS_WFE (UL(1) << 0)
#define ESR_ELx_xVC_IMM_MASK ((1UL << 16) - 1)
+#define VSESR_ELx_IDS_ISS_MASK ((1UL << 25) - 1)
/* ESR value templates for specific events */
diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index f5ea0ba70f07..20d4da7f5dce 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -148,6 +148,18 @@ static inline u32 kvm_vcpu_get_hsr(const struct kvm_vcpu *vcpu)
return vcpu->arch.fault.esr_el2;
}
+#ifdef CONFIG_HAS_RAS_EXTENSION
+static inline u32 kvm_vcpu_get_vsesr(const struct kvm_vcpu *vcpu)
+{
+ return vcpu->arch.fault.vsesr_el2;
+}
+
+static inline void kvm_vcpu_set_vsesr(struct kvm_vcpu *vcpu, unsigned long val)
+{
+ vcpu->arch.fault.vsesr_el2 = val;
+}
+#endif
+
static inline int kvm_vcpu_get_condition(const struct kvm_vcpu *vcpu)
{
u32 esr = kvm_vcpu_get_hsr(vcpu);
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index e7705e7bb07b..f9e3bb57c461 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -83,6 +83,10 @@ struct kvm_mmu_memory_cache {
};
struct kvm_vcpu_fault_info {
+#ifdef CONFIG_HAS_RAS_EXTENSION
+ /* Virtual SError Exception Syndrome Register */
+ u32 vsesr_el2;
+#endif
u32 esr_el2; /* Hyp Syndrom Register */
u64 far_el2; /* Hyp Fault Address Register */
u64 hpfar_el2; /* Hyp IPA Fault Address Register */
diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
index aede1658aeda..770a153fb6ba 100644
--- a/arch/arm64/kvm/hyp/switch.c
+++ b/arch/arm64/kvm/hyp/switch.c
@@ -86,6 +86,13 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu)
isb();
}
write_sysreg(val, hcr_el2);
+#ifdef CONFIG_HAS_RAS_EXTENSION
+ /* If virtual System Error or Asynchronous Abort is pending. set
+ * the virtual exception syndrome information
+ */
+ if (vcpu->arch.hcr_el2 & HCR_VSE)
+ write_sysreg(vcpu->arch.fault.vsesr_el2, vsesr_el2);
+#endif
/* Trap on AArch32 cp15 c15 accesses (EL1 or EL0) */
write_sysreg(1 << 15, hstr_el2);
/*
@@ -139,8 +146,14 @@ static void __hyp_text __deactivate_traps(struct kvm_vcpu *vcpu)
* the crucial bit is "On taking a vSError interrupt,
* HCR_EL2.VSE is cleared to 0."
*/
- if (vcpu->arch.hcr_el2 & HCR_VSE)
+ if (vcpu->arch.hcr_el2 & HCR_VSE) {
vcpu->arch.hcr_el2 = read_sysreg(hcr_el2);
+#ifdef CONFIG_HAS_RAS_EXTENSION
+ /* set vsesr_el2[24:0] with esr_el2[24:0] */
+ kvm_vcpu_set_vsesr(vcpu, read_sysreg_el2(esr)
+ & VSESR_ELx_IDS_ISS_MASK);
+#endif
+ }
__deactivate_traps_arch()();
write_sysreg(0, hstr_el2);
diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c
index da6a8cfa54a0..08a13dfe28a8 100644
--- a/arch/arm64/kvm/inject_fault.c
+++ b/arch/arm64/kvm/inject_fault.c
@@ -242,4 +242,14 @@ void kvm_inject_undefined(struct kvm_vcpu *vcpu)
void kvm_inject_vabt(struct kvm_vcpu *vcpu)
{
vcpu_set_hcr(vcpu, vcpu_get_hcr(vcpu) | HCR_VSE);
+#ifdef CONFIG_HAS_RAS_EXTENSION
+ /* If virtual System Error or Asynchronous Abort is set. set
+ * the virtual exception syndrome information
+ */
+ kvm_vcpu_set_vsesr(vcpu, ((kvm_vcpu_get_vsesr(vcpu)
+ & (~VSESR_ELx_IDS_ISS_MASK))
+ | (kvm_vcpu_get_hsr(vcpu)
+ & VSESR_ELx_IDS_ISS_MASK)));
+#endif
+
}
--
2.11.0
[toc] | [next] | [standalone]
| From | Marc Zyngier <marc.zyngier@arm.com> |
|---|---|
| Date | 2017-03-20 12:30 +0100 |
| Message-ID | <tn3FE-3Z3-25@gated-at.bofh.it> |
| In reply to | #1604220 |
Please include James Morse on anything RAS related, as he's already
looking at related patches.
On 20/03/17 07:55, Dongjiu Geng wrote:
> In the RAS implementation, hardware pass the virtual SEI
> syndrome information through the VSESR_EL2, so set the virtual
> SEI syndrome using physical SEI syndrome el2_elr to pass to
> the guest OS
>
> Signed-off-by: Dongjiu Geng <gengdongjiu@huawei.com>
> Signed-off-by: Quanming wu <wuquanming@huawei.com>
> ---
> arch/arm64/Kconfig | 8 ++++++++
> arch/arm64/include/asm/esr.h | 1 +
> arch/arm64/include/asm/kvm_emulate.h | 12 ++++++++++++
> arch/arm64/include/asm/kvm_host.h | 4 ++++
> arch/arm64/kvm/hyp/switch.c | 15 ++++++++++++++-
> arch/arm64/kvm/inject_fault.c | 10 ++++++++++
> 6 files changed, 49 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 8c7c244247b6..ea62170a3b75 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -908,6 +908,14 @@ endmenu
>
> menu "ARMv8.2 architectural features"
>
> +config HAS_RAS_EXTENSION
> + bool "Support arm64 RAS extension"
> + default n
> + help
> + Reliability, Availability, Serviceability(RAS; part of the ARMv8.2 Extensions).
> +
> + Selecting this option OS will try to recover the error that RAS hardware node detected.
> +
As this is an architectural extension, this should be controlled by the
CPU feature mechanism, and not be chosen at compile time. What you have
here will break horribly when booted on a CPU that doesn't implement RAS.
> config ARM64_UAO
> bool "Enable support for User Access Override (UAO)"
> default y
> diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
> index d14c478976d0..e38d32b2bdad 100644
> --- a/arch/arm64/include/asm/esr.h
> +++ b/arch/arm64/include/asm/esr.h
> @@ -111,6 +111,7 @@
> #define ESR_ELx_COND_MASK (UL(0xF) << ESR_ELx_COND_SHIFT)
> #define ESR_ELx_WFx_ISS_WFE (UL(1) << 0)
> #define ESR_ELx_xVC_IMM_MASK ((1UL << 16) - 1)
> +#define VSESR_ELx_IDS_ISS_MASK ((1UL << 25) - 1)
>
> /* ESR value templates for specific events */
>
> diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
> index f5ea0ba70f07..20d4da7f5dce 100644
> --- a/arch/arm64/include/asm/kvm_emulate.h
> +++ b/arch/arm64/include/asm/kvm_emulate.h
> @@ -148,6 +148,18 @@ static inline u32 kvm_vcpu_get_hsr(const struct kvm_vcpu *vcpu)
> return vcpu->arch.fault.esr_el2;
> }
>
> +#ifdef CONFIG_HAS_RAS_EXTENSION
> +static inline u32 kvm_vcpu_get_vsesr(const struct kvm_vcpu *vcpu)
> +{
> + return vcpu->arch.fault.vsesr_el2;
> +}
> +
> +static inline void kvm_vcpu_set_vsesr(struct kvm_vcpu *vcpu, unsigned long val)
> +{
> + vcpu->arch.fault.vsesr_el2 = val;
> +}
> +#endif
> +
> static inline int kvm_vcpu_get_condition(const struct kvm_vcpu *vcpu)
> {
> u32 esr = kvm_vcpu_get_hsr(vcpu);
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index e7705e7bb07b..f9e3bb57c461 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -83,6 +83,10 @@ struct kvm_mmu_memory_cache {
> };
>
> struct kvm_vcpu_fault_info {
> +#ifdef CONFIG_HAS_RAS_EXTENSION
> + /* Virtual SError Exception Syndrome Register */
> + u32 vsesr_el2;
> +#endif
> u32 esr_el2; /* Hyp Syndrom Register */
> u64 far_el2; /* Hyp Fault Address Register */
> u64 hpfar_el2; /* Hyp IPA Fault Address Register */
> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
> index aede1658aeda..770a153fb6ba 100644
> --- a/arch/arm64/kvm/hyp/switch.c
> +++ b/arch/arm64/kvm/hyp/switch.c
> @@ -86,6 +86,13 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu)
> isb();
> }
> write_sysreg(val, hcr_el2);
> +#ifdef CONFIG_HAS_RAS_EXTENSION
> + /* If virtual System Error or Asynchronous Abort is pending. set
> + * the virtual exception syndrome information
> + */
> + if (vcpu->arch.hcr_el2 & HCR_VSE)
> + write_sysreg(vcpu->arch.fault.vsesr_el2, vsesr_el2);
> +#endif
> /* Trap on AArch32 cp15 c15 accesses (EL1 or EL0) */
> write_sysreg(1 << 15, hstr_el2);
> /*
> @@ -139,8 +146,14 @@ static void __hyp_text __deactivate_traps(struct kvm_vcpu *vcpu)
> * the crucial bit is "On taking a vSError interrupt,
> * HCR_EL2.VSE is cleared to 0."
> */
> - if (vcpu->arch.hcr_el2 & HCR_VSE)
> + if (vcpu->arch.hcr_el2 & HCR_VSE) {
> vcpu->arch.hcr_el2 = read_sysreg(hcr_el2);
> +#ifdef CONFIG_HAS_RAS_EXTENSION
> + /* set vsesr_el2[24:0] with esr_el2[24:0] */
> + kvm_vcpu_set_vsesr(vcpu, read_sysreg_el2(esr)
> + & VSESR_ELx_IDS_ISS_MASK);
What guarantees that ESR_EL2 still contains the latest exception? What
does it mean to store something that is the current EL2 exception
syndrome together with an SError that has already been injected?
Also, is it correct to directly copy the ESR_EL2 bits into VSESR_EL2? My
own reading of the specification seem to imply that there is at least
differences when the guest is AArch32. Surely there would be some
processing here.
> +#endif
> + }
>
> __deactivate_traps_arch()();
> write_sysreg(0, hstr_el2);
> diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c
> index da6a8cfa54a0..08a13dfe28a8 100644
> --- a/arch/arm64/kvm/inject_fault.c
> +++ b/arch/arm64/kvm/inject_fault.c
> @@ -242,4 +242,14 @@ void kvm_inject_undefined(struct kvm_vcpu *vcpu)
> void kvm_inject_vabt(struct kvm_vcpu *vcpu)
> {
> vcpu_set_hcr(vcpu, vcpu_get_hcr(vcpu) | HCR_VSE);
> +#ifdef CONFIG_HAS_RAS_EXTENSION
> + /* If virtual System Error or Asynchronous Abort is set. set
> + * the virtual exception syndrome information
> + */
> + kvm_vcpu_set_vsesr(vcpu, ((kvm_vcpu_get_vsesr(vcpu)
> + & (~VSESR_ELx_IDS_ISS_MASK))
> + | (kvm_vcpu_get_hsr(vcpu)
> + & VSESR_ELx_IDS_ISS_MASK)));
What is the rational for setting VSESR_EL2 with the EL1 syndrome
information? That doesn't make any sense to me.
Overall, this patch is completely inconsistent and unclear in what it
tries to achieve. Also, as I already tated before, I'd like to see the
"firmware first" mode of operation be enforced here, going back to
userspace and let the VMM decide what to do.
Thanks,
M.
--
Jazz is not dead. It just smells funny...
[toc] | [prev] | [next] | [standalone]
| From | gengdongjiu <gengdongjiu@huawei.com> |
|---|---|
| Date | 2017-03-20 13:40 +0100 |
| Message-ID | <tn4Ln-4J7-9@gated-at.bofh.it> |
| In reply to | #1604413 |
On 2017/3/20 19:24, Marc Zyngier wrote:
> Please include James Morse on anything RAS related, as he's already
> looking at related patches.
>
> On 20/03/17 07:55, Dongjiu Geng wrote:
>> In the RAS implementation, hardware pass the virtual SEI
>> syndrome information through the VSESR_EL2, so set the virtual
>> SEI syndrome using physical SEI syndrome el2_elr to pass to
>> the guest OS
>>
>> Signed-off-by: Dongjiu Geng <gengdongjiu@huawei.com>
>> Signed-off-by: Quanming wu <wuquanming@huawei.com>
>> ---
>> arch/arm64/Kconfig | 8 ++++++++
>> arch/arm64/include/asm/esr.h | 1 +
>> arch/arm64/include/asm/kvm_emulate.h | 12 ++++++++++++
>> arch/arm64/include/asm/kvm_host.h | 4 ++++
>> arch/arm64/kvm/hyp/switch.c | 15 ++++++++++++++-
>> arch/arm64/kvm/inject_fault.c | 10 ++++++++++
>> 6 files changed, 49 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>> index 8c7c244247b6..ea62170a3b75 100644
>> --- a/arch/arm64/Kconfig
>> +++ b/arch/arm64/Kconfig
>> @@ -908,6 +908,14 @@ endmenu
>>
>> menu "ARMv8.2 architectural features"
>>
>> +config HAS_RAS_EXTENSION
>> + bool "Support arm64 RAS extension"
>> + default n
>> + help
>> + Reliability, Availability, Serviceability(RAS; part of the ARMv8.2 Extensions).
>> +
>> + Selecting this option OS will try to recover the error that RAS hardware node detected.
>> +
>
> As this is an architectural extension, this should be controlled by the
> CPU feature mechanism, and not be chosen at compile time. What you have
> here will break horribly when booted on a CPU that doesn't implement RAS.
thanks very much for your review, yes, it is, you are right.
>
>> config ARM64_UAO
>> bool "Enable support for User Access Override (UAO)"
>> default y
>> diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
>> index d14c478976d0..e38d32b2bdad 100644
>> --- a/arch/arm64/include/asm/esr.h
>> +++ b/arch/arm64/include/asm/esr.h
>> @@ -111,6 +111,7 @@
>> #define ESR_ELx_COND_MASK (UL(0xF) << ESR_ELx_COND_SHIFT)
>> #define ESR_ELx_WFx_ISS_WFE (UL(1) << 0)
>> #define ESR_ELx_xVC_IMM_MASK ((1UL << 16) - 1)
>> +#define VSESR_ELx_IDS_ISS_MASK ((1UL << 25) - 1)
>>
>> /* ESR value templates for specific events */
>>
>> diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
>> index f5ea0ba70f07..20d4da7f5dce 100644
>> --- a/arch/arm64/include/asm/kvm_emulate.h
>> +++ b/arch/arm64/include/asm/kvm_emulate.h
>> @@ -148,6 +148,18 @@ static inline u32 kvm_vcpu_get_hsr(const struct kvm_vcpu *vcpu)
>> return vcpu->arch.fault.esr_el2;
>> }
>>
>> +#ifdef CONFIG_HAS_RAS_EXTENSION
>> +static inline u32 kvm_vcpu_get_vsesr(const struct kvm_vcpu *vcpu)
>> +{
>> + return vcpu->arch.fault.vsesr_el2;
>> +}
>> +
>> +static inline void kvm_vcpu_set_vsesr(struct kvm_vcpu *vcpu, unsigned long val)
>> +{
>> + vcpu->arch.fault.vsesr_el2 = val;
>> +}
>> +#endif
>> +
>> static inline int kvm_vcpu_get_condition(const struct kvm_vcpu *vcpu)
>> {
>> u32 esr = kvm_vcpu_get_hsr(vcpu);
>> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
>> index e7705e7bb07b..f9e3bb57c461 100644
>> --- a/arch/arm64/include/asm/kvm_host.h
>> +++ b/arch/arm64/include/asm/kvm_host.h
>> @@ -83,6 +83,10 @@ struct kvm_mmu_memory_cache {
>> };
>>
>> struct kvm_vcpu_fault_info {
>> +#ifdef CONFIG_HAS_RAS_EXTENSION
>> + /* Virtual SError Exception Syndrome Register */
>> + u32 vsesr_el2;
>> +#endif
>> u32 esr_el2; /* Hyp Syndrom Register */
>> u64 far_el2; /* Hyp Fault Address Register */
>> u64 hpfar_el2; /* Hyp IPA Fault Address Register */
>> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
>> index aede1658aeda..770a153fb6ba 100644
>> --- a/arch/arm64/kvm/hyp/switch.c
>> +++ b/arch/arm64/kvm/hyp/switch.c
>> @@ -86,6 +86,13 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu)
>> isb();
>> }
>> write_sysreg(val, hcr_el2);
>> +#ifdef CONFIG_HAS_RAS_EXTENSION
>> + /* If virtual System Error or Asynchronous Abort is pending. set
>> + * the virtual exception syndrome information
>> + */
>> + if (vcpu->arch.hcr_el2 & HCR_VSE)
>> + write_sysreg(vcpu->arch.fault.vsesr_el2, vsesr_el2);
>> +#endif
>> /* Trap on AArch32 cp15 c15 accesses (EL1 or EL0) */
>> write_sysreg(1 << 15, hstr_el2);
>> /*
>> @@ -139,8 +146,14 @@ static void __hyp_text __deactivate_traps(struct kvm_vcpu *vcpu)
>> * the crucial bit is "On taking a vSError interrupt,
>> * HCR_EL2.VSE is cleared to 0."
>> */
>> - if (vcpu->arch.hcr_el2 & HCR_VSE)
>> + if (vcpu->arch.hcr_el2 & HCR_VSE) {
>> vcpu->arch.hcr_el2 = read_sysreg(hcr_el2);
>> +#ifdef CONFIG_HAS_RAS_EXTENSION
>> + /* set vsesr_el2[24:0] with esr_el2[24:0] */
>> + kvm_vcpu_set_vsesr(vcpu, read_sysreg_el2(esr)
>> + & VSESR_ELx_IDS_ISS_MASK);
>
> What guarantees that ESR_EL2 still contains the latest exception? What
> does it mean to store something that is the current EL2 exception
> syndrome together with an SError that has already been injected?
yes, thanks for the review, I will add a judgement condition for the "exit_code"
if the "exit_code == ARM_EXCEPTION_EL1_SERROR" then set the vsesr_el2.
for the aarch32, it only need set the "ExT, bit [12]" and AET, "bits [15:14]", other bit is RES0
>
> Also, is it correct to directly copy the ESR_EL2 bits into VSESR_EL2? My
please see below spec description, it virtual SERROR syndrome from VSESR_EL2.
-----
Control returns to the OS, and the ESB instruction is re-executed.
— The physical asynchronous SError interrupt has been cleared, so it is not taken again.
— The PE sets VDISR_EL2.A to 1 and records the syndrome from VSESR_EL2 in VDISR_EL2.
-----
> own reading of the specification seem to imply that there is at least
> differences when the guest is AArch32. Surely there would be some
> processing here.
>
>> +#endif
>> + }
>>
>> __deactivate_traps_arch()();
>> write_sysreg(0, hstr_el2);
>> diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c
>> index da6a8cfa54a0..08a13dfe28a8 100644
>> --- a/arch/arm64/kvm/inject_fault.c
>> +++ b/arch/arm64/kvm/inject_fault.c
>> @@ -242,4 +242,14 @@ void kvm_inject_undefined(struct kvm_vcpu *vcpu)
>> void kvm_inject_vabt(struct kvm_vcpu *vcpu)
>> {
>> vcpu_set_hcr(vcpu, vcpu_get_hcr(vcpu) | HCR_VSE);
>> +#ifdef CONFIG_HAS_RAS_EXTENSION
>> + /* If virtual System Error or Asynchronous Abort is set. set
>> + * the virtual exception syndrome information
>> + */
>> + kvm_vcpu_set_vsesr(vcpu, ((kvm_vcpu_get_vsesr(vcpu)
>> + & (~VSESR_ELx_IDS_ISS_MASK))
>> + | (kvm_vcpu_get_hsr(vcpu)
>> + & VSESR_ELx_IDS_ISS_MASK)));
>
> What is the rational for setting VSESR_EL2 with the EL1 syndrome
> information? That doesn't make any sense to me.
thanks, I set the VSESR_EL2 using the EL2 syndrome information, "kvm_vcpu_get_hsr"
return the value of esr_el2, not EL1 syndrome information
>
> Overall, this patch is completely inconsistent and unclear in what it
> tries to achieve. Also, as I already tated before, I'd like to see the
> "firmware first" mode of operation be enforced here, going back to
> userspace and let the VMM decide what to do.
>
> Thanks,
>
> M.
>
[toc] | [prev] | [next] | [standalone]
| From | Marc Zyngier <marc.zyngier@arm.com> |
|---|---|
| Date | 2017-03-20 15:00 +0100 |
| Message-ID | <tn60P-5sH-47@gated-at.bofh.it> |
| In reply to | #1604469 |
On 20/03/17 12:28, gengdongjiu wrote:
>
>
> On 2017/3/20 19:24, Marc Zyngier wrote:
>> Please include James Morse on anything RAS related, as he's already
>> looking at related patches.
>>
>> On 20/03/17 07:55, Dongjiu Geng wrote:
>>> In the RAS implementation, hardware pass the virtual SEI
>>> syndrome information through the VSESR_EL2, so set the virtual
>>> SEI syndrome using physical SEI syndrome el2_elr to pass to
>>> the guest OS
>>>
>>> Signed-off-by: Dongjiu Geng <gengdongjiu@huawei.com>
>>> Signed-off-by: Quanming wu <wuquanming@huawei.com>
>>> ---
>>> arch/arm64/Kconfig | 8 ++++++++
>>> arch/arm64/include/asm/esr.h | 1 +
>>> arch/arm64/include/asm/kvm_emulate.h | 12 ++++++++++++
>>> arch/arm64/include/asm/kvm_host.h | 4 ++++
>>> arch/arm64/kvm/hyp/switch.c | 15 ++++++++++++++-
>>> arch/arm64/kvm/inject_fault.c | 10 ++++++++++
>>> 6 files changed, 49 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>>> index 8c7c244247b6..ea62170a3b75 100644
>>> --- a/arch/arm64/Kconfig
>>> +++ b/arch/arm64/Kconfig
>>> @@ -908,6 +908,14 @@ endmenu
>>>
>>> menu "ARMv8.2 architectural features"
>>>
>>> +config HAS_RAS_EXTENSION
>>> + bool "Support arm64 RAS extension"
>>> + default n
>>> + help
>>> + Reliability, Availability, Serviceability(RAS; part of the ARMv8.2 Extensions).
>>> +
>>> + Selecting this option OS will try to recover the error that RAS hardware node detected.
>>> +
>>
>> As this is an architectural extension, this should be controlled by the
>> CPU feature mechanism, and not be chosen at compile time. What you have
>> here will break horribly when booted on a CPU that doesn't implement RAS.
>
> thanks very much for your review, yes, it is, you are right.
>
>>
>>> config ARM64_UAO
>>> bool "Enable support for User Access Override (UAO)"
>>> default y
>>> diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
>>> index d14c478976d0..e38d32b2bdad 100644
>>> --- a/arch/arm64/include/asm/esr.h
>>> +++ b/arch/arm64/include/asm/esr.h
>>> @@ -111,6 +111,7 @@
>>> #define ESR_ELx_COND_MASK (UL(0xF) << ESR_ELx_COND_SHIFT)
>>> #define ESR_ELx_WFx_ISS_WFE (UL(1) << 0)
>>> #define ESR_ELx_xVC_IMM_MASK ((1UL << 16) - 1)
>>> +#define VSESR_ELx_IDS_ISS_MASK ((1UL << 25) - 1)
>>>
>>> /* ESR value templates for specific events */
>>>
>>> diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
>>> index f5ea0ba70f07..20d4da7f5dce 100644
>>> --- a/arch/arm64/include/asm/kvm_emulate.h
>>> +++ b/arch/arm64/include/asm/kvm_emulate.h
>>> @@ -148,6 +148,18 @@ static inline u32 kvm_vcpu_get_hsr(const struct kvm_vcpu *vcpu)
>>> return vcpu->arch.fault.esr_el2;
>>> }
>>>
>>> +#ifdef CONFIG_HAS_RAS_EXTENSION
>>> +static inline u32 kvm_vcpu_get_vsesr(const struct kvm_vcpu *vcpu)
>>> +{
>>> + return vcpu->arch.fault.vsesr_el2;
>>> +}
>>> +
>>> +static inline void kvm_vcpu_set_vsesr(struct kvm_vcpu *vcpu, unsigned long val)
>>> +{
>>> + vcpu->arch.fault.vsesr_el2 = val;
>>> +}
>>> +#endif
>>> +
>>> static inline int kvm_vcpu_get_condition(const struct kvm_vcpu *vcpu)
>>> {
>>> u32 esr = kvm_vcpu_get_hsr(vcpu);
>>> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
>>> index e7705e7bb07b..f9e3bb57c461 100644
>>> --- a/arch/arm64/include/asm/kvm_host.h
>>> +++ b/arch/arm64/include/asm/kvm_host.h
>>> @@ -83,6 +83,10 @@ struct kvm_mmu_memory_cache {
>>> };
>>>
>>> struct kvm_vcpu_fault_info {
>>> +#ifdef CONFIG_HAS_RAS_EXTENSION
>>> + /* Virtual SError Exception Syndrome Register */
>>> + u32 vsesr_el2;
>>> +#endif
>>> u32 esr_el2; /* Hyp Syndrom Register */
>>> u64 far_el2; /* Hyp Fault Address Register */
>>> u64 hpfar_el2; /* Hyp IPA Fault Address Register */
>>> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
>>> index aede1658aeda..770a153fb6ba 100644
>>> --- a/arch/arm64/kvm/hyp/switch.c
>>> +++ b/arch/arm64/kvm/hyp/switch.c
>>> @@ -86,6 +86,13 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu)
>>> isb();
>>> }
>>> write_sysreg(val, hcr_el2);
>>> +#ifdef CONFIG_HAS_RAS_EXTENSION
>>> + /* If virtual System Error or Asynchronous Abort is pending. set
>>> + * the virtual exception syndrome information
>>> + */
>>> + if (vcpu->arch.hcr_el2 & HCR_VSE)
>>> + write_sysreg(vcpu->arch.fault.vsesr_el2, vsesr_el2);
>>> +#endif
>>> /* Trap on AArch32 cp15 c15 accesses (EL1 or EL0) */
>>> write_sysreg(1 << 15, hstr_el2);
>>> /*
>>> @@ -139,8 +146,14 @@ static void __hyp_text __deactivate_traps(struct kvm_vcpu *vcpu)
>>> * the crucial bit is "On taking a vSError interrupt,
>>> * HCR_EL2.VSE is cleared to 0."
>>> */
>>> - if (vcpu->arch.hcr_el2 & HCR_VSE)
>>> + if (vcpu->arch.hcr_el2 & HCR_VSE) {
>>> vcpu->arch.hcr_el2 = read_sysreg(hcr_el2);
>>> +#ifdef CONFIG_HAS_RAS_EXTENSION
>>> + /* set vsesr_el2[24:0] with esr_el2[24:0] */
>>> + kvm_vcpu_set_vsesr(vcpu, read_sysreg_el2(esr)
>>> + & VSESR_ELx_IDS_ISS_MASK);
>>
>> What guarantees that ESR_EL2 still contains the latest exception? What
>> does it mean to store something that is the current EL2 exception
>> syndrome together with an SError that has already been injected?
>
> yes, thanks for the review, I will add a judgement condition for the "exit_code"
> if the "exit_code == ARM_EXCEPTION_EL1_SERROR" then set the vsesr_el2.
>
> for the aarch32, it only need set the "ExT, bit [12]" and AET, "bits [15:14]", other bit is RES0
>
>>
>> Also, is it correct to directly copy the ESR_EL2 bits into VSESR_EL2? My
> please see below spec description, it virtual SERROR syndrome from VSESR_EL2.
> -----
> Control returns to the OS, and the ESB instruction is re-executed.
> — The physical asynchronous SError interrupt has been cleared, so it is not taken again.
> — The PE sets VDISR_EL2.A to 1 and records the syndrome from VSESR_EL2 in VDISR_EL2.
> -----
Which doesn't say anything about directly using ESR_EL2 and propagating
it directly to the guest, specially when there is *already* an SError
pending (just in case you haven't noticed, this is the *exit* path, and
I can't see why you would overload VSESR_EL2 at at point).
>
>> own reading of the specification seem to imply that there is at least
>> differences when the guest is AArch32. Surely there would be some
>> processing here.
>
>
>
>>
>>> +#endif
>>> + }
>>>
>>> __deactivate_traps_arch()();
>>> write_sysreg(0, hstr_el2);
>>> diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c
>>> index da6a8cfa54a0..08a13dfe28a8 100644
>>> --- a/arch/arm64/kvm/inject_fault.c
>>> +++ b/arch/arm64/kvm/inject_fault.c
>>> @@ -242,4 +242,14 @@ void kvm_inject_undefined(struct kvm_vcpu *vcpu)
>>> void kvm_inject_vabt(struct kvm_vcpu *vcpu)
>>> {
>>> vcpu_set_hcr(vcpu, vcpu_get_hcr(vcpu) | HCR_VSE);
>>> +#ifdef CONFIG_HAS_RAS_EXTENSION
>>> + /* If virtual System Error or Asynchronous Abort is set. set
>>> + * the virtual exception syndrome information
>>> + */
>>> + kvm_vcpu_set_vsesr(vcpu, ((kvm_vcpu_get_vsesr(vcpu)
>>> + & (~VSESR_ELx_IDS_ISS_MASK))
>>> + | (kvm_vcpu_get_hsr(vcpu)
>>> + & VSESR_ELx_IDS_ISS_MASK)));
>>
>> What is the rational for setting VSESR_EL2 with the EL1 syndrome
>> information? That doesn't make any sense to me.
> thanks, I set the VSESR_EL2 using the EL2 syndrome information, "kvm_vcpu_get_hsr"
> return the value of esr_el2, not EL1 syndrome information
Ah, good point. But that doesn't make it more valid. I still don't see
anything in the spec that supports this behaviour, and I still propose
that when RAS is enabled, the VSError injection is mediated by userspace.
Thanks,
M.
--
Jazz is not dead. It just smells funny...
[toc] | [prev] | [next] | [standalone]
| From | James Morse <james.morse@arm.com> |
|---|---|
| Date | 2017-03-20 16:20 +0100 |
| Message-ID | <tn7gd-6yN-5@gated-at.bofh.it> |
| In reply to | #1604602 |
Hi Dongjiu Geng,
On 20/03/17 13:58, Marc Zyngier wrote:
> On 20/03/17 12:28, gengdongjiu wrote:
>> On 2017/3/20 19:24, Marc Zyngier wrote:
>>> Please include James Morse on anything RAS related, as he's already
>>> looking at related patches.
(Thanks Marc,)
>>> On 20/03/17 07:55, Dongjiu Geng wrote:
>>>> In the RAS implementation, hardware pass the virtual SEI
>>>> syndrome information through the VSESR_EL2, so set the virtual
>>>> SEI syndrome using physical SEI syndrome el2_elr to pass to
>>>> the guest OS
How does this work with firmware first?
If we took a Physical SError Interrupt the CPER records are in the hosts memory.
To deliver a RAS event to the guest something needs to generate CPER records and
put them in the guest memory. Only Qemu knows where these memory regions are.
Put another way, what is the guest expected to do with this SError interrupt?
The only choice is panic(). We should send this via Qemu so that we can add
proper guest RAS support later. Once Qemu has written the CPER records into
guest memory, it can notify the guest.
Is anyone from Huawei looking at adding RAS support for Qemu?
It looks like we should save/restore VSESR_EL2 as part of the guest CPU state,
but this needs doing with the cpufeature framework so that the single-image
kernel works on platforms with and without these features.
Xie XiuQi's series for SEI also touches the cpufeature framework.
>>>> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
>>>> index aede1658aeda..770a153fb6ba 100644
>>>> --- a/arch/arm64/kvm/hyp/switch.c
>>>> +++ b/arch/arm64/kvm/hyp/switch.c
>>>> @@ -86,6 +86,13 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu)
>>>> isb();
>>>> }
>>>> write_sysreg(val, hcr_el2);
>>>> +#ifdef CONFIG_HAS_RAS_EXTENSION
>>>> + /* If virtual System Error or Asynchronous Abort is pending. set
>>>> + * the virtual exception syndrome information
>>>> + */
>>>> + if (vcpu->arch.hcr_el2 & HCR_VSE)
>>>> + write_sysreg(vcpu->arch.fault.vsesr_el2, vsesr_el2);
This won't build with versions of binutils that don't recognise vsesr_el2.
Is there another patch out there that adds a sysreg definition for vsesr_el2?
>>>> diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c
>>>> index da6a8cfa54a0..08a13dfe28a8 100644
>>>> --- a/arch/arm64/kvm/inject_fault.c
>>>> +++ b/arch/arm64/kvm/inject_fault.c
>>>> @@ -242,4 +242,14 @@ void kvm_inject_undefined(struct kvm_vcpu *vcpu)
>>>> void kvm_inject_vabt(struct kvm_vcpu *vcpu)
>>>> {
>>>> vcpu_set_hcr(vcpu, vcpu_get_hcr(vcpu) | HCR_VSE);
>>>> +#ifdef CONFIG_HAS_RAS_EXTENSION
>>>> + /* If virtual System Error or Asynchronous Abort is set. set
>>>> + * the virtual exception syndrome information
>>>> + */
>>>> + kvm_vcpu_set_vsesr(vcpu, ((kvm_vcpu_get_vsesr(vcpu)
>>>> + & (~VSESR_ELx_IDS_ISS_MASK))
>>>> + | (kvm_vcpu_get_hsr(vcpu)
>>>> + & VSESR_ELx_IDS_ISS_MASK)));
>>>
>>> What is the rational for setting VSESR_EL2 with the EL1 syndrome
>>> information? That doesn't make any sense to me.
>> thanks, I set the VSESR_EL2 using the EL2 syndrome information, "kvm_vcpu_get_hsr"
>> return the value of esr_el2, not EL1 syndrome information
>
> Ah, good point. But that doesn't make it more valid. I still don't see
> anything in the spec that supports this behaviour, and I still propose
> that when RAS is enabled, the VSError injection is mediated by userspace.
I agree, we should be handling RAS errors as firmware-first, and Qemu plays the
part of firmware for a guest. We will probably need to have a KVM API for Qemu
to pend an SError with a specific ESR value.
If this isn't a firmware-first RAS error the existing code will pend an SError
for the guest.
Thanks,
James
[toc] | [prev] | [next] | [standalone]
| From | gengdongjiu <gengdongjiu@huawei.com> |
|---|---|
| Date | 2017-03-21 07:40 +0100 |
| Message-ID | <tnlCx-7XR-1@gated-at.bofh.it> |
| In reply to | #1604676 |
On 2017/3/20 23:08, James Morse wrote:
> Hi Dongjiu Geng,
>
> On 20/03/17 13:58, Marc Zyngier wrote:
>> On 20/03/17 12:28, gengdongjiu wrote:
>>> On 2017/3/20 19:24, Marc Zyngier wrote:
>>>> Please include James Morse on anything RAS related, as he's already
>>>> looking at related patches.
>
> (Thanks Marc,)
>
>>>> On 20/03/17 07:55, Dongjiu Geng wrote:
>>>>> In the RAS implementation, hardware pass the virtual SEI
>>>>> syndrome information through the VSESR_EL2, so set the virtual
>>>>> SEI syndrome using physical SEI syndrome el2_elr to pass to
>>>>> the guest OS
>
> How does this work with firmware first?
I explained it in previous mail about the work flow.
when the Guest OS triggers an SEI, it will firstly trap to EL3 firmware, El3 firmware records the error
info to the APEI table, then copy the ESR_EL3 ELR_EL3 to ESR_EL2 ELR_EL2 and transfers control to the
hypervisor, hypervisor delegates the error exception to EL1 guest OS by setting HCR_EL2.VSE to 1 and pass the
virtual SEI syndrome through vsesr_el2. The EL1 guest OS check the DISR_EL1 syndrome information to decide to
terminate the application, or do some other recovery action. because the HCR_EL2.AMO is set, so in fact, read
DISR_EL1, it returns the VDISR_EL2. and VDISR_EL2 is loaded from VSESR_EL2, so here I pass the virtual SEI
syndrome vsesr_el2.
> If we took a Physical SError Interrupt the CPER records are in the hosts memory.
> To deliver a RAS event to the guest something needs to generate CPER records and
> put them in the guest memory. Only Qemu knows where these memory regions are.
>
> Put another way, what is the guest expected to do with this SError interrupt?
No, we do not only panic,if it is EL0 application SEI. the OS error recovery
agent will terminate the EL0 application to isolate the error; If it is EL1 guest
OS SError, guest OS can see whether it can recover. if the error was in a read-only file cache buffer, guest OS
can invalidate the page and reload the data from disk.
if all of the above are failed, OS will panic.
> The only choice is panic(). We should send this via Qemu so that we can add
> proper guest RAS support later. Once Qemu has written the CPER records into
> guest memory, it can notify the guest.
>
> Is anyone from Huawei looking at adding RAS support for Qemu?
yes, I am looking at Qemu and want to add RAS support.
do you mean let Qemu inject both the SEA and SEI?
>
>
> It looks like we should save/restore VSESR_EL2 as part of the guest CPU state,
> but this needs doing with the cpufeature framework so that the single-image
> kernel works on platforms with and without these features.
yes, you are right, we will follow cpufeature framework.
>
> Xie XiuQi's series for SEI also touches the cpufeature framework.
>
>
>>>>> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
>>>>> index aede1658aeda..770a153fb6ba 100644
>>>>> --- a/arch/arm64/kvm/hyp/switch.c
>>>>> +++ b/arch/arm64/kvm/hyp/switch.c
>>>>> @@ -86,6 +86,13 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu)
>>>>> isb();
>>>>> }
>>>>> write_sysreg(val, hcr_el2);
>>>>> +#ifdef CONFIG_HAS_RAS_EXTENSION
>>>>> + /* If virtual System Error or Asynchronous Abort is pending. set
>>>>> + * the virtual exception syndrome information
>>>>> + */
>>>>> + if (vcpu->arch.hcr_el2 & HCR_VSE)
>
>>>>> + write_sysreg(vcpu->arch.fault.vsesr_el2, vsesr_el2);
>
> This won't build with versions of binutils that don't recognise vsesr_el2.
> Is there another patch out there that adds a sysreg definition for vsesr_el2?
>
>
>>>>> diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c
>>>>> index da6a8cfa54a0..08a13dfe28a8 100644
>>>>> --- a/arch/arm64/kvm/inject_fault.c
>>>>> +++ b/arch/arm64/kvm/inject_fault.c
>>>>> @@ -242,4 +242,14 @@ void kvm_inject_undefined(struct kvm_vcpu *vcpu)
>>>>> void kvm_inject_vabt(struct kvm_vcpu *vcpu)
>>>>> {
>>>>> vcpu_set_hcr(vcpu, vcpu_get_hcr(vcpu) | HCR_VSE);
>>>>> +#ifdef CONFIG_HAS_RAS_EXTENSION
>>>>> + /* If virtual System Error or Asynchronous Abort is set. set
>>>>> + * the virtual exception syndrome information
>>>>> + */
>>>>> + kvm_vcpu_set_vsesr(vcpu, ((kvm_vcpu_get_vsesr(vcpu)
>>>>> + & (~VSESR_ELx_IDS_ISS_MASK))
>>>>> + | (kvm_vcpu_get_hsr(vcpu)
>>>>> + & VSESR_ELx_IDS_ISS_MASK)));
>>>>
>>>> What is the rational for setting VSESR_EL2 with the EL1 syndrome
>>>> information? That doesn't make any sense to me.
>>> thanks, I set the VSESR_EL2 using the EL2 syndrome information, "kvm_vcpu_get_hsr"
>>> return the value of esr_el2, not EL1 syndrome information
>>
>> Ah, good point. But that doesn't make it more valid. I still don't see
>> anything in the spec that supports this behaviour, and I still propose
>> that when RAS is enabled, the VSError injection is mediated by userspace.
>
> I agree, we should be handling RAS errors as firmware-first, and Qemu plays the
> part of firmware for a guest. We will probably need to have a KVM API for Qemu
> to pend an SError with a specific ESR value.
>
> If this isn't a firmware-first RAS error the existing code will pend an SError
> for the guest.
>
so for both SEA and SEI, do you prefer to below steps?
EL0/EL1 SEI/SEA ---> EL3 firmware first handle ------> EL2 hypervisor notify the Qemu to inject SEI/SEA------>Qemu call KVM API to inject SEA/SEI---->KVM inject SEA/SEI to guest OS
>
> Thanks,
>
> James
>
>
> .
>
[toc] | [prev] | [next] | [standalone]
| From | Christoffer Dall <cdall@linaro.org> |
|---|---|
| Date | 2017-03-21 12:50 +0100 |
| Message-ID | <tnqsz-2K1-39@gated-at.bofh.it> |
| In reply to | #1605334 |
On Tue, Mar 21, 2017 at 02:32:29PM +0800, gengdongjiu wrote:
>
>
> On 2017/3/20 23:08, James Morse wrote:
> > Hi Dongjiu Geng,
> >
> > On 20/03/17 13:58, Marc Zyngier wrote:
> >> On 20/03/17 12:28, gengdongjiu wrote:
> >>> On 2017/3/20 19:24, Marc Zyngier wrote:
> >>>> Please include James Morse on anything RAS related, as he's already
> >>>> looking at related patches.
> >
> > (Thanks Marc,)
> >
> >>>> On 20/03/17 07:55, Dongjiu Geng wrote:
> >>>>> In the RAS implementation, hardware pass the virtual SEI
> >>>>> syndrome information through the VSESR_EL2, so set the virtual
> >>>>> SEI syndrome using physical SEI syndrome el2_elr to pass to
> >>>>> the guest OS
> >
> > How does this work with firmware first?
>
> I explained it in previous mail about the work flow.
When delivering and reporting SEIs to the VM, should this happen
directly to the OS running in the VM, or to the guest firmware (e.g.
UEFI) running in the VM as well?
Thanks,
-Christoffer
>
> when the Guest OS triggers an SEI, it will firstly trap to EL3 firmware, El3 firmware records the error
> info to the APEI table, then copy the ESR_EL3 ELR_EL3 to ESR_EL2 ELR_EL2 and transfers control to the
> hypervisor, hypervisor delegates the error exception to EL1 guest OS by setting HCR_EL2.VSE to 1 and pass the
> virtual SEI syndrome through vsesr_el2. The EL1 guest OS check the DISR_EL1 syndrome information to decide to
> terminate the application, or do some other recovery action. because the HCR_EL2.AMO is set, so in fact, read
> DISR_EL1, it returns the VDISR_EL2. and VDISR_EL2 is loaded from VSESR_EL2, so here I pass the virtual SEI
> syndrome vsesr_el2.
>
> > If we took a Physical SError Interrupt the CPER records are in the hosts memory.
> > To deliver a RAS event to the guest something needs to generate CPER records and
> > put them in the guest memory. Only Qemu knows where these memory regions are.
> >
> > Put another way, what is the guest expected to do with this SError interrupt?
> No, we do not only panic,if it is EL0 application SEI. the OS error recovery
> agent will terminate the EL0 application to isolate the error; If it is EL1 guest
> OS SError, guest OS can see whether it can recover. if the error was in a read-only file cache buffer, guest OS
> can invalidate the page and reload the data from disk.
>
> if all of the above are failed, OS will panic.
>
>
> > The only choice is panic(). We should send this via Qemu so that we can add
> > proper guest RAS support later. Once Qemu has written the CPER records into
> > guest memory, it can notify the guest.
> >
> > Is anyone from Huawei looking at adding RAS support for Qemu?
> yes, I am looking at Qemu and want to add RAS support.
> do you mean let Qemu inject both the SEA and SEI?
>
> >
> >
> > It looks like we should save/restore VSESR_EL2 as part of the guest CPU state,
> > but this needs doing with the cpufeature framework so that the single-image
> > kernel works on platforms with and without these features.
> yes, you are right, we will follow cpufeature framework.
>
>
> >
> > Xie XiuQi's series for SEI also touches the cpufeature framework.
> >
> >
> >>>>> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
> >>>>> index aede1658aeda..770a153fb6ba 100644
> >>>>> --- a/arch/arm64/kvm/hyp/switch.c
> >>>>> +++ b/arch/arm64/kvm/hyp/switch.c
> >>>>> @@ -86,6 +86,13 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu)
> >>>>> isb();
> >>>>> }
> >>>>> write_sysreg(val, hcr_el2);
> >>>>> +#ifdef CONFIG_HAS_RAS_EXTENSION
> >>>>> + /* If virtual System Error or Asynchronous Abort is pending. set
> >>>>> + * the virtual exception syndrome information
> >>>>> + */
> >>>>> + if (vcpu->arch.hcr_el2 & HCR_VSE)
> >
> >>>>> + write_sysreg(vcpu->arch.fault.vsesr_el2, vsesr_el2);
> >
> > This won't build with versions of binutils that don't recognise vsesr_el2.
> > Is there another patch out there that adds a sysreg definition for vsesr_el2?
> >
> >
> >>>>> diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c
> >>>>> index da6a8cfa54a0..08a13dfe28a8 100644
> >>>>> --- a/arch/arm64/kvm/inject_fault.c
> >>>>> +++ b/arch/arm64/kvm/inject_fault.c
> >>>>> @@ -242,4 +242,14 @@ void kvm_inject_undefined(struct kvm_vcpu *vcpu)
> >>>>> void kvm_inject_vabt(struct kvm_vcpu *vcpu)
> >>>>> {
> >>>>> vcpu_set_hcr(vcpu, vcpu_get_hcr(vcpu) | HCR_VSE);
> >>>>> +#ifdef CONFIG_HAS_RAS_EXTENSION
> >>>>> + /* If virtual System Error or Asynchronous Abort is set. set
> >>>>> + * the virtual exception syndrome information
> >>>>> + */
> >>>>> + kvm_vcpu_set_vsesr(vcpu, ((kvm_vcpu_get_vsesr(vcpu)
> >>>>> + & (~VSESR_ELx_IDS_ISS_MASK))
> >>>>> + | (kvm_vcpu_get_hsr(vcpu)
> >>>>> + & VSESR_ELx_IDS_ISS_MASK)));
> >>>>
> >>>> What is the rational for setting VSESR_EL2 with the EL1 syndrome
> >>>> information? That doesn't make any sense to me.
> >>> thanks, I set the VSESR_EL2 using the EL2 syndrome information, "kvm_vcpu_get_hsr"
> >>> return the value of esr_el2, not EL1 syndrome information
> >>
> >> Ah, good point. But that doesn't make it more valid. I still don't see
> >> anything in the spec that supports this behaviour, and I still propose
> >> that when RAS is enabled, the VSError injection is mediated by userspace.
> >
> > I agree, we should be handling RAS errors as firmware-first, and Qemu plays the
> > part of firmware for a guest. We will probably need to have a KVM API for Qemu
> > to pend an SError with a specific ESR value.
> >
> > If this isn't a firmware-first RAS error the existing code will pend an SError
> > for the guest.
> >
> so for both SEA and SEI, do you prefer to below steps?
> EL0/EL1 SEI/SEA ---> EL3 firmware first handle ------> EL2 hypervisor notify the Qemu to inject SEI/SEA------>Qemu call KVM API to inject SEA/SEI---->KVM inject SEA/SEI to guest OS
>
>
> >
> > Thanks,
> >
> > James
> >
> >
> > .
> >
>
[toc] | [prev] | [next] | [standalone]
| From | James Morse <james.morse@arm.com> |
|---|---|
| Date | 2017-03-21 20:20 +0100 |
| Message-ID | <tnxu2-7Db-31@gated-at.bofh.it> |
| In reply to | #1605533 |
Hi Christoffer, On 21/03/17 11:34, Christoffer Dall wrote: > On Tue, Mar 21, 2017 at 02:32:29PM +0800, gengdongjiu wrote: >> On 2017/3/20 23:08, James Morse wrote: >>>>>> On 20/03/17 07:55, Dongjiu Geng wrote: >>>>>>> In the RAS implementation, hardware pass the virtual SEI >>>>>>> syndrome information through the VSESR_EL2, so set the virtual >>>>>>> SEI syndrome using physical SEI syndrome el2_elr to pass to >>>>>>> the guest OS >>> >>> How does this work with firmware first? >> >> I explained it in previous mail about the work flow. > > When delivering and reporting SEIs to the VM, should this happen > directly to the OS running in the VM, or to the guest firmware (e.g. > UEFI) running in the VM as well? 'firmware first' is the ACPI specs name for x86's BIOS or management-mode handling the error. On arm64 we have multiple things called firmware, so the name might be more confusing than helpful. As far as I understand it, firmware here refers to the secure-world and EL3. Something like ATF can use SCR_EL3.EA to claim SErrors and external aborts, routing them to EL3 where secure platform specific firmware generates CPER records. For a guest, Qemu takes the role of this EL3-firmware. Thanks, James
[toc] | [prev] | [next] | [standalone]
| From | Christoffer Dall <cdall@linaro.org> |
|---|---|
| Date | 2017-03-21 21:00 +0100 |
| Message-ID | <tny6K-7WE-23@gated-at.bofh.it> |
| In reply to | #1605928 |
[resending as clear text - I thought GMail supported that - sorry] On Tue, Mar 21, 2017 at 07:11:44PM +0000, James Morse wrote: > Hi Christoffer, > > On 21/03/17 11:34, Christoffer Dall wrote: > > On Tue, Mar 21, 2017 at 02:32:29PM +0800, gengdongjiu wrote: > >> On 2017/3/20 23:08, James Morse wrote: > >>>>>> On 20/03/17 07:55, Dongjiu Geng wrote: > >>>>>>> In the RAS implementation, hardware pass the virtual SEI > >>>>>>> syndrome information through the VSESR_EL2, so set the virtual > >>>>>>> SEI syndrome using physical SEI syndrome el2_elr to pass to > >>>>>>> the guest OS > >>> > >>> How does this work with firmware first? > >> > >> I explained it in previous mail about the work flow. > > > > When delivering and reporting SEIs to the VM, should this happen > > directly to the OS running in the VM, or to the guest firmware (e.g. > > UEFI) running in the VM as well? > > 'firmware first' is the ACPI specs name for x86's BIOS or management-mode > handling the error. On arm64 we have multiple things called firmware, so the > name might be more confusing than helpful. > > As far as I understand it, firmware here refers to the secure-world and EL3. > Something like ATF can use SCR_EL3.EA to claim SErrors and external aborts, > routing them to EL3 where secure platform specific firmware generates CPER records. > For a guest, Qemu takes the role of this EL3-firmware. > Thanks for the clarification. So UEFI in the VM would not be involved in this at all? My confusion here comes from not thinking about QEMU or KVM as firmware, but as the machine, so it would be sort of like the functionality is baked into hardware rather than firmware. Note that to the VM, the environment will look like hardware without EL3 and without a secure world, so any software assuming there's something 'hidden' behind the available non-secure modes must not decide to disable features if discovering the lack of a secure world. Thanks, -Christoffer
[toc] | [prev] | [next] | [standalone]
| From | Peter Maydell <peter.maydell@linaro.org> |
|---|---|
| Date | 2017-03-21 23:20 +0100 |
| Message-ID | <tnAid-1cd-3@gated-at.bofh.it> |
| In reply to | #1605965 |
On 21 March 2017 at 19:39, Christoffer Dall <cdall@linaro.org> wrote: > My confusion here comes from not thinking about QEMU or KVM as firmware, > but as the machine, so it would be sort of like the functionality is > baked into hardware rather than firmware. There is precedent for that kind of thing -- we implement PSCI in KVM/QEMU for the guest, though in real hardware it would be provided by firmware at EL3. thanks -- PMM
[toc] | [prev] | [next] | [standalone]
| From | Marc Zyngier <marc.zyngier@arm.com> |
|---|---|
| Date | 2017-03-22 12:20 +0100 |
| Message-ID | <tnMt3-1zh-7@gated-at.bofh.it> |
| In reply to | #1606024 |
On 21/03/17 22:10, Peter Maydell wrote: > On 21 March 2017 at 19:39, Christoffer Dall <cdall@linaro.org> wrote: >> My confusion here comes from not thinking about QEMU or KVM as firmware, >> but as the machine, so it would be sort of like the functionality is >> baked into hardware rather than firmware. > > There is precedent for that kind of thing -- we implement PSCI > in KVM/QEMU for the guest, though in real hardware it would be > provided by firmware at EL3. [probably vastly off topic] In retrospect, I now believe this was a rather big mistake to implement PSCI in KVM. Eventually, we want to be able to handle the full spectrum of the SMCCC and forward things to an actual TEE if available. There is no real reason why PSCI shouldn't be handled in userspace the same way (and we already offload reset and halt to QEMU). Thanks, M. -- Jazz is not dead. It just smells funny...
[toc] | [prev] | [next] | [standalone]
| From | James Morse <james.morse@arm.com> |
|---|---|
| Date | 2017-03-21 14:20 +0100 |
| Message-ID | <tnrRD-3PG-3@gated-at.bofh.it> |
| In reply to | #1605334 |
Hi, On 21/03/17 06:32, gengdongjiu wrote: > On 2017/3/20 23:08, James Morse wrote: >> On 20/03/17 13:58, Marc Zyngier wrote: >>> On 20/03/17 12:28, gengdongjiu wrote: >>>> On 2017/3/20 19:24, Marc Zyngier wrote: >>>>> On 20/03/17 07:55, Dongjiu Geng wrote: >>>>>> In the RAS implementation, hardware pass the virtual SEI >>>>>> syndrome information through the VSESR_EL2, so set the virtual >>>>>> SEI syndrome using physical SEI syndrome el2_elr to pass to >>>>>> the guest OS (I've juggled the order of your replies:) > so for both SEA and SEI, do you prefer to below steps? > EL0/EL1 SEI/SEA ---> EL3 firmware first handle ------> EL2 hypervisor notify > the Qemu to inject SEI/SEA------>Qemu call KVM API to inject SEA/SEI---->KVM > inject SEA/SEI to guest OS Yes, to expand your EL2 hypervisor notify Qemu step: 1 The host should call its APEI code to parse the CPER records. 2 User space processes are then notified via SIGBUS (or for rasdaemon, trace points). 3 Qemu can take the address delivered via SIGBUS and generate CPER records for the guest. It knows how to convert host addresses to guest IPAs, and it knows where in guest memory to write the CPER records. 4 Qemu can then notify the guest via whatever mechanism it advertised via the HEST/GHES table. It might not be the same mechanism that the host received the notification through. Steps 1 and 2 are the same even if no guest is running, so we don't have to add any special case for KVM. This is existing code that x86 uses. We can test the Qemu parts without any firmware support and the APEI path in the host and guest is the same. >> Is anyone from Huawei looking at adding RAS support for Qemu? > yes, I am looking at Qemu and want to add RAS support. Great, support in Qemu is one of the missing pieces. On x86 it looks like it emulates machine-check-exceptions, which is how x86 did this before firmware-first and APEI became the standard. > do you mean let Qemu inject both the SEA and SEI? To do the notification, yes. It needs to happen after the CPER records have been written, and the mechanism and CPER memory location need to match what the guest was told via the HEST/GHES table. If Qemu didn't tell the guest about firmware-first, it can still deliver the guest an SError Interrupt. SEA should be possible to do with the KVM_SET_REG API, GPIO/GSIV and the other kind of interrupts can use irqfd. For SEI we may need to add an API call to KVM to let it pend SError with a specific ESR. >> How does this work with firmware first? > when the Guest OS triggers an SEI, it will firstly trap to EL3 firmware, El3 firmware records the error > info to the APEI table, These are CPER records in a memory area pointed to by one of HEST's GHES entries? > then copy the ESR_EL3 ELR_EL3 to ESR_EL2 ELR_EL2 and transfers control to the > hypervisor, hypervisor delegates the error exception to EL1 guest This is a problem, just because the error occurred while the guest was running doesn't mean we should deliver it directly to the guest. Some of these errors will be fatal for the CPU and the host should try and power it off to contain the fault. For example: CPER's 'micro-architectural error', should the guest power-off the vCPU? All that really does is return to the hypervisor, the error hasn't been contained. Firmware should handle the error first, then the host, finally the guest via Qemu. > OS by setting HCR_EL2.VSE to 1 and pass the virtual SEI syndrome through vsesr_el2. > The EL1 guest OS check the DISR_EL1 syndrome information to decide to > terminate the application, or do some other recovery action. because the HCR_EL2.AMO is set, so in fact, read > DISR_EL1, it returns the VDISR_EL2. and VDISR_EL2 is loaded from VSESR_EL2, so here I pass the virtual SEI > syndrome vsesr_el2. So this is how an SError Interrupt's ESR gets into a guest. How does it get hold of the CPER records? >> If we took a Physical SError Interrupt the CPER records are in the hosts memory. >> To deliver a RAS event to the guest something needs to generate CPER records and >> put them in the guest memory. Only Qemu knows where these memory regions are. >> >> Put another way, what is the guest expected to do with this SError interrupt? > > No, we do not only panic,if it is EL0 application SEI. the OS error recovery > agent will terminate the EL0 application to isolate the error; If it is EL1 guest > OS SError, guest OS can see whether it can recover. if the error was in a read-only file cache buffer, guest OS > can invalidate the page and reload the data from disk. How do we get an address for memory failure? SError is asynchronous, I don't think it sets the FAR. (SEA is synchronous and its not guaranteed to set the FAR..). As far as I understand this information is in the CPER records in host memory. If we did have an address it would be a host address, how is it converted to a guest IPA? I think Qemu should do this as part of its CPER record generation, once the host has decided the error wasn't catastrophic. Thanks, James
[toc] | [prev] | [next] | [standalone]
| From | gengdongjiu <gengdongjiu@huawei.com> |
|---|---|
| Date | 2017-03-22 14:50 +0100 |
| Message-ID | <tnOOd-3b8-3@gated-at.bofh.it> |
| In reply to | #1605582 |
Hi James, Thank you very much for your detailed comment and answer. On 2017/3/21 21:10, James Morse wrote: > Hi, > > On 21/03/17 06:32, gengdongjiu wrote: >> On 2017/3/20 23:08, James Morse wrote: >>> On 20/03/17 13:58, Marc Zyngier wrote: >>>> On 20/03/17 12:28, gengdongjiu wrote: >>>>> On 2017/3/20 19:24, Marc Zyngier wrote: >>>>>> On 20/03/17 07:55, Dongjiu Geng wrote: >>>>>>> In the RAS implementation, hardware pass the virtual SEI >>>>>>> syndrome information through the VSESR_EL2, so set the virtual >>>>>>> SEI syndrome using physical SEI syndrome el2_elr to pass to >>>>>>> the guest OS > > (I've juggled the order of your replies:) > >> so for both SEA and SEI, do you prefer to below steps? >> EL0/EL1 SEI/SEA ---> EL3 firmware first handle ------> EL2 hypervisor notify > > the Qemu to inject SEI/SEA------>Qemu call KVM API to inject SEA/SEI---->KVM > > inject SEA/SEI to guest OS > > Yes, to expand your EL2 hypervisor notify Qemu step: > 1 The host should call its APEI code to parse the CPER records. > 2 User space processes are then notified via SIGBUS (or for rasdaemon, trace > points). > 3 Qemu can take the address delivered via SIGBUS and generate CPER records for > the guest. It knows how to convert host addresses to guest IPAs, and it knows > where in guest memory to write the CPER records. > 4 Qemu can then notify the guest via whatever mechanism it advertised via the > HEST/GHES table. It might not be the same mechanism that the host received > the notification through. > > Steps 1 and 2 are the same even if no guest is running, so we don't have to add > any special case for KVM. This is existing code that x86 uses. > We can test the Qemu parts without any firmware support and the APEI path in the > host and guest is the same. here do you mean map host APEI table to guest for steps 1 and 2 test? so that the APEI path in the host and guest is the same. > > >>> Is anyone from Huawei looking at adding RAS support for Qemu? >> yes, I am looking at Qemu and want to add RAS support. > > Great, support in Qemu is one of the missing pieces. On x86 it looks like it > emulates machine-check-exceptions, which is how x86 did this before > firmware-first and APEI became the standard. > > >> do you mean let Qemu inject both the SEA and SEI? > > To do the notification, yes. It needs to happen after the CPER records have been > written, and the mechanism and CPER memory location need to match what the guest > was told via the HEST/GHES table. > > If Qemu didn't tell the guest about firmware-first, it can still deliver the > guest an SError Interrupt. > > > SEA should be possible to do with the KVM_SET_REG API, GPIO/GSIV and the other > kind of interrupts can use irqfd. For SEI we may need to add an API call to KVM > to let it pend SError with a specific ESR. > > > >>> How does this work with firmware first? > >> when the Guest OS triggers an SEI, it will firstly trap to EL3 firmware, El3 firmware records the error >> info to the APEI table, > > These are CPER records in a memory area pointed to by one of HEST's GHES entries? > > >> then copy the ESR_EL3 ELR_EL3 to ESR_EL2 ELR_EL2 and transfers control to the >> hypervisor, hypervisor delegates the error exception to EL1 guest > > This is a problem, just because the error occurred while the guest was running > doesn't mean we should deliver it directly to the guest. Some of these errors > will be fatal for the CPU and the host should try and power it off to contain yes, some of error does not need to deliver to guest OS directly. for example if the error is guest kernel fault error, hypervisor can directly power off the whole guest OS > the fault. For example: CPER's 'micro-architectural error', should the guest > power-off the vCPU? All that really does is return to the hypervisor, the error for this example, I think it is better hypervisor directly close the whole guest OS, instead of guest power-off the vCPU. > hasn't been contained. > > Firmware should handle the error first, then the host, finally the guest via Qemu. > > >> OS by setting HCR_EL2.VSE to 1 and pass the virtual SEI syndrome through vsesr_el2. >> The EL1 guest OS check the DISR_EL1 syndrome information to decide to >> terminate the application, or do some other recovery action. because the HCR_EL2.AMO is set, so in fact, read >> DISR_EL1, it returns the VDISR_EL2. and VDISR_EL2 is loaded from VSESR_EL2, so here I pass the virtual SEI >> syndrome vsesr_el2. > > So this is how an SError Interrupt's ESR gets into a guest. How does it get hold > of the CPER records? > > >>> If we took a Physical SError Interrupt the CPER records are in the hosts memory. >>> To deliver a RAS event to the guest something needs to generate CPER records and >>> put them in the guest memory. Only Qemu knows where these memory regions are. >>> >>> Put another way, what is the guest expected to do with this SError interrupt? >> >> No, we do not only panic,if it is EL0 application SEI. the OS error recovery >> agent will terminate the EL0 application to isolate the error; If it is EL1 guest >> OS SError, guest OS can see whether it can recover. if the error was in a read-only file cache buffer, guest OS >> can invalidate the page and reload the data from disk. > > How do we get an address for memory failure? SError is asynchronous, I don't > think it sets the FAR. (SEA is synchronous and its not guaranteed to set the Thank you to point that. sorry, my answer is not right. in fact, I think the FAR and CPER are both not accurate for the asynchronous SError. so guest OS can not try to recover. but it can still know which application create this SError which is deferred by ESB, then guest OS close the APP. by the way, for the synchronous SEA, do you think which address should be used? FAR or CPER that record come from ERR<n>ADDR? I see Qualcomm series patches mainly use FAR not CPER record that come from ERR<n>ADDR for SEA. so for the SEA case, I do not know which address is more accurate for FAR and CPER record > FAR..). As far as I understand this information is in the CPER records in host > memory. > > If we did have an address it would be a host address, how is it converted to a > guest IPA? I think Qemu should do this as part of its CPER record generation, > once the host has decided the error wasn't catastrophic. thanks for your suggestion. > > > Thanks, > > James > > > . >
[toc] | [prev] | [next] | [standalone]
| From | James Morse <james.morse@arm.com> |
|---|---|
| Date | 2017-03-22 20:00 +0100 |
| Message-ID | <tnTEe-6Xw-15@gated-at.bofh.it> |
| In reply to | #1606512 |
Hi gengdongjiu On 22/03/17 13:37, gengdongjiu wrote: > On 2017/3/21 21:10, James Morse wrote: >> On 21/03/17 06:32, gengdongjiu wrote: >>> so for both SEA and SEI, do you prefer to below steps? >>> EL0/EL1 SEI/SEA ---> EL3 firmware first handle ------> EL2 hypervisor notify > >> the Qemu to inject SEI/SEA------>Qemu call KVM API to inject SEA/SEI---->KVM > >> inject SEA/SEI to guest OS >> >> Yes, to expand your EL2 hypervisor notify Qemu step: >> 1 The host should call its APEI code to parse the CPER records. >> 2 User space processes are then notified via SIGBUS (or for rasdaemon, trace >> points). >> 3 Qemu can take the address delivered via SIGBUS and generate CPER records for >> the guest. It knows how to convert host addresses to guest IPAs, and it knows >> where in guest memory to write the CPER records. >> 4 Qemu can then notify the guest via whatever mechanism it advertised via the >> HEST/GHES table. It might not be the same mechanism that the host received >> the notification through. >> >> Steps 1 and 2 are the same even if no guest is running, so we don't have to add >> any special case for KVM. This is existing code that x86 uses. >> We can test the Qemu parts without any firmware support and the APEI path in the >> host and guest is the same. > here do you mean map host APEI table to guest for steps 1 and 2 test? so that the APEI path in the > host and guest is the same. No, the hosts ACPI/APEI tables describe host physical addresses, the guest can't access these. Instead we can use Linux's hwpoison mechanism to call memory_failure() and if we pick the address carefully, signal Qemu. From there we can test Qemu's generation of CPER records and signalling the guest. When a host and a guest both use APEI the HEST tables will be different because the memory layout is different, but the path through APEI and the kernel's error handling code would be the same. >>>> How does this work with firmware first? >> >>> when the Guest OS triggers an SEI, it will firstly trap to EL3 firmware, El3 firmware records the error >>> info to the APEI table, >> >> These are CPER records in a memory area pointed to by one of HEST's GHES entries? >> >> >>> then copy the ESR_EL3 ELR_EL3 to ESR_EL2 ELR_EL2 and transfers control to the >>> hypervisor, hypervisor delegates the error exception to EL1 guest >> >> This is a problem, just because the error occurred while the guest was running >> doesn't mean we should deliver it directly to the guest. Some of these errors >> will be fatal for the CPU and the host should try and power it off to contain > yes, some of error does not need to deliver to guest OS directly. for example if the error is guest kernel fault error, > hypervisor can directly power off the whole guest OS I agree, Qemu should make that decision, depending on the users choice it can print a helpful error message and exit, or try and restart the guest. >> the fault. For example: CPER's 'micro-architectural error', should the guest >> power-off the vCPU? All that really does is return to the hypervisor, the error > for this example, I think it is better hypervisor directly close the whole guest OS, instead of > guest power-off the vCPU. I picked this as an example because its not clear what it means and it probably affects the host as well as the guest. We need to do the host error containment first. >>>> If we took a Physical SError Interrupt the CPER records are in the hosts memory. >>>> To deliver a RAS event to the guest something needs to generate CPER records and >>>> put them in the guest memory. Only Qemu knows where these memory regions are. >>>> >>>> Put another way, what is the guest expected to do with this SError interrupt? >>> >>> No, we do not only panic,if it is EL0 application SEI. the OS error recovery >>> agent will terminate the EL0 application to isolate the error; If it is EL1 guest >>> OS SError, guest OS can see whether it can recover. if the error was in a read-only file cache buffer, guest OS >>> can invalidate the page and reload the data from disk. >> >> How do we get an address for memory failure? SError is asynchronous, I don't >> think it sets the FAR. (SEA is synchronous and its not guaranteed to set the > Thank you to point that. sorry, my answer is not right. in fact, I think the FAR and > CPER are both not accurate for the asynchronous SError. so guest OS can not try to recover. My point was only that the architecture doesn't tell us the FAR is always set, so we have to find out from somewhere else, like the host's CPER records. SError Interrupt is one of the notification types for GHES which may be triggered by firmware. Firmware should generate the CPER records before triggering the SEI notification. When the host gets an SEI it can parse the list of GHES addresses looking for CPER records. The asynchronous delay doesn't affect the CPER records from firmware. Qemu can do the same for a guest before it pends an SError. > but it can still know which application create this SError which is deferred by ESB, then guest OS close the APP. Once the host has done its error containment, yes. If the SError interrupted a vcpu and the host signalled Qemu the signal will be delivered before the vcpu is run again, (if (signal_pending(current))... in kvm_arch_vcpu_ioctl_run()). If Qemu does its work and decides to pend an SError before running the vcpu again then it will be as if the guest isn't running under a hypervisor. > by the way, for the synchronous SEA, do you think which address should be used? FAR or CPER that record come from ERR<n>ADDR? > I see Qualcomm series patches mainly use FAR not CPER record that come from ERR<n>ADDR for SEA. > so for the SEA case, I do not know which address is more accurate for FAR and CPER record It uses both. The FAR may get copied to the signal address if the ESR says the FAR is valid. This works on systems that don't have APEI SEA. Systems that do have APEI SEA will parse the CPER records as well to find the physical address and do the memory_failure() routine to signal all the affected processes, not just the one that was running. Thanks, James
[toc] | [prev] | [next] | [standalone]
| From | gengdongjiu <gengdongjiu@huawei.com> |
|---|---|
| Date | 2017-03-21 07:10 +0100 |
| Message-ID | <tnl9v-7Kc-7@gated-at.bofh.it> |
| In reply to | #1604602 |
Hi Marc,
Thank you very much for your review.
On 2017/3/20 21:58, Marc Zyngier wrote:
> On 20/03/17 12:28, gengdongjiu wrote:
>>
>>
>> On 2017/3/20 19:24, Marc Zyngier wrote:
>>> Please include James Morse on anything RAS related, as he's already
>>> looking at related patches.
>>>
>>> On 20/03/17 07:55, Dongjiu Geng wrote:
>>>> In the RAS implementation, hardware pass the virtual SEI
>>>> syndrome information through the VSESR_EL2, so set the virtual
>>>> SEI syndrome using physical SEI syndrome el2_elr to pass to
>>>> the guest OS
>>>>
>>>> Signed-off-by: Dongjiu Geng <gengdongjiu@huawei.com>
>>>> Signed-off-by: Quanming wu <wuquanming@huawei.com>
>>>> ---
>>>> arch/arm64/Kconfig | 8 ++++++++
>>>> arch/arm64/include/asm/esr.h | 1 +
>>>> arch/arm64/include/asm/kvm_emulate.h | 12 ++++++++++++
>>>> arch/arm64/include/asm/kvm_host.h | 4 ++++
>>>> arch/arm64/kvm/hyp/switch.c | 15 ++++++++++++++-
>>>> arch/arm64/kvm/inject_fault.c | 10 ++++++++++
>>>> 6 files changed, 49 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>>>> index 8c7c244247b6..ea62170a3b75 100644
>>>> --- a/arch/arm64/Kconfig
>>>> +++ b/arch/arm64/Kconfig
>>>> @@ -908,6 +908,14 @@ endmenu
>>>>
>>>> menu "ARMv8.2 architectural features"
>>>>
>>>> +config HAS_RAS_EXTENSION
>>>> + bool "Support arm64 RAS extension"
>>>> + default n
>>>> + help
>>>> + Reliability, Availability, Serviceability(RAS; part of the ARMv8.2 Extensions).
>>>> +
>>>> + Selecting this option OS will try to recover the error that RAS hardware node detected.
>>>> +
>>>
>>> As this is an architectural extension, this should be controlled by the
>>> CPU feature mechanism, and not be chosen at compile time. What you have
>>> here will break horribly when booted on a CPU that doesn't implement RAS.
>>
>> thanks very much for your review, yes, it is, you are right.
>>
>>>
>>>> config ARM64_UAO
>>>> bool "Enable support for User Access Override (UAO)"
>>>> default y
>>>> diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
>>>> index d14c478976d0..e38d32b2bdad 100644
>>>> --- a/arch/arm64/include/asm/esr.h
>>>> +++ b/arch/arm64/include/asm/esr.h
>>>> @@ -111,6 +111,7 @@
>>>> #define ESR_ELx_COND_MASK (UL(0xF) << ESR_ELx_COND_SHIFT)
>>>> #define ESR_ELx_WFx_ISS_WFE (UL(1) << 0)
>>>> #define ESR_ELx_xVC_IMM_MASK ((1UL << 16) - 1)
>>>> +#define VSESR_ELx_IDS_ISS_MASK ((1UL << 25) - 1)
>>>>
>>>> /* ESR value templates for specific events */
>>>>
>>>> diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
>>>> index f5ea0ba70f07..20d4da7f5dce 100644
>>>> --- a/arch/arm64/include/asm/kvm_emulate.h
>>>> +++ b/arch/arm64/include/asm/kvm_emulate.h
>>>> @@ -148,6 +148,18 @@ static inline u32 kvm_vcpu_get_hsr(const struct kvm_vcpu *vcpu)
>>>> return vcpu->arch.fault.esr_el2;
>>>> }
>>>>
>>>> +#ifdef CONFIG_HAS_RAS_EXTENSION
>>>> +static inline u32 kvm_vcpu_get_vsesr(const struct kvm_vcpu *vcpu)
>>>> +{
>>>> + return vcpu->arch.fault.vsesr_el2;
>>>> +}
>>>> +
>>>> +static inline void kvm_vcpu_set_vsesr(struct kvm_vcpu *vcpu, unsigned long val)
>>>> +{
>>>> + vcpu->arch.fault.vsesr_el2 = val;
>>>> +}
>>>> +#endif
>>>> +
>>>> static inline int kvm_vcpu_get_condition(const struct kvm_vcpu *vcpu)
>>>> {
>>>> u32 esr = kvm_vcpu_get_hsr(vcpu);
>>>> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
>>>> index e7705e7bb07b..f9e3bb57c461 100644
>>>> --- a/arch/arm64/include/asm/kvm_host.h
>>>> +++ b/arch/arm64/include/asm/kvm_host.h
>>>> @@ -83,6 +83,10 @@ struct kvm_mmu_memory_cache {
>>>> };
>>>>
>>>> struct kvm_vcpu_fault_info {
>>>> +#ifdef CONFIG_HAS_RAS_EXTENSION
>>>> + /* Virtual SError Exception Syndrome Register */
>>>> + u32 vsesr_el2;
>>>> +#endif
>>>> u32 esr_el2; /* Hyp Syndrom Register */
>>>> u64 far_el2; /* Hyp Fault Address Register */
>>>> u64 hpfar_el2; /* Hyp IPA Fault Address Register */
>>>> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
>>>> index aede1658aeda..770a153fb6ba 100644
>>>> --- a/arch/arm64/kvm/hyp/switch.c
>>>> +++ b/arch/arm64/kvm/hyp/switch.c
>>>> @@ -86,6 +86,13 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu)
>>>> isb();
>>>> }
>>>> write_sysreg(val, hcr_el2);
>>>> +#ifdef CONFIG_HAS_RAS_EXTENSION
>>>> + /* If virtual System Error or Asynchronous Abort is pending. set
>>>> + * the virtual exception syndrome information
>>>> + */
>>>> + if (vcpu->arch.hcr_el2 & HCR_VSE)
>>>> + write_sysreg(vcpu->arch.fault.vsesr_el2, vsesr_el2);
>>>> +#endif
>>>> /* Trap on AArch32 cp15 c15 accesses (EL1 or EL0) */
>>>> write_sysreg(1 << 15, hstr_el2);
>>>> /*
>>>> @@ -139,8 +146,14 @@ static void __hyp_text __deactivate_traps(struct kvm_vcpu *vcpu)
>>>> * the crucial bit is "On taking a vSError interrupt,
>>>> * HCR_EL2.VSE is cleared to 0."
>>>> */
>>>> - if (vcpu->arch.hcr_el2 & HCR_VSE)
>>>> + if (vcpu->arch.hcr_el2 & HCR_VSE) {
>>>> vcpu->arch.hcr_el2 = read_sysreg(hcr_el2);
>>>> +#ifdef CONFIG_HAS_RAS_EXTENSION
>>>> + /* set vsesr_el2[24:0] with esr_el2[24:0] */
>>>> + kvm_vcpu_set_vsesr(vcpu, read_sysreg_el2(esr)
>>>> + & VSESR_ELx_IDS_ISS_MASK);
>>>
>>> What guarantees that ESR_EL2 still contains the latest exception? What
>>> does it mean to store something that is the current EL2 exception
>>> syndrome together with an SError that has already been injected?
>>
>> yes, thanks for the review, I will add a judgement condition for the "exit_code"
>> if the "exit_code == ARM_EXCEPTION_EL1_SERROR" then set the vsesr_el2.
>>
>> for the aarch32, it only need set the "ExT, bit [12]" and AET, "bits [15:14]", other bit is RES0
>>
>>>
>>> Also, is it correct to directly copy the ESR_EL2 bits into VSESR_EL2? My
>> please see below spec description, it virtual SERROR syndrome from VSESR_EL2.
>> -----
>> Control returns to the OS, and the ESB instruction is re-executed.
>> — The physical asynchronous SError interrupt has been cleared, so it is not taken again.
>> — The PE sets VDISR_EL2.A to 1 and records the syndrome from VSESR_EL2 in VDISR_EL2.
>> -----
>
> Which doesn't say anything about directly using ESR_EL2 and propagating
> it directly to the guest, specially when there is *already* an SError
thank you for the comments.
In my current solution which I refer to ARM RAS spec(RAS_Extension_PRD03-PRDC-010953-32-0.pdf).
when the Guest OS triggers an SEI, it will firstly trap to EL3 firmware, El3 firmware records the error
info to the APEI table, then copy the ESR_EL3 ELR_EL3 to ESR_EL2 ELR_EL2 and transfers control to the
hypervisor, hypervisor delegates the error exception to EL1 guest OS by setting HCR_EL2.VSE to 1 and pass the
virtual SEI syndrome through vsesr_el2. The EL1 guest OS check the DISR_EL1 syndrome information to decide to
terminate the application, or do some other recovery action. because the HCR_EL2.AMO is set, so in fact, read
DISR_EL1, it returns the VDISR_EL2. and VDISR_EL2 is loaded from VSESR_EL2, so here I pass the virtual SEI
syndrome vsesr_el2.
please see the ARM spec example about SEI with ESB
----------------------------------------------------------------------------------------------------
The firmware logs, triages, and delegates the error exception to the hypervisor. As the error came
from EL1, it does by faking an SError interrupt exception entry to EL2.
Control transfers to the hypervisor’s delegated error recovery agent. It repeats the process of triaging
the error.
The hypervisor delegates the error exception to EL1 by setting HCR_EL2.VSE to 1, and returns
control to the OS using ERET.
Control returns to the OS, and the ESB instruction is re-executed.
— The physical asynchronous SError interrupt has been cleared, so it is not taken again.
— The PE sets VDISR_EL2.A to 1 and records the syndrome from VSESR_EL2 in VDISR_EL2.
The SVC exception entry code completes, and then the OS checks DISR_EL1 for a deferred SError
interrupt.
— See the example code sequence in Error Synchronization Barrier.
— This in fact returns VDISR_EL2 because the HCR_EL2.AMO bit is set.
Because this returns DISR_EL1.A set, the OS instead processes the error.
— Although the error exception was taken from EL1, the OS error recovery agent can use the
information that it was taken from the ESB instruction at the exception entry point to isolate
the error to the EL0 application and not affect the OS.
The error has been logged, triaged, and contained to the EL0 application.
-------------------------------------------------------------------------------------------------------------
> pending (just in case you haven't noticed, this is the *exit* path, and
> I can't see why you would overload VSESR_EL2 at at point).
>
thanks for the question.
This is exit path, for the case that already an SError is pending.it should be overload VSESR_EL2 using
the esr_el2 in below situation, right?
int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
int exception_index)
{
exit_handle_fn exit_handler;
if (ARM_SERROR_PENDING(exception_index)) {
u8 hsr_ec = ESR_ELx_EC(kvm_vcpu_get_hsr(vcpu));
/*
* HVC/SMC already have an adjusted PC, which we need
* to correct in order to return to after having
* injected the SError.
*/
if (hsr_ec == ESR_ELx_EC_HVC32 || hsr_ec == ESR_ELx_EC_HVC64 ||
hsr_ec == ESR_ELx_EC_SMC32 || hsr_ec == ESR_ELx_EC_SMC64) {
u32 adj = kvm_vcpu_trap_il_is32bit(vcpu) ? 4 : 2;
*vcpu_pc(vcpu) -= adj;
}
kvm_inject_vabt(vcpu);
return 1;
}
>>
>>> own reading of the specification seem to imply that there is at least
>>> differences when the guest is AArch32. Surely there would be some
>>> processing here.
>>
>>
>>
>>>
>>>> +#endif
>>>> + }
>>>>
>>>> __deactivate_traps_arch()();
>>>> write_sysreg(0, hstr_el2);
>>>> diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c
>>>> index da6a8cfa54a0..08a13dfe28a8 100644
>>>> --- a/arch/arm64/kvm/inject_fault.c
>>>> +++ b/arch/arm64/kvm/inject_fault.c
>>>> @@ -242,4 +242,14 @@ void kvm_inject_undefined(struct kvm_vcpu *vcpu)
>>>> void kvm_inject_vabt(struct kvm_vcpu *vcpu)
>>>> {
>>>> vcpu_set_hcr(vcpu, vcpu_get_hcr(vcpu) | HCR_VSE);
>>>> +#ifdef CONFIG_HAS_RAS_EXTENSION
>>>> + /* If virtual System Error or Asynchronous Abort is set. set
>>>> + * the virtual exception syndrome information
>>>> + */
>>>> + kvm_vcpu_set_vsesr(vcpu, ((kvm_vcpu_get_vsesr(vcpu)
>>>> + & (~VSESR_ELx_IDS_ISS_MASK))
>>>> + | (kvm_vcpu_get_hsr(vcpu)
>>>> + & VSESR_ELx_IDS_ISS_MASK)));
>>>
>>> What is the rational for setting VSESR_EL2 with the EL1 syndrome
>>> information? That doesn't make any sense to me.
>> thanks, I set the VSESR_EL2 using the EL2 syndrome information, "kvm_vcpu_get_hsr"
>> return the value of esr_el2, not EL1 syndrome information
>
> Ah, good point. But that doesn't make it more valid. I still don't see
> anything in the spec that supports this behaviour, and I still propose
> that when RAS is enabled, the VSError injection is mediated by userspace.
>
For the reason that set vsesr_el2 using esr_el2, I have explained it in above.
do you mean below steps?
EL0/EL1 SEI ---> EL3 firmware ------> EL2 hypervisor notify the Qemu to inject VSError ------>Qemu call KVM API to inject VSError ---->KVM
> Thanks,
>
> M.
>
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web