rkmem.c

Go to the documentation of this file.
00001 /*************************************************** */
00002 /* Rule Set Based Access Control                     */
00003 /* Author and (c) 1999-2005: Amon Ott <ao@rsbac.org> */
00004 /* (a lot copied from mm/slab.c, with other          */
00005 /*  copyrights)                                      */
00006 /* Memory allocation functions for all parts         */
00007 /* Last modified: 08/Jun/2005                        */
00008 /*************************************************** */
00009 
00010 #include <rsbac/types.h>
00011 #include <rsbac/rkmem.h>
00012 #include <rsbac/debug.h>
00013 #include <linux/init.h>
00014 #include <linux/kernel.h>
00015 #include <linux/module.h>
00016 #include <linux/slab.h>
00017 #include <linux/vmalloc.h>
00018 #include <linux/timer.h>
00019 
00020 /* Size description struct for general RSBAC caches. */
00021 typedef struct rsbac_cache_sizes {
00022         size_t           cs_size;
00023         kmem_cache_t    *cs_cachep;
00024         char             name[15];
00025 } rsbac_cache_sizes_t;
00026 
00027 static rsbac_cache_sizes_t rsbac_cache_sizes[] = {
00028 #if PAGE_SIZE == 4096
00029         {    32,        NULL,   "rsbac-32"},
00030 #endif
00031         {    64,        NULL,   "rsbac-64"},
00032 #if PAGE_SIZE == 4096
00033         {    96,        NULL,   "rsbac-96"},
00034 #endif
00035         {   128,        NULL,   "rsbac-128"},
00036         {   192,        NULL,   "rsbac-192"},
00037         {   256,        NULL,   "rsbac-256"},
00038         {   512,        NULL,   "rsbac-512"},
00039         {  1024,        NULL,   "rsbac-1024"},
00040         {  2048,        NULL,   "rsbac-2048"},
00041         {  4096,        NULL,   "rsbac-4096"},
00042         {  8192,        NULL,   "rsbac-8192"},
00043 /* Cannot use vmalloc in 2.6ff, so we need more space here */
00044 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
00045         { 16384,        NULL,   "rsbac-16384"},
00046         { 32768,        NULL,   "rsbac-32768"},
00047         { 65536,        NULL,   "rsbac-65536"},
00048         {131072,        NULL,   "rsbac-131072"},
00049 #ifndef CONFIG_MMU
00050         {262144,        NULL,   "rsbac-262144"},
00051         {524288,        NULL,   "rsbac-524288"},
00052         {1048576,        NULL,   "rsbac-1048576"},
00053 #ifdef CONFIG_LARGE_ALLOCS
00054         {2097152,        NULL,   "rsbac-2097152"},
00055         {4194304,        NULL,   "rsbac-4194304"},
00056         {8388608,        NULL,   "rsbac-8388608"},
00057         {16777216,        NULL,   "rsbac-16777216"},
00058         {33554432,        NULL,   "rsbac-33554432"},
00059 #endif /* CONFIG_LARGE_ALLOCS */
00060 #endif /* CONFIG_MMU */
00061 #endif
00062         {     0,        NULL,   "rsbac0"}
00063 };
00064 #ifdef CONFIG_RSBAC_INIT_DELAY
00065 void rsbac_kmem_cache_sizes_init(void)
00066 #else
00067 void __init rsbac_kmem_cache_sizes_init(void)
00068 #endif
00069 {
00070         rsbac_cache_sizes_t *sizes = rsbac_cache_sizes;
00071 
00072         while (sizes->cs_size) {
00073                 sizes->cs_cachep = kmem_cache_create(
00074                         sizes->name, sizes->cs_size,
00075                         0, SLAB_HWCACHE_ALIGN, NULL, NULL);
00076                 if (!sizes->cs_cachep)
00077                         BUG();
00078 
00079                 sizes++;
00080         }
00081 }
00082 
00083 
00084 /**
00085  * rsbac_kmalloc - allocate memory
00086  * @size: how many bytes of memory are required.
00087  *
00088  * rsbac_kmalloc is the normal method of allocating memory for RSBAC
00089  * in the kernel. It will always be of type GFP_KERNEL in 2.4 and
00090  * GFP_ATOMIC in 2.6.
00091  *
00092  * rsbac_kmalloc'd memory is freed by rsbac_kfree
00093  */
00094 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
00095 EXPORT_SYMBOL(rsbac_kmalloc);
00096 #endif
00097 void * rsbac_kmalloc (size_t size)
00098 {
00099         rsbac_cache_sizes_t *csizep = rsbac_cache_sizes;
00100 
00101         if(!size)
00102           return NULL;
00103         for (; csizep->cs_size; csizep++) {
00104                 if (size > csizep->cs_size)
00105                         continue;
00106 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
00107                 return kmem_cache_alloc(csizep->cs_cachep, GFP_ATOMIC);
00108 #else
00109                 return kmem_cache_alloc(csizep->cs_cachep, GFP_KERNEL);
00110 #endif
00111         }
00112         rsbac_printk(KERN_WARNING
00113                "rsbac_kmalloc: size %u requested, max size is %u!\n",
00114                size, RSBAC_MAX_KMALLOC);
00115         BUG();
00116         return NULL;
00117 }
00118 
00119 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
00120 EXPORT_SYMBOL(rsbac_vkmalloc);
00121 #endif
00122 void * rsbac_vkmalloc (size_t size, rsbac_boolean_t * vmalloc_used_p)
00123 {
00124         rsbac_cache_sizes_t *csizep = rsbac_cache_sizes;
00125         void * result;
00126 
00127         if(!size)
00128           return NULL;
00129         for (; csizep->cs_size; csizep++) {
00130                 if (size > csizep->cs_size)
00131                         continue;
00132 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
00133                 result = kmem_cache_alloc(csizep->cs_cachep, GFP_ATOMIC);
00134 #else
00135                 result = kmem_cache_alloc(csizep->cs_cachep, GFP_KERNEL);
00136 #endif
00137                 if(result)
00138                   {
00139                     if(vmalloc_used_p)
00140                       *vmalloc_used_p = FALSE;
00141                     return result;
00142                   }
00143         }
00144 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
00145         return NULL;
00146 #else
00147         if(vmalloc_used_p)
00148           *vmalloc_used_p = TRUE;
00149         return vmalloc(size);
00150 #endif
00151 }
00152 
00153 /**
00154  * rsbac_kfree - free previously allocated memory
00155  * @objp: pointer returned by kmalloc.
00156  *
00157  * Don't free memory not originally allocated by rsbac_kmalloc()
00158  * or you will run into trouble.
00159  *
00160  * We simply call general kfree, which does everything
00161  */
00162 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
00163 EXPORT_SYMBOL(rsbac_kfree);
00164 #endif
00165 void rsbac_kfree (const void *objp)
00166   {
00167     kfree(objp);
00168   }
00169 
00170 static void wakeup_kfree(u_long dk_dummy)
00171   {
00172     struct rsbac_delayed_kfree_t * dk_p = (struct rsbac_delayed_kfree_t *) dk_dummy;
00173 
00174     kfree(dk_p->objp);
00175     kfree(dk_p);
00176   }
00177 
00178 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
00179 EXPORT_SYMBOL(rsbac_delayed_kfree);
00180 #endif
00181 void rsbac_delayed_kfree(void *objp, rsbac_time_t delay)
00182   {
00183     struct rsbac_delayed_kfree_t * dk_p;
00184 
00185     if(!objp)
00186       return;
00187     dk_p = rsbac_kmalloc(sizeof(*dk_p));
00188     if(!dk_p)
00189       return;
00190 
00191     dk_p->objp = objp;
00192     init_timer(&dk_p->timer);
00193     dk_p->timer.function = wakeup_kfree;
00194     dk_p->timer.data = (u_long) dk_p;
00195     dk_p->timer.expires = jiffies + delay * HZ;
00196     add_timer(&dk_p->timer);
00197   }
00198 
00199 #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
00200 EXPORT_SYMBOL(rsbac_vkfree);
00201 #endif
00202 void rsbac_vkfree(void *objp, rsbac_boolean_t vmalloc_used)
00203   {
00204     if(vmalloc_used)
00205       vfree(objp);
00206     else
00207       kfree(objp);
00208   }
00209 
00210 /* end of rkmem.c */

Generated on Sun May 21 14:30:56 2006 for RSBAC by  doxygen 1.4.2