* [Qemu-devel] [PATCH 0/3] Support EEH Error Injection
@ 2015-03-11 6:39 Gavin Shan
2015-03-11 6:39 ` [Qemu-devel] [PATCH 1/3] linux-headers: Sync vfio.h Gavin Shan
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Gavin Shan @ 2015-03-11 6:39 UTC (permalink / raw)
To: qemu-devel; +Cc: aik, agraf, Gavin Shan, alex.williamson, qemu-ppc, david
The patchset depends on the corresponding host kernel changes:
https://patchwork.ozlabs.org/patch/448824/
https://patchwork.ozlabs.org/patch/448823/
According to PAPR specification 2.7, there're 3 RTAS calls relevent to error
injection: "ibm,open-errinjct", "ibm,close-errinjct", "ibm,errinjct". The userland
utility "errinjct" running on guest utilizes those 3 RTAS calls like this way:
Call "ibm,open-errinjct" that returns open-token, which is passed to "ibm,errinjct"
together with error specific arguments to do error injection. Finally, to return
the open-token by calling "ibm,close-errinject".
"ibm,errinjct" can be used to inject various errors, not limited to EEH errors.
However, this patchset is going to support injecting EEH errors only for VFIO
PCI devices.
Gavin Shan (3):
linux-headers: Sync vfio.h
sPAPR: Support RTAS call ibm,{open,close}-errinjct
sPAPR: Support RTAS call ibm,errinjct
hw/ppc/spapr_pci.c | 47 +++++++++++++
hw/ppc/spapr_pci_vfio.c | 99 +++++++++++++++++++++++++++
hw/ppc/spapr_rtas.c | 160 +++++++++++++++++++++++++++++++++++++++++++-
include/hw/pci-host/spapr.h | 2 +
include/hw/ppc/spapr.h | 55 ++++++++++++++-
linux-headers/linux/vfio.h | 34 +++++++++-
6 files changed, 393 insertions(+), 4 deletions(-)
--
1.8.3.2
^ permalink raw reply [flat|nested] 4+ messages in thread
* [Qemu-devel] [PATCH 1/3] linux-headers: Sync vfio.h
2015-03-11 6:39 [Qemu-devel] [PATCH 0/3] Support EEH Error Injection Gavin Shan
@ 2015-03-11 6:39 ` Gavin Shan
2015-03-11 6:39 ` [Qemu-devel] [PATCH 2/3] sPAPR: Support RTAS call ibm, {open, close}-errinjct Gavin Shan
2015-03-11 6:39 ` [Qemu-devel] [PATCH 3/3] sPAPR: Support RTAS call ibm,errinjct Gavin Shan
2 siblings, 0 replies; 4+ messages in thread
From: Gavin Shan @ 2015-03-11 6:39 UTC (permalink / raw)
To: qemu-devel; +Cc: aik, agraf, Gavin Shan, alex.williamson, qemu-ppc, david
The patch synchronizes vfio.h with the kernel to support EEH error
injection.
Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
---
| 34 +++++++++++++++++++++++++++++++++-
1 file changed, 33 insertions(+), 1 deletion(-)
--git a/linux-headers/linux/vfio.h b/linux-headers/linux/vfio.h
index 95ba870..61ed233 100644
--- a/linux-headers/linux/vfio.h
+++ b/linux-headers/linux/vfio.h
@@ -468,12 +468,21 @@ struct vfio_iommu_spapr_tce_info {
* - unfreeze IO/DMA for frozen PE;
* - read PE state;
* - reset PE;
- * - configure PE.
+ * - configure PE;
+ * - inject EEH error.
*/
+struct vfio_eeh_pe_err {
+ __u32 type;
+ __u32 func;
+ __u64 addr;
+ __u64 mask;
+};
+
struct vfio_eeh_pe_op {
__u32 argsz;
__u32 flags;
__u32 op;
+ __u8 data[];
};
#define VFIO_EEH_PE_DISABLE 0 /* Disable EEH functionality */
@@ -490,6 +499,29 @@ struct vfio_eeh_pe_op {
#define VFIO_EEH_PE_RESET_HOT 6 /* Assert hot reset */
#define VFIO_EEH_PE_RESET_FUNDAMENTAL 7 /* Assert fundamental reset */
#define VFIO_EEH_PE_CONFIGURE 8 /* PE configuration */
+#define VFIO_EEH_PE_INJECT_ERR 9 /* Inject EEH error */
+#define VFIO_EEH_ERR_TYPE_32 0 /* 32-bits EEH error type */
+#define VFIO_EEH_ERR_TYPE_64 1 /* 64-bits EEH error type */
+#define VFIO_EEH_ERR_FUNC_LD_MEM_ADDR 0 /* Memory load */
+#define VFIO_EEH_ERR_FUNC_LD_MEM_DATA 1
+#define VFIO_EEH_ERR_FUNC_LD_IO_ADDR 2 /* IO load */
+#define VFIO_EEH_ERR_FUNC_LD_IO_DATA 3
+#define VFIO_EEH_ERR_FUNC_LD_CFG_ADDR 4 /* Config load */
+#define VFIO_EEH_ERR_FUNC_LD_CFG_DATA 5
+#define VFIO_EEH_ERR_FUNC_ST_MEM_ADDR 6 /* Memory store */
+#define VFIO_EEH_ERR_FUNC_ST_MEM_DATA 7
+#define VFIO_EEH_ERR_FUNC_ST_IO_ADDR 8 /* IO store */
+#define VFIO_EEH_ERR_FUNC_ST_IO_DATA 9
+#define VFIO_EEH_ERR_FUNC_ST_CFG_ADDR 10 /* Config store */
+#define VFIO_EEH_ERR_FUNC_ST_CFG_DATA 11
+#define VFIO_EEH_ERR_FUNC_DMA_RD_ADDR 12 /* DMA read */
+#define VFIO_EEH_ERR_FUNC_DMA_RD_DATA 13
+#define VFIO_EEH_ERR_FUNC_DMA_RD_MASTER 14
+#define VFIO_EEH_ERR_FUNC_DMA_RD_TARGET 15
+#define VFIO_EEH_ERR_FUNC_DMA_WR_ADDR 16 /* DMA write */
+#define VFIO_EEH_ERR_FUNC_DMA_WR_DATA 17
+#define VFIO_EEH_ERR_FUNC_DMA_WR_MASTER 18
+#define VFIO_EEH_ERR_FUNC_DMA_WR_TARGET 19
#define VFIO_EEH_PE_OP _IO(VFIO_TYPE, VFIO_BASE + 21)
--
1.8.3.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [Qemu-devel] [PATCH 2/3] sPAPR: Support RTAS call ibm, {open, close}-errinjct
2015-03-11 6:39 [Qemu-devel] [PATCH 0/3] Support EEH Error Injection Gavin Shan
2015-03-11 6:39 ` [Qemu-devel] [PATCH 1/3] linux-headers: Sync vfio.h Gavin Shan
@ 2015-03-11 6:39 ` Gavin Shan
2015-03-11 6:39 ` [Qemu-devel] [PATCH 3/3] sPAPR: Support RTAS call ibm,errinjct Gavin Shan
2 siblings, 0 replies; 4+ messages in thread
From: Gavin Shan @ 2015-03-11 6:39 UTC (permalink / raw)
To: qemu-devel; +Cc: aik, agraf, Gavin Shan, alex.williamson, qemu-ppc, david
The patch supports RTAS calls "ibm,{open,close}-errinjct" to
manupliate the token, which is passed to RTAS call "ibm,errinjct"
to indicate the valid context for error injection. Each VM is
permitted to have only one token at once and we simply have one
random number for that.
Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
---
hw/ppc/spapr_rtas.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++
include/hw/ppc/spapr.h | 9 ++++++-
2 files changed, 81 insertions(+), 1 deletion(-)
diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index 0f1ae55..0afc5dd 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -245,6 +245,75 @@ static void rtas_ibm_os_term(PowerPCCPU *cpu,
rtas_st(rets, 0, ret);
}
+static void rtas_ibm_open_errinjct(PowerPCCPU *cpu,
+ sPAPREnvironment *spapr,
+ uint32_t token, uint32_t nargs,
+ target_ulong args, uint32_t nret,
+ target_ulong rets)
+{
+ int32_t ret;
+
+ /* Sanity check on number of arguments */
+ if ((nargs != 0) || (nret != 2)) {
+ ret = RTAS_OUT_PARAM_ERROR;
+ goto out;
+ }
+
+ /* Check if we already had token */
+ if (spapr->errinjct_token) {
+ ret = RTAS_OUT_TOKEN_OPENED;
+ goto out;
+ }
+
+ /* Grab random number as token */
+ spapr->errinjct_token = random();
+ if (spapr->errinjct_token == 0) {
+ ret = RTAS_OUT_BUSY;
+ goto out;
+ }
+
+ /* Success */
+ rtas_st(rets, 0, spapr->errinjct_token);
+ ret = RTAS_OUT_SUCCESS;
+out:
+ rtas_st(rets, 1, ret);
+}
+
+static void rtas_ibm_close_errinjct(PowerPCCPU *cpu,
+ sPAPREnvironment *spapr,
+ uint32_t token, uint32_t nargs,
+ target_ulong args, uint32_t nret,
+ target_ulong rets)
+{
+ uint32_t open_token;
+ int32_t ret;
+
+ /* Sanity check on number of arguments */
+ if ((nargs != 1) || (nret != 1)) {
+ ret = RTAS_OUT_PARAM_ERROR;
+ goto out;
+ }
+
+ /* Check if we had opened token */
+ if (!spapr->errinjct_token) {
+ ret = RTAS_OUT_CLOSE_ERROR;
+ goto out;
+ }
+
+ /* Check if it's the opened token */
+ open_token = rtas_ld(args, 0);
+ if (spapr->errinjct_token != open_token) {
+ ret = RTAS_OUT_CLOSE_ERROR;
+ goto out;
+ }
+
+ /* Success */
+ spapr->errinjct_token = 0;
+ ret = RTAS_OUT_SUCCESS;
+out:
+ rtas_st(rets, 0, ret);
+}
+
static struct rtas_call {
const char *name;
spapr_rtas_fn fn;
@@ -370,6 +439,10 @@ static void core_rtas_register_types(void)
rtas_ibm_set_system_parameter);
spapr_rtas_register(RTAS_IBM_OS_TERM, "ibm,os-term",
rtas_ibm_os_term);
+ spapr_rtas_register(RTAS_IBM_OPEN_ERRINJCT, "ibm,open-errinjct",
+ rtas_ibm_open_errinjct);
+ spapr_rtas_register(RTAS_IBM_CLOSE_ERRINJCT, "ibm,close-errinjct",
+ rtas_ibm_close_errinjct);
}
type_init(core_rtas_register_types)
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index af71e8b..4f7cc2e 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -39,6 +39,9 @@ typedef struct sPAPREnvironment {
bool htab_first_pass;
int htab_fd;
bool htab_fd_stale;
+
+ /* Error injection token */
+ uint32_t errinjct_token;
} sPAPREnvironment;
#define H_SUCCESS 0
@@ -379,6 +382,8 @@ int spapr_allocate_irq_block(int num, bool lsi, bool msi);
#define RTAS_OUT_BUSY -2
#define RTAS_OUT_PARAM_ERROR -3
#define RTAS_OUT_NOT_SUPPORTED -3
+#define RTAS_OUT_TOKEN_OPENED -4
+#define RTAS_OUT_CLOSE_ERROR -4
#define RTAS_OUT_NOT_AUTHORIZED -9002
/* RTAS tokens */
@@ -422,8 +427,10 @@ int spapr_allocate_irq_block(int num, bool lsi, bool msi);
#define RTAS_IBM_SET_SLOT_RESET (RTAS_TOKEN_BASE + 0x23)
#define RTAS_IBM_CONFIGURE_PE (RTAS_TOKEN_BASE + 0x24)
#define RTAS_IBM_SLOT_ERROR_DETAIL (RTAS_TOKEN_BASE + 0x25)
+#define RTAS_IBM_OPEN_ERRINJCT (RTAS_TOKEN_BASE + 0x26)
+#define RTAS_IBM_CLOSE_ERRINJCT (RTAS_TOKEN_BASE + 0x27)
-#define RTAS_TOKEN_MAX (RTAS_TOKEN_BASE + 0x26)
+#define RTAS_TOKEN_MAX (RTAS_TOKEN_BASE + 0x28)
/* RTAS ibm,get-system-parameter token values */
#define RTAS_SYSPARM_SPLPAR_CHARACTERISTICS 20
--
1.8.3.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [Qemu-devel] [PATCH 3/3] sPAPR: Support RTAS call ibm,errinjct
2015-03-11 6:39 [Qemu-devel] [PATCH 0/3] Support EEH Error Injection Gavin Shan
2015-03-11 6:39 ` [Qemu-devel] [PATCH 1/3] linux-headers: Sync vfio.h Gavin Shan
2015-03-11 6:39 ` [Qemu-devel] [PATCH 2/3] sPAPR: Support RTAS call ibm, {open, close}-errinjct Gavin Shan
@ 2015-03-11 6:39 ` Gavin Shan
2 siblings, 0 replies; 4+ messages in thread
From: Gavin Shan @ 2015-03-11 6:39 UTC (permalink / raw)
To: qemu-devel; +Cc: aik, agraf, Gavin Shan, alex.williamson, qemu-ppc, david
The patch supports RTAS call "ibm,errinjct" to allow injecting
EEH errors to VFIO PCI devices. The implementation is similiar
to EEH support for VFIO PCI devices: The RTAS request is captured
by QEMU and routed to sPAPRPHBClass::eeh_error_inject() where the
request is translated to VFIO container IOCTL command to be handled
by the host.
Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
---
hw/ppc/spapr_pci.c | 47 +++++++++++++++++++++
hw/ppc/spapr_pci_vfio.c | 99 +++++++++++++++++++++++++++++++++++++++++++++
hw/ppc/spapr_rtas.c | 87 ++++++++++++++++++++++++++++++++++++++-
include/hw/pci-host/spapr.h | 2 +
include/hw/ppc/spapr.h | 48 +++++++++++++++++++++-
5 files changed, 280 insertions(+), 3 deletions(-)
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 05f4fac..5f88d87 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -658,6 +658,53 @@ param_error_exit:
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
}
+int spapr_rtas_errinjct_ioa(sPAPREnvironment *spapr,
+ target_ulong param_buf,
+ bool is_64bits)
+{
+ sPAPRPHBState *sphb;
+ sPAPRPHBClass *spc;
+ uint64_t buid, addr, mask;
+ uint32_t func;
+ int ret;
+
+ if (is_64bits) {
+ addr = rtas_ldq(param_buf, 0);
+ mask = rtas_ldq(param_buf, 1);
+ buid = ((uint64_t)rtas_ld(param_buf, 5) << 32) | rtas_ld(param_buf, 6);
+ func = rtas_ld(param_buf, 7);
+ } else {
+ addr = rtas_ld(param_buf, 0);
+ mask = rtas_ld(param_buf, 1);
+ buid = ((uint64_t)rtas_ld(param_buf, 3) << 32) | rtas_ld(param_buf, 4);
+ func = rtas_ld(param_buf, 5);
+ }
+
+ /* Check function is valid */
+ if (func > RTAS_ERRINJCT_IOA_DMA_WR_MEM_TARGET) {
+ return RTAS_OUT_PARAM_ERROR;
+ }
+
+ /* Find PHB */
+ sphb = find_phb(spapr, buid);
+ if (!sphb) {
+ return RTAS_OUT_PARAM_ERROR;
+ }
+
+ spc = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(sphb);
+ if (!spc->eeh_error_inject) {
+ return RTAS_OUT_PARAM_ERROR;
+ }
+
+ /* Handle the request */
+ ret = spc->eeh_error_inject(sphb, func, addr, mask, is_64bits);
+ if (ret < 0) {
+ return RTAS_OUT_HW_ERROR;
+ }
+
+ return RTAS_OUT_SUCCESS;
+}
+
static int pci_spapr_swizzle(int slot, int pin)
{
return (slot + pin) % PCI_NUM_PINS;
diff --git a/hw/ppc/spapr_pci_vfio.c b/hw/ppc/spapr_pci_vfio.c
index 0cd96d3..6b8f7d2 100644
--- a/hw/ppc/spapr_pci_vfio.c
+++ b/hw/ppc/spapr_pci_vfio.c
@@ -199,6 +199,104 @@ static int spapr_phb_vfio_eeh_configure(sPAPRPHBState *sphb)
return RTAS_OUT_SUCCESS;
}
+static int spapr_phb_vfio_eeh_error_inject(sPAPRPHBState *sphb,
+ uint32_t func, uint64_t addr,
+ uint64_t mask, bool is_64bits)
+{
+ sPAPRPHBVFIOState *svphb = SPAPR_PCI_VFIO_HOST_BRIDGE(sphb);
+ struct vfio_eeh_pe_op *op;
+ struct vfio_eeh_pe_err *err;
+ int argsz = sizeof(*op) + sizeof(*err);
+ int ret = RTAS_OUT_SUCCESS;
+
+ op = g_malloc0(argsz);
+ err = (struct vfio_eeh_pe_err *)op->data;
+ op->argsz = argsz;
+ op->flags = 0;
+ op->op = VFIO_EEH_PE_INJECT_ERR;
+ err->type = is_64bits ? VFIO_EEH_ERR_TYPE_64 : VFIO_EEH_ERR_TYPE_32;
+ err->addr = addr;
+ err->mask = mask;
+
+ switch (func) {
+ case RTAS_ERRINJCT_IOA_LD_MEM_ADDR:
+ err->func = VFIO_EEH_ERR_FUNC_LD_MEM_ADDR;
+ break;
+ case RTAS_ERRINJCT_IOA_LD_MEM_DATA:
+ err->func = VFIO_EEH_ERR_FUNC_LD_MEM_DATA;
+ break;
+ case RTAS_ERRINJCT_IOA_LD_IO_ADDR:
+ err->func = VFIO_EEH_ERR_FUNC_LD_IO_ADDR;
+ break;
+ case RTAS_ERRINJCT_IOA_LD_IO_DATA:
+ err->func = VFIO_EEH_ERR_FUNC_LD_IO_DATA;
+ break;
+ case RTAS_ERRINJCT_IOA_LD_CONFIG_ADDR:
+ err->func = VFIO_EEH_ERR_FUNC_LD_CFG_ADDR;
+ break;
+ case RTAS_ERRINJCT_IOA_LD_CONFIG_DATA:
+ err->func = VFIO_EEH_ERR_FUNC_LD_CFG_DATA;
+ break;
+ case RTAS_ERRINJCT_IOA_ST_MEM_ADDR:
+ err->func = VFIO_EEH_ERR_FUNC_ST_MEM_ADDR;
+ break;
+ case RTAS_ERRINJCT_IOA_ST_MEM_DATA:
+ err->func = VFIO_EEH_ERR_FUNC_ST_MEM_DATA;
+ break;
+ case RTAS_ERRINJCT_IOA_ST_IO_ADDR:
+ err->func = VFIO_EEH_ERR_FUNC_ST_IO_ADDR;
+ break;
+ case RTAS_ERRINJCT_IOA_ST_IO_DATA:
+ err->func = VFIO_EEH_ERR_FUNC_ST_IO_DATA;
+ break;
+ case RTAS_ERRINJCT_IOA_ST_CONFIG_ADDR:
+ err->func = VFIO_EEH_ERR_FUNC_ST_CFG_ADDR;
+ break;
+ case RTAS_ERRINJCT_IOA_ST_CONFIG_DATA:
+ err->func = VFIO_EEH_ERR_FUNC_ST_CFG_DATA;
+ break;
+ case RTAS_ERRINJCT_IOA_DMA_RD_MEM_ADDR:
+ err->func = VFIO_EEH_ERR_FUNC_DMA_RD_ADDR;
+ break;
+ case RTAS_ERRINJCT_IOA_DMA_RD_MEM_DATA:
+ err->func = VFIO_EEH_ERR_FUNC_DMA_RD_DATA;
+ break;
+ case RTAS_ERRINJCT_IOA_DMA_RD_MEM_MASTER:
+ err->func = VFIO_EEH_ERR_FUNC_DMA_RD_MASTER;
+ break;
+ case RTAS_ERRINJCT_IOA_DMA_RD_MEM_TARGET:
+ err->func = VFIO_EEH_ERR_FUNC_DMA_RD_TARGET;
+ break;
+ case RTAS_ERRINJCT_IOA_DMA_WR_MEM_ADDR:
+ err->func = VFIO_EEH_ERR_FUNC_DMA_WR_ADDR;
+ break;
+ case RTAS_ERRINJCT_IOA_DMA_WR_MEM_DATA:
+ err->func = VFIO_EEH_ERR_FUNC_DMA_WR_DATA;
+ break;
+ case RTAS_ERRINJCT_IOA_DMA_WR_MEM_MASTER:
+ err->func = VFIO_EEH_ERR_FUNC_DMA_WR_MASTER;
+ break;
+ case RTAS_ERRINJCT_IOA_DMA_WR_MEM_TARGET:
+ err->func = VFIO_EEH_ERR_FUNC_DMA_WR_TARGET;
+ break;
+ default:
+ ret = RTAS_OUT_PARAM_ERROR;
+ goto out;
+ }
+
+ if (vfio_container_ioctl(&svphb->phb.iommu_as, svphb->iommugroupid,
+ VFIO_EEH_PE_OP, op) < 0) {
+ ret = RTAS_OUT_HW_ERROR;
+ goto out;
+ }
+
+ /* Success */
+ ret = RTAS_OUT_SUCCESS;
+out:
+ g_free(op);
+ return ret;
+}
+
static void spapr_phb_vfio_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
@@ -211,6 +309,7 @@ static void spapr_phb_vfio_class_init(ObjectClass *klass, void *data)
spc->eeh_get_state = spapr_phb_vfio_eeh_get_state;
spc->eeh_reset = spapr_phb_vfio_eeh_reset;
spc->eeh_configure = spapr_phb_vfio_eeh_configure;
+ spc->eeh_error_inject = spapr_phb_vfio_eeh_error_inject;
}
static const TypeInfo spapr_phb_vfio_info = {
diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index 0afc5dd..ed110aa 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -279,6 +279,53 @@ out:
rtas_st(rets, 1, ret);
}
+static void rtas_ibm_errinjct(PowerPCCPU *cpu,
+ sPAPREnvironment *spapr,
+ uint32_t token, uint32_t nargs,
+ target_ulong args, uint32_t nret,
+ target_ulong rets)
+{
+ target_ulong param_buf;
+ uint32_t type, open_token;
+ int32_t ret;
+
+ /* Sanity check on number of arguments */
+ if ((nargs != 3) || (nret != 1)) {
+ ret = RTAS_OUT_PARAM_ERROR;
+ goto out;
+ }
+
+ /* Check if we had opened token */
+ open_token = rtas_ld(args, 1);
+ if (spapr->errinjct_token != open_token) {
+ ret = RTAS_OUT_TOKEN_OPENED;
+ goto out;
+ }
+
+ /* The parameter buffer should be 1KB aligned */
+ param_buf = rtas_ld(args, 2);
+ if (param_buf & 0x3ff) {
+ ret = RTAS_OUT_PARAM_ERROR;
+ goto out;
+ }
+
+ /* Check the error type */
+ type = rtas_ld(args, 0);
+ switch (type) {
+ case RTAS_ERRINJCT_TYPE_IOA_BUS_ERROR:
+ ret = spapr_rtas_errinjct_ioa(spapr, param_buf, false);
+ break;
+ case RTAS_ERRINJCT_TYPE_IOA_BUS_ERROR64:
+ ret = spapr_rtas_errinjct_ioa(spapr, param_buf, true);
+ break;
+ default:
+ ret = RTAS_OUT_PARAM_ERROR;
+ }
+
+out:
+ rtas_st(rets, 0, ret);
+}
+
static void rtas_ibm_close_errinjct(PowerPCCPU *cpu,
sPAPREnvironment *spapr,
uint32_t token, uint32_t nargs,
@@ -367,8 +414,42 @@ void spapr_rtas_register(int token, const char *name, spapr_rtas_fn fn)
int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
hwaddr rtas_size)
{
- int ret;
- int i;
+ const char *tokens[] = {
+ "fatal",
+ "recovered-random-event",
+ "recovered-special-event",
+ "corrupted-page",
+ "corrupted-slb",
+ "translator-failure",
+ "ioa-bus-error",
+ "ioa-bus-error-64",
+ "platform-specific",
+ "corrupted-dcache-start",
+ "corrupted-dcache-end",
+ "corrupted-icache-start",
+ "corrupted-icache-end",
+ "corrupted-tlb-start",
+ "corrupted-tlb-end"
+ };
+ char errinjct_tokens[1024];
+ int fdt_offset, offset, i, ret;
+
+ /* ibm,errinjct-tokens */
+ offset = 0;
+ for (i = 0; i < ARRAY_SIZE(tokens); i++) {
+ offset += sprintf(errinjct_tokens + offset, "%s", tokens[i]);
+ errinjct_tokens[offset++] = '\0';
+ *(int *)(&errinjct_tokens[offset]) = i+1;
+ offset += sizeof(int);
+ }
+
+ fdt_offset = fdt_path_offset(fdt, "/rtas");
+ ret = fdt_setprop(fdt, fdt_offset, "ibm,errinjct-tokens",
+ errinjct_tokens, offset);
+ if (ret < 0) {
+ fprintf(stderr, "Couldn't add ibm,errinjct-tokens\n");
+ return ret;
+ }
ret = fdt_add_mem_rsv(fdt, rtas_addr, rtas_size);
if (ret < 0) {
@@ -441,6 +522,8 @@ static void core_rtas_register_types(void)
rtas_ibm_os_term);
spapr_rtas_register(RTAS_IBM_OPEN_ERRINJCT, "ibm,open-errinjct",
rtas_ibm_open_errinjct);
+ spapr_rtas_register(RTAS_IBM_ERRINJCT, "ibm,errinjct",
+ rtas_ibm_errinjct);
spapr_rtas_register(RTAS_IBM_CLOSE_ERRINJCT, "ibm,close-errinjct",
rtas_ibm_close_errinjct);
}
diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h
index 895d273..3546dc6 100644
--- a/include/hw/pci-host/spapr.h
+++ b/include/hw/pci-host/spapr.h
@@ -53,6 +53,8 @@ struct sPAPRPHBClass {
int (*eeh_get_state)(sPAPRPHBState *sphb, int *state);
int (*eeh_reset)(sPAPRPHBState *sphb, int option);
int (*eeh_configure)(sPAPRPHBState *sphb);
+ int (*eeh_error_inject)(sPAPRPHBState *sphb, uint32_t func,
+ uint64_t addr, uint64_t mask, bool is_64bits);
};
typedef struct spapr_pci_msi {
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 4f7cc2e..de0466a 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -375,6 +375,44 @@ int spapr_allocate_irq_block(int num, bool lsi, bool msi);
#define RTAS_SLOT_TEMP_ERR_LOG 1
#define RTAS_SLOT_PERM_ERR_LOG 2
+/* ibm,errinjct */
+#define RTAS_ERRINJCT_TYPE_FATAL 1
+#define RTAS_ERRINJCT_TYPE_RANDOM_EVENT 2
+#define RTAS_ERRINJCT_TYPE_SPECIAL_EVENT 3
+#define RTAS_ERRINJCT_TYPE_CORRUPTED_PAGE 4
+#define RTAS_ERRINJCT_TYPE_CORRUPTED_SLB 5
+#define RTAS_ERRINJCT_TYPE_TRANSLATOR_FAILURE 6
+#define RTAS_ERRINJCT_TYPE_IOA_BUS_ERROR 7
+#define RTAS_ERRINJCT_TYPE_IOA_BUS_ERROR64 8
+#define RTAS_ERRINJCT_IOA_LD_MEM_ADDR 0
+#define RTAS_ERRINJCT_IOA_LD_MEM_DATA 1
+#define RTAS_ERRINJCT_IOA_LD_IO_ADDR 2
+#define RTAS_ERRINJCT_IOA_LD_IO_DATA 3
+#define RTAS_ERRINJCT_IOA_LD_CONFIG_ADDR 4
+#define RTAS_ERRINJCT_IOA_LD_CONFIG_DATA 5
+#define RTAS_ERRINJCT_IOA_ST_MEM_ADDR 6
+#define RTAS_ERRINJCT_IOA_ST_MEM_DATA 7
+#define RTAS_ERRINJCT_IOA_ST_IO_ADDR 8
+#define RTAS_ERRINJCT_IOA_ST_IO_DATA 9
+#define RTAS_ERRINJCT_IOA_ST_CONFIG_ADDR 10
+#define RTAS_ERRINJCT_IOA_ST_CONFIG_DATA 11
+#define RTAS_ERRINJCT_IOA_DMA_RD_MEM_ADDR 12
+#define RTAS_ERRINJCT_IOA_DMA_RD_MEM_DATA 13
+#define RTAS_ERRINJCT_IOA_DMA_RD_MEM_MASTER 14
+#define RTAS_ERRINJCT_IOA_DMA_RD_MEM_TARGET 15
+#define RTAS_ERRINJCT_IOA_DMA_WR_MEM_ADDR 16
+#define RTAS_ERRINJCT_IOA_DMA_WR_MEM_DATA 17
+#define RTAS_ERRINJCT_IOA_DMA_WR_MEM_MASTER 18
+#define RTAS_ERRINJCT_IOA_DMA_WR_MEM_TARGET 19
+#define RTAS_ERRINJCT_TYPE_PLATFORM_SPECIFIC 9
+#define RTAS_ERRINJCT_TYPE_DCACHE_START 10
+#define RTAS_ERRINJCT_TYPE_DCACHE_END 11
+#define RTAS_ERRINJCT_TYPE_ICACHE_START 12
+#define RTAS_ERRINJCT_TYPE_ICACHE_END 13
+#define RTAS_ERRINJCT_TYPE_TLB_START 14
+#define RTAS_ERRINJCT_TYPE_TLB_END 15
+#define RTAS_ERRINJCT_TYPE_UPSTREAM_IO_ERROR 16
+
/* RTAS return codes */
#define RTAS_OUT_SUCCESS 0
#define RTAS_OUT_NO_ERRORS_FOUND 1
@@ -429,8 +467,9 @@ int spapr_allocate_irq_block(int num, bool lsi, bool msi);
#define RTAS_IBM_SLOT_ERROR_DETAIL (RTAS_TOKEN_BASE + 0x25)
#define RTAS_IBM_OPEN_ERRINJCT (RTAS_TOKEN_BASE + 0x26)
#define RTAS_IBM_CLOSE_ERRINJCT (RTAS_TOKEN_BASE + 0x27)
+#define RTAS_IBM_ERRINJCT (RTAS_TOKEN_BASE + 0x28)
-#define RTAS_TOKEN_MAX (RTAS_TOKEN_BASE + 0x28)
+#define RTAS_TOKEN_MAX (RTAS_TOKEN_BASE + 0x29)
/* RTAS ibm,get-system-parameter token values */
#define RTAS_SYSPARM_SPLPAR_CHARACTERISTICS 20
@@ -455,6 +494,11 @@ static inline uint32_t rtas_ld(target_ulong phys, int n)
return ldl_be_phys(&address_space_memory, ppc64_phys_to_real(phys + 4*n));
}
+static inline uint64_t rtas_ldq(target_ulong phys, int n)
+{
+ return ldq_be_phys(&address_space_memory, ppc64_phys_to_real(phys + 8*n));
+}
+
static inline void rtas_st(target_ulong phys, int n, uint32_t val)
{
stl_be_phys(&address_space_memory, ppc64_phys_to_real(phys + 4*n), val);
@@ -528,6 +572,8 @@ int spapr_dma_dt(void *fdt, int node_off, const char *propname,
int spapr_tcet_dma_dt(void *fdt, int node_off, const char *propname,
sPAPRTCETable *tcet);
void spapr_pci_switch_vga(bool big_endian);
+int spapr_rtas_errinjct_ioa(sPAPREnvironment *spapr,
+ target_ulong param_buf, bool is_64bits);
#define TYPE_SPAPR_RTC "spapr-rtc"
--
1.8.3.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2015-03-11 6:40 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-03-11 6:39 [Qemu-devel] [PATCH 0/3] Support EEH Error Injection Gavin Shan
2015-03-11 6:39 ` [Qemu-devel] [PATCH 1/3] linux-headers: Sync vfio.h Gavin Shan
2015-03-11 6:39 ` [Qemu-devel] [PATCH 2/3] sPAPR: Support RTAS call ibm, {open, close}-errinjct Gavin Shan
2015-03-11 6:39 ` [Qemu-devel] [PATCH 3/3] sPAPR: Support RTAS call ibm,errinjct Gavin Shan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).