mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-09 18:44:58 -06:00
s390x: improve error handling for SSCH and RSCH
Simplify the error handling of the SSCH and RSCH handler avoiding arbitrary and cryptic error codes being used to tell how the instruction is supposed to end. Let the code detecting the condition tell how it's to be handled in a less ambiguous way. It's best to handle SSCH and RSCH in one go as the emulation of the two shares a lot of code. For passthrough this change isn't pure refactoring, but changes the way kernel reported EFAULT is handled. After clarifying the kernel interface we decided that EFAULT shall be mapped to unit exception. Same goes for unexpected error codes and absence of required ORB flags. Signed-off-by: Halil Pasic <pasic@linux.vnet.ibm.com> Message-Id: <20171017140453.51099-4-pasic@linux.vnet.ibm.com> Tested-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com> [CH: cosmetic changes] Reviewed-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
This commit is contained in:
parent
e443ef9f21
commit
66dc50f705
6 changed files with 75 additions and 126 deletions
|
@ -47,9 +47,9 @@ struct VFIODeviceOps vfio_ccw_ops = {
|
|||
.vfio_compute_needs_reset = vfio_ccw_compute_needs_reset,
|
||||
};
|
||||
|
||||
static int vfio_ccw_handle_request(ORB *orb, SCSW *scsw, void *data)
|
||||
static IOInstEnding vfio_ccw_handle_request(SubchDev *sch)
|
||||
{
|
||||
S390CCWDevice *cdev = data;
|
||||
S390CCWDevice *cdev = sch->driver_data;
|
||||
VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
|
||||
struct ccw_io_region *region = vcdev->io_region;
|
||||
int ret;
|
||||
|
@ -60,8 +60,8 @@ static int vfio_ccw_handle_request(ORB *orb, SCSW *scsw, void *data)
|
|||
|
||||
memset(region, 0, sizeof(*region));
|
||||
|
||||
memcpy(region->orb_area, orb, sizeof(ORB));
|
||||
memcpy(region->scsw_area, scsw, sizeof(SCSW));
|
||||
memcpy(region->orb_area, &sch->orb, sizeof(ORB));
|
||||
memcpy(region->scsw_area, &sch->curr_status.scsw, sizeof(SCSW));
|
||||
|
||||
again:
|
||||
ret = pwrite(vcdev->vdev.fd, region,
|
||||
|
@ -71,10 +71,24 @@ again:
|
|||
goto again;
|
||||
}
|
||||
error_report("vfio-ccw: wirte I/O region failed with errno=%d", errno);
|
||||
return -errno;
|
||||
ret = -errno;
|
||||
} else {
|
||||
ret = region->ret_code;
|
||||
}
|
||||
switch (ret) {
|
||||
case 0:
|
||||
return IOINST_CC_EXPECTED;
|
||||
case -EBUSY:
|
||||
return IOINST_CC_BUSY;
|
||||
case -ENODEV:
|
||||
case -EACCES:
|
||||
return IOINST_CC_NOT_OPERATIONAL;
|
||||
case -EFAULT:
|
||||
default:
|
||||
sch_gen_unit_exception(sch);
|
||||
css_inject_io_interrupt(sch);
|
||||
return IOINST_CC_EXPECTED;
|
||||
}
|
||||
|
||||
return region->ret_code;
|
||||
}
|
||||
|
||||
static void vfio_ccw_reset(DeviceState *dev)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue