Krishna iResearch Intelligent Cloud Platform - VIRtual Generic Os - VIRGO - Linux kernel extensions for cloud
 All Classes
virgo_cloud_mempool_kernelspace.c
1 /***************************************************************************************
2 VIRGO - a linux module extension with CPU and Memory pooling with cloud capabilities
3 
4 
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18 --------------------------------------------------------------------------------------------------
19 Copyright (C):
20 Srinivasan Kannan (alias) Ka.Shrinivaasan (alias) Shrinivas Kannan
21 Independent Open Source Developer, Researcher and Consultant
22 Ph: 9789346927, 9003082186, 9791165980
23 Open Source Products Profile(Krishna iResearch): http://sourceforge.net/users/ka_shrinivaasan
24 Personal website(research): https://sites.google.com/site/kuja27/
25 emails: ka.shrinivaasan@gmail.com, shrinivas.kannan@gmail.com, kashrinivaasan@live.com
26 --------------------------------------------------------------------------------------------------
27 
28 *****************************************************************************************/
29 
30 
31 #include <linux/string.h>
32 #include <linux/module.h>
33 #include <linux/virgo_mempool.h>
34 #include <linux/string.h>
35 #include <kstrtox.h>
36 #include <linux/ctype.h>
37 
38 unsigned int virgo_parse_integer(const char *s, unsigned int base, unsigned long long *p);
39 void printBytes(const char* str);
40 char* toKernelAddress(const char*);
41 int toInteger(char*);
42 void* virgo_cloud_malloc_kernelspace(struct virgo_mempool_args*);
43 void* virgo_cloud_free_kernelspace(struct virgo_mempool_args*);
44 void* virgo_cloud_get_kernelspace(struct virgo_mempool_args*);
45 void* virgo_cloud_set_kernelspace(struct virgo_mempool_args*);
46 struct virgo_mempool_args* parse_virgomempool_command_kernelspace(char* mempoolFunction);
47 
48 static int __init
49 virgo_cloud_mempool_kernelspace_init(void)
50 {
51  printk(KERN_INFO "virgo_cloud_mempool_kernelspace_init(): doing init() of virgo cloud kernel space test module\n");
52  unsigned long test_ul;
53  char* test_str="ef098363";
54  kstrtoul(test_str,16,&test_ul);
55  printk(KERN_INFO "virgo_cloud_mempool_kernelspace_init(): test_str=%s, test_ul=%u\n",test_str,test_ul);
56  return 0;
57 }
58 EXPORT_SYMBOL(virgo_cloud_mempool_kernelspace_init);
59 
60 
61 static void __exit
62 virgo_cloud_mempool_kernelspace_exit(void)
63 {
64  printk(KERN_INFO "virgo_cloud_mempool_kernelspace_exit(): exiting virgo cloud test kernel space module \n");
65  do_exit(1);
66 }
67 EXPORT_SYMBOL(virgo_cloud_mempool_kernelspace_exit);
68 
69 
70 
71 void* virgo_cloud_malloc_kernelspace(struct virgo_mempool_args* args)
72 {
73  printk(KERN_INFO "virgo_cloud_mempool_kernelspace.c:Executing virgo_cloud_mempool on cloud node, Invoking virgo_cloud_malloc_kernelspace(), Writing to file opened by Kernel, Kernel Space to User space communication works\n");
74  struct virgo_mempool_args* vmargs=(struct virgo_mempool_args*)args;
75  printk(KERN_INFO "virgo_cloud_mempool_kernelspace.c:virgo_cloud_malloc_kernelspace(): size str=%s\n",vmargs->mempool_args[0]);
76 
77  int size=toInteger(vmargs->mempool_args[0]);
78  printk(KERN_INFO "virgo_cloud_mempool_kernelspace.c:virgo_cloud_malloc_kernelspace(): size=%d\n",size);
79  void* ptr=kmalloc(size,GFP_KERNEL);
80  printk(KERN_INFO "virgo_cloud_mempool_kernelspace.c:virgo_cloud_malloc_kernelspace(): ptr=%p\n",ptr);
81  vmargs->ptr=(char*)ptr;
82  printk(KERN_INFO "virgo_cloud_mempool_kernelspace.c:virgo_cloud_malloc_kernelspace(): setting ptr=%p in vmargs as an out arg\n",ptr);
83  return ptr;
84 }
85 EXPORT_SYMBOL(virgo_cloud_malloc_kernelspace);
86 
87 void* virgo_cloud_get_kernelspace(struct virgo_mempool_args* args)
88 {
89  printk(KERN_INFO "virgo_cloud_mempool_kernelspace.c:Executing virgo_cloud_mempool on cloud node, Invoking virgo_cloud_get_kernelspace(), Writing to file opened by Kernel, Kernel Space to User space communication works\n");
90  struct virgo_mempool_args* vmargs=args;
91  char* ptr=toKernelAddress(vmargs->mempool_args[0]);
92  printk(KERN_INFO "virgo_cloud_mempool_kernelspace.c: virgo_cloud_get_kernelspace(): data at ptr parsed by toKernelAddress() = [%s]\n",ptr);
93  char virgodata_prefix[500];
94  strcpy(virgodata_prefix,"virgodata:");
95  char* data=kstrdup(strcat(virgodata_prefix,ptr),GFP_KERNEL);
96  printk(KERN_INFO "virgo_cloud_mempool_kernelspace.c: virgo_cloud_get_kernelspace(): address=%p, data=%s, data with added prefix=%s\n",ptr,ptr,data);
97  return data;
98 }
99 EXPORT_SYMBOL(virgo_cloud_get_kernelspace);
100 
101 void* virgo_cloud_set_kernelspace(struct virgo_mempool_args* args)
102 {
103  printk(KERN_INFO "virgo_cloud_mempool_kernelspace.c:Executing virgo_cloud_mempool on cloud node, Invoking virgo_cloud_set_kernelspace(), Writing to file opened by Kernel, Kernel Space to User space communication works\n");
104  struct virgo_mempool_args* vmargs=args;
105  printk(KERN_INFO "virgo_cloud_set_kernelspace(): vmargs->mempool_cmd=%s, vmargs->mempool_args[0] = %s\n, vmargs->mempool_args[1]=%s \n",vmargs->mempool_cmd, vmargs->mempool_args[0],vmargs->mempool_args[1]);
106  char* ptr=toKernelAddress(vmargs->mempool_args[0]);
107  /***********************toKernelAddress()******************************************
108  unsigned long ull;
109  char* mempool_args_dup=kstrdup(vmargs->mempool_args[0],GFP_KERNEL);
110  mempool_args_dup=kstrdup(strcat(mempool_args_dup,"\n\0"),GFP_KERNEL);
111  kstrtoul(mempool_args_dup,0,&ull);
112  void* voidptr_ull=(void*)ull;
113  printk(KERN_INFO "virgo_cloud_set_kernelspace(): kstrtoull: ull=%u, (void*)ull=%p,vmargs->mempool_args[0]=[%s],mempool_args_dup=[%s]", ull, voidptr_ull, vmargs->mempool_args[0],mempool_args_dup);
114  *********************************************************************************/
115  printk(KERN_INFO "virgo_cloud_set_kernelspace(): ptr set by toKernelAddress=%p\n",ptr);
116 
117  /*
118  To differentiate address from data a special prefix virgodata: is prepended to data retrieved
119  This will be removed by virgo_cloudexec_send_to() module op and only data will be sent to client.
120  Similar prefix can also be done for address but for the timebeing one prefix is enough to
121  distinguish address and data.
122  - Ka.Shrinivaasan 7November2013
123  */
124  strcpy(ptr,kstrdup(vmargs->mempool_args[1],GFP_KERNEL));
125  printk(KERN_INFO "virgo_cloud_set_kernelspace(): address=%p, data to be set=%s, data after set=%s\n",ptr,vmargs->mempool_args[1], ptr);
126  return ptr;
127 }
128 EXPORT_SYMBOL(virgo_cloud_set_kernelspace);
129 
130 void* virgo_cloud_free_kernelspace(struct virgo_mempool_args* args)
131 {
132  printk(KERN_INFO "virgo_cloud_mempool_kernelspace.c:Executing virgo_cloud_mempool on cloud node, Invoking virgo_cloud_free_kernelspace(), Writing to file opened by Kernel, Kernel Space to User space communication works\n");
133  struct virgo_mempool_args* vmargs=(struct virgo_mempool_args*)args;
134  char* ptr=toKernelAddress(vmargs->mempool_args[0]);
135  printk(KERN_INFO "virgo_cloud_mempool_kernelspace.c: virgo_cloud_free_kernelspace(): address=%p\n",ptr);
136  kfree(ptr);
137  return 0;
138 }
139 EXPORT_SYMBOL(virgo_cloud_free_kernelspace);
140 
141 
142 /*
143 This function parses the address within the string strAddress and returns as the kernel address
144 Example: "0x0000ffff" to 0x0000ffff
145 */
146 
147 inline char* toKernelAddress(const char* strAddress)
148 {
149  char *ptr=NULL;
150 
151  /*
152  char* strAddress1=kmalloc(50,GFP_KERNEL);
153  char* strAddress2=kmalloc(50,GFP_KERNEL);
154  memcpy(strAddress1,strAddress,50);
155  memcpy(strAddress2,strAddress,50);
156  sscanf(strAddress1,"%p",(void**)&ptr);
157  printk(KERN_INFO "toKernelAddress(): sscanf: strAddress1=[%s], ptr = %p\n", strAddress1, ptr);
158 
159  added simple_strtoll() as done in virgo_malloc.c syscall client
160  as sscanf returns null similar to virgo_malloc.c.
161  simple_strtoul() is sscanf internal call which is deeper than sscanf.
162  - Ka.Shrinivaasan 25October2013, 31October2013
163  const char* endptr;
164  printk(KERN_INFO "toKernelAddress(): before simple_strtoll: strAddress=[%s]\n",strAddress);
165  unsigned long ll1=simple_strtoll(strAddress, &endptr, 16);
166  void* voidptr_ll1=(void*)ll1;
167  printk(KERN_INFO "toKernelAddress(): after simple_strtoll: strAddress=[%s], (void*)ll1=%p, ll1=%u\n", strAddress, voidptr_ll1, ll1);
168 
169  unsigned long ll2;
170  kstrtoll(strAddress,16,&ll2);
171  void* voidptr_ll2=(void*)ll2;
172  printk(KERN_INFO "toKernelAddress(): kstrtoll: ll2=%u, (void*)ll2=%p,strAddress=[%s]", ll2, voidptr_ll2, strAddress);
173  */
174 
175  /*
176  virgo_parse_integer() which is underlying all strtoXXX() functions is
177  directly invoked with some modifications to handle quotes.
178  - Ka.Shrinivaasan 6November2013
179  */
180  unsigned long long ll3;
181  virgo_parse_integer(strAddress,16,&ll3);
182  printk(KERN_INFO "toKernelAddress(): virgo_parse_integer: ll3=%ld, (char*)ll3=%p, (void*)ll3=%p, strAddress=[%s]\n", ll3, (char*)ll3, (void*)ll3, strAddress);
183  printk(KERN_INFO "toKernelAddress(): virgo_parse_integer: data at (char*)ll3=[%s]\n", (char*)ll3);
184 
185  /*
186  char* ultovoidptr= (char*)ul;
187  printk(KERN_INFO "toKernelAddress(): after cast: kstrtoul: ul=%u, strAddress=[%s], ultovoidptr = %p\n", ul, strAddress, ultovoidptr);
188  if(ultovoidptr)
189  {
190  return ultovoidptr;
191  }
192  else
193  return ptr;
194  */
195  return (char*)ll3;
196 }
197 EXPORT_SYMBOL(toKernelAddress);
198 
199 int toInteger(char* strInt)
200 {
201  int n;
202  sscanf(strInt, "%d", &n);
203  printk(KERN_INFO "toInteger(): strInt=[%s], integer=%d\n", strInt, n);
204  return n;
205 }
206 
207 void printBytes(const char* str)
208 {
209  const char* p=str;
210  while(*p != '\0')
211  {
212  printk(KERN_INFO "printBytes(): %c\n",*p);
213  p++;
214  }
215  return;
216 }
217 
218 /*
219 Carried over _parse_integer() from lib/kstrtox.c and modified for VIRGO by
220 adding an additional if clause for quote and unquote as below.
221 Probably this missing clause could be causing the kstrtoll() and simple_strtoll()
222 which use _parse_integer() internally to randomly return junk addresses.
223 - Ka.Shrinivaasan 6November2013
224 */
225 unsigned int virgo_parse_integer(const char *s, unsigned int base, unsigned long long *p)
226 {
227  unsigned long long res;
228  unsigned int rv;
229  int overflow;
230 
231  res = 0;
232  rv = 0;
233  overflow = 0;
234  while (*s) {
235  printk(KERN_INFO "virgo_parse_integer(): *s=%c, res=%ld\n",*s, res);
236  unsigned int val;
237  if(*s=='\"')
238  {
239  s++;
240  continue;
241  }
242  if ('0' <= *s && *s <= '9')
243  val = *s - '0';
244  else if ('a' <= tolower(*s) && tolower(*s) <= 'f')
245  val = tolower(*s) - 'a' + 10;
246  else
247  break;
248 
249  if (val >= base)
250  break;
251  /*
252  * Check for overflow only if we are within range of
253  * it in the max base we support (16)
254  if (unlikely(res & (~0ull << 60))) {
255  if (res > div_u64(ULLONG_MAX - val, base))
256  overflow = 1;
257  }
258  */
259  res = res * base + val;
260  rv++;
261  s++;
262  }
263  *p = res;
264  return rv;
265 }
266 
267 
268 
269 MODULE_LICENSE("GPL");
270 module_init(virgo_cloud_mempool_kernelspace_init);
271 module_exit(virgo_cloud_mempool_kernelspace_exit);