KVM: PPC: Add FWNMI support for KVM guests on POWER
Subsystems (4)
v5 cover KVM: PPC: Add FWNMI support for KVM guests on POWER
This series of patches add FWNMI support for KVM guests on POWER.
Memory errors such as bit flips that cannot be corrected by hardware is passed on to the kernel for handling by raising machine check exception (an NMI). Upon such machine check exceptions, if the address in error belongs to the guest, the error is passed on to the guest kernel for handling. However, for guest kernels that have issued "ibm,nmi-register" call, QEMU should build an error log and pass on the error log to the guest- kernel registered machine check handler routine.
This patch series adds the functionality to pass on the machine check exception to the guest kernel by giving control to QEMU. QEMU builds the error log and invokes the guest-kernel registered handler.
QEMU part can be found at:
http://lists.nongnu.org/archive/html/qemu-ppc/2015-12/msg00199.html
Change Log v5:
- Added capability documentation. No functionality/code change.
Change Log v4:
- Allow host-side handling of the machine check exception before passing on the exception to the guest.
Change Log v3:
- Split the patch into 2. First patch introduces the new capability while the second one enhances KVM to redirect MCE.
- Fix access width bug
Change Log v2:
- Added KVM capability
---
Aravinda Prasad (2):
KVM: PPC: Add new capability to control MCE behaviour
KVM: PPC: Exit guest upon MCE when FWNMI capability is enabled
Documentation/virtual/kvm/api.txt | 11 +++++++ arch/powerpc/include/asm/kvm_host.h | 1 + arch/powerpc/kernel/asm-offsets.c | 1 + arch/powerpc/kvm/book3s_hv.c | 27 +++++++++++++----- arch/powerpc/kvm/book3s_hv_rmhandlers.S | 47 ++++++++++++++++--------------- arch/powerpc/kvm/powerpc.c | 7 +++++ arch/powerpc/platforms/powernv/opal.c | 10 +++++++ include/uapi/linux/kvm.h | 1 + 8 files changed, 75 insertions(+), 30 deletions(-)
--
Aravinda Prasad
PATCH v5 1/2 KVM: PPC: Add new capability to control MCE behaviour
This patch introduces a new KVM capability to control how KVM behaves on machine check exception (MCE). Without this capability, KVM redirects machine check exceptions to guest's 0x200 vector, if the address in error belongs to the guest. With this capability KVM causes a guest exit with NMI exit reason.
The new capability is required to avoid problems if a new kernel/KVM is used with an old QEMU for guests that don't issue "ibm,nmi-register". As old QEMU does not understand the NMI exit type, it treats it as a fatal error. However, the guest could have handled the machine check error if the exception was delivered to guest's 0x200 interrupt vector instead of NMI exit in case of old QEMU.
--- Documentation/virtual/kvm/api.txt | 11 +++++++++++ arch/powerpc/include/asm/kvm_host.h | 1 + arch/powerpc/kernel/asm-offsets.c | 1 + arch/powerpc/kvm/powerpc.c | 7 +++++++ include/uapi/linux/kvm.h | 1 + 5 files changed, 21 insertions(+)
Documentation/virtual/kvm/api.txt +11 -0
@@ -3911,6 +3911,17 @@ to take care of that. This capability can be enabled dynamically even if VCPUs were already created and are running. +7.9 KVM_CAP_PPC_FWNMI + +Architectures: ppc +Parameters: none + +With this capability a machine check exception in the guest address +space will cause KVM to exit the guest with NMI exit reason. This +enables QEMU to build error log and branch to guest kernel registered +machine check handling routine. Without this capability KVM will +branch to guests' 0x200 interrupt vector. + 8. Other capabilities. ----------------------
arch/powerpc/include/asm/kvm_host.h +1 -0
@@ -264,6 +264,7 @@ struct kvm_arch {int hpt_cma_alloc;struct dentry *debugfs_dir;struct dentry *htab_dentry; +u8 fwnmi_enabled;#endif /* CONFIG_KVM_BOOK3S_HV_POSSIBLE */ #ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE struct mutex hpt_mutex;
arch/powerpc/kernel/asm-offsets.c +1 -0
@@ -494,6 +494,7 @@ int main(void) DEFINE(KVM_NEED_FLUSH, offsetof(struct kvm, arch.need_tlb_flush.bits)); DEFINE(KVM_ENABLED_HCALLS, offsetof(struct kvm, arch.enabled_hcalls)); DEFINE(KVM_VRMA_SLB_V, offsetof(struct kvm, arch.vrma_slb_v)); + DEFINE(KVM_FWNMI, offsetof(struct kvm, arch.fwnmi_enabled)); DEFINE(VCPU_DSISR, offsetof(struct kvm_vcpu, arch.shregs.dsisr)); DEFINE(VCPU_DAR, offsetof(struct kvm_vcpu, arch.shregs.dar)); DEFINE(VCPU_VPA, offsetof(struct kvm_vcpu, arch.vpa.pinned_addr));
arch/powerpc/kvm/powerpc.c +7 -0
@@ -604,6 +604,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) r =cpu_has_feature (CPU_FTR_TM_COMP ) &&is_kvmppc_hv_enabled (kvm);break ; +case KVM_CAP_PPC_FWNMI : + r =1 ; +break ;default : r =0 ;break ;
@@ -1204,6 +1207,10 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu, break; }#endif /* CONFIG_KVM_XICS */ +case KVM_CAP_PPC_FWNMI : + r =0 ; + vcpu->kvm->arch.fwnmi_enabled = true; +break ;default : r = -EINVAL ;break ;
include/uapi/linux/kvm.h +1 -0
@@ -870,6 +870,7 @@ struct kvm_ppc_smmu_info {#define KVM_CAP_S390_USER_INSTR0 130#define KVM_CAP_MSI_DEVID 131#define KVM_CAP_PPC_HTM 132 +#define KVM_CAP_PPC_FWNMI 133#ifdef KVM_CAP_IRQ_ROUTING
PATCH v5 2/2 KVM: PPC: Exit guest upon MCE when FWNMI capability is enabled
In reply to Aravinda PrasadEnhance KVM to cause a guest exit with KVM_EXIT_NMI exit reason upon a machine check exception (MCE) in the guest address space if the KVM_CAP_PPC_FWNMI capability is enabled (instead of delivering a 0x200 interrupt to guest). This enables QEMU to build error log and deliver machine check exception to guest via guest registered machine check handler.
This approach simplifies the delivery of machine check exception to guest OS compared to the earlier approach of KVM directly invoking 0x200 guest interrupt vector.
This design/approach is based on the feedback for the QEMU patches to handle machine check exception. Details of earlier approach of handling machine check exception in QEMU and related discussions can be found at:
https://lists.nongnu.org/archive/html/qemu-devel/2014-11/msg00813.html
Note:
This patch introduces a hook which is invoked at the time of guest exit to facilitate the host-side handling of machine check exception before the exception is passed on to the guest. Hence, the host-side handling which was performed earlier via machine_check_fwnmi is removed.
The reasons for this approach is (i) it is not possible to distinguish whether the exception occurred in the guest or the host from the pt_regs passed on the machine_check_exception(). Hence machine_check_exception() calls panic, instead of passing on the exception to the guest, if the machine check exception is not recoverable. (ii) the approach introduced in this patch gives opportunity to the host kernel to perform actions in virtual mode before passing on the exception to the guest. This approach does not require complex tweaks to machine_check_fwnmi and friends.
--- arch/powerpc/kvm/book3s_hv.c | 27 +++++++++++++----- arch/powerpc/kvm/book3s_hv_rmhandlers.S | 47 ++++++++++++++++--------------- arch/powerpc/platforms/powernv/opal.c | 10 +++++++ 3 files changed, 54 insertions(+), 30 deletions(-)
arch/powerpc/kvm/book3s_hv.c +20 -7
@@ -123,6 +123,7 @@ MODULE_PARM_DESC(halt_poll_ns_shrink, "Factor halt poll time is shrunk by");static void kvmppc_end_cede (struct kvm_vcpu *vcpu);static int kvmppc_hv_setup_htab_rma (struct kvm_vcpu *vcpu); +static void kvmppc_machine_check_hook (void );static inline struct kvm_vcpu *next_runnable_thread (struct kvmppc_vcore *vc,int *ip)
@@ -954,15 +955,14 @@ static int kvmppc_handle_exit_hv(struct kvm_run *run, struct kvm_vcpu *vcpu, r =RESUME_GUEST ;break ;case BOOK3S_INTERRUPT_MACHINE_CHECK : +/* Exit to guest with KVM_EXIT_NMI as exit reason */ + run->exit_reason =KVM_EXIT_NMI ; + r =RESUME_HOST ;/* -* Deliver a machine check interrupt to the guest. -* We have to do this, even if the host has handled the -* machine check, because machine checks use SRR0/1 and -* the interrupt might have trashed guest state in them. +* Invoke host-kernel handler to perform any host-side +* handling before exiting the guest. */ -kvmppc_book3s_queue_irqprio (vcpu, -BOOK3S_INTERRUPT_MACHINE_CHECK ); - r =RESUME_GUEST ; +kvmppc_machine_check_hook ();break ;case BOOK3S_INTERRUPT_PROGRAM : {
@@ -3491,6 +3491,19 @@ static void kvmppc_irq_bypass_del_producer_hv(struct irq_bypass_consumer *cons, }#endif +/* +* Hook to handle machine check exceptions occurred inside a guest. +* This hook is invoked from host virtual mode from KVM before exiting +* the guest with KVM_EXIT_NMI exit reason. This gives an opportunity +* for the host to take action (if any) before passing on the machine +* check exception to the guest kernel. +*/ +static void kvmppc_machine_check_hook (void ) +{ +if (ppc_md.machine_check_exception) + ppc_md.machine_check_exception (NULL ); +} +static long kvm_arch_vm_ioctl_hv (struct file *filp,unsigned int ioctl,unsigned long arg) {
arch/powerpc/kvm/book3s_hv_rmhandlers.S +24 -23
82 lines not on this page · raw message
arch/powerpc/platforms/powernv/opal.c +10 -0
@@ -446,6 +446,16 @@ int opal_machine_check(struct pt_regs *regs) }machine_check_print_event_info (&evt); +/* +* If regs is NULL, then the machine check exception occurred +* in the guest. Currently no action is performed in the host +* other than printing the event information. The machine check +* exception is passed on to the guest kernel and the guest +* kernel will attempt for recovery. +*/ +if (!regs) +return 0 ; +if (opal_recover_mce (regs, &evt))return 1 ;
Re: [PATCH v5 2/2] KVM: PPC: Exit guest upon MCE when FWNMI capability is enabled
Quoted 40 lines · Aravinda Prasad
Enhance KVM to cause a guest exit with
KVM_EXIT_NMIexit reason upon a machine check exception (MCE) in the guest address space if theKVM_CAP_PPC_FWNMIcapability is enabled (instead of delivering a0x200interrupt to guest). This enables QEMU to build error log and deliver machine check exception to guest via guest registered machine check handler.This approach simplifies the delivery of machine check exception to guest OS compared to the earlier approach of KVM directly invoking
0x200guest interrupt vector.This design/approach is based on the feedback for the QEMU patches to handle machine check exception. Details of earlier approach of handling machine check exception in QEMU and related discussions can be found at:
https://lists.nongnu.org/archive/html/qemu-devel/2014-11/msg00813.html
Note:
This patch introduces a hook which is invoked at the time of guest exit to facilitate the host-side handling of machine check exception before the exception is passed on to the guest. Hence, the host-side handling which was performed earlier via
machine_check_fwnmiis removed.The reasons for this approach is (i) it is not possible to distinguish whether the exception occurred in the guest or the host from the
pt_regspassed on themachine_check_exception(). Hencemachine_check_exception()calls panic, instead of passing on the exception to the guest, if the machine check exception is not recoverable. (ii) the approach introduced in this patch gives opportunity to the host kernel to perform actions in virtual mode before passing on the exception to the guest. This approach does not require complex tweaks tomachine_check_fwnmiand friends.
Quoted 2 lines
Signed-off-by Aravinda Prasad <[email protected]>Reviewed-by David Gibson <[email protected]>
This patch mostly looks OK. I have a few relatively minor comments below.
Quoted 27 lines
--- arch/powerpc/kvm/book3s_hv.c | 27 +++++++++++++----- arch/powerpc/kvm/book3s_hv_rmhandlers.S | 47 ++++++++++++++++--------------- arch/powerpc/platforms/powernv/opal.c | 10 +++++++ 3 files changed, 54 insertions(+), 30 deletions(-)arch/powerpc/kvm/book3s_hv.c +4
-1@@ -123,6 +123,7 @@ MODULE_PARM_DESC(halt_poll_ns_shrink, "Factor halt poll time is shrunk by");static void kvmppc_end_cede (struct kvm_vcpu *vcpu);static int kvmppc_hv_setup_htab_rma (struct kvm_vcpu *vcpu); +static void kvmppc_machine_check_hook (void );static inline struct kvm_vcpu *next_runnable_thread (struct kvmppc_vcore *vc,int *ip)@@ -954,15 +955,14 @@ static int kvmppc_handle_exit_hv(struct kvm_run *run, struct kvm_vcpu *vcpu, r =RESUME_GUEST ;break ;case BOOK3S_INTERRUPT_MACHINE_CHECK : +/* Exit to guest with KVM_EXIT_NMI as exit reason */ + run->exit_reason =KVM_EXIT_NMI ; + r =RESUME_HOST ;/* -* Deliver a machine check interrupt to the guest.
arch/powerpc/kvm/book3s_hv.c static int kvmppc_handle_exit_hv(struct kvm_run *run, struct kvm_vcpu *vcpu, · line 965
Quoted 10 lines
arch/powerpc/kvm/book3s_hv.c +3
-6-* We have to do this, even if the host has handled the -* machine check, because machine checks use SRR0/1 and -* the interrupt might have trashed guest state in them. +* Invoke host-kernel handler to perform any host-side +* handling before exiting the guest. */ -kvmppc_book3s_queue_irqprio (vcpu, -BOOK3S_INTERRUPT_MACHINE_CHECK ); - r =RESUME_GUEST ; +kvmppc_machine_check_hook ();
Note that this won't necessarily be called on the same CPU that received the machine check. This will be called on thread 0 of the core (or subcore), whereas the machine check could have occurred on some other thread. Are you sure that the machine check handling code will be OK with that?
Quoted 9 lines
arch/powerpc/kvm/book3s_hv.c +2
-0break ;case BOOK3S_INTERRUPT_PROGRAM : {@@ -3491,6 +3491,19 @@ static void kvmppc_irq_bypass_del_producer_hv(struct irq_bypass_consumer *cons, }#endif +/* +* Hook to handle machine check exceptions occurred inside a guest.
arch/powerpc/kvm/book3s_hv.c static void kvmppc_irq_bypass_del_producer_hv(struct irq_bypass_consumer *cons, · line 3505
Quoted 10 lines
arch/powerpc/kvm/book3s_hv.c +10
-0+* This hook is invoked from host virtual mode from KVM before exiting +* the guest with KVM_EXIT_NMI exit reason. This gives an opportunity +* for the host to take action (if any) before passing on the machine +* check exception to the guest kernel. +*/ +static void kvmppc_machine_check_hook (void ) +{ +if (ppc_md.machine_check_exception) + ppc_md.machine_check_exception (NULL ); +}
What is the advantage of having this as a separate function, as opposed to just putting those two lines of code in line in the one place where this gets called?
Paul.
Re: [PATCH v5 2/2] KVM: PPC: Exit guest upon MCE when FWNMI capability is enabled
Quoted 82 lines · Paul Mackerras
Quoted 40 lines · Aravinda Prasad
Enhance KVM to cause a guest exit with
KVM_EXIT_NMIexit reason upon a machine check exception (MCE) in the guest address space if theKVM_CAP_PPC_FWNMIcapability is enabled (instead of delivering a0x200interrupt to guest). This enables QEMU to build error log and deliver machine check exception to guest via guest registered machine check handler.This approach simplifies the delivery of machine check exception to guest OS compared to the earlier approach of KVM directly invoking
0x200guest interrupt vector.This design/approach is based on the feedback for the QEMU patches to handle machine check exception. Details of earlier approach of handling machine check exception in QEMU and related discussions can be found at:
https://lists.nongnu.org/archive/html/qemu-devel/2014-11/msg00813.html
Note:
This patch introduces a hook which is invoked at the time of guest exit to facilitate the host-side handling of machine check exception before the exception is passed on to the guest. Hence, the host-side handling which was performed earlier via
machine_check_fwnmiis removed.The reasons for this approach is (i) it is not possible to distinguish whether the exception occurred in the guest or the host from the
pt_regspassed on themachine_check_exception(). Hencemachine_check_exception()calls panic, instead of passing on the exception to the guest, if the machine check exception is not recoverable. (ii) the approach introduced in this patch gives opportunity to the host kernel to perform actions in virtual mode before passing on the exception to the guest. This approach does not require complex tweaks tomachine_check_fwnmiand friends.Quoted 2 lines
Signed-off-by Aravinda Prasad <[email protected]>Reviewed-by David Gibson <[email protected]>This patch mostly looks OK. I have a few relatively minor comments below.
Quoted 35 lines
--- arch/powerpc/kvm/book3s_hv.c | 27 +++++++++++++----- arch/powerpc/kvm/book3s_hv_rmhandlers.S | 47 ++++++++++++++++--------------- arch/powerpc/platforms/powernv/opal.c | 10 +++++++ 3 files changed, 54 insertions(+), 30 deletions(-)arch/powerpc/kvm/book3s_hv.c +6
-6@@ -123,6 +123,7 @@ MODULE_PARM_DESC(halt_poll_ns_shrink, "Factor halt poll time is shrunk by");static void kvmppc_end_cede (struct kvm_vcpu *vcpu);static int kvmppc_hv_setup_htab_rma (struct kvm_vcpu *vcpu); +static void kvmppc_machine_check_hook (void );static inline struct kvm_vcpu *next_runnable_thread (struct kvmppc_vcore *vc,int *ip)@@ -954,15 +955,14 @@ static int kvmppc_handle_exit_hv(struct kvm_run *run, struct kvm_vcpu *vcpu, r =RESUME_GUEST ;break ;case BOOK3S_INTERRUPT_MACHINE_CHECK : +/* Exit to guest with KVM_EXIT_NMI as exit reason */ + run->exit_reason =KVM_EXIT_NMI ; + r =RESUME_HOST ;/* -* Deliver a machine check interrupt to the guest. -* We have to do this, even if the host has handled the -* machine check, because machine checks use SRR0/1 and -* the interrupt might have trashed guest state in them. +* Invoke host-kernel handler to perform any host-side +* handling before exiting the guest. */ -kvmppc_book3s_queue_irqprio (vcpu, -BOOK3S_INTERRUPT_MACHINE_CHECK );
Quoted 8 lines
arch/powerpc/kvm/book3s_hv.c static int kvmppc_handle_exit_hv(struct kvm_run *run, struct kvm_vcpu *vcpu, · line 965
Quoted 2 lines
arch/powerpc/kvm/book3s_hv.c +1
-1- r =RESUME_GUEST ; +kvmppc_machine_check_hook ();Note that this won't necessarily be called on the same CPU that received the machine check. This will be called on thread 0 of the core (or subcore), whereas the machine check could have occurred on some other thread. Are you sure that the machine check handling code will be OK with that?
That will have only one problem. get_mce_event() from opal_machine_check() may not be able to pull mce event for error on non-zero thread. We should hook the mce event into vcpu structure during kvmppc_realmode_machine_check() and then pass it to ppc_md.machine_check_exception() as an additional argument.
Quoted 27 lines
Quoted 10 lines
arch/powerpc/kvm/book3s_hv.c +2
-0break ;case BOOK3S_INTERRUPT_PROGRAM : {@@ -3491,6 +3491,19 @@ static void kvmppc_irq_bypass_del_producer_hv(struct irq_bypass_consumer *cons, }#endif +/* +* Hook to handle machine check exceptions occurred inside a guest. arch/powerpc/kvm/book3s_hv.c static void kvmppc_irq_bypass_del_producer_hv(struct irq_bypass_consumer *cons, · line 3505
Quoted 10 lines
arch/powerpc/kvm/book3s_hv.c +10
-0+* This hook is invoked from host virtual mode from KVM before exiting +* the guest with KVM_EXIT_NMI exit reason. This gives an opportunity +* for the host to take action (if any) before passing on the machine +* check exception to the guest kernel. +*/ +static void kvmppc_machine_check_hook (void ) +{ +if (ppc_md.machine_check_exception) + ppc_md.machine_check_exception (NULL ); +}What is the advantage of having this as a separate function, as opposed to just putting those two lines of code in line in the one place where this gets called?
Paul.
Re: [PATCH v5 2/2] KVM: PPC: Exit guest upon MCE when FWNMI capability is enabled
Quoted 2 lines · Mahesh Jagannath Salgaonkar
Quoted 1 line · Paul Mackerras
On Fri, Jan 13, 2017 at 04:51:45PM +0530, Aravinda Prasad wrote:
[snip]
Quoted 23 lines
Quoted 14 lines
Quoted 14 lines
arch/powerpc/kvm/book3s_hv.c +5
-6case BOOK3S_INTERRUPT_MACHINE_CHECK : +/* Exit to guest with KVM_EXIT_NMI as exit reason */ + run->exit_reason =KVM_EXIT_NMI ; + r =RESUME_HOST ;/* -* Deliver a machine check interrupt to the guest. -* We have to do this, even if the host has handled the -* machine check, because machine checks use SRR0/1 and -* the interrupt might have trashed guest state in them. +* Invoke host-kernel handler to perform any host-side +* handling before exiting the guest. */ -kvmppc_book3s_queue_irqprio (vcpu, -BOOK3S_INTERRUPT_MACHINE_CHECK );Quoted 8 lines
arch/powerpc/kvm/book3s_hv.c static int kvmppc_handle_exit_hv(struct kvm_run *run, struct kvm_vcpu *vcpu, · line 965
Quoted 2 lines
arch/powerpc/kvm/book3s_hv.c +1
-1- r =RESUME_GUEST ; +kvmppc_machine_check_hook ();Note that this won't necessarily be called on the same CPU that received the machine check. This will be called on thread 0 of the core (or subcore), whereas the machine check could have occurred on some other thread. Are you sure that the machine check handling code will be OK with that?
Quoted 5 lines
That will have only one problem.
get_mce_event()fromopal_machine_check()may not be able to pull mce event for error on non-zero thread. We should hook the mce event into vcpu structure duringkvmppc_realmode_machine_check()and then pass it toppc_md.machine_check_exception()as an additional argument.
To move things along...
Mahesh, how would we get hold of the mce event from real-mode assembly code? What function would we need to call to get the event? Could you write some code (or at least some pseudo-code) to illustrate how it would be done?
Thanks,
Paul.
Mahesh J Salgaonkar
Reviewed-by David GibsonRe: [PATCH v5 2/2] KVM: PPC: Exit guest upon MCE when FWNMI capability is enabled
Quoted 35 lines · Paul Mackerras
Quoted 2 lines · Mahesh Jagannath Salgaonkar
Quoted 1 line · Paul Mackerras
On Fri, Jan 13, 2017 at 04:51:45PM +0530, Aravinda Prasad wrote:
[snip]
Quoted 23 lines
Quoted 14 lines
Quoted 14 lines
(quoted diff) +5
-6case BOOK3S_INTERRUPT_MACHINE_CHECK: + /* Exit to guest with KVM_EXIT_NMI as exit reason */ + run->exit_reason = KVM_EXIT_NMI; + r = RESUME_HOST; /* - * Deliver a machine check interrupt to the guest. - * We have to do this, even if the host has handled the - * machine check, because machine checks use SRR0/1 and - * the interrupt might have trashed guest state in them. + * Invoke host-kernel handler to perform any host-side + * handling before exiting the guest. */ - kvmppc_book3s_queue_irqprio(vcpu, - BOOK3S_INTERRUPT_MACHINE_CHECK);Quoted 8 lines
Review
Quoted 2 lines
(quoted diff) +1
-1- r = RESUME_GUEST; + kvmppc_machine_check_hook();Note that this won't necessarily be called on the same CPU that received the machine check. This will be called on thread 0 of the core (or subcore), whereas the machine check could have occurred on some other thread. Are you sure that the machine check handling code will be OK with that?
Quoted 5 lines
That will have only one problem.
get_mce_event()fromopal_machine_check()may not be able to pull mce event for error on non-zero thread. We should hook the mce event into vcpu structure duringkvmppc_realmode_machine_check()and then pass it toppc_md.machine_check_exception()as an additional argument.
Quoted 6 lines
To move things along...
Mahesh, how would we get hold of the mce event from real-mode assembly code? What function would we need to call to get the event? Could you write some code (or at least some pseudo-code) to illustrate how it would be done?
I am thinking of passing all the handled/unhandled mce errors to guest if fwnmi capability is supported by QEMU. Otherwise fall back to the old behaviour. I have done modifications to this patch which is almost ready. Planning to pass additional info to QEMU about whether MCE error was recovered or not, so that QEMU can correctly set the RTAS DISPOSITION.
Below is the modified patch. It uses one bit from kvm_run->flags to pass disposition information (0 = unrecovred, 1 = recovred). But RTAS disposition can have 3 values as per PAPR. The 3rd value indicates limited recovery. For PAPR compliance, I am thiniking of using two bits from kvm_run->flags (b00 = Fully recovered, b01 = Limited recovery, b10= Not recovered.).
Let me know what you think about this approach.
------------------------------------------
Enhance KVM to cause a guest exit with KVM_EXIT_NMI
From: Aravinda Prasad <[email protected]>
exit reason upon a machine check exception (MCE) in the guest address space if the KVM_CAP_PPC_FWNMI capability is enabled (instead of delivering a 0x200 interrupt to guest). This enables QEMU to build error log and deliver machine check exception to guest via guest registered machine check handler.
This approach simplifies the delivery of machine check exception to guest OS compared to the earlier approach of KVM directly invoking 0x200 guest interrupt vector.
This design/approach is based on the feedback for the QEMU patches to handle machine check exception. Details of earlier approach of handling machine check exception in QEMU and related discussions can be found at:
https://lists.nongnu.org/archive/html/qemu-devel/2014-11/msg00813.html
Note:
This patch introduces a hook which is invoked at the time of guest exit to facilitate the host-side handling of machine check exception before the exception is passed on to the guest. Hence, the host-side handling which was performed earlier via machine_check_fwnmi is removed.
The reasons for this approach is (i) it is not possible to distinguish whether the exception occurred in the guest or the host from the pt_regs passed on the machine_check_exception(). Hence machine_check_exception() calls panic, instead of passing on the exception to the guest, if the machine check exception is not recoverable. (ii) the approach introduced in this patch gives opportunity to the host kernel to perform actions in virtual mode before passing on the exception to the guest. This approach does not require complex tweaks to machine_check_fwnmi and friends.
--- arch/powerpc/include/asm/kvm_host.h | 2 + arch/powerpc/include/asm/machdep.h | 7 +++++ arch/powerpc/include/asm/opal.h | 4 +++ arch/powerpc/include/uapi/asm/kvm.h | 3 ++ arch/powerpc/kvm/book3s_hv.c | 21 +++++++++----- arch/powerpc/kvm/book3s_hv_ras.c | 14 +++++++++ arch/powerpc/kvm/book3s_hv_rmhandlers.S | 47 ++++++++++++++++--------------- arch/powerpc/platforms/powernv/opal.c | 26 +++++++++++++++++ arch/powerpc/platforms/powernv/setup.c | 3 ++ 9 files changed, 96 insertions(+), 31 deletions(-)
arch/powerpc/include/asm/kvm_host.h +2 -0
@@ -35,6 +35,7 @@#include <asm/page.h> #include <asm/cacheflush.h> #include <asm/hvcall.h> +#include <asm/mce.h> #define KVM_MAX_VCPUS NR_CPUS#define KVM_MAX_VCORES NR_CPUS
@@ -637,6 +638,7 @@ struct kvm_vcpu_arch {int thread_cpu;bool timer_running;wait_queue_head_t cpu_run; +struct machine_check_event mce_evt;/* Valid if trap == 0x200 */ struct kvm_vcpu_arch_shared *shared;#if defined(CONFIG_PPC_BOOK3S_64 ) && defined(CONFIG_KVM_BOOK3S_PR_POSSIBLE )
arch/powerpc/include/asm/machdep.h +7 -0
@@ -15,6 +15,7 @@#include <linux/export.h> #include <asm/setup.h> +#include <asm/mce.h> /* We export this macro for external modules like Alsa to know if * ppc_md.feature_call is implemented or not
@@ -112,6 +113,12 @@ struct machdep_calls {/* Called during machine check exception to retrive fixup address. */ bool (*mce_check_early_recovery)(struct pt_regs *regs); +#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE +/* Called after KVM interrupt handler finishes handling MCE for guest */ +int (*machine_check_exception_guest) + (struct machine_check_event *evt); +#endif +/* Motherboard/chipset features. This is a kind of general purpose * hook used to control some machine specific features (like reset * lines, chip power control, etc...).
arch/powerpc/include/asm/opal.h +4 -0
@@ -17,6 +17,7 @@#ifndef __ASSEMBLY__#include <linux/notifier.h> +#include <asm/mce.h> /* We calculate number of sg entries based on PAGE_SIZE */ #define SG_ENTRIES_PER_NODE ((PAGE_SIZE - 16) / sizeof(struct opal_sg_entry))
@@ -276,6 +277,9 @@ extern int opal_hmi_handler_init(void);extern int opal_event_init (void );extern int opal_machine_check (struct pt_regs *regs); +#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE +extern int opal_machine_check_guest (struct machine_check_event *evt); +#endif extern bool opal_mce_check_early_recovery (struct pt_regs *regs);extern int opal_hmi_exception_early (struct pt_regs *regs);extern int opal_handle_hmi_exception (struct pt_regs *regs);
arch/powerpc/include/uapi/asm/kvm.h +3 -0
@@ -57,6 +57,9 @@ struct kvm_regs {#define KVM_SREGS_E_FSL_PIDn (1 << 0)/* PID1/PID2 */ +/* flags for kvm_run.flags */ +#define KVM_RUN_PPC_NMI_RECOVERED (1 << 0) +/* * Feature bits indicate which sections of the sregs struct are valid, * both in KVM_GET_SREGS and KVM_SET_SREGS. On KVM_SET_SREGS, registers
arch/powerpc/kvm/book3s_hv.c +14 -7
@@ -954,15 +954,22 @@ static int kvmppc_handle_exit_hv(struct kvm_run *run, struct kvm_vcpu *vcpu, r =RESUME_GUEST ;break ;case BOOK3S_INTERRUPT_MACHINE_CHECK : +/* Exit to guest with KVM_EXIT_NMI as exit reason */ + run->exit_reason =KVM_EXIT_NMI ; + run->hw.hardware_exit_reason = vcpu->arch.trap; +if (vcpu->arch.mce_evt.disposition ==MCE_DISPOSITION_RECOVERED ) + run->flags |=KVM_RUN_PPC_NMI_RECOVERED ; +else + run->flags &= ~KVM_RUN_PPC_NMI_RECOVERED ; + + r =RESUME_HOST ;/* -* Deliver a machine check interrupt to the guest. -* We have to do this, even if the host has handled the -* machine check, because machine checks use SRR0/1 and -* the interrupt might have trashed guest state in them. +* Invoke host-kernel handler to perform any host-side +* handling before exiting the guest. */ -kvmppc_book3s_queue_irqprio (vcpu, -BOOK3S_INTERRUPT_MACHINE_CHECK ); - r =RESUME_GUEST ; +if (ppc_md.machine_check_exception_guest) + ppc_md.machine_check_exception_guest ( + &vcpu->arch.mce_evt);break ;case BOOK3S_INTERRUPT_PROGRAM : {
arch/powerpc/kvm/book3s_hv_ras.c +13 -1
@@ -133,8 +133,20 @@ static long kvmppc_realmode_mc_power7(struct kvm_vcpu *vcpu)* interrupt (for unhandled errors) or will continue from * current HSRR0 (for handled errors) in guest. Hence * queue up the event so that we can log it from host console later. +* If QEMU support FWNMI capability then hook the MCE event into +* vcpu structure. */ -machine_check_queue_event (); +if (vcpu->arch.fwnmi_enabled) { +/* +* Hook up the mce event on to vcpu structure. +* First clear the old event. +*/ +memset (&vcpu->arch.mce_evt,0 ,sizeof (vcpu->arch.mce_evt)); +if (get_mce_event (&mce_evt,MCE_EVENT_RELEASE )) { + vcpu->arch.mce_evt = mce_evt; + } + }else +machine_check_queue_event ();return handled; }
arch/powerpc/kvm/book3s_hv_rmhandlers.S +24 -23
88 lines not on this page · raw message
arch/powerpc/platforms/powernv/opal.c +26 -0
@@ -488,6 +488,32 @@ int opal_machine_check(struct pt_regs *regs)return 0 ; } +#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE +/* +* opal_machine_check_guest() is a hook which is invoked at the time +* of guest exit to facilitate the host-side handling of machine check +* exception before the exception is passed on to the guest. This hook +* is invoked from host virtual mode from KVM (before exiting the guest +* with KVM_EXIT_NMI reason) for machine check exception that occurs in +* the guest. +* +* Currently no action is performed in the host other than printing the +* event information. The machine check exception is passed on to the +* guest kernel and the guest kernel will attempt for recovery. +*/ +int opal_machine_check_guest (struct machine_check_event *evt) +{ +/* Print things out */ +if (evt->version !=MCE_V1 ) { +pr_err ("Machine Check Exception, Unknown event version %d !\n" , + evt->version); +return 0 ; + } +machine_check_print_event_info (evt); +return 0 ; +} +#endif +/* Early hmi handler called in real mode. */ int opal_hmi_exception_early (struct pt_regs *regs) {
arch/powerpc/platforms/powernv/setup.c +3 -0
@@ -264,6 +264,9 @@ static void __init pnv_setup_machdep_opal(void) ppc_md.mce_check_early_recovery = opal_mce_check_early_recovery; ppc_md.hmi_exception_early = opal_hmi_exception_early; ppc_md.handle_hmi_exception = opal_handle_hmi_exception; +#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE + ppc_md.machine_check_exception_guest = opal_machine_check_guest; +#endif }static int __init pnv_probe (void )