diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 882454156df36e9b6a069af49ac245839168510d..9acf8e42e1408322c944fd92b8c1096c3f37ad4a 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -11447,22 +11447,8 @@ qemuBuildCommandLine(virConnectPtr conn, goto error; } - if (mlock) { - unsigned long long memKB; - - /* VFIO requires all of the guest's memory to be - * locked resident, plus some amount for IO - * space. Alex Williamson suggested adding 1GiB for IO - * space just to be safe (some finer tuning might be - * nice, though). - */ - if (virMemoryLimitIsSet(def->mem.hard_limit)) - memKB = def->mem.hard_limit; - else - memKB = virDomainDefGetMemoryActual(def) + 1024 * 1024; - - virCommandSetMaxMemLock(cmd, memKB * 1024); - } + if (mlock) + virCommandSetMaxMemLock(cmd, qemuDomainGetMlockLimitBytes(def)); if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MSG_TIMESTAMP) && cfg->logTimestamp) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 890d8ed1117e5dc704b569ad4109d6e443abc41c..f016e8b3f6223256b21835458beb3063496a4eb3 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -3616,3 +3616,30 @@ qemuDomainUpdateCurrentMemorySize(virQEMUDriverPtr driver, return 0; } + + +/** + * qemuDomainGetMlockLimitBytes: + * + * @def: domain definition + * + * Returns the size of the memory in bytes that needs to be set as + * RLIMIT_MEMLOCK for purpose of VFIO device passthrough. + * If a mem.hard_limit is set, then that value is preferred; otherwise, the + * value returned may depend upon the architecture or devices present. + */ +unsigned long long +qemuDomainGetMlockLimitBytes(virDomainDefPtr def) +{ + unsigned long long memKB; + + /* VFIO requires all of the guest's memory to be locked resident, plus some + * amount for IO space. Alex Williamson suggested adding 1GiB for IO space + * just to be safe (some finer tuning might be nice, though). */ + if (virMemoryLimitIsSet(def->mem.hard_limit)) + memKB = def->mem.hard_limit; + else + memKB = virDomainDefGetMemoryActual(def) + 1024 * 1024; + + return memKB << 10; +} diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 64cd7e1a124ec6f47df1e5c7b3a48560c93b3759..e34370b08b56eaebed915103ee22115f896e8af1 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -482,4 +482,6 @@ bool qemuDomainMachineIsS390CCW(const virDomainDef *def); int qemuDomainUpdateCurrentMemorySize(virQEMUDriverPtr driver, virDomainObjPtr vm); +unsigned long long qemuDomainGetMlockLimitBytes(virDomainDefPtr def); + #endif /* __QEMU_DOMAIN_H__ */ diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 8f2fda996e3faea9b729a78b403773d1b54da122..e7fc036471c21abe639fdf646f8c3b77a12c9dc9 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1254,7 +1254,6 @@ qemuDomainAttachHostPCIDevice(virQEMUDriverPtr driver, bool teardowncgroup = false; bool teardownlabel = false; int backend; - unsigned long long memKB; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); unsigned int flags = 0; @@ -1279,20 +1278,8 @@ qemuDomainAttachHostPCIDevice(virQEMUDriverPtr driver, goto error; } - /* VFIO requires all of the guest's memory to be locked - * resident (plus an additional 1GiB to cover IO space). During - * hotplug, the guest's memory may already be locked, but it - * doesn't hurt to "change" the limit to the same value. - * NB: the domain's memory tuning parameters are stored as - * Kibibytes, but virProcessSetMaxMemLock expects the value in - * bytes. - */ - if (virMemoryLimitIsSet(vm->def->mem.hard_limit)) - memKB = vm->def->mem.hard_limit; - else - memKB = virDomainDefGetMemoryActual(vm->def) + (1024 * 1024); - - virProcessSetMaxMemLock(vm->pid, memKB * 1024); + /* setup memory locking limits, that are necessary for VFIO */ + virProcessSetMaxMemLock(vm->pid, qemuDomainGetMlockLimitBytes(vm->def)); break; default: