From: Gavin Shan <gwshan@linux.vnet.ibm.com>
To: linuxppc-dev@lists.ozlabs.org
Cc: kvm-ppc@vger.kernel.org, kvm@vger.kernel.org,
david@gibson.dropbear.id.au, alex.williamson@redhat.com,
Gavin Shan <gwshan@linux.vnet.ibm.com>
Subject: [PATCH 2/2] drivers/vfio: Support IOMMU group for EEH operations
Date: Fri, 18 Sep 2015 16:24:29 +1000 [thread overview]
Message-ID: <1442557469-22185-3-git-send-email-gwshan@linux.vnet.ibm.com> (raw)
In-Reply-To: <1442557469-22185-1-git-send-email-gwshan@linux.vnet.ibm.com>
Currently, EEH module works based on the assumption that every
container has only one attached IOMMU group. It's not true any
more. So the userland has to specify the IOMMU group (PE) to
which the requested EEH operation is applied.
This exposes "v2" interface for the userland to specify IOMMU
group (PE) ID when requesting EEH operation.
Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
---
drivers/vfio/vfio_iommu_spapr_tce.c | 51 ++++++++++++++++++++++++++++++++-----
drivers/vfio/vfio_spapr_eeh.c | 39 ++++++++++++++++------------
include/linux/vfio.h | 7 ++---
include/uapi/linux/vfio.h | 3 +++
4 files changed, 75 insertions(+), 25 deletions(-)
diff --git a/drivers/vfio/vfio_iommu_spapr_tce.c b/drivers/vfio/vfio_iommu_spapr_tce.c
index 812b43b..f85bde7 100644
--- a/drivers/vfio/vfio_iommu_spapr_tce.c
+++ b/drivers/vfio/vfio_iommu_spapr_tce.c
@@ -724,7 +724,8 @@ static long tce_iommu_ioctl(void *iommu_data,
ret = 1;
break;
default:
- ret = vfio_spapr_iommu_eeh_ioctl(NULL, cmd, arg);
+ ret = vfio_spapr_iommu_eeh_ioctl(NULL, cmd,
+ arg, NULL, 0);
break;
}
@@ -953,17 +954,55 @@ static long tce_iommu_ioctl(void *iommu_data,
return 0;
case VFIO_EEH_PE_OP: {
- struct tce_iommu_group *tcegrp;
- int eeh_enabled;
+ struct tce_iommu_group *tmp, *tcegrp;
+ struct vfio_eeh_pe_op op;
+ int enabled, flag;
+
+ enabled = vfio_spapr_pci_eeh_enabled();
+ if (enabled == VFIO_EEH_DISABLED)
+ return -ENOTTY;
- eeh_enabled = vfio_spapr_pci_eeh_enabled();
- if (eeh_enabled == VFIO_EEH_DISABLED)
+ /* Get the specified version */
+ minsz = offsetofend(struct vfio_eeh_pe_op, flags);
+ if (copy_from_user(&op, (void __user *)arg, minsz))
+ return -EFAULT;
+ flag = (op.flags & VFIO_EEH_ENABLED_MASK);
+ if (flag > enabled)
return -ENOTTY;
+ else if (flag == VFIO_EEH_DISABLED)
+ flag = VFIO_EEH_ENABLED_V1;
+
+ if (flag == VFIO_EEH_ENABLED_V1)
+ minsz = offsetofend(struct vfio_eeh_pe_op, op);
+ else if (flag == VFIO_EEH_ENABLED_V2)
+ minsz = offsetofend(struct vfio_eeh_pe_op, groupid);
+ if (copy_from_user(&op, (void __user *)arg, minsz))
+ return -EFAULT;
+
+ if (op.argsz < minsz)
+ return -EINVAL;
+
+ if (flag == VFIO_EEH_ENABLED_V2) {
+ tcegrp = NULL;
+ list_for_each_entry(tmp, &container->group_list, next) {
+ if (tmp->grp &&
+ iommu_group_id(tmp->grp) == op.groupid) {
+ tcegrp = tmp;
+ break;
+ }
+ }
+
+ if (!tcegrp)
+ return -ENODEV;
+
+ return vfio_spapr_iommu_eeh_ioctl(tcegrp->grp,
+ cmd, arg, &op, flag);
+ }
ret = 0;
list_for_each_entry(tcegrp, &container->group_list, next) {
ret = vfio_spapr_iommu_eeh_ioctl(tcegrp->grp,
- cmd, arg);
+ cmd, arg, &op, flag);
if (ret)
return ret;
}
diff --git a/drivers/vfio/vfio_spapr_eeh.c b/drivers/vfio/vfio_spapr_eeh.c
index d208d77..e77dcb8 100644
--- a/drivers/vfio/vfio_spapr_eeh.c
+++ b/drivers/vfio/vfio_spapr_eeh.c
@@ -20,7 +20,7 @@
int vfio_spapr_pci_eeh_enabled(void)
{
- return VFIO_EEH_ENABLED_V1;
+ return VFIO_EEH_ENABLED_V2;
}
EXPORT_SYMBOL_GPL(vfio_spapr_pci_eeh_enabled);
@@ -38,11 +38,12 @@ void vfio_spapr_pci_eeh_release(struct pci_dev *pdev)
EXPORT_SYMBOL_GPL(vfio_spapr_pci_eeh_release);
long vfio_spapr_iommu_eeh_ioctl(struct iommu_group *group,
- unsigned int cmd, unsigned long arg)
+ unsigned int cmd, unsigned long arg,
+ void *parm, int flag)
{
struct eeh_pe *pe;
- struct vfio_eeh_pe_op op;
- unsigned long minsz;
+ struct vfio_eeh_pe_op *op;
+ unsigned long src, dst, len;
long ret = -EINVAL;
switch (cmd) {
@@ -54,17 +55,12 @@ long vfio_spapr_iommu_eeh_ioctl(struct iommu_group *group,
ret = 0;
break;
case VFIO_EEH_PE_OP:
+ op = (struct vfio_eeh_pe_op *)parm;
pe = eeh_iommu_group_to_pe(group);
if (!pe)
return -ENODEV;
- minsz = offsetofend(struct vfio_eeh_pe_op, op);
- if (copy_from_user(&op, (void __user *)arg, minsz))
- return -EFAULT;
- if (op.argsz < minsz || op.flags)
- return -EINVAL;
-
- switch (op.op) {
+ switch (op->op) {
case VFIO_EEH_PE_DISABLE:
ret = eeh_pe_set_option(pe, EEH_OPT_DISABLE);
break;
@@ -93,14 +89,25 @@ long vfio_spapr_iommu_eeh_ioctl(struct iommu_group *group,
ret = eeh_pe_configure(pe);
break;
case VFIO_EEH_PE_INJECT_ERR:
- minsz = offsetofend(struct vfio_eeh_pe_op, err.mask);
- if (op.argsz < minsz)
+ if (flag == VFIO_EEH_ENABLED_V1)
+ src = offsetofend(struct vfio_eeh_pe_op, op);
+ else if (flag == VFIO_EEH_ENABLED_V2)
+ src = offsetofend(struct vfio_eeh_pe_op,
+ groupid);
+ else
+ return -ENOTTY;
+
+ len = sizeof(struct vfio_eeh_pe_err);
+ if (op->argsz < src + len)
return -EINVAL;
- if (copy_from_user(&op, (void __user *)arg, minsz))
+
+ dst = offsetofend(struct vfio_eeh_pe_op, groupid);
+ if (copy_from_user(parm + dst,
+ (void __user *)(arg + src), len))
return -EFAULT;
- ret = eeh_pe_inject_err(pe, op.err.type, op.err.func,
- op.err.addr, op.err.mask);
+ ret = eeh_pe_inject_err(pe, op->err.type, op->err.func,
+ op->err.addr, op->err.mask);
break;
default:
ret = -EINVAL;
diff --git a/include/linux/vfio.h b/include/linux/vfio.h
index ff036ca..c004307 100644
--- a/include/linux/vfio.h
+++ b/include/linux/vfio.h
@@ -95,8 +95,8 @@ extern int vfio_spapr_pci_eeh_enabled(void);
extern void vfio_spapr_pci_eeh_open(struct pci_dev *pdev);
extern void vfio_spapr_pci_eeh_release(struct pci_dev *pdev);
extern long vfio_spapr_iommu_eeh_ioctl(struct iommu_group *group,
- unsigned int cmd,
- unsigned long arg);
+ unsigned int cmd, unsigned long arg,
+ void *param, int flag);
#else
static inline int vfio_spapr_pci_eeh_enabled(void)
{
@@ -113,7 +113,8 @@ static inline void vfio_spapr_pci_eeh_release(struct pci_dev *pdev)
static inline long vfio_spapr_iommu_eeh_ioctl(struct iommu_group *group,
unsigned int cmd,
- unsigned long arg)
+ unsigned long arg,
+ void *param, int flag)
{
return -ENOTTY;
}
diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
index 74f5b8b..66ded6b 100644
--- a/include/uapi/linux/vfio.h
+++ b/include/uapi/linux/vfio.h
@@ -497,6 +497,7 @@ struct vfio_iommu_spapr_tce_info {
*/
#define VFIO_EEH_DISABLED 0
#define VFIO_EEH_ENABLED_V1 1
+#define VFIO_EEH_ENABLED_V2 2
struct vfio_eeh_pe_err {
__u32 type;
@@ -508,7 +509,9 @@ struct vfio_eeh_pe_err {
struct vfio_eeh_pe_op {
__u32 argsz;
__u32 flags;
+#define VFIO_EEH_ENABLED_MASK 0xFF
__u32 op;
+ __u32 groupid;
union {
struct vfio_eeh_pe_err err;
};
--
2.1.0
next prev parent reply other threads:[~2015-09-18 6:25 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-09-18 6:24 [PATCH 0/2] VFIO: Accept IOMMU group (PE) ID Gavin Shan
2015-09-18 6:24 ` [PATCH 1/2] drivers/vfio: Support EEH API revision Gavin Shan
2015-09-18 6:24 ` Gavin Shan [this message]
2015-09-18 15:47 ` [PATCH 0/2] VFIO: Accept IOMMU group (PE) ID Alex Williamson
2015-09-19 6:22 ` David Gibson
2015-09-21 1:42 ` David Gibson
2015-09-21 5:21 ` Gavin Shan
2015-09-21 12:11 ` Gavin Shan
2015-09-21 16:41 ` Alex Williamson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1442557469-22185-3-git-send-email-gwshan@linux.vnet.ibm.com \
--to=gwshan@linux.vnet.ibm.com \
--cc=alex.williamson@redhat.com \
--cc=david@gibson.dropbear.id.au \
--cc=kvm-ppc@vger.kernel.org \
--cc=kvm@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).