Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

s390/diag: add diag26c support

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>

authored by

Julian Wiedmann and committed by
David S. Miller
1b030478 3cdc8a25

+55
+26
arch/s390/include/asm/diag.h
··· 8 8 #ifndef _ASM_S390_DIAG_H 9 9 #define _ASM_S390_DIAG_H 10 10 11 + #include <linux/if_ether.h> 11 12 #include <linux/percpu.h> 12 13 13 14 enum diag_stat_enum { ··· 25 24 DIAG_STAT_X224, 26 25 DIAG_STAT_X250, 27 26 DIAG_STAT_X258, 27 + DIAG_STAT_X26C, 28 28 DIAG_STAT_X288, 29 29 DIAG_STAT_X2C4, 30 30 DIAG_STAT_X2FC, ··· 227 225 struct diag204_x_phys_cpu cpus[]; 228 226 } __packed; 229 227 228 + enum diag26c_sc { 229 + DIAG26C_MAC_SERVICES = 0x00000030 230 + }; 231 + 232 + enum diag26c_version { 233 + DIAG26C_VERSION2 = 0x00000002 /* z/VM 5.4.0 */ 234 + }; 235 + 236 + #define DIAG26C_GET_MAC 0x0000 237 + struct diag26c_mac_req { 238 + u32 resp_buf_len; 239 + u32 resp_version; 240 + u16 op_code; 241 + u16 devno; 242 + u8 res[4]; 243 + }; 244 + 245 + struct diag26c_mac_resp { 246 + u32 version; 247 + u8 mac[ETH_ALEN]; 248 + u8 res[2]; 249 + } __aligned(8); 250 + 230 251 int diag204(unsigned long subcode, unsigned long size, void *addr); 231 252 int diag224(void *ptr); 253 + int diag26c(void *req, void *resp, enum diag26c_sc subcode); 232 254 #endif /* _ASM_S390_DIAG_H */
+29
arch/s390/kernel/diag.c
··· 38 38 [DIAG_STAT_X224] = { .code = 0x224, .name = "EBCDIC-Name Table" }, 39 39 [DIAG_STAT_X250] = { .code = 0x250, .name = "Block I/O" }, 40 40 [DIAG_STAT_X258] = { .code = 0x258, .name = "Page-Reference Services" }, 41 + [DIAG_STAT_X26C] = { .code = 0x26c, .name = "Certain System Information" }, 41 42 [DIAG_STAT_X288] = { .code = 0x288, .name = "Time Bomb" }, 42 43 [DIAG_STAT_X2C4] = { .code = 0x2c4, .name = "FTP Services" }, 43 44 [DIAG_STAT_X2FC] = { .code = 0x2fc, .name = "Guest Performance Data" }, ··· 237 236 return rc; 238 237 } 239 238 EXPORT_SYMBOL(diag224); 239 + 240 + /* 241 + * Diagnose 26C: Access Certain System Information 242 + */ 243 + static inline int __diag26c(void *req, void *resp, enum diag26c_sc subcode) 244 + { 245 + register unsigned long _req asm("2") = (addr_t) req; 246 + register unsigned long _resp asm("3") = (addr_t) resp; 247 + register unsigned long _subcode asm("4") = subcode; 248 + register unsigned long _rc asm("5") = -EOPNOTSUPP; 249 + 250 + asm volatile( 251 + " sam31\n" 252 + " diag %[rx],%[ry],0x26c\n" 253 + "0: sam64\n" 254 + EX_TABLE(0b,0b) 255 + : "+d" (_rc) 256 + : [rx] "d" (_req), "d" (_resp), [ry] "d" (_subcode) 257 + : "cc", "memory"); 258 + return _rc; 259 + } 260 + 261 + int diag26c(void *req, void *resp, enum diag26c_sc subcode) 262 + { 263 + diag_stat_inc(DIAG_STAT_X26C); 264 + return __diag26c(req, resp, subcode); 265 + } 266 + EXPORT_SYMBOL(diag26c);