aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-05-02 12:26:09 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-05-02 12:26:09 -0400
commite7e6d2a4a1aecb087c0f522d8d131a0252691398 (patch)
treedc81a974f3a8510c88f3e40427be68c8a03a5727 /arch/x86
parentb28e4f08d43beca4ac8ba2f768f4aaa8b056c4cf (diff)
parenta5a5aef451430dbd48f5bf32029b8b98b690074d (diff)
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull KVM fixes from Paolo Bonzini: - Fix for a Haswell regression in nested virtualization, introduced during the merge window. - A fix from Oleg to async page faults. - A bunch of small ARM changes. - A trivial patch to use the new MSI-X API introduced during the merge window. * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: KVM: ARM: vgic: Fix the overlap check action about setting the GICD & GICC base address. KVM: arm/arm64: vgic: fix GICD_ICFGR register accesses KVM: async_pf: mm->mm_users can not pin apf->mm KVM: ARM: vgic: Fix sgi dispatch problem MAINTAINERS: co-maintainance of KVM/{arm,arm64} arm: KVM: fix possible misalignment of PGDs and bounce page KVM: x86: Check for host supported fields in shadow vmcs kvm: Use pci_enable_msix_exact() instead of pci_enable_msix() ARM: KVM: disable KVM in Kconfig on big-endian systems
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/kvm/vmx.c53
1 files changed, 41 insertions, 12 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 1f68c5831924..33e8c028842f 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -503,7 +503,7 @@ static inline struct vcpu_vmx *to_vmx(struct kvm_vcpu *vcpu)
503 [number##_HIGH] = VMCS12_OFFSET(name)+4 503 [number##_HIGH] = VMCS12_OFFSET(name)+4
504 504
505 505
506static const unsigned long shadow_read_only_fields[] = { 506static unsigned long shadow_read_only_fields[] = {
507 /* 507 /*
508 * We do NOT shadow fields that are modified when L0 508 * We do NOT shadow fields that are modified when L0
509 * traps and emulates any vmx instruction (e.g. VMPTRLD, 509 * traps and emulates any vmx instruction (e.g. VMPTRLD,
@@ -526,10 +526,10 @@ static const unsigned long shadow_read_only_fields[] = {
526 GUEST_LINEAR_ADDRESS, 526 GUEST_LINEAR_ADDRESS,
527 GUEST_PHYSICAL_ADDRESS 527 GUEST_PHYSICAL_ADDRESS
528}; 528};
529static const int max_shadow_read_only_fields = 529static int max_shadow_read_only_fields =
530 ARRAY_SIZE(shadow_read_only_fields); 530 ARRAY_SIZE(shadow_read_only_fields);
531 531
532static const unsigned long shadow_read_write_fields[] = { 532static unsigned long shadow_read_write_fields[] = {
533 GUEST_RIP, 533 GUEST_RIP,
534 GUEST_RSP, 534 GUEST_RSP,
535 GUEST_CR0, 535 GUEST_CR0,
@@ -558,7 +558,7 @@ static const unsigned long shadow_read_write_fields[] = {
558 HOST_FS_SELECTOR, 558 HOST_FS_SELECTOR,
559 HOST_GS_SELECTOR 559 HOST_GS_SELECTOR
560}; 560};
561static const int max_shadow_read_write_fields = 561static int max_shadow_read_write_fields =
562 ARRAY_SIZE(shadow_read_write_fields); 562 ARRAY_SIZE(shadow_read_write_fields);
563 563
564static const unsigned short vmcs_field_to_offset_table[] = { 564static const unsigned short vmcs_field_to_offset_table[] = {
@@ -3009,6 +3009,41 @@ static void free_kvm_area(void)
3009 } 3009 }
3010} 3010}
3011 3011
3012static void init_vmcs_shadow_fields(void)
3013{
3014 int i, j;
3015
3016 /* No checks for read only fields yet */
3017
3018 for (i = j = 0; i < max_shadow_read_write_fields; i++) {
3019 switch (shadow_read_write_fields[i]) {
3020 case GUEST_BNDCFGS:
3021 if (!vmx_mpx_supported())
3022 continue;
3023 break;
3024 default:
3025 break;
3026 }
3027
3028 if (j < i)
3029 shadow_read_write_fields[j] =
3030 shadow_read_write_fields[i];
3031 j++;
3032 }
3033 max_shadow_read_write_fields = j;
3034
3035 /* shadowed fields guest access without vmexit */
3036 for (i = 0; i < max_shadow_read_write_fields; i++) {
3037 clear_bit(shadow_read_write_fields[i],
3038 vmx_vmwrite_bitmap);
3039 clear_bit(shadow_read_write_fields[i],
3040 vmx_vmread_bitmap);
3041 }
3042 for (i = 0; i < max_shadow_read_only_fields; i++)
3043 clear_bit(shadow_read_only_fields[i],
3044 vmx_vmread_bitmap);
3045}
3046
3012static __init int alloc_kvm_area(void) 3047static __init int alloc_kvm_area(void)
3013{ 3048{
3014 int cpu; 3049 int cpu;
@@ -3039,6 +3074,8 @@ static __init int hardware_setup(void)
3039 enable_vpid = 0; 3074 enable_vpid = 0;
3040 if (!cpu_has_vmx_shadow_vmcs()) 3075 if (!cpu_has_vmx_shadow_vmcs())
3041 enable_shadow_vmcs = 0; 3076 enable_shadow_vmcs = 0;
3077 if (enable_shadow_vmcs)
3078 init_vmcs_shadow_fields();
3042 3079
3043 if (!cpu_has_vmx_ept() || 3080 if (!cpu_has_vmx_ept() ||
3044 !cpu_has_vmx_ept_4levels()) { 3081 !cpu_has_vmx_ept_4levels()) {
@@ -8803,14 +8840,6 @@ static int __init vmx_init(void)
8803 8840
8804 memset(vmx_vmread_bitmap, 0xff, PAGE_SIZE); 8841 memset(vmx_vmread_bitmap, 0xff, PAGE_SIZE);
8805 memset(vmx_vmwrite_bitmap, 0xff, PAGE_SIZE); 8842 memset(vmx_vmwrite_bitmap, 0xff, PAGE_SIZE);
8806 /* shadowed read/write fields */
8807 for (i = 0; i < max_shadow_read_write_fields; i++) {
8808 clear_bit(shadow_read_write_fields[i], vmx_vmwrite_bitmap);
8809 clear_bit(shadow_read_write_fields[i], vmx_vmread_bitmap);
8810 }
8811 /* shadowed read only fields */
8812 for (i = 0; i < max_shadow_read_only_fields; i++)
8813 clear_bit(shadow_read_only_fields[i], vmx_vmread_bitmap);
8814 8843
8815 /* 8844 /*
8816 * Allow direct access to the PC debug port (it is often used for I/O 8845 * Allow direct access to the PC debug port (it is often used for I/O