diff options
-rw-r--r-- | arch/mips/kernel/vpe.c | 100 |
1 files changed, 44 insertions, 56 deletions
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c index 97fefcc9dbe7..06be405be399 100644 --- a/arch/mips/kernel/vpe.c +++ b/arch/mips/kernel/vpe.c | |||
@@ -58,10 +58,6 @@ | |||
58 | 58 | ||
59 | typedef void *vpe_handle; | 59 | typedef void *vpe_handle; |
60 | 60 | ||
61 | // defined here because the kernel module loader doesn't have | ||
62 | // anything to do with it. | ||
63 | #define SHN_MIPS_SCOMMON 0xff03 | ||
64 | |||
65 | #ifndef ARCH_SHF_SMALL | 61 | #ifndef ARCH_SHF_SMALL |
66 | #define ARCH_SHF_SMALL 0 | 62 | #define ARCH_SHF_SMALL 0 |
67 | #endif | 63 | #endif |
@@ -69,11 +65,8 @@ typedef void *vpe_handle; | |||
69 | /* If this is set, the section belongs in the init part of the module */ | 65 | /* If this is set, the section belongs in the init part of the module */ |
70 | #define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1)) | 66 | #define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1)) |
71 | 67 | ||
72 | // temp number, | ||
73 | #define VPE_MAJOR 63 | ||
74 | |||
75 | static char module_name[] = "vpe"; | 68 | static char module_name[] = "vpe"; |
76 | static int major = 0; | 69 | static int major; |
77 | 70 | ||
78 | /* grab the likely amount of memory we will need. */ | 71 | /* grab the likely amount of memory we will need. */ |
79 | #ifdef CONFIG_MIPS_VPE_LOADER_TOM | 72 | #ifdef CONFIG_MIPS_VPE_LOADER_TOM |
@@ -98,22 +91,7 @@ enum tc_state { | |||
98 | TC_STATE_DYNAMIC | 91 | TC_STATE_DYNAMIC |
99 | }; | 92 | }; |
100 | 93 | ||
101 | struct vpe; | 94 | struct vpe { |
102 | typedef struct tc { | ||
103 | enum tc_state state; | ||
104 | int index; | ||
105 | |||
106 | /* parent VPE */ | ||
107 | struct vpe *pvpe; | ||
108 | |||
109 | /* The list of TC's with this VPE */ | ||
110 | struct list_head tc; | ||
111 | |||
112 | /* The global list of tc's */ | ||
113 | struct list_head list; | ||
114 | } tc_t; | ||
115 | |||
116 | typedef struct vpe { | ||
117 | enum vpe_state state; | 95 | enum vpe_state state; |
118 | 96 | ||
119 | /* (device) minor associated with this vpe */ | 97 | /* (device) minor associated with this vpe */ |
@@ -135,7 +113,21 @@ typedef struct vpe { | |||
135 | 113 | ||
136 | /* shared symbol address */ | 114 | /* shared symbol address */ |
137 | void *shared_ptr; | 115 | void *shared_ptr; |
138 | } vpe_t; | 116 | }; |
117 | |||
118 | struct tc { | ||
119 | enum tc_state state; | ||
120 | int index; | ||
121 | |||
122 | /* parent VPE */ | ||
123 | struct vpe *pvpe; | ||
124 | |||
125 | /* The list of TC's with this VPE */ | ||
126 | struct list_head tc; | ||
127 | |||
128 | /* The global list of tc's */ | ||
129 | struct list_head list; | ||
130 | }; | ||
139 | 131 | ||
140 | struct vpecontrol_ { | 132 | struct vpecontrol_ { |
141 | /* Virtual processing elements */ | 133 | /* Virtual processing elements */ |
@@ -146,7 +138,7 @@ struct vpecontrol_ { | |||
146 | } vpecontrol; | 138 | } vpecontrol; |
147 | 139 | ||
148 | static void release_progmem(void *ptr); | 140 | static void release_progmem(void *ptr); |
149 | static void dump_vpe(vpe_t * v); | 141 | static void dump_vpe(struct vpe * v); |
150 | extern void save_gp_address(unsigned int secbase, unsigned int rel); | 142 | extern void save_gp_address(unsigned int secbase, unsigned int rel); |
151 | 143 | ||
152 | /* get the vpe associated with this minor */ | 144 | /* get the vpe associated with this minor */ |
@@ -197,13 +189,11 @@ struct vpe *alloc_vpe(int minor) | |||
197 | { | 189 | { |
198 | struct vpe *v; | 190 | struct vpe *v; |
199 | 191 | ||
200 | if ((v = kmalloc(sizeof(struct vpe), GFP_KERNEL)) == NULL) { | 192 | if ((v = kzalloc(sizeof(struct vpe), GFP_KERNEL)) == NULL) { |
201 | printk(KERN_WARNING "VPE: alloc_vpe no mem\n"); | 193 | printk(KERN_WARNING "VPE: alloc_vpe no mem\n"); |
202 | return NULL; | 194 | return NULL; |
203 | } | 195 | } |
204 | 196 | ||
205 | memset(v, 0, sizeof(struct vpe)); | ||
206 | |||
207 | INIT_LIST_HEAD(&v->tc); | 197 | INIT_LIST_HEAD(&v->tc); |
208 | list_add_tail(&v->list, &vpecontrol.vpe_list); | 198 | list_add_tail(&v->list, &vpecontrol.vpe_list); |
209 | 199 | ||
@@ -216,13 +206,11 @@ struct tc *alloc_tc(int index) | |||
216 | { | 206 | { |
217 | struct tc *t; | 207 | struct tc *t; |
218 | 208 | ||
219 | if ((t = kmalloc(sizeof(struct tc), GFP_KERNEL)) == NULL) { | 209 | if ((t = kzalloc(sizeof(struct tc), GFP_KERNEL)) == NULL) { |
220 | printk(KERN_WARNING "VPE: alloc_tc no mem\n"); | 210 | printk(KERN_WARNING "VPE: alloc_tc no mem\n"); |
221 | return NULL; | 211 | return NULL; |
222 | } | 212 | } |
223 | 213 | ||
224 | memset(t, 0, sizeof(struct tc)); | ||
225 | |||
226 | INIT_LIST_HEAD(&t->tc); | 214 | INIT_LIST_HEAD(&t->tc); |
227 | list_add_tail(&t->list, &vpecontrol.tc_list); | 215 | list_add_tail(&t->list, &vpecontrol.tc_list); |
228 | 216 | ||
@@ -412,16 +400,17 @@ static int apply_r_mips_26(struct module *me, uint32_t *location, | |||
412 | return -ENOEXEC; | 400 | return -ENOEXEC; |
413 | } | 401 | } |
414 | 402 | ||
415 | /* Not desperately convinced this is a good check of an overflow condition | 403 | /* |
416 | anyway. But it gets in the way of handling undefined weak symbols which | 404 | * Not desperately convinced this is a good check of an overflow condition |
417 | we want to set to zero. | 405 | * anyway. But it gets in the way of handling undefined weak symbols which |
418 | if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) { | 406 | * we want to set to zero. |
419 | printk(KERN_ERR | 407 | * if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) { |
420 | "module %s: relocation overflow\n", | 408 | * printk(KERN_ERR |
421 | me->name); | 409 | * "module %s: relocation overflow\n", |
422 | return -ENOEXEC; | 410 | * me->name); |
423 | } | 411 | * return -ENOEXEC; |
424 | */ | 412 | * } |
413 | */ | ||
425 | 414 | ||
426 | *location = (*location & ~0x03ffffff) | | 415 | *location = (*location & ~0x03ffffff) | |
427 | ((*location + (v >> 2)) & 0x03ffffff); | 416 | ((*location + (v >> 2)) & 0x03ffffff); |
@@ -681,7 +670,7 @@ static void dump_tclist(void) | |||
681 | } | 670 | } |
682 | 671 | ||
683 | /* We are prepared so configure and start the VPE... */ | 672 | /* We are prepared so configure and start the VPE... */ |
684 | int vpe_run(vpe_t * v) | 673 | int vpe_run(struct vpe * v) |
685 | { | 674 | { |
686 | unsigned long val; | 675 | unsigned long val; |
687 | struct tc *t; | 676 | struct tc *t; |
@@ -772,7 +761,7 @@ int vpe_run(vpe_t * v) | |||
772 | return 0; | 761 | return 0; |
773 | } | 762 | } |
774 | 763 | ||
775 | static unsigned long find_vpe_symbols(vpe_t * v, Elf_Shdr * sechdrs, | 764 | static unsigned long find_vpe_symbols(struct vpe * v, Elf_Shdr * sechdrs, |
776 | unsigned int symindex, const char *strtab, | 765 | unsigned int symindex, const char *strtab, |
777 | struct module *mod) | 766 | struct module *mod) |
778 | { | 767 | { |
@@ -792,10 +781,12 @@ static unsigned long find_vpe_symbols(vpe_t * v, Elf_Shdr * sechdrs, | |||
792 | return 0; | 781 | return 0; |
793 | } | 782 | } |
794 | 783 | ||
795 | /* Allocates a VPE with some program code space(the load address), copies the contents | 784 | /* |
796 | of the program (p)buffer performing relocatations/etc, free's it when finished. | 785 | * Allocates a VPE with some program code space(the load address), copies |
786 | * the contents of the program (p)buffer performing relocatations/etc, | ||
787 | * free's it when finished. | ||
797 | */ | 788 | */ |
798 | int vpe_elfload(vpe_t * v) | 789 | int vpe_elfload(struct vpe * v) |
799 | { | 790 | { |
800 | Elf_Ehdr *hdr; | 791 | Elf_Ehdr *hdr; |
801 | Elf_Shdr *sechdrs; | 792 | Elf_Shdr *sechdrs; |
@@ -931,7 +922,7 @@ cleanup: | |||
931 | return err; | 922 | return err; |
932 | } | 923 | } |
933 | 924 | ||
934 | static void dump_vpe(vpe_t * v) | 925 | static void dump_vpe(struct vpe * v) |
935 | { | 926 | { |
936 | struct tc *t; | 927 | struct tc *t; |
937 | 928 | ||
@@ -947,7 +938,7 @@ static void dump_vpe(vpe_t * v) | |||
947 | static int vpe_open(struct inode *inode, struct file *filp) | 938 | static int vpe_open(struct inode *inode, struct file *filp) |
948 | { | 939 | { |
949 | int minor; | 940 | int minor; |
950 | vpe_t *v; | 941 | struct vpe *v; |
951 | 942 | ||
952 | /* assume only 1 device at the mo. */ | 943 | /* assume only 1 device at the mo. */ |
953 | if ((minor = MINOR(inode->i_rdev)) != 1) { | 944 | if ((minor = MINOR(inode->i_rdev)) != 1) { |
@@ -1001,7 +992,7 @@ static int vpe_open(struct inode *inode, struct file *filp) | |||
1001 | static int vpe_release(struct inode *inode, struct file *filp) | 992 | static int vpe_release(struct inode *inode, struct file *filp) |
1002 | { | 993 | { |
1003 | int minor, ret = 0; | 994 | int minor, ret = 0; |
1004 | vpe_t *v; | 995 | struct vpe *v; |
1005 | Elf_Ehdr *hdr; | 996 | Elf_Ehdr *hdr; |
1006 | 997 | ||
1007 | minor = MINOR(inode->i_rdev); | 998 | minor = MINOR(inode->i_rdev); |
@@ -1035,7 +1026,7 @@ static ssize_t vpe_write(struct file *file, const char __user * buffer, | |||
1035 | { | 1026 | { |
1036 | int minor; | 1027 | int minor; |
1037 | size_t ret = count; | 1028 | size_t ret = count; |
1038 | vpe_t *v; | 1029 | struct vpe *v; |
1039 | 1030 | ||
1040 | minor = MINOR(file->f_dentry->d_inode->i_rdev); | 1031 | minor = MINOR(file->f_dentry->d_inode->i_rdev); |
1041 | if ((v = get_vpe(minor)) == NULL) | 1032 | if ((v = get_vpe(minor)) == NULL) |
@@ -1180,14 +1171,11 @@ static int __init vpe_module_init(void) | |||
1180 | return -ENODEV; | 1171 | return -ENODEV; |
1181 | } | 1172 | } |
1182 | 1173 | ||
1183 | if ((major = register_chrdev(VPE_MAJOR, module_name, &vpe_fops) < 0)) { | 1174 | if ((major = register_chrdev(0, module_name, &vpe_fops) < 0)) { |
1184 | printk("VPE loader: unable to register character device\n"); | 1175 | printk("VPE loader: unable to register character device\n"); |
1185 | return -EBUSY; | 1176 | return major; |
1186 | } | 1177 | } |
1187 | 1178 | ||
1188 | if (major == 0) | ||
1189 | major = VPE_MAJOR; | ||
1190 | |||
1191 | dmt(); | 1179 | dmt(); |
1192 | dvpe(); | 1180 | dvpe(); |
1193 | 1181 | ||