@@ -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);
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 <gwshan@linux.vnet.ibm.com> --- arch/powerpc/platforms/powernv/eeh-rtas.c | 75 +++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+)