xref: /netbsd-src/sys/modules/lua/lua.c (revision 97f8debd624665fdeaf9373bf4602036de3fcd85)
1 /*	$NetBSD: lua.c,v 1.28 2022/03/31 19:30:17 pgoyette Exp $ */
2 
3 /*
4  * Copyright (c) 2011 - 2017 by Marc Balmer <mbalmer@NetBSD.org>.
5  * Copyright (c) 2014 by Lourival Vieira Neto <lneto@NetBSD.org>.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. The name of the Author may not be used to endorse or promote products
17  *    derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31 
32 /* Lua device driver */
33 
34 #include <sys/param.h>
35 #include <sys/fcntl.h>
36 #include <sys/conf.h>
37 #include <sys/condvar.h>
38 #include <sys/device.h>
39 #include <sys/ioctl.h>
40 #include <sys/kmem.h>
41 #include <sys/lock.h>
42 #include <sys/lua.h>
43 #include <sys/module.h>
44 #include <sys/mutex.h>
45 #include <sys/namei.h>
46 #include <sys/queue.h>
47 #include <sys/sysctl.h>
48 #include <sys/vnode.h>
49 #include <sys/cpu.h>
50 
51 #include <lauxlib.h>
52 
53 #include "luavar.h"
54 
55 struct lua_softc {
56 	device_t		 sc_dev;
57 
58 	kmutex_t		 sc_lock;
59 	kcondvar_t		 sc_inuse_cv;
60 	bool			 sc_inuse;
61 
62 	/* Locking access to state queues */
63 	kmutex_t		 sc_state_lock;
64 	kcondvar_t		 sc_state_cv;
65 	bool			 sc_state;
66 
67 	struct sysctllog	*sc_log;
68 };
69 
70 static device_t	sc_self;
71 static bool	lua_autoload_on = true;
72 static bool	lua_require_on = true;
73 static bool	lua_bytecode_on = false;
74 static int	lua_verbose;
75 static int	lua_max_instr;
76 
77 static LIST_HEAD(, lua_state)	lua_states =
78     LIST_HEAD_INITIALIZER(lua_states);
79 static LIST_HEAD(, lua_module)	lua_modules =
80     LIST_HEAD_INITIALIZER(lua_modules);
81 
82 static int lua_match(device_t, cfdata_t, void *);
83 static void lua_attach(device_t, device_t, void *);
84 static int lua_detach(device_t, int);
85 static klua_State *klua_find(const char *);
86 static const char *lua_reader(lua_State *, void *, size_t *);
87 static void lua_maxcount(lua_State *, lua_Debug *);
88 
89 static int lua_require(lua_State *);
90 
91 CFATTACH_DECL_NEW(lua, sizeof(struct lua_softc),
92 	lua_match, lua_attach, lua_detach, NULL);
93 
94 dev_type_open(luaopen);
95 dev_type_close(luaclose);
96 dev_type_ioctl(luaioctl);
97 
98 const struct cdevsw lua_cdevsw = {
99 	.d_open = luaopen,
100 	.d_close = luaclose,
101 	.d_read = noread,
102 	.d_write = nowrite,
103 	.d_ioctl = luaioctl,
104 	.d_stop = nostop,
105 	.d_tty = notty,
106 	.d_poll = nopoll,
107 	.d_mmap = nommap,
108 	.d_kqfilter = nokqfilter,
109 	.d_discard = nodiscard,
110 	.d_flag = D_OTHER | D_MPSAFE
111 };
112 
113 struct lua_loadstate {
114 	struct vnode	*vp;
115 	size_t		 size;
116 	off_t		 off;
117 };
118 
119 extern struct cfdriver lua_cd;
120 
121 static int
lua_match(device_t parent,cfdata_t match,void * aux)122 lua_match(device_t parent, cfdata_t match, void *aux)
123 {
124 	return 1;
125 }
126 
127 static void
lua_attach(device_t parent,device_t self,void * aux)128 lua_attach(device_t parent, device_t self, void *aux)
129 {
130 	struct lua_softc *sc;
131 	const struct sysctlnode *node;
132 
133 	if (sc_self)
134 		return;
135 
136 	sc = device_private(self);
137 	sc->sc_dev = self;
138 	sc_self = self;
139 
140 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM);
141 	cv_init(&sc->sc_inuse_cv, "luactl");
142 
143 	mutex_init(&sc->sc_state_lock, MUTEX_DEFAULT, IPL_VM);
144 	cv_init(&sc->sc_state_cv, "luastate");
145 
146 	if (!pmf_device_register(self, NULL, NULL))
147 		aprint_error_dev(self, "couldn't establish power handler\n");
148 
149 	/* Sysctl to provide some control over behaviour */
150         sysctl_createv(&sc->sc_log, 0, NULL, &node,
151             CTLFLAG_OWNDESC,
152             CTLTYPE_NODE, "lua",
153             SYSCTL_DESCR("Lua options"),
154             NULL, 0, NULL, 0,
155             CTL_KERN, CTL_CREATE, CTL_EOL);
156 
157         if (node == NULL) {
158 		aprint_error(": can't create sysctl node\n");
159                 return;
160 	}
161 
162 	/*
163 	 * XXX Some of the sysctl values must not be changed after the
164 	 * securelevel has been raised.
165 	 */
166         sysctl_createv(&sc->sc_log, 0, &node, NULL,
167             CTLFLAG_READWRITE | CTLFLAG_OWNDESC,
168             CTLTYPE_BOOL, "require",
169             SYSCTL_DESCR("Enable the require command"),
170             NULL, 0, &lua_require_on, 0,
171 	    CTL_CREATE, CTL_EOL);
172 
173         sysctl_createv(&sc->sc_log, 0, &node, NULL,
174             CTLFLAG_READWRITE | CTLFLAG_OWNDESC,
175             CTLTYPE_BOOL, "autoload",
176             SYSCTL_DESCR("Enable automatic load of modules"),
177             NULL, 0, &lua_autoload_on, 0,
178 	    CTL_CREATE, CTL_EOL);
179 
180         sysctl_createv(&sc->sc_log, 0, &node, NULL,
181             CTLFLAG_READWRITE | CTLFLAG_OWNDESC,
182             CTLTYPE_BOOL, "bytecode",
183             SYSCTL_DESCR("Enable loading of bytecode"),
184             NULL, 0, &lua_bytecode_on, 0,
185 	    CTL_CREATE, CTL_EOL);
186 
187         sysctl_createv(&sc->sc_log, 0, &node, NULL,
188             CTLFLAG_READWRITE | CTLFLAG_OWNDESC,
189             CTLTYPE_INT, "verbose",
190             SYSCTL_DESCR("Enable verbose output"),
191             NULL, 0, &lua_verbose, 0,
192 	    CTL_CREATE, CTL_EOL);
193 
194         sysctl_createv(&sc->sc_log, 0, &node, NULL,
195             CTLFLAG_READWRITE | CTLFLAG_OWNDESC,
196             CTLTYPE_INT, "maxcount",
197             SYSCTL_DESCR("Limit maximum instruction count"),
198             NULL, 0, &lua_max_instr, 0,
199 	    CTL_CREATE, CTL_EOL);
200 
201 	aprint_normal_dev(self, "%s\n", LUA_COPYRIGHT);
202 }
203 
204 static int
lua_detach(device_t self,int flags)205 lua_detach(device_t self, int flags)
206 {
207 	struct lua_softc *sc;
208 	struct lua_state *s;
209 
210 	sc = device_private(self);
211 	pmf_device_deregister(self);
212 
213 	if (sc->sc_log != NULL) {
214 		sysctl_teardown(&sc->sc_log);
215 		sc->sc_log = NULL;
216 	}
217 
218 	/* Traverse the list of states and close them */
219 	while ((s = LIST_FIRST(&lua_states)) != NULL) {
220 		LIST_REMOVE(s, lua_next);
221 		klua_close(s->K);
222 		if (lua_verbose)
223 			device_printf(self, "state %s destroyed\n",
224 			    s->lua_name);
225 		kmem_free(s, sizeof(struct lua_state));
226 	}
227 	mutex_destroy(&sc->sc_lock);
228 	cv_destroy(&sc->sc_inuse_cv);
229 	mutex_destroy(&sc->sc_state_lock);
230 	cv_destroy(&sc->sc_state_cv);
231 	sc_self = NULL;
232 	return 0;
233 }
234 
235 int
luaopen(dev_t dev,int flag,int mode,struct lwp * l)236 luaopen(dev_t dev, int flag, int mode, struct lwp *l)
237 {
238 	struct lua_softc *sc;
239 	int error = 0;
240 
241 	if (minor(dev) > 0)
242 		return ENXIO;
243 
244 	sc = device_lookup_private(&lua_cd, minor(dev));
245 	if (sc == NULL)
246 		return ENXIO;
247 
248 	mutex_enter(&sc->sc_lock);
249 	while (sc->sc_inuse == true) {
250 		error = cv_wait_sig(&sc->sc_inuse_cv, &sc->sc_lock);
251 		if (error)
252 			break;
253 	}
254 	if (!error)
255 		sc->sc_inuse = true;
256 	mutex_exit(&sc->sc_lock);
257 
258 	if (error)
259 		return error;
260 	return 0;
261 }
262 
263 int
luaclose(dev_t dev,int flag,int mode,struct lwp * l)264 luaclose(dev_t dev, int flag, int mode, struct lwp *l)
265 {
266 	struct lua_softc *sc;
267 
268 	if (minor(dev) > 0)
269 		return ENXIO;
270 	sc = device_lookup_private(&lua_cd, minor(dev));
271 	mutex_enter(&sc->sc_lock);
272 	sc->sc_inuse = false;
273 	cv_signal(&sc->sc_inuse_cv);
274 	mutex_exit(&sc->sc_lock);
275 	return 0;
276 }
277 
278 int
luaioctl(dev_t dev,u_long cmd,void * data,int flag,struct lwp * l)279 luaioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
280 {
281 	struct lua_softc *sc;
282 	struct lua_info *info;
283 	struct lua_create *create;
284 	struct lua_require *require;
285 	struct lua_load *load;
286 	struct lua_state *s;
287 	struct lua_module *m;
288 	kauth_cred_t cred;
289 	struct vnode *vp;
290 	struct pathbuf *pb;
291 	struct vattr va;
292 	struct lua_loadstate ls;
293 	struct lua_state_info *states;
294 	int error, n;
295 	klua_State *K;
296 
297 	sc = device_lookup_private(&lua_cd, minor(dev));
298 	if (!device_is_active(sc->sc_dev))
299 		return EBUSY;
300 
301 	switch (cmd) {
302 	case LUAINFO:
303 		info = data;
304 		if (info->states == NULL) {
305 			info->num_states = 0;
306 			LIST_FOREACH(s, &lua_states, lua_next)
307 				info->num_states++;
308 		} else {
309 			n = 0;
310 			LIST_FOREACH(s, &lua_states, lua_next) {
311 				if (n > info->num_states)
312 					break;
313 				n++;
314 			}
315 			info->num_states = n;
316 			states = kmem_alloc(sizeof(*states) * n, KM_SLEEP);
317 			if (copyin(info->states, states, sizeof(*states) * n)
318 			    == 0) {
319 				n = 0;
320 				LIST_FOREACH(s, &lua_states, lua_next) {
321 					if (n > info->num_states)
322 						break;
323 					strcpy(states[n].name, s->lua_name);
324 					strcpy(states[n].desc, s->lua_desc);
325 					states[n].user = s->K->ks_user;
326 					n++;
327 				}
328 				copyout(states, info->states,
329 				    sizeof(*states) * n);
330 				kmem_free(states, sizeof(*states) * n);
331 			}
332 		}
333 		break;
334 	case LUACREATE:
335 		create = data;
336 
337 		if (*create->name == '_') {
338 			if (lua_verbose)
339 				device_printf(sc->sc_dev, "names of user "
340 				    "created states must not begin with '_'");
341 				return ENXIO;
342 		}
343 		LIST_FOREACH(s, &lua_states, lua_next)
344 			if (!strcmp(s->lua_name, create->name)) {
345 				if (lua_verbose)
346 					device_printf(sc->sc_dev,
347 					    "state %s exists\n", create->name);
348 				return EBUSY;
349 			}
350 
351 		K = kluaL_newstate(create->name, create->desc, IPL_NONE);
352 
353 		if (K == NULL)
354 			return ENOMEM;
355 
356 		K->ks_user = true;
357 
358 		if (lua_verbose)
359 			device_printf(sc->sc_dev, "state %s created\n",
360 			    create->name);
361 		break;
362 	case LUADESTROY:
363 		create = data;
364 
365 		K = klua_find(create->name);
366 
367 		if (K != NULL && (K->ks_user == true)) {
368 			klua_close(K);
369 			return 0;
370 		}
371 		return EBUSY;
372 	case LUAREQUIRE:	/* 'require' a module in a State */
373 		require = data;
374 		LIST_FOREACH(s, &lua_states, lua_next)
375 			if (!strcmp(s->lua_name, require->state)) {
376 				LIST_FOREACH(m, &s->lua_modules, mod_next)
377 					if (!strcmp(m->mod_name, require->module))
378 						return ENXIO;
379 				LIST_FOREACH(m, &lua_modules, mod_next)
380 					if (!strcmp(m->mod_name,
381 					    require->module)) {
382 					    	if (lua_verbose)
383 						    	device_printf(
384 						    	    sc->sc_dev,
385 					    		    "requiring module "
386 					    		    "%s to state %s\n",
387 					    		    m->mod_name,
388 					    		    s->lua_name);
389 						klua_lock(s->K);
390 						luaL_requiref(
391 							s->K->L,
392 							m->mod_name,
393 							m->open,
394 							1);
395 						klua_unlock(s->K);
396 					    	m->refcount++;
397 					    	LIST_INSERT_HEAD(
398 					    	    &s->lua_modules, m,
399 					    	    mod_next);
400 					    	return 0;
401 					}
402 			}
403 		return ENXIO;
404 	case LUALOAD:
405 		load = data;
406 		if (strrchr(load->path, '/') == NULL)
407 			return ENXIO;
408 
409 		LIST_FOREACH(s, &lua_states, lua_next)
410 			if (!strcmp(s->lua_name, load->state)) {
411 				if (lua_verbose)
412 					device_printf(sc->sc_dev,
413 					    "loading %s into state %s\n",
414 					    load->path, s->lua_name);
415 				cred = kauth_cred_get();
416 				pb = pathbuf_create(load->path);
417 				if (pb == NULL)
418 					return ENOMEM;
419 				error = vn_open(NULL, pb, NOCHROOT, FREAD, 0,
420 				    &vp, NULL, NULL);
421 				pathbuf_destroy(pb);
422 				if (error) {
423 					if (lua_verbose)
424 						device_printf(sc->sc_dev,
425 						    "error vn_open %d\n",
426 						    error);
427 					return error;
428 				}
429 				error = VOP_GETATTR(vp, &va,
430 				    kauth_cred_get());
431 				if (error) {
432 					VOP_UNLOCK(vp);
433 					vn_close(vp, FREAD,
434 					    kauth_cred_get());
435 					if (lua_verbose)
436 						device_printf(sc->sc_dev,
437 						    "erro VOP_GETATTR %d\n",
438 						    error);
439 					return error;
440 				}
441 				if (va.va_type != VREG) {
442 					VOP_UNLOCK(vp);
443 					vn_close(vp, FREAD,
444 					    kauth_cred_get());
445 					return EINVAL;
446 				}
447 				ls.vp = vp;
448 				ls.off = 0L;
449 				ls.size = va.va_size;
450 				VOP_UNLOCK(vp);
451 				klua_lock(s->K);
452 				error = lua_load(s->K->L, lua_reader, &ls,
453 				    strrchr(load->path, '/') + 1, "bt");
454 				vn_close(vp, FREAD, cred);
455 				switch (error) {
456 				case 0:	/* no error */
457 					break;
458 				case LUA_ERRSYNTAX:
459 					if (lua_verbose)
460 						device_printf(sc->sc_dev,
461 						    "syntax error\n");
462 					klua_unlock(s->K);
463 					return EINVAL;
464 				case LUA_ERRMEM:
465 					if (lua_verbose)
466 						device_printf(sc->sc_dev,
467 						    "memory error\n");
468 					klua_unlock(s->K);
469 					return ENOMEM;
470 				default:
471 					if (lua_verbose)
472 						device_printf(sc->sc_dev,
473 						    "load error %d: %s\n",
474 						    error,
475 						    lua_tostring(s->K->L, -1));
476 					klua_unlock(s->K);
477 					return EINVAL;
478 				}
479 				if (lua_max_instr > 0)
480 					lua_sethook(s->K->L, lua_maxcount,
481 					    LUA_MASKCOUNT, lua_max_instr);
482 				error = lua_pcall(s->K->L, 0, LUA_MULTRET, 0);
483 				if (error) {
484 					if (lua_verbose) {
485 						device_printf(sc->sc_dev,
486 						    "execution error: %s\n",
487 						    lua_tostring(s->K->L, -1));
488 					}
489 					klua_unlock(s->K);
490 					return EINVAL;
491 				}
492 				klua_unlock(s->K);
493 				return 0;
494 			}
495 		return ENXIO;
496 	}
497 	return 0;
498 }
499 
500 static int
lua_require(lua_State * L)501 lua_require(lua_State *L)
502 {
503 	struct lua_state *s;
504 	struct lua_module *m, *md;
505 	const char *module;
506 	char name[MAXPATHLEN];
507 
508 	module = lua_tostring(L, -1);
509 	md = NULL;
510 	LIST_FOREACH(m, &lua_modules, mod_next)
511 		if (!strcmp(m->mod_name, module)) {
512 			md = m;
513 			break;
514 		}
515 
516 	if (md == NULL && lua_autoload_on && strchr(module, '/') == NULL) {
517 		snprintf(name, sizeof name, "lua%s", module);
518 		if (lua_verbose)
519 			device_printf(sc_self, "autoload %s\n", name);
520 		module_autoload(name, MODULE_CLASS_MISC);
521 		LIST_FOREACH(m, &lua_modules, mod_next)
522 			if (!strcmp(m->mod_name, module)) {
523 				md = m;
524 				break;
525 			}
526 	}
527 
528 	if (md != NULL)
529 		LIST_FOREACH(s, &lua_states, lua_next)
530 			if (s->K->L == L) {
531 				if (lua_verbose)
532 					device_printf(sc_self,
533 					    "require module %s\n",
534 					    md->mod_name);
535 				luaL_requiref(L, md->mod_name, md->open, 0);
536 
537 				LIST_FOREACH(m, &s->lua_modules, mod_next)
538 					if (m == md)
539 						return 1;
540 
541 				md->refcount++;
542 				LIST_INSERT_HEAD(&s->lua_modules, md, mod_next);
543 				return 1;
544 			}
545 
546 	lua_pushstring(L, "module not found");
547 	return lua_error(L);
548 }
549 
550 typedef struct {
551 	size_t size;
552 } alloc_header_t;
553 
554 static void *
lua_alloc(void * ud,void * ptr,size_t osize,size_t nsize)555 lua_alloc(void *ud, void *ptr, size_t osize, size_t nsize)
556 {
557 	void *nptr = NULL;
558 
559 	/*
560 	 * Make sure that buffers allocated by lua_alloc() are aligned to
561 	 * 8-byte boundaries as done by kmem_alloc(9).
562 	 */
563 	const size_t hdr_size = roundup(sizeof(alloc_header_t), 8);
564 	alloc_header_t *hdr = (alloc_header_t *) ((char *) ptr - hdr_size);
565 
566 	if (nsize == 0) { /* freeing */
567 		if (ptr != NULL)
568 			kmem_intr_free(hdr, hdr->size);
569 	} else if (ptr != NULL && nsize <= hdr->size - hdr_size) /* shrinking */
570 		return ptr; /* don't need to reallocate */
571 	else { /* creating or expanding */
572 		km_flag_t sleep = cpu_intr_p() || cpu_softintr_p() ?
573 			KM_NOSLEEP : KM_SLEEP;
574 
575 		size_t alloc_size = nsize + hdr_size;
576 		alloc_header_t *nhdr = kmem_intr_alloc(alloc_size, sleep);
577 		if (nhdr == NULL) /* failed to allocate */
578 			return NULL;
579 
580 		nhdr->size = alloc_size;
581 		nptr = (void *) ((char *) nhdr + hdr_size);
582 
583 		if (ptr != NULL) { /* expanding */
584 			memcpy(nptr, ptr, osize);
585 			kmem_intr_free(hdr, hdr->size);
586 		}
587 	}
588 	return nptr;
589 }
590 
591 static const char *
lua_reader(lua_State * L,void * data,size_t * size)592 lua_reader(lua_State *L, void *data, size_t *size)
593 {
594 	struct lua_loadstate *ls;
595 	static char buf[1024];
596 	size_t rsiz;
597 
598 	ls = data;
599 	if (ls->size < sizeof(buf))
600 		rsiz = ls->size;
601 	else
602 		rsiz = sizeof(buf);
603 	vn_rdwr(UIO_READ, ls->vp, buf, rsiz, ls->off, UIO_SYSSPACE,
604 	    0, curlwp->l_cred, NULL, curlwp);
605 	if (ls->off == 0L && lua_bytecode_on == false && buf[0] == 0x1b) {
606 		*size = 0L;
607 		lua_pushstring(L, "loading of bytecode is not allowed");
608 		lua_error(L);
609 		return NULL;
610 	} else {
611 		*size = rsiz;
612 		ls->off += *size;
613 		ls->size -= *size;
614 	}
615 	return buf;
616 }
617 
618 static void
lua_maxcount(lua_State * L,lua_Debug * d)619 lua_maxcount(lua_State *L, lua_Debug *d)
620 {
621 	lua_pushstring(L, "maximum instruction count exceeded");
622 	lua_error(L);
623 }
624 
625 int
klua_mod_register(const char * name,lua_CFunction open)626 klua_mod_register(const char *name, lua_CFunction open)
627 {
628 	struct lua_module *m;
629 
630 	LIST_FOREACH(m, &lua_modules, mod_next)
631 		if (!strcmp(m->mod_name, name))
632 			return EBUSY;
633 	m = kmem_zalloc(sizeof(struct lua_module), KM_SLEEP);
634 	strlcpy(m->mod_name, name, LUA_MAX_MODNAME);
635 	m->open = open;
636 	m->refcount = 0;
637 	LIST_INSERT_HEAD(&lua_modules, m, mod_next);
638 	if (lua_verbose)
639 		device_printf(sc_self, "registered lua module %s\n", name);
640 	return 0;
641 }
642 
643 int
klua_mod_unregister(const char * name)644 klua_mod_unregister(const char *name)
645 {
646 	struct lua_module *m;
647 
648 	LIST_FOREACH(m, &lua_modules, mod_next)
649 		if (!strcmp(m->mod_name, name)) {
650 			if (m->refcount == 0) {
651 				LIST_REMOVE(m, mod_next);
652 				kmem_free(m, sizeof(struct lua_module));
653 				if (lua_verbose)
654 					device_printf(sc_self,
655 					    "unregistered lua module %s\n",
656 					    name);
657 				return 0;
658 			} else
659 				return EBUSY;
660 		}
661 	return 0;
662 }
663 
664 klua_State *
klua_newstate(lua_Alloc f,void * ud,const char * name,const char * desc,int ipl)665 klua_newstate(lua_Alloc f, void *ud, const char *name, const char *desc,
666     int ipl)
667 {
668 	klua_State *K;
669 	struct lua_state *s;
670 	struct lua_softc *sc;
671 	int error = 0;
672 
673 	s = kmem_zalloc(sizeof(struct lua_state), KM_SLEEP);
674 	sc = device_private(sc_self);
675 	mutex_enter(&sc->sc_state_lock);
676 	while (sc->sc_state == true) {
677 		error = cv_wait_sig(&sc->sc_state_cv, &sc->sc_state_lock);
678 		if (error)
679 			break;
680 	}
681 	if (!error)
682 		sc->sc_state = true;
683 	mutex_exit(&sc->sc_state_lock);
684 
685 	if (error) {
686 		kmem_free(s, sizeof(struct lua_state));
687 		return NULL;
688 	}
689 
690 	K = kmem_zalloc(sizeof(klua_State), KM_SLEEP);
691 	K->L = lua_newstate(f, ud);
692 	K->ks_user = false;
693 	if (K->L == NULL) {
694 		kmem_free(K, sizeof(klua_State));
695 		K = NULL;
696 		goto finish;
697 	}
698 
699 	strlcpy(s->lua_name, name, MAX_LUA_NAME);
700 	strlcpy(s->lua_desc, desc, MAX_LUA_DESC);
701 	s->K = K;
702 
703 	if (lua_require_on || lua_autoload_on) {
704 		lua_pushcfunction(K->L, lua_require);
705 		lua_setglobal(K->L, "require");
706 	}
707 	LIST_INSERT_HEAD(&lua_states, s, lua_next);
708 
709 	mutex_init(&K->ks_lock, MUTEX_DEFAULT, ipl);
710 
711 finish:
712 	mutex_enter(&sc->sc_state_lock);
713 	sc->sc_state = false;
714 	cv_signal(&sc->sc_state_cv);
715 	mutex_exit(&sc->sc_state_lock);
716 	return K;
717 }
718 
719 inline klua_State *
kluaL_newstate(const char * name,const char * desc,int ipl)720 kluaL_newstate(const char *name, const char *desc, int ipl)
721 {
722 	return klua_newstate(lua_alloc, NULL, name, desc, ipl);
723 }
724 
725 void
klua_close(klua_State * K)726 klua_close(klua_State *K)
727 {
728 	struct lua_state *s, *ns;
729 	struct lua_softc *sc;
730 	struct lua_module *m;
731 	int error = 0;
732 
733 	/* XXX consider registering a handler instead of a fixed name. */
734 	lua_getglobal(K->L, "onClose");
735 	if (lua_isfunction(K->L, -1))
736 		lua_pcall(K->L, -1, 0, 0);
737 
738 	sc = device_private(sc_self);
739 	mutex_enter(&sc->sc_state_lock);
740 	while (sc->sc_state == true) {
741 		error = cv_wait_sig(&sc->sc_state_cv, &sc->sc_state_lock);
742 		if (error)
743 			break;
744 	}
745 	if (!error)
746 		sc->sc_state = true;
747 	mutex_exit(&sc->sc_state_lock);
748 
749 	if (error)
750 		return;		/* Nothing we can do... */
751 
752 	LIST_FOREACH_SAFE(s, &lua_states, lua_next, ns)
753 		if (s->K == K) {
754 			LIST_REMOVE(s, lua_next);
755 			LIST_FOREACH(m, &s->lua_modules, mod_next)
756 				m->refcount--;
757 			kmem_free(s, sizeof(struct lua_state));
758 		}
759 
760 	lua_close(K->L);
761 	mutex_destroy(&K->ks_lock);
762 	kmem_free(K, sizeof(klua_State));
763 
764 	mutex_enter(&sc->sc_state_lock);
765 	sc->sc_state = false;
766 	cv_signal(&sc->sc_state_cv);
767 	mutex_exit(&sc->sc_state_lock);
768 }
769 
770 static klua_State *
klua_find(const char * name)771 klua_find(const char *name)
772 {
773 	struct lua_state *s;
774 	struct lua_softc *sc;
775 	klua_State *K;
776 	int error = 0;
777 
778 	K = NULL;
779 	sc = device_private(sc_self);
780 	mutex_enter(&sc->sc_state_lock);
781 	while (sc->sc_state == true) {
782 		error = cv_wait_sig(&sc->sc_state_cv, &sc->sc_state_lock);
783 		if (error)
784 			break;
785 	}
786 	if (!error)
787 		sc->sc_state = true;
788 	mutex_exit(&sc->sc_state_lock);
789 
790 	if (error)
791 		return NULL;
792 
793 	LIST_FOREACH(s, &lua_states, lua_next)
794 		if (!strcmp(s->lua_name, name)) {
795 			K = s->K;
796 			break;
797 		}
798 
799 	mutex_enter(&sc->sc_state_lock);
800 	sc->sc_state = false;
801 	cv_signal(&sc->sc_state_cv);
802 	mutex_exit(&sc->sc_state_lock);
803 	return K;
804 }
805 
806 inline void
klua_lock(klua_State * K)807 klua_lock(klua_State *K)
808 {
809 	mutex_enter(&K->ks_lock);
810 }
811 
812 inline void
klua_unlock(klua_State * K)813 klua_unlock(klua_State *K)
814 {
815 	mutex_exit(&K->ks_lock);
816 }
817 
818 MODULE(MODULE_CLASS_MISC, lua, NULL);
819 
820 #ifdef _MODULE
821 static const struct cfiattrdata luabus_iattrdata = {
822 	"luabus", 0, { { NULL, NULL, 0 },}
823 };
824 
825 static const struct cfiattrdata *const lua_attrs[] = {
826 	&luabus_iattrdata, NULL
827 };
828 
829 CFDRIVER_DECL(lua, DV_DULL, lua_attrs);
830 extern struct cfattach lua_ca;
831 static int lualoc[] = {
832 	-1,
833 	-1,
834 	-1
835 };
836 
837 static struct cfdata lua_cfdata[] = {
838 	{
839 		.cf_name = "lua",
840 		.cf_atname = "lua",
841 		.cf_unit = 0,
842 		.cf_fstate = FSTATE_STAR,
843 		.cf_loc = lualoc,
844 		.cf_flags = 0,
845 		.cf_pspec = NULL,
846 	},
847 	{ NULL, NULL, 0, FSTATE_NOTFOUND, NULL, 0, NULL }
848 };
849 #endif
850 
851 static int
lua_modcmd(modcmd_t cmd,void * opaque)852 lua_modcmd(modcmd_t cmd, void *opaque)
853 {
854 #ifdef _MODULE
855 	devmajor_t cmajor, bmajor;
856 	int error = 0;
857 
858 	cmajor = bmajor = NODEVMAJOR;
859 #endif
860 	switch (cmd) {
861 	case MODULE_CMD_INIT:
862 #ifdef _MODULE
863 		error = devsw_attach(lua_cd.cd_name, NULL, &bmajor,
864 		    &lua_cdevsw, &cmajor);
865 		if (error) {
866 			aprint_error("%s: unable to register devsw\n",
867 			    lua_cd.cd_name);
868 			return error;
869 		}
870 
871 		error = config_cfdriver_attach(&lua_cd);
872 		if (error) {
873 			devsw_detach(NULL, &lua_cdevsw);
874 			return error;
875 		}
876 
877 		error = config_cfattach_attach(lua_cd.cd_name,
878 		    &lua_ca);
879 		if (error) {
880 			config_cfdriver_detach(&lua_cd);
881 			devsw_detach(NULL, &lua_cdevsw);
882 			aprint_error("%s: unable to register cfattach\n",
883 			    lua_cd.cd_name);
884 			return error;
885 		}
886 		error = config_cfdata_attach(lua_cfdata, 1);
887 		if (error) {
888 			config_cfattach_detach(lua_cd.cd_name,
889 			    &lua_ca);
890 			config_cfdriver_detach(&lua_cd);
891 			devsw_detach(NULL, &lua_cdevsw);
892 			aprint_error("%s: unable to register cfdata\n",
893 			    lua_cd.cd_name);
894 			return error;
895 		}
896 		config_attach_pseudo(lua_cfdata);
897 #endif
898 		return 0;
899 	case MODULE_CMD_FINI:
900 #ifdef _MODULE
901 		error = config_cfdata_detach(lua_cfdata);
902 		if (error)
903 			return error;
904 
905 		config_cfattach_detach(lua_cd.cd_name, &lua_ca);
906 		config_cfdriver_detach(&lua_cd);
907 		devsw_detach(NULL, &lua_cdevsw);
908 #endif
909 		return 0;
910 	case MODULE_CMD_AUTOUNLOAD:
911 		/* no auto-unload */
912 		return EBUSY;
913 	default:
914 		return ENOTTY;
915 	}
916 }
917