diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-25 14:01:10 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-25 14:01:10 -0400 |
commit | a9417357cff6027f9d6b1740f821baa59f2381f4 (patch) | |
tree | 15306e02a9a5c244fdf9c97e34c6cd3e4c45ef20 /drivers | |
parent | 17c38b7490b3f0300c7812aefdae2ddda7ab4112 (diff) | |
parent | d37c85571904a622cbabc7a2e04b8c919de75ac0 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/avi/kvm
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/avi/kvm:
KVM: disable writeback for 0x0f 0x01 instructions.
KVM: Fix removal of nx capability from guest cpuid
Revert "KVM: Avoid useless memory write when possible"
KVM: Fix unlikely kvm_create vs decache_vcpus_on_cpu race
KVM: Correctly handle writes crossing a page boundary
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/kvm/kvm_main.c | 44 | ||||
-rw-r--r-- | drivers/kvm/x86_emulate.c | 2 |
2 files changed, 33 insertions, 13 deletions
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c index bcbe6835beb4..96856097d15b 100644 --- a/drivers/kvm/kvm_main.c +++ b/drivers/kvm/kvm_main.c | |||
@@ -297,9 +297,6 @@ static struct kvm *kvm_create_vm(void) | |||
297 | kvm_io_bus_init(&kvm->pio_bus); | 297 | kvm_io_bus_init(&kvm->pio_bus); |
298 | spin_lock_init(&kvm->lock); | 298 | spin_lock_init(&kvm->lock); |
299 | INIT_LIST_HEAD(&kvm->active_mmu_pages); | 299 | INIT_LIST_HEAD(&kvm->active_mmu_pages); |
300 | spin_lock(&kvm_lock); | ||
301 | list_add(&kvm->vm_list, &vm_list); | ||
302 | spin_unlock(&kvm_lock); | ||
303 | kvm_io_bus_init(&kvm->mmio_bus); | 300 | kvm_io_bus_init(&kvm->mmio_bus); |
304 | for (i = 0; i < KVM_MAX_VCPUS; ++i) { | 301 | for (i = 0; i < KVM_MAX_VCPUS; ++i) { |
305 | struct kvm_vcpu *vcpu = &kvm->vcpus[i]; | 302 | struct kvm_vcpu *vcpu = &kvm->vcpus[i]; |
@@ -309,6 +306,9 @@ static struct kvm *kvm_create_vm(void) | |||
309 | vcpu->kvm = kvm; | 306 | vcpu->kvm = kvm; |
310 | vcpu->mmu.root_hpa = INVALID_PAGE; | 307 | vcpu->mmu.root_hpa = INVALID_PAGE; |
311 | } | 308 | } |
309 | spin_lock(&kvm_lock); | ||
310 | list_add(&kvm->vm_list, &vm_list); | ||
311 | spin_unlock(&kvm_lock); | ||
312 | return kvm; | 312 | return kvm; |
313 | } | 313 | } |
314 | 314 | ||
@@ -1070,18 +1070,16 @@ static int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa, | |||
1070 | return 0; | 1070 | return 0; |
1071 | mark_page_dirty(vcpu->kvm, gpa >> PAGE_SHIFT); | 1071 | mark_page_dirty(vcpu->kvm, gpa >> PAGE_SHIFT); |
1072 | virt = kmap_atomic(page, KM_USER0); | 1072 | virt = kmap_atomic(page, KM_USER0); |
1073 | if (memcmp(virt + offset_in_page(gpa), val, bytes)) { | 1073 | kvm_mmu_pte_write(vcpu, gpa, virt + offset, val, bytes); |
1074 | kvm_mmu_pte_write(vcpu, gpa, virt + offset, val, bytes); | 1074 | memcpy(virt + offset_in_page(gpa), val, bytes); |
1075 | memcpy(virt + offset_in_page(gpa), val, bytes); | ||
1076 | } | ||
1077 | kunmap_atomic(virt, KM_USER0); | 1075 | kunmap_atomic(virt, KM_USER0); |
1078 | return 1; | 1076 | return 1; |
1079 | } | 1077 | } |
1080 | 1078 | ||
1081 | static int emulator_write_emulated(unsigned long addr, | 1079 | static int emulator_write_emulated_onepage(unsigned long addr, |
1082 | const void *val, | 1080 | const void *val, |
1083 | unsigned int bytes, | 1081 | unsigned int bytes, |
1084 | struct x86_emulate_ctxt *ctxt) | 1082 | struct x86_emulate_ctxt *ctxt) |
1085 | { | 1083 | { |
1086 | struct kvm_vcpu *vcpu = ctxt->vcpu; | 1084 | struct kvm_vcpu *vcpu = ctxt->vcpu; |
1087 | struct kvm_io_device *mmio_dev; | 1085 | struct kvm_io_device *mmio_dev; |
@@ -1113,6 +1111,26 @@ static int emulator_write_emulated(unsigned long addr, | |||
1113 | return X86EMUL_CONTINUE; | 1111 | return X86EMUL_CONTINUE; |
1114 | } | 1112 | } |
1115 | 1113 | ||
1114 | static int emulator_write_emulated(unsigned long addr, | ||
1115 | const void *val, | ||
1116 | unsigned int bytes, | ||
1117 | struct x86_emulate_ctxt *ctxt) | ||
1118 | { | ||
1119 | /* Crossing a page boundary? */ | ||
1120 | if (((addr + bytes - 1) ^ addr) & PAGE_MASK) { | ||
1121 | int rc, now; | ||
1122 | |||
1123 | now = -addr & ~PAGE_MASK; | ||
1124 | rc = emulator_write_emulated_onepage(addr, val, now, ctxt); | ||
1125 | if (rc != X86EMUL_CONTINUE) | ||
1126 | return rc; | ||
1127 | addr += now; | ||
1128 | val += now; | ||
1129 | bytes -= now; | ||
1130 | } | ||
1131 | return emulator_write_emulated_onepage(addr, val, bytes, ctxt); | ||
1132 | } | ||
1133 | |||
1116 | static int emulator_cmpxchg_emulated(unsigned long addr, | 1134 | static int emulator_cmpxchg_emulated(unsigned long addr, |
1117 | const void *old, | 1135 | const void *old, |
1118 | const void *new, | 1136 | const void *new, |
@@ -2414,9 +2432,9 @@ static void cpuid_fix_nx_cap(struct kvm_vcpu *vcpu) | |||
2414 | break; | 2432 | break; |
2415 | } | 2433 | } |
2416 | } | 2434 | } |
2417 | if (entry && (entry->edx & EFER_NX) && !(efer & EFER_NX)) { | 2435 | if (entry && (entry->edx & (1 << 20)) && !(efer & EFER_NX)) { |
2418 | entry->edx &= ~(1 << 20); | 2436 | entry->edx &= ~(1 << 20); |
2419 | printk(KERN_INFO ": guest NX capability removed\n"); | 2437 | printk(KERN_INFO "kvm: guest NX capability removed\n"); |
2420 | } | 2438 | } |
2421 | } | 2439 | } |
2422 | 2440 | ||
diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c index 1b800fc00342..1f979cb0df31 100644 --- a/drivers/kvm/x86_emulate.c +++ b/drivers/kvm/x86_emulate.c | |||
@@ -1178,6 +1178,8 @@ pop_instruction: | |||
1178 | twobyte_insn: | 1178 | twobyte_insn: |
1179 | switch (b) { | 1179 | switch (b) { |
1180 | case 0x01: /* lgdt, lidt, lmsw */ | 1180 | case 0x01: /* lgdt, lidt, lmsw */ |
1181 | /* Disable writeback. */ | ||
1182 | no_wb = 1; | ||
1181 | switch (modrm_reg) { | 1183 | switch (modrm_reg) { |
1182 | u16 size; | 1184 | u16 size; |
1183 | unsigned long address; | 1185 | unsigned long address; |