s390/diag: add diag26c support
authorJulian Wiedmann <jwi@linux.vnet.ibm.com>
Tue, 20 Jun 2017 14:00:33 +0000 (16:00 +0200)
committerDavid S. Miller <davem@davemloft.net>
Tue, 20 Jun 2017 19:44:15 +0000 (15:44 -0400)
Implement support for the hypervisor diagnose 0x26c
('Access Certain System Information').
It passes a request buffer and a subfunction code, and receives
a response buffer and a return code.

Also add the scaffolding for the 'MAC Services' subfunction.
It may be used by network devices to obtain a hypervisor-managed
MAC address.

Signed-off-by: Julian Wiedmann <jwi@linux.vnet.ibm.com>
Acked-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
arch/s390/include/asm/diag.h
arch/s390/kernel/diag.c

index 8acf482162ed4f85109cdc8e944b64e9036c8155..88162bb5c19009cf3474d3110de3b988d25ecd9a 100644 (file)
@@ -8,6 +8,7 @@
 #ifndef _ASM_S390_DIAG_H
 #define _ASM_S390_DIAG_H
 
+#include <linux/if_ether.h>
 #include <linux/percpu.h>
 
 enum diag_stat_enum {
@@ -24,6 +25,7 @@ enum diag_stat_enum {
        DIAG_STAT_X224,
        DIAG_STAT_X250,
        DIAG_STAT_X258,
+       DIAG_STAT_X26C,
        DIAG_STAT_X288,
        DIAG_STAT_X2C4,
        DIAG_STAT_X2FC,
@@ -225,6 +227,30 @@ struct diag204_x_phys_block {
        struct diag204_x_phys_cpu cpus[];
 } __packed;
 
+enum diag26c_sc {
+       DIAG26C_MAC_SERVICES = 0x00000030
+};
+
+enum diag26c_version {
+       DIAG26C_VERSION2 = 0x00000002   /* z/VM 5.4.0 */
+};
+
+#define DIAG26C_GET_MAC        0x0000
+struct diag26c_mac_req {
+       u32     resp_buf_len;
+       u32     resp_version;
+       u16     op_code;
+       u16     devno;
+       u8      res[4];
+};
+
+struct diag26c_mac_resp {
+       u32     version;
+       u8      mac[ETH_ALEN];
+       u8      res[2];
+} __aligned(8);
+
 int diag204(unsigned long subcode, unsigned long size, void *addr);
 int diag224(void *ptr);
+int diag26c(void *req, void *resp, enum diag26c_sc subcode);
 #endif /* _ASM_S390_DIAG_H */
index ac6abcd3fe6a83945d563e252c357eb0551a842c..349914571772e1313fa1dccaffaf193123dc06c3 100644 (file)
@@ -38,6 +38,7 @@ static const struct diag_desc diag_map[NR_DIAG_STAT] = {
        [DIAG_STAT_X224] = { .code = 0x224, .name = "EBCDIC-Name Table" },
        [DIAG_STAT_X250] = { .code = 0x250, .name = "Block I/O" },
        [DIAG_STAT_X258] = { .code = 0x258, .name = "Page-Reference Services" },
+       [DIAG_STAT_X26C] = { .code = 0x26c, .name = "Certain System Information" },
        [DIAG_STAT_X288] = { .code = 0x288, .name = "Time Bomb" },
        [DIAG_STAT_X2C4] = { .code = 0x2c4, .name = "FTP Services" },
        [DIAG_STAT_X2FC] = { .code = 0x2fc, .name = "Guest Performance Data" },
@@ -236,3 +237,31 @@ int diag224(void *ptr)
        return rc;
 }
 EXPORT_SYMBOL(diag224);
+
+/*
+ * Diagnose 26C: Access Certain System Information
+ */
+static inline int __diag26c(void *req, void *resp, enum diag26c_sc subcode)
+{
+       register unsigned long _req asm("2") = (addr_t) req;
+       register unsigned long _resp asm("3") = (addr_t) resp;
+       register unsigned long _subcode asm("4") = subcode;
+       register unsigned long _rc asm("5") = -EOPNOTSUPP;
+
+       asm volatile(
+               "       sam31\n"
+               "       diag    %[rx],%[ry],0x26c\n"
+               "0:     sam64\n"
+               EX_TABLE(0b,0b)
+               : "+d" (_rc)
+               : [rx] "d" (_req), "d" (_resp), [ry] "d" (_subcode)
+               : "cc", "memory");
+       return _rc;
+}
+
+int diag26c(void *req, void *resp, enum diag26c_sc subcode)
+{
+       diag_stat_inc(DIAG_STAT_X26C);
+       return __diag26c(req, resp, subcode);
+}
+EXPORT_SYMBOL(diag26c);