[PATCH 8/8] powerpc/powernv: Error injection infrastructure

2014-05-13 Thread Gavin Shan
The patch intends to implement the error injection infrastructure
for PowerNV platform. The predetermined handlers will be called
according to the type of injected error (e.g. OpalErrinjctTypeIoaBusError).
For now, we just support PCI error injection. We need support
injecting other types of errors in future.

Signed-off-by: Gavin Shan 
---
 arch/powerpc/include/asm/opal.h|   6 +
 arch/powerpc/platforms/powernv/Makefile|   2 +-
 arch/powerpc/platforms/powernv/errinject.c | 224 +
 3 files changed, 231 insertions(+), 1 deletion(-)
 create mode 100644 arch/powerpc/platforms/powernv/errinject.c

diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 7c4ffd0..7bf86ba 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -794,6 +794,12 @@ typedef struct oppanel_line {
uint64_tline_len;
 } oppanel_line_t;
 
+enum OpalCallToken{
+   OPAL_CALL_TOKEN_MIN = 0,
+   OPAL_CALL_TOKEN_ERRINJCT,
+   OPAL_CALL_TOKEN_MAX
+};
+
 /* /sys/firmware/opal */
 extern struct kobject *opal_kobj;
 
diff --git a/arch/powerpc/platforms/powernv/Makefile 
b/arch/powerpc/platforms/powernv/Makefile
index 2b15a03..5ae8257 100644
--- a/arch/powerpc/platforms/powernv/Makefile
+++ b/arch/powerpc/platforms/powernv/Makefile
@@ -1,7 +1,7 @@
 obj-y  += setup.o opal-takeover.o opal-wrappers.o opal.o 
opal-async.o
 obj-y  += opal-rtc.o opal-nvram.o opal-lpc.o opal-flash.o
 obj-y  += rng.o opal-elog.o opal-dump.o opal-sysparam.o 
opal-sensor.o
-obj-y  += opal-msglog.o
+obj-y  += opal-msglog.o errinject.o
 
 obj-$(CONFIG_SMP)  += smp.o
 obj-$(CONFIG_PCI)  += pci.o pci-p5ioc2.o pci-ioda.o
diff --git a/arch/powerpc/platforms/powernv/errinject.c 
b/arch/powerpc/platforms/powernv/errinject.c
new file mode 100644
index 000..aa892d4
--- /dev/null
+++ b/arch/powerpc/platforms/powernv/errinject.c
@@ -0,0 +1,224 @@
+/*
+ * The file intends to support error injection requests from host OS
+ * owned utility (e.g. errinjct) or VM. We need parse the information
+ * passed from user space and call to appropriate OPAL API accordingly.
+ *
+ * Copyright Benjamin Herrenschmidt & Gavin Shan, IBM Corporation 2014.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "powernv.h"
+#include "pci.h"
+
+static int powernv_errinjct_ioa(struct rtas_args *args)
+{
+   return -ENXIO;
+}
+
+static int powernv_errinjct_ioa64(struct rtas_args *args)
+{
+   return -ENXIO;
+}
+
+#ifdef CONFIG_VFIO_EEH
+static int powernv_errinjct_ioa_virt(struct rtas_args *args)
+{
+   uint32_t addr, mask, cfg_addr;
+   uint32_t buid_hi, buid_lo, op;
+   uint64_t buf_addr = ((uint64_t)(args->args[3])) << 32 |
+   args->args[4];
+   void __user *buf = (void __user *)buf_addr;
+   struct eeh_vfio_pci_addr vfio_addr;
+   struct pnv_phb *phb;
+   struct eeh_pe *pe;
+   struct OpalErrinjct ej;
+
+   /* Extract parameters */
+   if (get_user(addr, (uint32_t __user *)buf) ||
+   get_user(mask, (uint32_t __user *)(buf + 4)) ||
+   get_user(cfg_addr, (uint32_t __user *)(buf + 8)) ||
+   get_user(buid_hi, (uint32_t __user *)(buf + 12)) ||
+   get_user(buid_lo, (uint32_t __user *)(buf + 16)) ||
+   get_user(op, (uint32_t __user *)(buf + 20)))
+   return -EFAULT;
+
+   /* Check opcode */
+   if (op < OpalEjtIoaLoadMemAddr ||
+   op > OpalEjtIoaDmaWriteMemTarget)
+   return -EINVAL;
+
+   /* Find PE */
+   vfio_addr.buid = uint64_t)buid_hi) << 32) | buid_lo);
+   vfio_addr.pe_addr = cfg_addr;
+   pe = eeh_vfio_pe_get(&vfio_addr);
+   if (!pe)
+   return -ENODEV;
+   phb = pe->phb->private_data;
+
+   /* OPAL call */
+   ej.type = OpalErrinjctTypeIoaBusError;
+   ej.ioa.addr = addr;
+   ej.ioa.mask = mask;
+   ej.ioa.phb_id = phb->opal_id;
+   ej.ioa.pe = pe->addr;
+   ej.ioa.function = op;
+   if (opal_err_injct(&ej) != OPAL_SUCCESS)
+   return -EIO;
+
+   return 0;
+}
+
+static int powernv_errinjct_ioa64_virt(struct rtas_args *args)
+{
+   uint32_t addr_hi, addr_lo, mask_hi, mask_lo;
+   uint32_t cfg_addr, buid_hi, buid_lo, op;
+   uint64_t buf_addr = ((uint64_t)(args->args[3])) << 32 |
+   args->args[4];
+   void __user *buf = (void __user *)buf_addr;
+   struct eeh_vfio_pci_addr vfio_addr;
+   struct

Re: [PATCH 8/8] powerpc/powernv: Error injection infrastructure

2014-05-19 Thread Alexander Graf


On 14.05.14 06:12, Gavin Shan wrote:

The patch intends to implement the error injection infrastructure
for PowerNV platform. The predetermined handlers will be called
according to the type of injected error (e.g. OpalErrinjctTypeIoaBusError).
For now, we just support PCI error injection. We need support
injecting other types of errors in future.


Your token to a VFIO device is the VFIO fd. If you want to inject an 
error into that device, you should do it via that token. That gets you 
all permission problems solved for free.


But I still didn't quite grasp why you need to do this. Why do we need 
to inject an error into a device via OPAL when we want to do EEH inside 
of a guest? Are you trying to emulate guest side error injection?



Alex

--
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


Re: [PATCH 8/8] powerpc/powernv: Error injection infrastructure

2014-05-19 Thread Benjamin Herrenschmidt
On Mon, 2014-05-19 at 15:04 +0200, Alexander Graf wrote:
> On 14.05.14 06:12, Gavin Shan wrote:
> > The patch intends to implement the error injection infrastructure
> > for PowerNV platform. The predetermined handlers will be called
> > according to the type of injected error (e.g. OpalErrinjctTypeIoaBusError).
> > For now, we just support PCI error injection. We need support
> > injecting other types of errors in future.
> 
> Your token to a VFIO device is the VFIO fd. If you want to inject an 
> error into that device, you should do it via that token. That gets you 
> all permission problems solved for free.
> 
> But I still didn't quite grasp why you need to do this. Why do we need 
> to inject an error into a device via OPAL when we want to do EEH inside 
> of a guest? Are you trying to emulate guest side error injection?

Yes, that's what he's trying to do but let's keep that separate from
the core EEH. I'd like the latter to be reviewed /fixed and upstream
first, then we can look at guest side injection.

Cheers,
Ben.


--
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