summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHalil Pasic <pasic@linux.vnet.ibm.com>2017-07-27 17:48:42 +0200
committerCornelia Huck <cohuck@redhat.com>2017-07-28 10:06:25 +0200
commit198c0d1f9df8c429502cb744fc26b6ba6e71db74 (patch)
tree3066c448ac8e007229fc6b36d803745334fb7f93
parent98987d30b636b1d066eae73178cce71638c20c74 (diff)
s390x/css: check ccw address validity
According to the PoP channel command words (CCW) must be doubleword aligned and 31 bit addressable for format 1 and 24 bit addressable for format 0 CCWs. If the channel subsystem encounters a ccw address which does not satisfy this alignment requirement a program-check condition is recognised. The situation with 31 bit addressable is a bit more complicated: both the ORB and a format 1 CCW TIC hold the address of (the rest of) the channel program, that is the address of the next CCW in a word, and the PoP mandates that bit 0 of that word shall be zero -- or a program-check condition is to be recognized -- and does not belong to the field holding the ccw address. Since in code the corresponding fields span across the whole word (unlike in PoP where these are defined as 31 bit wide) we can check this by applying a mask. The 24 addressable case isn't affecting TIC because the address is composed of a halfword and a byte portion (no additional zero bit requirements) and just slightly complicates the ORB case where also bits 1-7 need to be zero. The same requirements (especially n-bit addressability) apply to the ccw addresses generated while chaining. Let's make our CSS implementation follow the AR more closely. Signed-off-by: Halil Pasic <pasic@linux.vnet.ibm.com> Message-Id: <20170727154842.23427-1-pasic@linux.vnet.ibm.com> Reviewed-by: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
-rw-r--r--hw/s390x/css.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index 6a42b95cee..177cbfc92d 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -795,6 +795,10 @@ static int css_interpret_ccw(SubchDev *sch, hwaddr ccw_addr,
if (!ccw_addr) {
return -EIO;
}
+ /* Check doubleword aligned and 31 or 24 (fmt 0) bit addressable. */
+ if (ccw_addr & (sch->ccw_fmt_1 ? 0x80000007 : 0xff000007)) {
+ return -EINVAL;
+ }
/* Translate everything to format-1 ccws - the information is the same. */
ccw = copy_ccw_from_guest(ccw_addr, sch->ccw_fmt_1);