• Sascha Silbe's avatar
    s390/zcrypt: Fix kernel crash on systems without AP bus support · e387753c
    Sascha Silbe authored
    On systems without AP bus (e.g. KVM) the kernel crashes during init
    calls when zcrypt is built-in:
    
    kernel BUG at drivers/base/driver.c:153!
    illegal operation: 0001 ilc:1 [#1] SMP
    Modules linked in:
    CPU: 1 PID: 1 Comm: swapper/0 Not tainted 4.2.0+ #221
    task: 0000000010a40000 ti: 0000000010a48000 task.ti:0000000010a48000
    Krnl PSW : 0704c00180000000 0000000000592bd6(driver_register+0x106/0x140)
               R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:0 AS:3 CC:0 PM:0 EA:3
               0000000000000012 0000000000000000 0000000000c45328 0000000000c44e30
               00000000009ef63c 000000000067f598 0000000000cf3c58 0000000000000000
               000000000000007b 0000000000cb1030 0000000000000002 0000000000000000
               0000000000ca8580 0000000010306700 00000000001001d8 0000000010a4bd88
    Krnl Code: 0000000000592bc6: f0b00004ebcf	srp 4(12,%r0),3023(%r14),0
               0000000000592bcc: f0a0000407f4       srp     4(11,%r0),2036,0
              #0000000000592bd2: a7f40001           brc     15,592bd4
              >0000000000592bd6: e330d0000004       lg      %r3,0(%r13)
               0000000000592bdc: c0200021edfd       larl    %r2,9d07d6
               0000000000592be2: c0e500126d8f       brasl   %r14,7e0700
               0000000000592be8: e330d0080004       lg      %r3,8(%r13)
               0000000000592bee: a7f4ffab           brc     15,592b44
    Call Trace:
    ([<00000000001001c8>] do_one_initcall+0x90/0x1d0)
     [<0000000000c6dd34>] kernel_init_freeable+0x1e4/0x2a0
     [<00000000007db53a>] kernel_init+0x2a/0x120
     [<00000000007e8ece>] kernel_thread_starter+0x6/0xc
     [<00000000007e8ec8>] kernel_thread_starter+0x0/0xc
    Last Breaking-Event-Address:
     [<0000000000592bd2>] driver_register+0x102/0x140
    
    When zcrypt is built as a module, the module loader ensures that the
    driver modules cannot be loaded if the AP bus module returns an error
    during initialisation. But if zcrypt and the driver are built-in, the
    driver is getting initialised even if the AP bus initialisation
    failed. The driver invokes ap_driver_register() during initialisation,
    which then causes operations on uninitialised data structures to be
    performed.
    
    Explicitly protect ap_driver_register() by introducing an
    "initialised" flag that gets set iff the AP bus initialisation was
    successful. When the AP bus initialisation failed,
    ap_driver_register() will error out with -ENODEV, causing the driver
    initialisation to fail as well.
    
    Test results:
    1. Inside KVM (no AP bus), zcrypt built-in
    
       Boots. /sys/bus/ap not present (expected).
    
    2. Inside KVM (no AP bus), zcrypt as module
    
       Boots. Loading zcrypt_cex4 fails because loading ap_bus fails
       (expected).
    
    3. On LPAR with CEX5, zcrypt built-in
    
       Boots. /sys/bus/ap/devices/card* present but .../card*/type missing
       (i.e. zcrypt_device_register() fails, unrelated issue).
    
    4. On LPAR with CEX5, zcrypt as module
    
       Boots. Loading zcrypt_cex4 successful,
       /sys/bus/ap/devices/card*/type present. No further testing
       (user-space functionality) was done.
    Signed-off-by: default avatarSascha Silbe <silbe@linux.vnet.ibm.com>
    Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
    e387753c
ap_bus.c 47.7 KB