diff options
author | Avi Kivity <avi@qumranet.com> | 2006-12-31 12:25:01 +0000 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2006-12-31 12:25:01 +0000 |
commit | ad4ec7d7b48d7b2253c877281adaf1f56dc1ac51 (patch) | |
tree | c3dee9cd3ef5aed4915172489e4869adbd32396d | |
parent | ec13fb6daa33bf4829a22d79437c5c51ee9a0322 (diff) |
kvm: release: merge from trunk
-rw-r--r-- | hw/hypercall.c | 39 | ||||
-rw-r--r-- | kvm/kernel/kvm.h | 3 | ||||
-rw-r--r-- | kvm/kernel/kvm_main.c | 18 | ||||
-rw-r--r-- | kvm/kernel/mmu.c | 24 | ||||
-rw-r--r-- | kvm/kernel/vmx.c | 36 | ||||
-rw-r--r-- | vl.c | 18 | ||||
-rw-r--r-- | vl.h | 1 |
7 files changed, 100 insertions, 39 deletions
diff --git a/hw/hypercall.c b/hw/hypercall.c index 11e3a321a..d4de16a28 100644 --- a/hw/hypercall.c +++ b/hw/hypercall.c @@ -24,6 +24,8 @@ */ #include "vl.h" +int use_hypercall_dev = 0; + typedef struct HypercallState { uint8_t cmd; uint32_t start; @@ -63,10 +65,13 @@ static void hp_map(PCIDevice *pci_dev, int region_num, void pci_hypercall_init(PCIBus *bus) { PCIHypercallState *d; - uint8_t *pci_conf; - //printf("pci_hypercall_init\n"); + + // If the vmchannel wasn't initialized, we don't want the Hypercall device in the guest + if (use_hypercall_dev == 0) { + return; + } d = (PCIHypercallState *)pci_register_device(bus, "HPNAME", sizeof(PCIHypercallState), @@ -89,3 +94,33 @@ void pci_hypercall_init(PCIBus *bus) pci_register_io_region(&d->dev, 0, 0x100, PCI_ADDRESS_SPACE_IO, hp_map); } + + +static CharDriverState *vmchannel_hd; + +static int vmchannel_can_read(void *opaque) +{ + return 128; +} + +static void vmchannel_read(void *opaque, const uint8_t *buf, int size) +{ + int i; + + //printf("vmchannel_read buf:%p, size:%d\n", buf, size); + + for(i = 0; i < size; i++) { + printf("buf[i]=%c\n",buf[i]); + readline_handle_byte(buf[i]); + } +} + +void vmchannel_init(CharDriverState *hd) +{ + vmchannel_hd = hd; + + use_hypercall_dev = 1; + + qemu_chr_add_read_handler(hd, vmchannel_can_read, vmchannel_read, NULL); + //vmchannel_start_input(); +} diff --git a/kvm/kernel/kvm.h b/kvm/kernel/kvm.h index 2670219a9..100df6f38 100644 --- a/kvm/kernel/kvm.h +++ b/kvm/kernel/kvm.h @@ -319,7 +319,8 @@ int kvm_init_arch(struct kvm_arch_ops *ops, struct module *module); void kvm_exit_arch(void); void kvm_mmu_destroy(struct kvm_vcpu *vcpu); -int kvm_mmu_init(struct kvm_vcpu *vcpu); +int kvm_mmu_create(struct kvm_vcpu *vcpu); +int kvm_mmu_setup(struct kvm_vcpu *vcpu); int kvm_mmu_reset_context(struct kvm_vcpu *vcpu); void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot); diff --git a/kvm/kernel/kvm_main.c b/kvm/kernel/kvm_main.c index 973544553..b54caf0ce 100644 --- a/kvm/kernel/kvm_main.c +++ b/kvm/kernel/kvm_main.c @@ -522,12 +522,14 @@ static int kvm_dev_ioctl_create_vcpu(struct kvm *kvm, int n) if (r < 0) goto out_free_vcpus; - kvm_arch_ops->vcpu_load(vcpu); + r = kvm_mmu_create(vcpu); + if (r < 0) + goto out_free_vcpus; - r = kvm_arch_ops->vcpu_setup(vcpu); + kvm_arch_ops->vcpu_load(vcpu); + r = kvm_mmu_setup(vcpu); if (r >= 0) - r = kvm_mmu_init(vcpu); - + r = kvm_arch_ops->vcpu_setup(vcpu); vcpu_put(vcpu); if (r < 0) @@ -1942,17 +1944,17 @@ int kvm_init_arch(struct kvm_arch_ops *ops, struct module *module) return -EEXIST; } - kvm_arch_ops = ops; - - if (!kvm_arch_ops->cpu_has_kvm_support()) { + if (!ops->cpu_has_kvm_support()) { printk(KERN_ERR "kvm: no hardware support\n"); return -EOPNOTSUPP; } - if (kvm_arch_ops->disabled_by_bios()) { + if (ops->disabled_by_bios()) { printk(KERN_ERR "kvm: disabled by bios\n"); return -EOPNOTSUPP; } + kvm_arch_ops = ops; + r = kvm_arch_ops->hardware_setup(); if (r < 0) return r; diff --git a/kvm/kernel/mmu.c b/kvm/kernel/mmu.c index 85887fcd5..790423c5f 100644 --- a/kvm/kernel/mmu.c +++ b/kvm/kernel/mmu.c @@ -639,28 +639,22 @@ error_1: return -ENOMEM; } -int kvm_mmu_init(struct kvm_vcpu *vcpu) +int kvm_mmu_create(struct kvm_vcpu *vcpu) { - int r; - ASSERT(vcpu); ASSERT(!VALID_PAGE(vcpu->mmu.root_hpa)); ASSERT(list_empty(&vcpu->free_pages)); - r = alloc_mmu_pages(vcpu); - if (r) - goto out; - - r = init_kvm_mmu(vcpu); - if (r) - goto out_free_pages; + return alloc_mmu_pages(vcpu); +} - return 0; +int kvm_mmu_setup(struct kvm_vcpu *vcpu) +{ + ASSERT(vcpu); + ASSERT(!VALID_PAGE(vcpu->mmu.root_hpa)); + ASSERT(!list_empty(&vcpu->free_pages)); -out_free_pages: - free_mmu_pages(vcpu); -out: - return r; + return init_kvm_mmu(vcpu); } void kvm_mmu_destroy(struct kvm_vcpu *vcpu) diff --git a/kvm/kernel/vmx.c b/kvm/kernel/vmx.c index d0a2c2d53..2d204fd45 100644 --- a/kvm/kernel/vmx.c +++ b/kvm/kernel/vmx.c @@ -116,7 +116,7 @@ static void vmcs_clear(struct vmcs *vmcs) static void __vcpu_clear(void *arg) { struct kvm_vcpu *vcpu = arg; - int cpu = smp_processor_id(); + int cpu = raw_smp_processor_id(); if (vcpu->cpu == cpu) vmcs_clear(vcpu->vmcs); @@ -541,7 +541,7 @@ static struct vmcs *alloc_vmcs_cpu(int cpu) static struct vmcs *alloc_vmcs(void) { - return alloc_vmcs_cpu(smp_processor_id()); + return alloc_vmcs_cpu(raw_smp_processor_id()); } static void free_vmcs(struct vmcs *vmcs) @@ -1094,14 +1094,6 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu) rdmsrl(MSR_IA32_SYSENTER_EIP, a); vmcs_writel(HOST_IA32_SYSENTER_EIP, a); /* 22.2.3 */ - ret = -ENOMEM; - vcpu->guest_msrs = kmalloc(PAGE_SIZE, GFP_KERNEL); - if (!vcpu->guest_msrs) - goto out; - vcpu->host_msrs = kmalloc(PAGE_SIZE, GFP_KERNEL); - if (!vcpu->host_msrs) - goto out_free_guest_msrs; - for (i = 0; i < NR_VMX_MSR; ++i) { u32 index = vmx_msr_index[i]; u32 data_low, data_high; @@ -1155,8 +1147,6 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu) return 0; -out_free_guest_msrs: - kfree(vcpu->guest_msrs); out: return ret; } @@ -1906,13 +1896,33 @@ static int vmx_create_vcpu(struct kvm_vcpu *vcpu) { struct vmcs *vmcs; + vcpu->guest_msrs = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (!vcpu->guest_msrs) + return -ENOMEM; + + vcpu->host_msrs = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (!vcpu->host_msrs) + goto out_free_guest_msrs; + vmcs = alloc_vmcs(); if (!vmcs) - return -ENOMEM; + goto out_free_msrs; + vmcs_clear(vmcs); vcpu->vmcs = vmcs; vcpu->launched = 0; + return 0; + +out_free_msrs: + kfree(vcpu->host_msrs); + vcpu->host_msrs = NULL; + +out_free_guest_msrs: + kfree(vcpu->guest_msrs); + vcpu->guest_msrs = NULL; + + return -ENOMEM; } static struct kvm_arch_ops vmx_arch_ops = { @@ -5446,6 +5446,7 @@ enum { QEMU_OPTION_g, QEMU_OPTION_std_vga, QEMU_OPTION_monitor, + QEMU_OPTION_vmchannel, QEMU_OPTION_serial, QEMU_OPTION_parallel, QEMU_OPTION_loadvm, @@ -5525,6 +5526,7 @@ const QEMUOption qemu_options[] = { { "localtime", 0, QEMU_OPTION_localtime }, { "std-vga", 0, QEMU_OPTION_std_vga }, { "monitor", 1, QEMU_OPTION_monitor }, + { "vmchannel", 1, QEMU_OPTION_vmchannel }, { "serial", 1, QEMU_OPTION_serial }, { "parallel", 1, QEMU_OPTION_parallel }, { "loadvm", HAS_ARG, QEMU_OPTION_loadvm }, @@ -5760,6 +5762,8 @@ int main(int argc, char **argv) const char *r, *optarg; CharDriverState *monitor_hd; char monitor_device[128]; + CharDriverState *vmchannel_hd; + char vmchannel_device[128]; char serial_devices[MAX_SERIAL_PORTS][128]; int serial_device_index; char parallel_devices[MAX_PARALLEL_PORTS][128]; @@ -5827,6 +5831,8 @@ int main(int argc, char **argv) translation = BIOS_ATA_TRANSLATION_AUTO; pstrcpy(monitor_device, sizeof(monitor_device), "vc"); + vmchannel_device[0] = '\0'; + pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "vc"); for(i = 1; i < MAX_SERIAL_PORTS; i++) serial_devices[i][0] = '\0'; @@ -6111,6 +6117,9 @@ int main(int argc, char **argv) case QEMU_OPTION_monitor: pstrcpy(monitor_device, sizeof(monitor_device), optarg); break; + case QEMU_OPTION_vmchannel: + pstrcpy(vmchannel_device, sizeof(vmchannel_device), optarg); + break; case QEMU_OPTION_serial: if (serial_device_index >= MAX_SERIAL_PORTS) { fprintf(stderr, "qemu: too many serial ports\n"); @@ -6345,6 +6354,15 @@ int main(int argc, char **argv) } monitor_init(monitor_hd, !nographic); + if (*vmchannel_device) { + vmchannel_hd = qemu_chr_open(vmchannel_device); + if (!vmchannel_hd) { + fprintf(stderr, "qemu: could not open vmchannel device '%s'\n", vmchannel_device); + exit(1); + } + vmchannel_init(vmchannel_hd); + } + for(i = 0; i < MAX_SERIAL_PORTS; i++) { if (serial_devices[i][0] != '\0') { serial_hds[i] = qemu_chr_open(serial_devices[i]); @@ -1034,6 +1034,7 @@ typedef struct ADBDevice ADBDevice; /* hypercall.c */ void pci_hypercall_init(PCIBus *bus); +void vmchannel_init(CharDriverState *hd); /* buf = NULL means polling */ typedef int ADBDeviceRequest(ADBDevice *d, uint8_t *buf_out, |