int kvm_cpu__init(struct kvm *kvm) { int max_cpus, recommended_cpus, i; max_cpus = kvm__max_cpus(kvm); recommended_cpus = kvm__recommended_cpus(kvm); if (kvm->cfg.nrcpus > max_cpus) { printf(" # Limit the number of CPUs to %d\n", max_cpus); kvm->cfg.nrcpus = max_cpus; } else if (kvm->cfg.nrcpus > recommended_cpus) { printf(" # Warning: The maximum recommended amount of VCPUs" " is %d\n", recommended_cpus); } kvm->nrcpus = kvm->cfg.nrcpus; /* Alloc one pointer too many, so array ends up 0-terminated */ kvm->cpus = calloc(kvm->nrcpus + 1, sizeof(void *)); if (!kvm->cpus) { pr_warning("Couldn't allocate array for %d CPUs", kvm->nrcpus); return -ENOMEM; } for (i = 0; i < kvm->nrcpus; i++) { kvm->cpus[i] = kvm_cpu__arch_init(kvm, i); if (!kvm->cpus[i]) { pr_warning("unable to initialize KVM VCPU"); goto fail_alloc; } } return 0; fail_alloc: for (i = 0; i < kvm->nrcpus; i++) free(kvm->cpus[i]); return -ENOMEM; }
int kvm_cmd_run(int argc, const char **argv, const char *prefix) { struct virtio_net_parameters net_params; static char real_cmdline[2048]; struct framebuffer *fb = NULL; unsigned int nr_online_cpus; int exit_code = 0; int max_cpus; char *hi; int i; void *ret; signal(SIGALRM, handle_sigalrm); signal(SIGQUIT, handle_sigquit); signal(SIGUSR1, handle_sigusr1); signal(SIGUSR2, handle_sigusr2); nr_online_cpus = sysconf(_SC_NPROCESSORS_ONLN); while (argc != 0) { argc = parse_options(argc, argv, options, run_usage, PARSE_OPT_STOP_AT_NON_OPTION); if (argc != 0) { if (kernel_filename) { fprintf(stderr, "Cannot handle parameter: " "%s\n", argv[0]); usage_with_options(run_usage, options); return EINVAL; } /* first unhandled parameter is treated as a kernel image */ kernel_filename = argv[0]; argv++; argc--; } } if (!kernel_filename) kernel_filename = find_kernel(); if (!kernel_filename) { kernel_usage_with_options(); return EINVAL; } vmlinux_filename = find_vmlinux(); if (nrcpus == 0) nrcpus = nr_online_cpus; else if (nrcpus < 1 || nrcpus > KVM_NR_CPUS) die("Number of CPUs %d is out of [1;%d] range", nrcpus, KVM_NR_CPUS); if (!ram_size) ram_size = get_ram_size(nrcpus); if (ram_size < MIN_RAM_SIZE_MB) die("Not enough memory specified: %lluMB (min %lluMB)", ram_size, MIN_RAM_SIZE_MB); if (ram_size > host_ram_size()) pr_warning("Guest memory size %lluMB exceeds host physical RAM size %lluMB", ram_size, host_ram_size()); ram_size <<= MB_SHIFT; if (!kvm_dev) kvm_dev = DEFAULT_KVM_DEV; if (!console) console = DEFAULT_CONSOLE; if (!strncmp(console, "virtio", 6)) active_console = CONSOLE_VIRTIO; else active_console = CONSOLE_8250; if (!host_ip_addr) host_ip_addr = DEFAULT_HOST_ADDR; if (!guest_mac) guest_mac = DEFAULT_GUEST_MAC; if (!script) script = DEFAULT_SCRIPT; if (virtio_9p_dir) { char tmp[PATH_MAX]; if (realpath(virtio_9p_dir, tmp)) virtio_9p__init(kvm, tmp); else die("Failed resolving 9p path"); } symbol__init(vmlinux_filename); term_init(); kvm = kvm__init(kvm_dev, ram_size); ioeventfd__init(); max_cpus = kvm__max_cpus(kvm); if (nrcpus > max_cpus) { printf(" # Limit the number of CPUs to %d\n", max_cpus); kvm->nrcpus = max_cpus; } kvm->nrcpus = nrcpus; /* * vidmode should be either specified * either set by default */ if (vnc || sdl) { if (vidmode == -1) vidmode = 0x312; } else vidmode = 0; memset(real_cmdline, 0, sizeof(real_cmdline)); strcpy(real_cmdline, "notsc noapic noacpi pci=conf1"); if (vnc || sdl) { strcat(real_cmdline, " video=vesafb console=tty0"); } else strcat(real_cmdline, " console=ttyS0 earlyprintk=serial"); strcat(real_cmdline, " "); if (kernel_cmdline) strlcat(real_cmdline, kernel_cmdline, sizeof(real_cmdline)); hi = NULL; if (!image_filename[0]) { hi = host_image(real_cmdline, sizeof(real_cmdline)); if (hi) { image_filename[0] = hi; readonly_image[0] = true; image_count++; } } if (!strstr(real_cmdline, "root=")) strlcat(real_cmdline, " root=/dev/vda rw ", sizeof(real_cmdline)); if (image_count) { kvm->nr_disks = image_count; kvm->disks = disk_image__open_all(image_filename, readonly_image, image_count); if (!kvm->disks) die("Unable to load all disk images."); virtio_blk__init_all(kvm); } free(hi); printf(" # kvm run -k %s -m %Lu -c %d\n", kernel_filename, ram_size / 1024 / 1024, nrcpus); if (!kvm__load_kernel(kvm, kernel_filename, initrd_filename, real_cmdline, vidmode)) die("unable to load kernel %s", kernel_filename); kvm->vmlinux = vmlinux_filename; ioport__setup_legacy(); rtc__init(); serial8250__init(kvm); pci__init(); if (active_console == CONSOLE_VIRTIO) virtio_console__init(kvm); if (virtio_rng) while (virtio_rng--) virtio_rng__init(kvm); if (!network) network = DEFAULT_NETWORK; if (!strncmp(network, "virtio", 6)) { net_params = (struct virtio_net_parameters) { .host_ip = host_ip_addr, .kvm = kvm, .script = script }; sscanf(guest_mac, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", net_params.guest_mac, net_params.guest_mac+1, net_params.guest_mac+2, net_params.guest_mac+3, net_params.guest_mac+4, net_params.guest_mac+5); virtio_net__init(&net_params); }