aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvi Kivity <avi@qumranet.com>2006-12-31 12:25:01 +0000
committerAvi Kivity <avi@qumranet.com>2006-12-31 12:25:01 +0000
commitad4ec7d7b48d7b2253c877281adaf1f56dc1ac51 (patch)
treec3dee9cd3ef5aed4915172489e4869adbd32396d
parentec13fb6daa33bf4829a22d79437c5c51ee9a0322 (diff)
kvm: release: merge from trunk
-rw-r--r--hw/hypercall.c39
-rw-r--r--kvm/kernel/kvm.h3
-rw-r--r--kvm/kernel/kvm_main.c18
-rw-r--r--kvm/kernel/mmu.c24
-rw-r--r--kvm/kernel/vmx.c36
-rw-r--r--vl.c18
-rw-r--r--vl.h1
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 = {
diff --git a/vl.c b/vl.c
index 0ebc32919..988893755 100644
--- a/vl.c
+++ b/vl.c
@@ -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]);
diff --git a/vl.h b/vl.h
index 3b90138ce..9917afa5c 100644
--- a/vl.h
+++ b/vl.h
@@ -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,