s390x/css: Add passthrough IRB
Wire in the subchannel callback for building the IRB ESW and ECW space for passthrough devices, and copy the hardware's ESW into the IRB we are building. If the hardware presented concurrent sense, then copy that sense data into the IRB's ECW space. Signed-off-by: Eric Farman <farman@linux.ibm.com> Message-Id: <20210617232537.1337506-5-farman@linux.ibm.com> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
This commit is contained in:
parent
0599a046ac
commit
c626710fc7
@ -1335,7 +1335,7 @@ static void copy_schib_to_guest(SCHIB *dest, const SCHIB *src)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void copy_esw_to_guest(ESW *dest, const ESW *src)
|
void copy_esw_to_guest(ESW *dest, const ESW *src)
|
||||||
{
|
{
|
||||||
dest->word0 = cpu_to_be32(src->word0);
|
dest->word0 = cpu_to_be32(src->word0);
|
||||||
dest->erw = cpu_to_be32(src->erw);
|
dest->erw = cpu_to_be32(src->erw);
|
||||||
@ -1650,6 +1650,20 @@ static void build_irb_sense_data(SubchDev *sch, IRB *irb)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void build_irb_passthrough(SubchDev *sch, IRB *irb)
|
||||||
|
{
|
||||||
|
/* Copy ESW from hardware */
|
||||||
|
irb->esw = sch->esw;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If (irb->esw.erw & ESW_ERW_SENSE) is true, then the contents
|
||||||
|
* of the ECW is sense data. If false, then it is model-dependent
|
||||||
|
* information. Either way, copy it into the IRB for the guest to
|
||||||
|
* read/decide what to do with.
|
||||||
|
*/
|
||||||
|
build_irb_sense_data(sch, irb);
|
||||||
|
}
|
||||||
|
|
||||||
void build_irb_virtual(SubchDev *sch, IRB *irb)
|
void build_irb_virtual(SubchDev *sch, IRB *irb)
|
||||||
{
|
{
|
||||||
SCHIB *schib = &sch->curr_status;
|
SCHIB *schib = &sch->curr_status;
|
||||||
|
@ -124,6 +124,7 @@ static void s390_ccw_realize(S390CCWDevice *cdev, char *sysfsdev, Error **errp)
|
|||||||
}
|
}
|
||||||
sch->driver_data = cdev;
|
sch->driver_data = cdev;
|
||||||
sch->do_subchannel_work = do_subchannel_work_passthrough;
|
sch->do_subchannel_work = do_subchannel_work_passthrough;
|
||||||
|
sch->irb_cb = build_irb_passthrough;
|
||||||
|
|
||||||
ccw_dev->sch = sch;
|
ccw_dev->sch = sch;
|
||||||
ret = css_sch_build_schib(sch, &cdev->hostid);
|
ret = css_sch_build_schib(sch, &cdev->hostid);
|
||||||
|
@ -321,6 +321,7 @@ static void vfio_ccw_io_notifier_handler(void *opaque)
|
|||||||
SCHIB *schib = &sch->curr_status;
|
SCHIB *schib = &sch->curr_status;
|
||||||
SCSW s;
|
SCSW s;
|
||||||
IRB irb;
|
IRB irb;
|
||||||
|
ESW esw;
|
||||||
int size;
|
int size;
|
||||||
|
|
||||||
if (!event_notifier_test_and_clear(&vcdev->io_notifier)) {
|
if (!event_notifier_test_and_clear(&vcdev->io_notifier)) {
|
||||||
@ -371,6 +372,9 @@ static void vfio_ccw_io_notifier_handler(void *opaque)
|
|||||||
copy_scsw_to_guest(&s, &irb.scsw);
|
copy_scsw_to_guest(&s, &irb.scsw);
|
||||||
schib->scsw = s;
|
schib->scsw = s;
|
||||||
|
|
||||||
|
copy_esw_to_guest(&esw, &irb.esw);
|
||||||
|
sch->esw = esw;
|
||||||
|
|
||||||
/* If a uint check is pending, copy sense data. */
|
/* If a uint check is pending, copy sense data. */
|
||||||
if ((schib->scsw.dstat & SCSW_DSTAT_UNIT_CHECK) &&
|
if ((schib->scsw.dstat & SCSW_DSTAT_UNIT_CHECK) &&
|
||||||
(schib->pmcw.chars & PMCW_CHARS_MASK_CSENSE)) {
|
(schib->pmcw.chars & PMCW_CHARS_MASK_CSENSE)) {
|
||||||
|
@ -141,6 +141,7 @@ struct SubchDev {
|
|||||||
void (*irb_cb)(SubchDev *, IRB *);
|
void (*irb_cb)(SubchDev *, IRB *);
|
||||||
SenseId id;
|
SenseId id;
|
||||||
void *driver_data;
|
void *driver_data;
|
||||||
|
ESW esw;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline void sch_gen_unit_exception(SubchDev *sch)
|
static inline void sch_gen_unit_exception(SubchDev *sch)
|
||||||
@ -202,6 +203,7 @@ int css_sch_build_schib(SubchDev *sch, CssDevId *dev_id);
|
|||||||
unsigned int css_find_free_chpid(uint8_t cssid);
|
unsigned int css_find_free_chpid(uint8_t cssid);
|
||||||
uint16_t css_build_subchannel_id(SubchDev *sch);
|
uint16_t css_build_subchannel_id(SubchDev *sch);
|
||||||
void copy_scsw_to_guest(SCSW *dest, const SCSW *src);
|
void copy_scsw_to_guest(SCSW *dest, const SCSW *src);
|
||||||
|
void copy_esw_to_guest(ESW *dest, const ESW *src);
|
||||||
void css_inject_io_interrupt(SubchDev *sch);
|
void css_inject_io_interrupt(SubchDev *sch);
|
||||||
void css_reset(void);
|
void css_reset(void);
|
||||||
void css_reset_sch(SubchDev *sch);
|
void css_reset_sch(SubchDev *sch);
|
||||||
@ -216,6 +218,7 @@ void css_clear_sei_pending(void);
|
|||||||
IOInstEnding s390_ccw_cmd_request(SubchDev *sch);
|
IOInstEnding s390_ccw_cmd_request(SubchDev *sch);
|
||||||
IOInstEnding do_subchannel_work_virtual(SubchDev *sub);
|
IOInstEnding do_subchannel_work_virtual(SubchDev *sub);
|
||||||
IOInstEnding do_subchannel_work_passthrough(SubchDev *sub);
|
IOInstEnding do_subchannel_work_passthrough(SubchDev *sub);
|
||||||
|
void build_irb_passthrough(SubchDev *sch, IRB *irb);
|
||||||
void build_irb_virtual(SubchDev *sch, IRB *irb);
|
void build_irb_virtual(SubchDev *sch, IRB *irb);
|
||||||
|
|
||||||
int s390_ccw_halt(SubchDev *sch);
|
int s390_ccw_halt(SubchDev *sch);
|
||||||
|
Loading…
Reference in New Issue
Block a user