Commit 0a587956 authored by Jason Gunthorpe's avatar Jason Gunthorpe Committed by Alex Williamson

vfio/ccw: Remove mdev from struct channel_program

The next patch wants the vfio_device instead. There is no reason to store
a pointer here since we can container_of back to the vfio_device.
Reviewed-by: default avatarEric Farman <farman@linux.ibm.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
Link: https://lore.kernel.org/r/2-v4-8045e76bf00b+13d-vfio_mdev_no_group_jgg@nvidia.comSigned-off-by: default avatarAlex Williamson <alex.williamson@redhat.com>
parent 09ea48ef
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <asm/idals.h> #include <asm/idals.h>
#include "vfio_ccw_cp.h" #include "vfio_ccw_cp.h"
#include "vfio_ccw_private.h"
struct pfn_array { struct pfn_array {
/* Starting guest physical I/O address. */ /* Starting guest physical I/O address. */
...@@ -98,17 +99,17 @@ static int pfn_array_alloc(struct pfn_array *pa, u64 iova, unsigned int len) ...@@ -98,17 +99,17 @@ static int pfn_array_alloc(struct pfn_array *pa, u64 iova, unsigned int len)
* If the pin request partially succeeds, or fails completely, * If the pin request partially succeeds, or fails completely,
* all pages are left unpinned and a negative error value is returned. * all pages are left unpinned and a negative error value is returned.
*/ */
static int pfn_array_pin(struct pfn_array *pa, struct device *mdev) static int pfn_array_pin(struct pfn_array *pa, struct vfio_device *vdev)
{ {
int ret = 0; int ret = 0;
ret = vfio_pin_pages(mdev, pa->pa_iova_pfn, pa->pa_nr, ret = vfio_pin_pages(vdev->dev, pa->pa_iova_pfn, pa->pa_nr,
IOMMU_READ | IOMMU_WRITE, pa->pa_pfn); IOMMU_READ | IOMMU_WRITE, pa->pa_pfn);
if (ret < 0) { if (ret < 0) {
goto err_out; goto err_out;
} else if (ret > 0 && ret != pa->pa_nr) { } else if (ret > 0 && ret != pa->pa_nr) {
vfio_unpin_pages(mdev, pa->pa_iova_pfn, ret); vfio_unpin_pages(vdev->dev, pa->pa_iova_pfn, ret);
ret = -EINVAL; ret = -EINVAL;
goto err_out; goto err_out;
} }
...@@ -122,11 +123,11 @@ static int pfn_array_pin(struct pfn_array *pa, struct device *mdev) ...@@ -122,11 +123,11 @@ static int pfn_array_pin(struct pfn_array *pa, struct device *mdev)
} }
/* Unpin the pages before releasing the memory. */ /* Unpin the pages before releasing the memory. */
static void pfn_array_unpin_free(struct pfn_array *pa, struct device *mdev) static void pfn_array_unpin_free(struct pfn_array *pa, struct vfio_device *vdev)
{ {
/* Only unpin if any pages were pinned to begin with */ /* Only unpin if any pages were pinned to begin with */
if (pa->pa_nr) if (pa->pa_nr)
vfio_unpin_pages(mdev, pa->pa_iova_pfn, pa->pa_nr); vfio_unpin_pages(vdev->dev, pa->pa_iova_pfn, pa->pa_nr);
pa->pa_nr = 0; pa->pa_nr = 0;
kfree(pa->pa_iova_pfn); kfree(pa->pa_iova_pfn);
} }
...@@ -190,8 +191,7 @@ static void convert_ccw0_to_ccw1(struct ccw1 *source, unsigned long len) ...@@ -190,8 +191,7 @@ static void convert_ccw0_to_ccw1(struct ccw1 *source, unsigned long len)
* Within the domain (@mdev), copy @n bytes from a guest physical * Within the domain (@mdev), copy @n bytes from a guest physical
* address (@iova) to a host physical address (@to). * address (@iova) to a host physical address (@to).
*/ */
static long copy_from_iova(struct device *mdev, static long copy_from_iova(struct vfio_device *vdev, void *to, u64 iova,
void *to, u64 iova,
unsigned long n) unsigned long n)
{ {
struct pfn_array pa = {0}; struct pfn_array pa = {0};
...@@ -203,9 +203,9 @@ static long copy_from_iova(struct device *mdev, ...@@ -203,9 +203,9 @@ static long copy_from_iova(struct device *mdev,
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = pfn_array_pin(&pa, mdev); ret = pfn_array_pin(&pa, vdev);
if (ret < 0) { if (ret < 0) {
pfn_array_unpin_free(&pa, mdev); pfn_array_unpin_free(&pa, vdev);
return ret; return ret;
} }
...@@ -226,7 +226,7 @@ static long copy_from_iova(struct device *mdev, ...@@ -226,7 +226,7 @@ static long copy_from_iova(struct device *mdev,
break; break;
} }
pfn_array_unpin_free(&pa, mdev); pfn_array_unpin_free(&pa, vdev);
return l; return l;
} }
...@@ -423,11 +423,13 @@ static int ccwchain_loop_tic(struct ccwchain *chain, ...@@ -423,11 +423,13 @@ static int ccwchain_loop_tic(struct ccwchain *chain,
static int ccwchain_handle_ccw(u32 cda, struct channel_program *cp) static int ccwchain_handle_ccw(u32 cda, struct channel_program *cp)
{ {
struct vfio_device *vdev =
&container_of(cp, struct vfio_ccw_private, cp)->vdev;
struct ccwchain *chain; struct ccwchain *chain;
int len, ret; int len, ret;
/* Copy 2K (the most we support today) of possible CCWs */ /* Copy 2K (the most we support today) of possible CCWs */
len = copy_from_iova(cp->mdev, cp->guest_cp, cda, len = copy_from_iova(vdev, cp->guest_cp, cda,
CCWCHAIN_LEN_MAX * sizeof(struct ccw1)); CCWCHAIN_LEN_MAX * sizeof(struct ccw1));
if (len) if (len)
return len; return len;
...@@ -508,6 +510,8 @@ static int ccwchain_fetch_direct(struct ccwchain *chain, ...@@ -508,6 +510,8 @@ static int ccwchain_fetch_direct(struct ccwchain *chain,
int idx, int idx,
struct channel_program *cp) struct channel_program *cp)
{ {
struct vfio_device *vdev =
&container_of(cp, struct vfio_ccw_private, cp)->vdev;
struct ccw1 *ccw; struct ccw1 *ccw;
struct pfn_array *pa; struct pfn_array *pa;
u64 iova; u64 iova;
...@@ -526,7 +530,7 @@ static int ccwchain_fetch_direct(struct ccwchain *chain, ...@@ -526,7 +530,7 @@ static int ccwchain_fetch_direct(struct ccwchain *chain,
if (ccw_is_idal(ccw)) { if (ccw_is_idal(ccw)) {
/* Read first IDAW to see if it's 4K-aligned or not. */ /* Read first IDAW to see if it's 4K-aligned or not. */
/* All subsequent IDAws will be 4K-aligned. */ /* All subsequent IDAws will be 4K-aligned. */
ret = copy_from_iova(cp->mdev, &iova, ccw->cda, sizeof(iova)); ret = copy_from_iova(vdev, &iova, ccw->cda, sizeof(iova));
if (ret) if (ret)
return ret; return ret;
} else { } else {
...@@ -555,7 +559,7 @@ static int ccwchain_fetch_direct(struct ccwchain *chain, ...@@ -555,7 +559,7 @@ static int ccwchain_fetch_direct(struct ccwchain *chain,
if (ccw_is_idal(ccw)) { if (ccw_is_idal(ccw)) {
/* Copy guest IDAL into host IDAL */ /* Copy guest IDAL into host IDAL */
ret = copy_from_iova(cp->mdev, idaws, ccw->cda, idal_len); ret = copy_from_iova(vdev, idaws, ccw->cda, idal_len);
if (ret) if (ret)
goto out_unpin; goto out_unpin;
...@@ -574,7 +578,7 @@ static int ccwchain_fetch_direct(struct ccwchain *chain, ...@@ -574,7 +578,7 @@ static int ccwchain_fetch_direct(struct ccwchain *chain,
} }
if (ccw_does_data_transfer(ccw)) { if (ccw_does_data_transfer(ccw)) {
ret = pfn_array_pin(pa, cp->mdev); ret = pfn_array_pin(pa, vdev);
if (ret < 0) if (ret < 0)
goto out_unpin; goto out_unpin;
} else { } else {
...@@ -590,7 +594,7 @@ static int ccwchain_fetch_direct(struct ccwchain *chain, ...@@ -590,7 +594,7 @@ static int ccwchain_fetch_direct(struct ccwchain *chain,
return 0; return 0;
out_unpin: out_unpin:
pfn_array_unpin_free(pa, cp->mdev); pfn_array_unpin_free(pa, vdev);
out_free_idaws: out_free_idaws:
kfree(idaws); kfree(idaws);
out_init: out_init:
...@@ -632,8 +636,10 @@ static int ccwchain_fetch_one(struct ccwchain *chain, ...@@ -632,8 +636,10 @@ static int ccwchain_fetch_one(struct ccwchain *chain,
* Returns: * Returns:
* %0 on success and a negative error value on failure. * %0 on success and a negative error value on failure.
*/ */
int cp_init(struct channel_program *cp, struct device *mdev, union orb *orb) int cp_init(struct channel_program *cp, union orb *orb)
{ {
struct vfio_device *vdev =
&container_of(cp, struct vfio_ccw_private, cp)->vdev;
/* custom ratelimit used to avoid flood during guest IPL */ /* custom ratelimit used to avoid flood during guest IPL */
static DEFINE_RATELIMIT_STATE(ratelimit_state, 5 * HZ, 1); static DEFINE_RATELIMIT_STATE(ratelimit_state, 5 * HZ, 1);
int ret; int ret;
...@@ -650,11 +656,12 @@ int cp_init(struct channel_program *cp, struct device *mdev, union orb *orb) ...@@ -650,11 +656,12 @@ int cp_init(struct channel_program *cp, struct device *mdev, union orb *orb)
* the problem if something does break. * the problem if something does break.
*/ */
if (!orb->cmd.pfch && __ratelimit(&ratelimit_state)) if (!orb->cmd.pfch && __ratelimit(&ratelimit_state))
dev_warn(mdev, "Prefetching channel program even though prefetch not specified in ORB"); dev_warn(
vdev->dev,
"Prefetching channel program even though prefetch not specified in ORB");
INIT_LIST_HEAD(&cp->ccwchain_list); INIT_LIST_HEAD(&cp->ccwchain_list);
memcpy(&cp->orb, orb, sizeof(*orb)); memcpy(&cp->orb, orb, sizeof(*orb));
cp->mdev = mdev;
/* Build a ccwchain for the first CCW segment */ /* Build a ccwchain for the first CCW segment */
ret = ccwchain_handle_ccw(orb->cmd.cpa, cp); ret = ccwchain_handle_ccw(orb->cmd.cpa, cp);
...@@ -682,6 +689,8 @@ int cp_init(struct channel_program *cp, struct device *mdev, union orb *orb) ...@@ -682,6 +689,8 @@ int cp_init(struct channel_program *cp, struct device *mdev, union orb *orb)
*/ */
void cp_free(struct channel_program *cp) void cp_free(struct channel_program *cp)
{ {
struct vfio_device *vdev =
&container_of(cp, struct vfio_ccw_private, cp)->vdev;
struct ccwchain *chain, *temp; struct ccwchain *chain, *temp;
int i; int i;
...@@ -691,7 +700,7 @@ void cp_free(struct channel_program *cp) ...@@ -691,7 +700,7 @@ void cp_free(struct channel_program *cp)
cp->initialized = false; cp->initialized = false;
list_for_each_entry_safe(chain, temp, &cp->ccwchain_list, next) { list_for_each_entry_safe(chain, temp, &cp->ccwchain_list, next) {
for (i = 0; i < chain->ch_len; i++) { for (i = 0; i < chain->ch_len; i++) {
pfn_array_unpin_free(chain->ch_pa + i, cp->mdev); pfn_array_unpin_free(chain->ch_pa + i, vdev);
ccwchain_cda_free(chain, i); ccwchain_cda_free(chain, i);
} }
ccwchain_free(chain); ccwchain_free(chain);
......
...@@ -37,13 +37,11 @@ ...@@ -37,13 +37,11 @@
struct channel_program { struct channel_program {
struct list_head ccwchain_list; struct list_head ccwchain_list;
union orb orb; union orb orb;
struct device *mdev;
bool initialized; bool initialized;
struct ccw1 *guest_cp; struct ccw1 *guest_cp;
}; };
extern int cp_init(struct channel_program *cp, struct device *mdev, extern int cp_init(struct channel_program *cp, union orb *orb);
union orb *orb);
extern void cp_free(struct channel_program *cp); extern void cp_free(struct channel_program *cp);
extern int cp_prefetch(struct channel_program *cp); extern int cp_prefetch(struct channel_program *cp);
extern union orb *cp_get_orb(struct channel_program *cp, u32 intparm, u8 lpm); extern union orb *cp_get_orb(struct channel_program *cp, u32 intparm, u8 lpm);
......
...@@ -262,8 +262,7 @@ static void fsm_io_request(struct vfio_ccw_private *private, ...@@ -262,8 +262,7 @@ static void fsm_io_request(struct vfio_ccw_private *private,
errstr = "transport mode"; errstr = "transport mode";
goto err_out; goto err_out;
} }
io_region->ret_code = cp_init(&private->cp, mdev_dev(mdev), io_region->ret_code = cp_init(&private->cp, orb);
orb);
if (io_region->ret_code) { if (io_region->ret_code) {
VFIO_CCW_MSG_EVENT(2, VFIO_CCW_MSG_EVENT(2,
"%pUl (%x.%x.%04x): cp_init=%d\n", "%pUl (%x.%x.%04x): cp_init=%d\n",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment