On 3/19/21 10:18 AM, Janosch Frank wrote:
On 3/18/21 2:26 PM, Pierre Morel wrote:
Checking error response on various eroneous SSCH instructions:
- ORB alignment
- ORB above 2G
- CCW above 2G
- bad ORB flags
Signed-off-by: Pierre Morel <pmorel@xxxxxxxxxxxxx>
---
s390x/css.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 102 insertions(+)
diff --git a/s390x/css.c b/s390x/css.c
index a6a9773..1c891f8 100644
--- a/s390x/css.c
+++ b/s390x/css.c
@@ -51,6 +51,107 @@ static void test_enable(void)
report(cc == 0, "Enable subchannel %08x", test_device_sid);
}
+static void test_ssch(void)
+{
+ struct orb orb = {
+ .intparm = test_device_sid,
+ .ctrl = ORB_CTRL_ISIC | ORB_CTRL_FMT | ORB_LPM_DFLT,
+ };
+ int i;
+ phys_addr_t base, top;
+
+ assert(css_enable(test_device_sid, IO_SCH_ISC) == 0);
+ assert(register_io_int_func(css_irq_io) == 0);
+
+ /* ORB address should be aligned on 32 bits */
+ report_prefix_push("ORB alignment");
+ expect_pgm_int();
+ ssch(test_device_sid, (void *)0x110002);
+ check_pgm_int_code(PGM_INT_CODE_SPECIFICATION);
+ report_prefix_pop();
+
+ /* ORB address should be lower than 2G */
+ report_prefix_push("ORB Address above 2G");
+ expect_pgm_int();
+ ssch(test_device_sid, (void *)0x80000000);
+ check_pgm_int_code(PGM_INT_CODE_ADDRESSING);
+ report_prefix_pop();
+
+ phys_alloc_get_unused(&base, &top);
+ report_info("base %08lx, top %08lx", base, top);
Please use this function from lib/s390x/sclp.c
uint64_t get_ram_size(void)
{
return ram_size;
}
thanks, I was not aware of this function.
+
+ /* ORB address should be available we check 1G*/
+ report_prefix_push("ORB Address must be available");
+ if (top < 0x40000000) {
+ expect_pgm_int();
+ ssch(test_device_sid, (void *)0x40000000);
+ check_pgm_int_code(PGM_INT_CODE_ADDRESSING);
+ } else {
+ report_skip("guest started with more than 1G memory");
+ }
+ report_prefix_pop();
+
+ report_prefix_push("CCW address above 2G");
+ orb.cpa = 0x80000000;
+ expect_pgm_int();
+ ssch(test_device_sid, &orb);
+ check_pgm_int_code(PGM_INT_CODE_OPERAND);
+ report_prefix_pop();
+
+ senseid = alloc_io_mem(sizeof(*senseid), 0);
+ assert(senseid);
+ orb.cpa = (uint64_t)ccw_alloc(CCW_CMD_SENSE_ID, senseid,
+ sizeof(*senseid), CCW_F_SLI);
+ assert(orb.cpa);
+
+ report_prefix_push("Disabled subchannel");
+ assert(css_disable(test_device_sid) == 0);
+ report(ssch(test_device_sid, &orb) == 3, "CC = 3");
+ assert(css_enable(test_device_sid, IO_SCH_ISC) == 0);
+ report_prefix_pop();
+
+ /*
+ * Check sending a second SSCH before clearing the status with TSCH >> + * the subchannel is left disabled.
If a second SSCH is sent before clearing via TSCH the subchannel is
disabled by firmware? Did I get that right?
Oh, no, sorry, the comment is not good, no the firmware does not disable
the subchannel, the comment is not at the right place.
+ */
+ report_prefix_push("SSCH on channel with status pending");
+ assert(css_enable(test_device_sid, IO_SCH_ISC) == 0);
+ assert(ssch(test_device_sid, &orb) == 0);
+ report(ssch(test_device_sid, &orb) == 1, "CC = 1");
+ /* now we clear the status */
+ assert(wait_and_check_io_completion(test_device_sid, SCSW_FC_START) == 0);
The comment about leaving the channel disabled should be here should be
here... :(
The idea about disabling the subchannel is to make sure to have a clean
subchannel for the next test.
However I am not so sure it really bring something.
Thanks,
Pierre
--
Pierre Morel
IBM Lab Boeblingen