Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Avoid strict-aliasing related issues when compiling with optimization
[palacios.git] / linux_module / allow_devmem.c
1 #include <linux/kernel.h>
2 #include <linux/module.h>
3 #include <linux/kprobes.h>
4
5 #include "palacios.h"
6 #include "allow_devmem.h"
7
8 /*
9   The purpose of this component is to disable and reenable
10   strict devmem control.
11
12   On kernels compiled with CONFIG_STRICT_DEVMEM, /dev/mem access
13   from user space is limited to the first 1 MB and to non-memory
14   regions (ie, devices).  For various purposes in Palacios,
15   for example linux_usr/v3_guest_mem.[ch], we want to allow 
16   host user space access to guest memory via mmap.   
17
18   This borrows from Dave Anderson @ Red Hat's implementation
19 */
20
21 #define DEVMEM_CHECK_FUNC "devmem_is_allowed"
22
23 static enum { NOTRUN=0, OPEN, SET, NOTSET } devmem_state = NOTRUN;
24
25
26 // this is invoked after return from devmem_is_allowed()
27 static int devmem_ret_handler(struct kretprobe_instance *ri, 
28                               struct pt_regs *regs)
29 {
30   regs->ax = 1;  // yes, it's allowed - "ax"  now means "rax"
31   return 0;
32 }
33
34 static struct kretprobe devmem_kretprobe = {
35   .handler = devmem_ret_handler,
36   .maxactive = 20 // up to 20 at a time
37 };
38
39
40 int palacios_allow_devmem(void)
41 {
42 #ifndef CONFIG_STRICT_DEVMEM
43   INFO("System already has open /dev/mem - doing nothing\n");
44   devmem_state = OPEN;
45   return 0;
46 #else
47   switch (devmem_state) { 
48   case NOTRUN:
49   case NOTSET: {
50     int rc;
51
52     devmem_kretprobe.kp.symbol_name = DEVMEM_CHECK_FUNC;
53     
54     rc = register_kretprobe(&devmem_kretprobe);
55     
56     if (rc<0) {
57       ERROR("register_kretprobe failed, returned %d\n", rc);
58       return -1;
59     }
60     
61     devmem_state=SET;
62     INFO("/dev/mem is now enabled (probe at %p)\n",devmem_kretprobe.kp.addr);
63
64     return 0;
65   }
66
67     break;
68   default:
69     // already set
70     return 0;
71     break;
72   }
73 #endif    
74 }
75
76
77 int palacios_restore_devmem(void) 
78 {
79 #ifndef CONFIG_STRICT_DEVMEM
80   INFO("System already has open /dev/mem - doing nothing\n");
81   devmem_state = OPEN;
82   return 0;
83 #else 
84   switch (devmem_state) { 
85   case NOTRUN: 
86     ERROR("Ignoring disable of dev mem\n");
87     return 0;
88   case NOTSET: 
89     INFO("/dev/mem not explicitly enabled, ignoring restore request\n");
90     return 0;
91     break;
92
93   case SET: {
94
95     unregister_kretprobe(&devmem_kretprobe);
96     
97     if (devmem_kretprobe.nmissed>0) { 
98       ERROR("Note: missed %d instances of %s\n", 
99             devmem_kretprobe.nmissed, DEVMEM_CHECK_FUNC);
100     }
101     
102     devmem_state=NOTSET;
103
104     INFO("Restored strict /dev/mem access\n");
105     return 0;
106   }
107
108     break;
109   default:
110     // already set
111     return 0;
112     break;
113   }
114
115   return 0;
116 #endif
117 }
118
119