diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2015-01-23 07:39:51 -0500 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2015-01-23 07:39:51 -0500 |
commit | 1c6007d59a20762052cc92c0a2889ff11030d23a (patch) | |
tree | 40bd72fe4e4d38a811312e5ae35bafd04c995d40 /arch/x86 | |
parent | c6156df9d32141e5f1abb43078c56f2e5a0cb294 (diff) | |
parent | 4b990589952f0e30aa860184ac6c76219a74632e (diff) |
Merge tag 'kvm-arm-for-3.20' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into kvm-next
KVM/ARM changes for v3.20 including GICv3 emulation, dirty page logging, added
trace symbols, and adding an explicit VGIC init device control IOCTL.
Conflicts:
arch/arm64/include/asm/kvm_arm.h
arch/arm64/kvm/handle_exit.c
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/include/asm/kvm_host.h | 3 | ||||
-rw-r--r-- | arch/x86/kvm/Kconfig | 1 | ||||
-rw-r--r-- | arch/x86/kvm/mmu.c | 4 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 72 |
4 files changed, 16 insertions, 64 deletions
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 4327af53e544..843bea0e70fd 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h | |||
@@ -835,9 +835,6 @@ void kvm_mmu_set_mask_ptes(u64 user_mask, u64 accessed_mask, | |||
835 | 835 | ||
836 | void kvm_mmu_reset_context(struct kvm_vcpu *vcpu); | 836 | void kvm_mmu_reset_context(struct kvm_vcpu *vcpu); |
837 | void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot); | 837 | void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot); |
838 | void kvm_mmu_write_protect_pt_masked(struct kvm *kvm, | ||
839 | struct kvm_memory_slot *slot, | ||
840 | gfn_t gfn_offset, unsigned long mask); | ||
841 | void kvm_mmu_zap_all(struct kvm *kvm); | 838 | void kvm_mmu_zap_all(struct kvm *kvm); |
842 | void kvm_mmu_invalidate_mmio_sptes(struct kvm *kvm); | 839 | void kvm_mmu_invalidate_mmio_sptes(struct kvm *kvm); |
843 | unsigned int kvm_mmu_calculate_mmu_pages(struct kvm *kvm); | 840 | unsigned int kvm_mmu_calculate_mmu_pages(struct kvm *kvm); |
diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig index f9d16ff56c6b..d07359466d5d 100644 --- a/arch/x86/kvm/Kconfig +++ b/arch/x86/kvm/Kconfig | |||
@@ -39,6 +39,7 @@ config KVM | |||
39 | select PERF_EVENTS | 39 | select PERF_EVENTS |
40 | select HAVE_KVM_MSI | 40 | select HAVE_KVM_MSI |
41 | select HAVE_KVM_CPU_RELAX_INTERCEPT | 41 | select HAVE_KVM_CPU_RELAX_INTERCEPT |
42 | select KVM_GENERIC_DIRTYLOG_READ_PROTECT | ||
42 | select KVM_VFIO | 43 | select KVM_VFIO |
43 | ---help--- | 44 | ---help--- |
44 | Support hosting fully virtualized guest machines using hardware | 45 | Support hosting fully virtualized guest machines using hardware |
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 97898abe8386..0ed9f795e4f0 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c | |||
@@ -1216,7 +1216,7 @@ static bool __rmap_write_protect(struct kvm *kvm, unsigned long *rmapp, | |||
1216 | } | 1216 | } |
1217 | 1217 | ||
1218 | /** | 1218 | /** |
1219 | * kvm_mmu_write_protect_pt_masked - write protect selected PT level pages | 1219 | * kvm_arch_mmu_write_protect_pt_masked - write protect selected PT level pages |
1220 | * @kvm: kvm instance | 1220 | * @kvm: kvm instance |
1221 | * @slot: slot to protect | 1221 | * @slot: slot to protect |
1222 | * @gfn_offset: start of the BITS_PER_LONG pages we care about | 1222 | * @gfn_offset: start of the BITS_PER_LONG pages we care about |
@@ -1225,7 +1225,7 @@ static bool __rmap_write_protect(struct kvm *kvm, unsigned long *rmapp, | |||
1225 | * Used when we do not need to care about huge page mappings: e.g. during dirty | 1225 | * Used when we do not need to care about huge page mappings: e.g. during dirty |
1226 | * logging we do not have any such mappings. | 1226 | * logging we do not have any such mappings. |
1227 | */ | 1227 | */ |
1228 | void kvm_mmu_write_protect_pt_masked(struct kvm *kvm, | 1228 | void kvm_arch_mmu_write_protect_pt_masked(struct kvm *kvm, |
1229 | struct kvm_memory_slot *slot, | 1229 | struct kvm_memory_slot *slot, |
1230 | gfn_t gfn_offset, unsigned long mask) | 1230 | gfn_t gfn_offset, unsigned long mask) |
1231 | { | 1231 | { |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 917672f8034a..d2bbb2d86610 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -3759,83 +3759,37 @@ static int kvm_vm_ioctl_reinject(struct kvm *kvm, | |||
3759 | * @kvm: kvm instance | 3759 | * @kvm: kvm instance |
3760 | * @log: slot id and address to which we copy the log | 3760 | * @log: slot id and address to which we copy the log |
3761 | * | 3761 | * |
3762 | * We need to keep it in mind that VCPU threads can write to the bitmap | 3762 | * Steps 1-4 below provide general overview of dirty page logging. See |
3763 | * concurrently. So, to avoid losing data, we keep the following order for | 3763 | * kvm_get_dirty_log_protect() function description for additional details. |
3764 | * each bit: | 3764 | * |
3765 | * We call kvm_get_dirty_log_protect() to handle steps 1-3, upon return we | ||
3766 | * always flush the TLB (step 4) even if previous step failed and the dirty | ||
3767 | * bitmap may be corrupt. Regardless of previous outcome the KVM logging API | ||
3768 | * does not preclude user space subsequent dirty log read. Flushing TLB ensures | ||
3769 | * writes will be marked dirty for next log read. | ||
3765 | * | 3770 | * |
3766 | * 1. Take a snapshot of the bit and clear it if needed. | 3771 | * 1. Take a snapshot of the bit and clear it if needed. |
3767 | * 2. Write protect the corresponding page. | 3772 | * 2. Write protect the corresponding page. |
3768 | * 3. Flush TLB's if needed. | 3773 | * 3. Copy the snapshot to the userspace. |
3769 | * 4. Copy the snapshot to the userspace. | 3774 | * 4. Flush TLB's if needed. |
3770 | * | ||
3771 | * Between 2 and 3, the guest may write to the page using the remaining TLB | ||
3772 | * entry. This is not a problem because the page will be reported dirty at | ||
3773 | * step 4 using the snapshot taken before and step 3 ensures that successive | ||
3774 | * writes will be logged for the next call. | ||
3775 | */ | 3775 | */ |
3776 | int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log) | 3776 | int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log) |
3777 | { | 3777 | { |
3778 | int r; | ||
3779 | struct kvm_memory_slot *memslot; | ||
3780 | unsigned long n, i; | ||
3781 | unsigned long *dirty_bitmap; | ||
3782 | unsigned long *dirty_bitmap_buffer; | ||
3783 | bool is_dirty = false; | 3778 | bool is_dirty = false; |
3779 | int r; | ||
3784 | 3780 | ||
3785 | mutex_lock(&kvm->slots_lock); | 3781 | mutex_lock(&kvm->slots_lock); |
3786 | 3782 | ||
3787 | r = -EINVAL; | 3783 | r = kvm_get_dirty_log_protect(kvm, log, &is_dirty); |
3788 | if (log->slot >= KVM_USER_MEM_SLOTS) | ||
3789 | goto out; | ||
3790 | |||
3791 | memslot = id_to_memslot(kvm->memslots, log->slot); | ||
3792 | |||
3793 | dirty_bitmap = memslot->dirty_bitmap; | ||
3794 | r = -ENOENT; | ||
3795 | if (!dirty_bitmap) | ||
3796 | goto out; | ||
3797 | |||
3798 | n = kvm_dirty_bitmap_bytes(memslot); | ||
3799 | |||
3800 | dirty_bitmap_buffer = dirty_bitmap + n / sizeof(long); | ||
3801 | memset(dirty_bitmap_buffer, 0, n); | ||
3802 | |||
3803 | spin_lock(&kvm->mmu_lock); | ||
3804 | |||
3805 | for (i = 0; i < n / sizeof(long); i++) { | ||
3806 | unsigned long mask; | ||
3807 | gfn_t offset; | ||
3808 | |||
3809 | if (!dirty_bitmap[i]) | ||
3810 | continue; | ||
3811 | |||
3812 | is_dirty = true; | ||
3813 | |||
3814 | mask = xchg(&dirty_bitmap[i], 0); | ||
3815 | dirty_bitmap_buffer[i] = mask; | ||
3816 | |||
3817 | offset = i * BITS_PER_LONG; | ||
3818 | kvm_mmu_write_protect_pt_masked(kvm, memslot, offset, mask); | ||
3819 | } | ||
3820 | |||
3821 | spin_unlock(&kvm->mmu_lock); | ||
3822 | |||
3823 | /* See the comments in kvm_mmu_slot_remove_write_access(). */ | ||
3824 | lockdep_assert_held(&kvm->slots_lock); | ||
3825 | 3784 | ||
3826 | /* | 3785 | /* |
3827 | * All the TLBs can be flushed out of mmu lock, see the comments in | 3786 | * All the TLBs can be flushed out of mmu lock, see the comments in |
3828 | * kvm_mmu_slot_remove_write_access(). | 3787 | * kvm_mmu_slot_remove_write_access(). |
3829 | */ | 3788 | */ |
3789 | lockdep_assert_held(&kvm->slots_lock); | ||
3830 | if (is_dirty) | 3790 | if (is_dirty) |
3831 | kvm_flush_remote_tlbs(kvm); | 3791 | kvm_flush_remote_tlbs(kvm); |
3832 | 3792 | ||
3833 | r = -EFAULT; | ||
3834 | if (copy_to_user(log->dirty_bitmap, dirty_bitmap_buffer, n)) | ||
3835 | goto out; | ||
3836 | |||
3837 | r = 0; | ||
3838 | out: | ||
3839 | mutex_unlock(&kvm->slots_lock); | 3793 | mutex_unlock(&kvm->slots_lock); |
3840 | return r; | 3794 | return r; |
3841 | } | 3795 | } |