visorkmodutils.c revision fcd0157ece8a1bf36b877a9c8078ea721678a38b
1/* timskmodutils.c 2 * 3 * Copyright (C) 2010 - 2013 UNISYS CORPORATION 4 * All rights reserved. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or (at 9 * your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, but 12 * WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 14 * NON INFRINGEMENT. See the GNU General Public License for more 15 * details. 16 */ 17 18#include "uniklog.h" 19#include "timskmod.h" 20 21#define MYDRVNAME "timskmodutils" 22 23/* s-Par uses the Intel processor's VT-X features to separate groups of 24 * processors into partitions. The firmware sets the hypervisor bit and 25 * reports an ID in the HV capabilities leaf so that the partition's OS 26 * knows s-Par is present and managing the processors. 27 */ 28 29#define UNISYS_SPAR_LEAF_ID 0x40000000 30 31/* The s-Par leaf ID returns "UnisysSpar64" encoded across ebx, ecx, edx */ 32#define UNISYS_SPAR_ID_EBX 0x73696e55 33#define UNISYS_SPAR_ID_ECX 0x70537379 34#define UNISYS_SPAR_ID_EDX 0x34367261 35 36int unisys_spar_platform; 37EXPORT_SYMBOL_GPL(unisys_spar_platform); 38 39/** Callers to interfaces that set __GFP_NORETRY flag below 40 * must check for a NULL (error) result as we are telling the 41 * kernel interface that it is okay to fail. 42 */ 43 44void *kmalloc_kernel(size_t siz) 45{ 46 return kmalloc(siz, GFP_KERNEL | __GFP_NORETRY); 47} 48 49/* Use these handy-dandy seq_file_xxx functions if you want to call some 50 * functions that write stuff into a seq_file, but you actually just want 51 * to dump that output into a buffer. Use them as follows: 52 * - call visor_seq_file_new_buffer to create the seq_file (you supply the buf) 53 * - call whatever functions you want that take a seq_file as an argument 54 * (the buf you supplied will get the output data) 55 * - call visor_seq_file_done_buffer to dispose of your seq_file 56 */ 57struct seq_file *visor_seq_file_new_buffer(void *buf, size_t buf_size) 58{ 59 struct seq_file *rc = NULL; 60 struct seq_file *m = kmalloc_kernel(sizeof(struct seq_file)); 61 62 if (m == NULL) { 63 rc = NULL; 64 goto Away; 65 } 66 memset(m, 0, sizeof(struct seq_file)); 67 m->buf = buf; 68 m->size = buf_size; 69 rc = m; 70Away: 71 if (rc == NULL) { 72 visor_seq_file_done_buffer(m); 73 m = NULL; 74 } 75 return rc; 76} 77EXPORT_SYMBOL_GPL(visor_seq_file_new_buffer); 78 79 80 81void visor_seq_file_done_buffer(struct seq_file *m) 82{ 83 if (!m) 84 return; 85 kfree(m); 86} 87EXPORT_SYMBOL_GPL(visor_seq_file_done_buffer); 88 89static __init uint32_t 90visorutil_spar_detect(void) 91{ 92 unsigned int eax, ebx, ecx, edx; 93 94 if (cpu_has_hypervisor) { 95 /* check the ID */ 96 cpuid(UNISYS_SPAR_LEAF_ID, &eax, &ebx, &ecx, &edx); 97 return (ebx == UNISYS_SPAR_ID_EBX) && 98 (ecx == UNISYS_SPAR_ID_ECX) && 99 (edx == UNISYS_SPAR_ID_EDX); 100 } else 101 return 0; 102 103} 104 105 106 107 108static __init int 109visorutil_mod_init(void) 110{ 111 if (visorutil_spar_detect()) { 112 unisys_spar_platform = TRUE; 113 return 0; 114 } else 115 return -ENODEV; 116} 117 118static __exit void 119visorutil_mod_exit(void) 120{ 121} 122 123module_init(visorutil_mod_init); 124module_exit(visorutil_mod_exit); 125 126