Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Hypervisor filesystem for Linux on s390
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Diag 0C implementation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Copyright IBM Corp. 2014
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/cpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <asm/diag.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <asm/hypfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include "hypfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #define DBFS_D0C_HDR_VERSION 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  * Get hypfs_diag0c_entry from CPU vector and store diag0c data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) static void diag0c_fn(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 	diag_stat_inc(DIAG_STAT_X00C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 	diag_dma_ops.diag0c(((void **) data)[smp_processor_id()]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  * Allocate buffer and store diag 0c data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) static void *diag0c_store(unsigned int *count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	struct hypfs_diag0c_data *diag0c_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	unsigned int cpu_count, cpu, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	void **cpu_vec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	get_online_cpus();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	cpu_count = num_online_cpus();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	cpu_vec = kmalloc_array(num_possible_cpus(), sizeof(*cpu_vec),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 				GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	if (!cpu_vec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 		goto fail_put_online_cpus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	/* Note: Diag 0c needs 8 byte alignment and real storage */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	diag0c_data = kzalloc(struct_size(diag0c_data, entry, cpu_count),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 			      GFP_KERNEL | GFP_DMA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	if (!diag0c_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 		goto fail_kfree_cpu_vec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	/* Fill CPU vector for each online CPU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	for_each_online_cpu(cpu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 		diag0c_data->entry[i].cpu = cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 		cpu_vec[cpu] = &diag0c_data->entry[i++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	/* Collect data all CPUs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	on_each_cpu(diag0c_fn, cpu_vec, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	*count = cpu_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	kfree(cpu_vec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	put_online_cpus();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	return diag0c_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) fail_kfree_cpu_vec:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	kfree(cpu_vec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) fail_put_online_cpus:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	put_online_cpus();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68)  * Hypfs DBFS callback: Free diag 0c data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) static void dbfs_diag0c_free(const void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	kfree(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76)  * Hypfs DBFS callback: Create diag 0c data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) static int dbfs_diag0c_create(void **data, void **data_free_ptr, size_t *size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	struct hypfs_diag0c_data *diag0c_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	unsigned int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	diag0c_data = diag0c_store(&count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	if (IS_ERR(diag0c_data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		return PTR_ERR(diag0c_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	memset(&diag0c_data->hdr, 0, sizeof(diag0c_data->hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	get_tod_clock_ext(diag0c_data->hdr.tod_ext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	diag0c_data->hdr.len = count * sizeof(struct hypfs_diag0c_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	diag0c_data->hdr.version = DBFS_D0C_HDR_VERSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	diag0c_data->hdr.count = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	*data = diag0c_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	*data_free_ptr = diag0c_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	*size = diag0c_data->hdr.len + sizeof(struct hypfs_diag0c_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98)  * Hypfs DBFS file structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static struct hypfs_dbfs_file dbfs_file_0c = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	.name		= "diag_0c",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	.data_create	= dbfs_diag0c_create,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	.data_free	= dbfs_diag0c_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)  * Initialize diag 0c interface for z/VM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) int __init hypfs_diag0c_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	if (!MACHINE_IS_VM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	hypfs_dbfs_create_file(&dbfs_file_0c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)  * Shutdown diag 0c interface for z/VM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) void hypfs_diag0c_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	if (!MACHINE_IS_VM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	hypfs_dbfs_remove_file(&dbfs_file_0c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }