提交 eed34197 编写于 作者: H Heiko Carstens

Merge tag 'vfio-ccw-20190717-2' of...

Merge tag 'vfio-ccw-20190717-2' of https://git.kernel.org/pub/scm/linux/kernel/git/kvms390/vfio-ccw into fixes

Fixes in vfio-ccw for older and newer issues.
...@@ -180,6 +180,13 @@ The process of how these work together. ...@@ -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 add it to an iommu_group and a vfio_group. Then we could pass through
the mdev to a guest. 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 vfio-ccw I/O region
------------------- -------------------
...@@ -205,6 +212,25 @@ irb_area stores the I/O result. ...@@ -205,6 +212,25 @@ irb_area stores the I/O result.
ret_code stores a return code for each access of the region. 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 vfio-ccw operation details
-------------------------- --------------------------
...@@ -306,9 +332,8 @@ Together with the corresponding work in QEMU, we can bring the passed ...@@ -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 through DASD/ECKD device online in a guest now and use it as a block
device. device.
While the current code allows the guest to start channel programs via The current code allows the guest to start channel programs via
START SUBCHANNEL, support for HALT SUBCHANNEL or CLEAR SUBCHANNEL is START SUBCHANNEL, and to issue HALT SUBCHANNEL and CLEAR SUBCHANNEL.
not yet implemented.
vfio-ccw supports classic (command mode) channel I/O only. Transport vfio-ccw supports classic (command mode) channel I/O only. Transport
mode (HPF) is not supported. mode (HPF) is not supported.
......
...@@ -72,8 +72,10 @@ static int pfn_array_alloc(struct pfn_array *pa, u64 iova, unsigned int len) ...@@ -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_iova_pfn) +
sizeof(*pa->pa_pfn), sizeof(*pa->pa_pfn),
GFP_KERNEL); GFP_KERNEL);
if (unlikely(!pa->pa_iova_pfn)) if (unlikely(!pa->pa_iova_pfn)) {
pa->pa_nr = 0;
return -ENOMEM; return -ENOMEM;
}
pa->pa_pfn = pa->pa_iova_pfn + pa->pa_nr; pa->pa_pfn = pa->pa_iova_pfn + pa->pa_nr;
pa->pa_iova_pfn[0] = pa->pa_iova >> PAGE_SHIFT; pa->pa_iova_pfn[0] = pa->pa_iova >> PAGE_SHIFT;
...@@ -421,7 +423,7 @@ static int ccwchain_loop_tic(struct ccwchain *chain, ...@@ -421,7 +423,7 @@ 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 ccwchain *chain; struct ccwchain *chain;
int len; 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(cp->mdev, cp->guest_cp, cda,
...@@ -448,7 +450,12 @@ static int ccwchain_handle_ccw(u32 cda, struct channel_program *cp) ...@@ -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)); memcpy(chain->ch_ccw, cp->guest_cp, len * sizeof(struct ccw1));
/* Loop for tics on this new chain. */ /* 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. */ /* Loop for TICs. */
...@@ -642,17 +649,16 @@ int cp_init(struct channel_program *cp, struct device *mdev, union orb *orb) ...@@ -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 */ /* Build a ccwchain for the first CCW segment */
ret = ccwchain_handle_ccw(orb->cmd.cpa, cp); 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; 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; return ret;
} }
......
...@@ -88,7 +88,7 @@ static void vfio_ccw_sch_io_todo(struct work_struct *work) ...@@ -88,7 +88,7 @@ static void vfio_ccw_sch_io_todo(struct work_struct *work)
(SCSW_ACTL_DEVACT | SCSW_ACTL_SCHACT)); (SCSW_ACTL_DEVACT | SCSW_ACTL_SCHACT));
if (scsw_is_solicited(&irb->scsw)) { if (scsw_is_solicited(&irb->scsw)) {
cp_update_scsw(&private->cp, &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); cp_free(&private->cp);
} }
mutex_lock(&private->io_mutex); mutex_lock(&private->io_mutex);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册