The RTAS call "ibm,slot-error-detail" is being used to retrieve the
error log (either permanent or temporary) from the underlying firmware.
The patch implements the backend to emulate the RTAS call.

Signed-off-by: Gavin Shan <gws...@linux.vnet.ibm.com>
---
 arch/powerpc/platforms/powernv/eeh-rtas.c | 75 +++++++++++++++++++++++++++++++
 1 file changed, 75 insertions(+)

diff --git a/arch/powerpc/platforms/powernv/eeh-rtas.c 
b/arch/powerpc/platforms/powernv/eeh-rtas.c
index 4a9c2c7..8934564 100644
--- a/arch/powerpc/platforms/powernv/eeh-rtas.c
+++ b/arch/powerpc/platforms/powernv/eeh-rtas.c
@@ -390,6 +390,78 @@ out:
        return ret;
 }
 
+static int kvmppc_eeh_get_error(struct kvm_vcpu *vcpu,
+                               struct rtas_args *args)
+{
+       struct pci_controller *hose;
+       struct pnv_phb *phb;
+       struct eeh_dev *edev;
+       struct eeh_pe *pe;
+       struct eeh_vfio_pci_addr addr;
+       char *log;
+       int guest_log;
+       int len, severity;
+       int ret = 0;
+
+       /* Sanity check on parameter */
+       if (args->nargs != 8 || args->nret != 1) {
+               pr_warn("%s: Non-matched arguments (%d, %d) - (8, 1)\n",
+                       __func__, args->nargs, args->nret);
+               ret = 1;
+               goto out;
+       } else if (args->args[7] != 1 && args->args[7] != 2) {
+               pr_warn("%s: Invalid Log type\n", __func__);
+               ret = 1;
+               goto out;
+       }
+
+       /* Figure out the address */
+       if (kvmppc_eeh_format_addr(vcpu, args, &addr, false, &edev, &pe)) {
+               ret = 1;
+               goto out;
+       }
+
+       /* Make sure that the EEH stuff has been initialized */
+       hose = pe->phb;
+       phb = hose->private_data;
+       if (!(phb->flags & PNV_PHB_FLAG_EEH)) {
+               pr_warn("%s: EEH disabled on PHB#%d\n",
+                       __func__, hose->global_number);
+               ret = 1;
+               goto out;
+       }
+
+       /*
+        * Retrieve error log from PE. We don't have cached error
+        * log for one specific PE yet, which need to be figured
+        * out later.
+        */
+       if (phb->eeh_ops && phb->eeh_ops->get_log) {
+               guest_log = args->args[5];
+               len = args->args[6];
+               severity = args->args[7];
+               log = kzalloc(len, GFP_KERNEL);
+               if (!log) {
+                       pr_err("%s: Out of memory!\n", __func__);
+                       ret = 1;
+                       goto out;
+               }
+
+               phb->eeh_ops->get_log(pe, severity, log, len);
+               if (kvm_write_guest(vcpu->kvm, guest_log, log, len)) {
+                       pr_warn("%s: Fail pushing log to guest\n",
+                               __func__);
+                       ret = 1;
+               }
+
+               kfree(log);
+       } else {
+               ret = 1;
+       }
+out:
+       return ret;
+}
+
 /**
  * kvmppc_eeh_rtas - Backend for EEH RTAS emulation
  * @vcpu: KVM virtual CPU
@@ -418,6 +490,9 @@ void kvmppc_eeh_rtas(struct kvm_vcpu *vcpu, struct 
rtas_args *args, int op)
        case eeh_rtas_get_config_addr_info2:
                ret = kvmppc_eeh_get_addr2(vcpu, args);
                break;
+       case eeh_rtas_slot_error_detail:
+               ret = kvmppc_eeh_get_error(vcpu, args);
+               break;
        default:
                pr_warn("%s: Unsupported EEH RTAS service#%d\n",
                        __func__, op);
-- 
1.8.3.2

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

Reply via email to