178527Sassar/*	$NetBSD: lua.c,v 1.28 2022/03/31 19:30:17 pgoyette Exp $ */
2233294Sstas
3233294Sstas/*
4233294Sstas * Copyright (c) 2011 - 2017 by Marc Balmer <mbalmer@NetBSD.org>.
578527Sassar * Copyright (c) 2014 by Lourival Vieira Neto <lneto@NetBSD.org>.
6233294Sstas * All rights reserved.
7233294Sstas *
8233294Sstas * Redistribution and use in source and binary forms, with or without
978527Sassar * modification, are permitted provided that the following conditions
10233294Sstas * are met:
11233294Sstas * 1. Redistributions of source code must retain the above copyright
1278527Sassar *    notice, this list of conditions and the following disclaimer.
13233294Sstas * 2. Redistributions in binary form must reproduce the above copyright
14233294Sstas *    notice, this list of conditions and the following disclaimer in the
15233294Sstas *    documentation and/or other materials provided with the distribution.
1678527Sassar * 3. The name of the Author may not be used to endorse or promote products
17233294Sstas *    derived from this software without specific prior written permission.
18233294Sstas *
19233294Sstas * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
2078527Sassar * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22233294Sstas * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29233294Sstas * SUCH DAMAGE.
30233294Sstas */
31233294Sstas
3278527Sassar/* Lua device driver */
3378527Sassar
34233294Sstas#include <sys/param.h>
3578527Sassar#include <sys/fcntl.h>
3678527Sassar#include <sys/conf.h>
3778527Sassar#include <sys/condvar.h>
3878527Sassar#include <sys/device.h>
3978527Sassar#include <sys/ioctl.h>
4078527Sassar#include <sys/kmem.h>
4178527Sassar#include <sys/lock.h>
4278527Sassar#include <sys/lua.h>
43102644Snectar#include <sys/module.h>
4478527Sassar#include <sys/mutex.h>
45102644Snectar#include <sys/namei.h>
46102644Snectar#include <sys/queue.h>
47102644Snectar#include <sys/sysctl.h>
48102644Snectar#include <sys/vnode.h>
49102644Snectar#include <sys/cpu.h>
50178825Sdfr
51178825Sdfr#include <lauxlib.h>
52178825Sdfr
5378527Sassar#include "luavar.h"
54102644Snectar
55233294Sstasstruct lua_softc {
56102644Snectar	device_t		 sc_dev;
57102644Snectar
58233294Sstas	kmutex_t		 sc_lock;
59102644Snectar	kcondvar_t		 sc_inuse_cv;
60102644Snectar	bool			 sc_inuse;
61233294Sstas
62102644Snectar	/* Locking access to state queues */
6390926Snectar	kmutex_t		 sc_state_lock;
6478527Sassar	kcondvar_t		 sc_state_cv;
65	bool			 sc_state;
66
67	struct sysctllog	*sc_log;
68};
69
70static device_t	sc_self;
71static bool	lua_autoload_on = true;
72static bool	lua_require_on = true;
73static bool	lua_bytecode_on = false;
74static int	lua_verbose;
75static int	lua_max_instr;
76
77static LIST_HEAD(, lua_state)	lua_states =
78    LIST_HEAD_INITIALIZER(lua_states);
79static LIST_HEAD(, lua_module)	lua_modules =
80    LIST_HEAD_INITIALIZER(lua_modules);
81
82static int lua_match(device_t, cfdata_t, void *);
83static void lua_attach(device_t, device_t, void *);
84static int lua_detach(device_t, int);
85static klua_State *klua_find(const char *);
86static const char *lua_reader(lua_State *, void *, size_t *);
87static void lua_maxcount(lua_State *, lua_Debug *);
88
89static int lua_require(lua_State *);
90
91CFATTACH_DECL_NEW(lua, sizeof(struct lua_softc),
92	lua_match, lua_attach, lua_detach, NULL);
93
94dev_type_open(luaopen);
95dev_type_close(luaclose);
96dev_type_ioctl(luaioctl);
97
98const 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
113struct lua_loadstate {
114	struct vnode	*vp;
115	size_t		 size;
116	off_t		 off;
117};
118
119extern struct cfdriver lua_cd;
120
121static int
122lua_match(device_t parent, cfdata_t match, void *aux)
123{
124	return 1;
125}
126
127static void
128lua_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
204static int
205lua_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
235int
236luaopen(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
263int
264luaclose(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
278int
279luaioctl(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
500static int
501lua_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
550typedef struct {
551	size_t size;
552} alloc_header_t;
553
554static void *
555lua_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
591static const char *
592lua_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
618static void
619lua_maxcount(lua_State *L, lua_Debug *d)
620{
621	lua_pushstring(L, "maximum instruction count exceeded");
622	lua_error(L);
623}
624
625int
626klua_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
643int
644klua_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
664klua_State *
665klua_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
711finish:
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
719inline klua_State *
720kluaL_newstate(const char *name, const char *desc, int ipl)
721{
722	return klua_newstate(lua_alloc, NULL, name, desc, ipl);
723}
724
725void
726klua_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
770static klua_State *
771klua_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
806inline void
807klua_lock(klua_State *K)
808{
809	mutex_enter(&K->ks_lock);
810}
811
812inline void
813klua_unlock(klua_State *K)
814{
815	mutex_exit(&K->ks_lock);
816}
817
818MODULE(MODULE_CLASS_MISC, lua, NULL);
819
820#ifdef _MODULE
821static const struct cfiattrdata luabus_iattrdata = {
822	"luabus", 0, { { NULL, NULL, 0 },}
823};
824
825static const struct cfiattrdata *const lua_attrs[] = {
826	&luabus_iattrdata, NULL
827};
828
829CFDRIVER_DECL(lua, DV_DULL, lua_attrs);
830extern struct cfattach lua_ca;
831static int lualoc[] = {
832	-1,
833	-1,
834	-1
835};
836
837static 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
851static int
852lua_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