diff options
-rw-r--r-- | hw/pc.c | 8 | ||||
-rw-r--r-- | hw/virtio-console.c | 20 | ||||
-rw-r--r-- | hw/virtio-serial-bus.c | 6 | ||||
-rw-r--r-- | target-i386/cpu.h | 3 | ||||
-rw-r--r-- | target-i386/cpuid.c | 17 | ||||
-rw-r--r-- | target-i386/kvm.c | 34 | ||||
-rw-r--r-- | vl.c | 2 |
7 files changed, 57 insertions, 33 deletions
@@ -624,9 +624,9 @@ static void *bochs_bios_init(void) * of nodes, one word for each VCPU->node and one word for each node to * hold the amount of memory. */ - numa_fw_cfg = g_malloc0((1 + smp_cpus + nb_numa_nodes) * 8); + numa_fw_cfg = g_malloc0((1 + max_cpus + nb_numa_nodes) * 8); numa_fw_cfg[0] = cpu_to_le64(nb_numa_nodes); - for (i = 0; i < smp_cpus; i++) { + for (i = 0; i < max_cpus; i++) { for (j = 0; j < nb_numa_nodes; j++) { if (node_cpumask[j] & (1 << i)) { numa_fw_cfg[i + 1] = cpu_to_le64(j); @@ -635,10 +635,10 @@ static void *bochs_bios_init(void) } } for (i = 0; i < nb_numa_nodes; i++) { - numa_fw_cfg[smp_cpus + 1 + i] = cpu_to_le64(node_mem[i]); + numa_fw_cfg[max_cpus + 1 + i] = cpu_to_le64(node_mem[i]); } fw_cfg_add_bytes(fw_cfg, FW_CFG_NUMA, (uint8_t *)numa_fw_cfg, - (1 + smp_cpus + nb_numa_nodes) * 8); + (1 + max_cpus + nb_numa_nodes) * 8); return fw_cfg; } diff --git a/hw/virtio-console.c b/hw/virtio-console.c index d3351c83ff..73d866a52d 100644 --- a/hw/virtio-console.c +++ b/hw/virtio-console.c @@ -27,6 +27,11 @@ static ssize_t flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len) VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port); ssize_t ret; + if (!vcon->chr) { + /* If there's no backend, we can just say we consumed all data. */ + return len; + } + ret = qemu_chr_fe_write(vcon->chr, buf, len); trace_virtio_console_flush_buf(port->id, len, ret); @@ -52,6 +57,9 @@ static void guest_open(VirtIOSerialPort *port) { VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port); + if (!vcon->chr) { + return; + } qemu_chr_fe_open(vcon->chr); } @@ -60,6 +68,9 @@ static void guest_close(VirtIOSerialPort *port) { VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port); + if (!vcon->chr) { + return; + } qemu_chr_fe_close(vcon->chr); } @@ -109,9 +120,6 @@ static int virtconsole_initfn(VirtIOSerialPort *port) if (vcon->chr) { qemu_chr_add_handlers(vcon->chr, chr_can_read, chr_read, chr_event, vcon); - info->have_data = flush_buf; - info->guest_open = guest_open; - info->guest_close = guest_close; } return 0; @@ -138,6 +146,9 @@ static VirtIOSerialPortInfo virtconsole_info = { .is_console = true, .init = virtconsole_initfn, .exit = virtconsole_exitfn, + .have_data = flush_buf, + .guest_open = guest_open, + .guest_close = guest_close, .qdev.props = (Property[]) { DEFINE_PROP_CHR("chardev", VirtConsole, chr), DEFINE_PROP_END_OF_LIST(), @@ -155,6 +166,9 @@ static VirtIOSerialPortInfo virtserialport_info = { .qdev.size = sizeof(VirtConsole), .init = virtconsole_initfn, .exit = virtconsole_exitfn, + .have_data = flush_buf, + .guest_open = guest_open, + .guest_close = guest_close, .qdev.props = (Property[]) { DEFINE_PROP_CHR("chardev", VirtConsole, chr), DEFINE_PROP_END_OF_LIST(), diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c index a4825b9eeb..fe0233f6f1 100644 --- a/hw/virtio-serial-bus.c +++ b/hw/virtio-serial-bus.c @@ -466,13 +466,11 @@ static void handle_output(VirtIODevice *vdev, VirtQueue *vq) { VirtIOSerial *vser; VirtIOSerialPort *port; - VirtIOSerialPortInfo *info; vser = DO_UPCAST(VirtIOSerial, vdev, vdev); port = find_port_by_vq(vser, vq); - info = port ? DO_UPCAST(VirtIOSerialPortInfo, qdev, port->dev.info) : NULL; - if (!port || !port->host_connected || !info->have_data) { + if (!port || !port->host_connected) { discard_vq_data(vq, vdev); return; } @@ -746,6 +744,8 @@ static int virtser_port_qdev_init(DeviceState *qdev, DeviceInfo *base) port->vser = bus->vser; port->bh = qemu_bh_new(flush_queued_data_bh, port); + assert(info->have_data); + /* * Is the first console port we're seeing? If so, put it up at * location 0. This is done for backward compatibility (old diff --git a/target-i386/cpu.h b/target-i386/cpu.h index a08ce9d873..37dde79581 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -751,7 +751,8 @@ typedef struct CPUX86State { uint32_t cpuid_svm_features; bool tsc_valid; int tsc_khz; - + void *kvm_xsave_buf; + /* in order to simplify APIC support, we leave this pointer to the user */ struct DeviceState *apic_state; diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c index 0b3af9060c..91a104ba0b 100644 --- a/target-i386/cpuid.c +++ b/target-i386/cpuid.c @@ -1180,10 +1180,19 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, break; case 0xA: /* Architectural Performance Monitoring Leaf */ - *eax = 0; - *ebx = 0; - *ecx = 0; - *edx = 0; + if (kvm_enabled()) { + KVMState *s = env->kvm_state; + + *eax = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EAX); + *ebx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EBX); + *ecx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_ECX); + *edx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EDX); + } else { + *eax = 0; + *ebx = 0; + *ecx = 0; + *edx = 0; + } break; case 0xD: /* Processor Extended State */ diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 5bfc21fc53..d206852904 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -516,6 +516,10 @@ int kvm_arch_init_vcpu(CPUState *env) } } + if (kvm_has_xsave()) { + env->kvm_xsave_buf = qemu_memalign(4096, sizeof(struct kvm_xsave)); + } + return 0; } @@ -759,6 +763,8 @@ static int kvm_put_fpu(CPUState *env) return kvm_vcpu_ioctl(env, KVM_SET_FPU, &fpu); } +#define XSAVE_FCW_FSW 0 +#define XSAVE_FTW_FOP 1 #define XSAVE_CWD_RIP 2 #define XSAVE_CWD_RDP 4 #define XSAVE_MXCSR 6 @@ -769,15 +775,14 @@ static int kvm_put_fpu(CPUState *env) static int kvm_put_xsave(CPUState *env) { - int i, r; - struct kvm_xsave* xsave; + struct kvm_xsave* xsave = env->kvm_xsave_buf; uint16_t cwd, swd, twd; + int i, r; if (!kvm_has_xsave()) { return kvm_put_fpu(env); } - xsave = qemu_memalign(4096, sizeof(struct kvm_xsave)); memset(xsave, 0, sizeof(struct kvm_xsave)); twd = 0; swd = env->fpus & ~(7 << 11); @@ -786,8 +791,8 @@ static int kvm_put_xsave(CPUState *env) for (i = 0; i < 8; ++i) { twd |= (!env->fptags[i]) << i; } - xsave->region[0] = (uint32_t)(swd << 16) + cwd; - xsave->region[1] = (uint32_t)(env->fpop << 16) + twd; + xsave->region[XSAVE_FCW_FSW] = (uint32_t)(swd << 16) + cwd; + xsave->region[XSAVE_FTW_FOP] = (uint32_t)(env->fpop << 16) + twd; memcpy(&xsave->region[XSAVE_CWD_RIP], &env->fpip, sizeof(env->fpip)); memcpy(&xsave->region[XSAVE_CWD_RDP], &env->fpdp, sizeof(env->fpdp)); memcpy(&xsave->region[XSAVE_ST_SPACE], env->fpregs, @@ -799,7 +804,6 @@ static int kvm_put_xsave(CPUState *env) memcpy(&xsave->region[XSAVE_YMMH_SPACE], env->ymmh_regs, sizeof env->ymmh_regs); r = kvm_vcpu_ioctl(env, KVM_SET_XSAVE, xsave); - g_free(xsave); return r; } @@ -976,7 +980,7 @@ static int kvm_get_fpu(CPUState *env) static int kvm_get_xsave(CPUState *env) { - struct kvm_xsave* xsave; + struct kvm_xsave* xsave = env->kvm_xsave_buf; int ret, i; uint16_t cwd, swd, twd; @@ -984,17 +988,15 @@ static int kvm_get_xsave(CPUState *env) return kvm_get_fpu(env); } - xsave = qemu_memalign(4096, sizeof(struct kvm_xsave)); ret = kvm_vcpu_ioctl(env, KVM_GET_XSAVE, xsave); if (ret < 0) { - g_free(xsave); return ret; } - cwd = (uint16_t)xsave->region[0]; - swd = (uint16_t)(xsave->region[0] >> 16); - twd = (uint16_t)xsave->region[1]; - env->fpop = (uint16_t)(xsave->region[1] >> 16); + cwd = (uint16_t)xsave->region[XSAVE_FCW_FSW]; + swd = (uint16_t)(xsave->region[XSAVE_FCW_FSW] >> 16); + twd = (uint16_t)xsave->region[XSAVE_FTW_FOP]; + env->fpop = (uint16_t)(xsave->region[XSAVE_FTW_FOP] >> 16); env->fpstt = (swd >> 11) & 7; env->fpus = swd; env->fpuc = cwd; @@ -1011,7 +1013,6 @@ static int kvm_get_xsave(CPUState *env) env->xstate_bv = *(uint64_t *)&xsave->region[XSAVE_XSTATE_BV]; memcpy(env->ymmh_regs, &xsave->region[XSAVE_YMMH_SPACE], sizeof env->ymmh_regs); - g_free(xsave); return 0; } @@ -1081,10 +1082,9 @@ static int kvm_get_sregs(CPUState *env) env->cr[3] = sregs.cr3; env->cr[4] = sregs.cr4; - cpu_set_apic_base(env->apic_state, sregs.apic_base); - env->efer = sregs.efer; - //cpu_set_apic_tpr(env->apic_state, sregs.cr8); + + /* changes to apic base and cr8/tpr are read back via kvm_arch_post_run */ #define HFLAG_COPY_MASK \ ~( HF_CPL_MASK | HF_PE_MASK | HF_MP_MASK | HF_EM_MASK | \ @@ -3305,7 +3305,7 @@ int main(int argc, char **argv, char **envp) * real machines which also use this scheme. */ if (i == nb_numa_nodes) { - for (i = 0; i < smp_cpus; i++) { + for (i = 0; i < max_cpus; i++) { node_cpumask[i % nb_numa_nodes] |= 1 << i; } } |