Message ID | 1393990609-12361-1-git-send-email-bharata@linux.vnet.ibm.com |
---|---|
State | New |
Headers | show |
On 03/04/2014 08:36 PM, Bharata B Rao wrote: > PowerPC kernel expects the number of SMT threads in a core to be a power > of 2. Since QEMU doesn't enforce this, it leads to an early guest kernel > crash if invalid threads count is specified. > > Prevent this crash and make it a graceful exit from QEMU itself by > validating the user supplied threads count. > > > +#include <math.h> > } > + threads_shift = log2(smp_threads); Overkill. qemu-common.h gives you is_power_of_2() that uses just integer math rather than dragging in floating-point overhead of libm.
On Tue, Mar 04, 2014 at 09:13:38PM -0700, Eric Blake wrote: > On 03/04/2014 08:36 PM, Bharata B Rao wrote: > > PowerPC kernel expects the number of SMT threads in a core to be a power > > of 2. Since QEMU doesn't enforce this, it leads to an early guest kernel > > crash if invalid threads count is specified. > > > > Prevent this crash and make it a graceful exit from QEMU itself by > > validating the user supplied threads count. > > > > > > > +#include <math.h> > > > } > > + threads_shift = log2(smp_threads); > > Overkill. qemu-common.h gives you is_power_of_2() that uses just > integer math rather than dragging in floating-point overhead of libm. Nice. Using is_power_of_2() in v2. Regards, Bharata.
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 445c360..9ed22bb 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -18,6 +18,7 @@ * License along with this library; if not, see <http://www.gnu.org/licenses/>. */ +#include <math.h> #include "disas/bfd.h" #include "exec/gdbstub.h" #include <sysemu/kvm.h> @@ -7979,6 +7980,7 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp) Error *local_err = NULL; #if !defined(CONFIG_USER_ONLY) int max_smt = kvm_enabled() ? kvmppc_smt_threads() : 1; + int threads_shift; #endif #if !defined(CONFIG_USER_ONLY) @@ -7987,6 +7989,13 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp) max_smt, kvm_enabled() ? "KVM" : "TCG"); return; } + threads_shift = log2(smp_threads); + if (smp_threads != (1 << threads_shift)) { + error_setg(errp, "Cannot support %d threads on PPC with %s, " + "threads count must be a power of 2.", + smp_threads, kvm_enabled() ? "KVM" : "TCG"); + return; + } #endif if (kvm_enabled()) {