Page MenuHomeFreeBSD

D53728.id166350.diff
No OneTemporary

D53728.id166350.diff

diff --git a/sys/dev/vmm/vmm_dev.c b/sys/dev/vmm/vmm_dev.c
--- a/sys/dev/vmm/vmm_dev.c
+++ b/sys/dev/vmm/vmm_dev.c
@@ -17,6 +17,7 @@
#include <sys/module.h>
#include <sys/priv.h>
#include <sys/proc.h>
+#include <sys/resourcevar.h>
#include <sys/queue.h>
#include <sys/smp.h>
#include <sys/sx.h>
@@ -96,6 +97,10 @@
SYSCTL_UINT(_hw_vmm, OID_AUTO, maxcpu, CTLFLAG_RDTUN | CTLFLAG_NOFETCH,
&vm_maxcpu, 0, "Maximum number of vCPUs");
+u_int vm_maxvmms;
+SYSCTL_UINT(_hw_vmm, OID_AUTO, maxvmms, CTLFLAG_RW,
+ &vm_maxvmms, 0, "Maximum number of VMM instances per user");
+
static void devmem_destroy(void *arg);
static int devmem_create_cdev(struct vmmdev_softc *sc, int id, char *devmem);
@@ -898,8 +903,10 @@
if (sc->vm != NULL)
vm_destroy(sc->vm);
- if (sc->ucred != NULL)
+ if (sc->ucred != NULL) {
+ chgvmmcnt(sc->ucred->cr_ruidinfo, -1, 0);
crfree(sc->ucred);
+ }
sx_xlock(&vmmdev_mtx);
SLIST_REMOVE(&head, sc, vmmdev_softc, link);
@@ -981,17 +988,20 @@
}
static int
-vmmdev_create(const char *name, struct ucred *cred)
+vmmdev_create(const char *name, struct thread *td)
{
struct make_dev_args mda;
struct cdev *cdev;
struct vmmdev_softc *sc;
+ struct ucred *cred;
+
struct vm *vm;
int error;
if (name == NULL || strlen(name) > VM_MAX_NAMELEN)
return (EINVAL);
+ cred = td->td_ucred;
sx_xlock(&vmmdev_mtx);
sc = vmmdev_lookup(name, cred);
if (sc != NULL) {
@@ -999,6 +1009,11 @@
return (EEXIST);
}
+ if (!chgvmmcnt(cred->cr_ruidinfo, 1, vm_maxvmms)) {
+ sx_xunlock(&vmmdev_mtx);
+ return (ENOMEM);
+ }
+
error = vm_create(name, &vm);
if (error != 0) {
sx_xunlock(&vmmdev_mtx);
@@ -1043,7 +1058,7 @@
buf = malloc(buflen, M_VMMDEV, M_WAITOK | M_ZERO);
error = sysctl_handle_string(oidp, buf, buflen, req);
if (error == 0 && req->newptr != NULL)
- error = vmmdev_create(buf, req->td->td_ucred);
+ error = vmmdev_create(buf, req->td);
free(buf, M_VMMDEV);
return (error);
}
@@ -1086,7 +1101,7 @@
}
}
- error = vmmdev_create(vmc->name, td->td_ucred);
+ error = vmmdev_create(vmc->name, td);
break;
}
case VMMCTL_VM_DESTROY: {
@@ -1172,7 +1187,7 @@
}
if (vm_maxcpu == 0)
vm_maxcpu = 1;
-
+ vm_maxvmms = MAX(mp_ncpus * 2, 1024);
error = vmm_modinit();
if (error == 0)
vmm_initialized = true;
diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c
--- a/sys/kern/kern_resource.c
+++ b/sys/kern/kern_resource.c
@@ -895,6 +895,9 @@
case RLIMIT_PIPEBUF:
*res = ui->ui_pipecnt;
break;
+ case RLIMIT_VMM:
+ *res = ui->ui_vmmcnt;
+ break;
default:
error = EINVAL;
break;
@@ -1643,6 +1646,9 @@
if (uip->ui_inotifywatchcnt != 0)
printf("freeing uidinfo: uid = %d, inotifywatchcnt = %ld\n",
uip->ui_uid, uip->ui_inotifywatchcnt);
+ if (uip->ui_vmmcnt != 0)
+ printf("freeing vmmcnt: uid = %d, vmmcnt = %ld\n",
+ uip->ui_uid, uip->ui_vmmcnt);
free(uip, M_UIDINFO);
}
@@ -1763,6 +1769,13 @@
"inotifywatchcnt"));
}
+int
+chgvmmcnt(struct uidinfo *uip, int diff, rlim_t max)
+{
+
+ return (chglimit(uip, &uip->ui_vmmcnt, diff, max, "proccnt"));
+}
+
static int
sysctl_kern_proc_rlimit_usage(SYSCTL_HANDLER_ARGS)
{
diff --git a/sys/sys/resource.h b/sys/sys/resource.h
--- a/sys/sys/resource.h
+++ b/sys/sys/resource.h
@@ -115,8 +115,9 @@
#define RLIMIT_KQUEUES 13 /* kqueues allocated */
#define RLIMIT_UMTXP 14 /* process-shared umtx */
#define RLIMIT_PIPEBUF 15 /* pipes/fifos buffers */
+#define RLIMIT_VMM 16 /* virtual machines */
-#define RLIM_NLIMITS 16 /* number of resource limits */
+#define RLIM_NLIMITS 17 /* number of resource limits */
#define RLIM_INFINITY ((rlim_t)(((__uint64_t)1 << 63) - 1))
#define RLIM_SAVED_MAX RLIM_INFINITY
@@ -144,6 +145,7 @@
"kqueues",
"umtx",
"pipebuf",
+ "vmm",
};
#endif
diff --git a/sys/sys/resourcevar.h b/sys/sys/resourcevar.h
--- a/sys/sys/resourcevar.h
+++ b/sys/sys/resourcevar.h
@@ -124,6 +124,7 @@
long ui_pipecnt; /* (b) consumption of pipe buffers */
long ui_inotifycnt; /* (b) number of inotify descriptors */
long ui_inotifywatchcnt; /* (b) number of inotify watches */
+ long ui_vmmcnt; /* (b) number of vmm instances */
uid_t ui_uid; /* (a) uid */
u_int ui_ref; /* (b) reference count */
#ifdef RACCT
@@ -148,6 +149,7 @@
int chgpipecnt(struct uidinfo *uip, int diff, rlim_t max);
int chginotifycnt(struct uidinfo *uip, int diff, rlim_t maxval);
int chginotifywatchcnt(struct uidinfo *uip, int diff, rlim_t maxval);
+int chgvmmcnt(struct uidinfo *uip, int diff, rlim_t max);
int kern_proc_setrlimit(struct thread *td, struct proc *p, u_int which,
struct rlimit *limp);
struct plimit

File Metadata

Mime Type
text/plain
Expires
Thu, Jan 15, 12:20 PM (1 h, 24 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27649921
Default Alt Text
D53728.id166350.diff (4 KB)

Event Timeline