Skip to content

Commit

Permalink
Merge tag 'vfio-ccw-20190717-2' of https://git.kernel.org/pub/scm/lin…
Browse files Browse the repository at this point in the history
…ux/kernel/git/kvms390/vfio-ccw into fixes

Fixes in vfio-ccw for older and newer issues.
  • Loading branch information
heicarst committed Jul 23, 2019
2 parents 69e9620 + 4c4cbba commit eed3419
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 15 deletions.
31 changes: 28 additions & 3 deletions Documentation/s390/vfio-ccw.rst
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,13 @@ The process of how these work together.
add it to an iommu_group and a vfio_group. Then we could pass through
the mdev to a guest.


VFIO-CCW Regions
----------------

The vfio-ccw driver exposes MMIO regions to accept requests from and return
results to userspace.

vfio-ccw I/O region
-------------------

Expand All @@ -205,6 +212,25 @@ irb_area stores the I/O result.

ret_code stores a return code for each access of the region.

This region is always available.

vfio-ccw cmd region
-------------------

The vfio-ccw cmd region is used to accept asynchronous instructions
from userspace::

#define VFIO_CCW_ASYNC_CMD_HSCH (1 << 0)
#define VFIO_CCW_ASYNC_CMD_CSCH (1 << 1)
struct ccw_cmd_region {
__u32 command;
__u32 ret_code;
} __packed;

This region is exposed via region type VFIO_REGION_SUBTYPE_CCW_ASYNC_CMD.

Currently, CLEAR SUBCHANNEL and HALT SUBCHANNEL use this region.

vfio-ccw operation details
--------------------------

Expand Down Expand Up @@ -306,9 +332,8 @@ Together with the corresponding work in QEMU, we can bring the passed
through DASD/ECKD device online in a guest now and use it as a block
device.

While the current code allows the guest to start channel programs via
START SUBCHANNEL, support for HALT SUBCHANNEL or CLEAR SUBCHANNEL is
not yet implemented.
The current code allows the guest to start channel programs via
START SUBCHANNEL, and to issue HALT SUBCHANNEL and CLEAR SUBCHANNEL.

vfio-ccw supports classic (command mode) channel I/O only. Transport
mode (HPF) is not supported.
Expand Down
28 changes: 17 additions & 11 deletions drivers/s390/cio/vfio_ccw_cp.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,10 @@ static int pfn_array_alloc(struct pfn_array *pa, u64 iova, unsigned int len)
sizeof(*pa->pa_iova_pfn) +
sizeof(*pa->pa_pfn),
GFP_KERNEL);
if (unlikely(!pa->pa_iova_pfn))
if (unlikely(!pa->pa_iova_pfn)) {
pa->pa_nr = 0;
return -ENOMEM;
}
pa->pa_pfn = pa->pa_iova_pfn + pa->pa_nr;

pa->pa_iova_pfn[0] = pa->pa_iova >> PAGE_SHIFT;
Expand Down Expand Up @@ -421,7 +423,7 @@ static int ccwchain_loop_tic(struct ccwchain *chain,
static int ccwchain_handle_ccw(u32 cda, struct channel_program *cp)
{
struct ccwchain *chain;
int len;
int len, ret;

/* Copy 2K (the most we support today) of possible CCWs */
len = copy_from_iova(cp->mdev, cp->guest_cp, cda,
Expand All @@ -448,7 +450,12 @@ static int ccwchain_handle_ccw(u32 cda, struct channel_program *cp)
memcpy(chain->ch_ccw, cp->guest_cp, len * sizeof(struct ccw1));

/* Loop for tics on this new chain. */
return ccwchain_loop_tic(chain, cp);
ret = ccwchain_loop_tic(chain, cp);

if (ret)
ccwchain_free(chain);

return ret;
}

/* Loop for TICs. */
Expand Down Expand Up @@ -642,17 +649,16 @@ int cp_init(struct channel_program *cp, struct device *mdev, union orb *orb)

/* Build a ccwchain for the first CCW segment */
ret = ccwchain_handle_ccw(orb->cmd.cpa, cp);
if (ret)
cp_free(cp);

/* It is safe to force: if not set but idals used
* ccwchain_calc_length returns an error.
*/
cp->orb.cmd.c64 = 1;

if (!ret)
if (!ret) {
cp->initialized = true;

/* It is safe to force: if it was not set but idals used
* ccwchain_calc_length would have returned an error.
*/
cp->orb.cmd.c64 = 1;
}

return ret;
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/s390/cio/vfio_ccw_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ static void vfio_ccw_sch_io_todo(struct work_struct *work)
(SCSW_ACTL_DEVACT | SCSW_ACTL_SCHACT));
if (scsw_is_solicited(&irb->scsw)) {
cp_update_scsw(&private->cp, &irb->scsw);
if (is_final)
if (is_final && private->state == VFIO_CCW_STATE_CP_PENDING)
cp_free(&private->cp);
}
mutex_lock(&private->io_mutex);
Expand Down

0 comments on commit eed3419

Please sign in to comment.