diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2016-02-16 12:51:55 -0500 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2016-02-16 12:51:55 -0500 |
commit | c53d7a846ee7273c21ca317500480eb7dcdd2c5a (patch) | |
tree | 100375bae0a491968cc65d717bf96d1b8b38e840 | |
parent | c05235d50f681bf685e7290cae05ab3b4fa493f3 (diff) | |
parent | 3c5b1d92b3b02be07873d611a27950addff544d3 (diff) |
Merge tag 'kvm-arm-for-4.5-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into kvm-master
KVM/ARM fixes for 4.5-rc4
- Fix for an unpleasant crash when the VM is created without a timer
- Allow HYP mode to access the full PA space, and not only 40bit
-rw-r--r-- | arch/arm64/include/asm/kvm_arm.h | 2 | ||||
-rw-r--r-- | arch/arm64/kvm/hyp-init.S | 12 | ||||
-rw-r--r-- | virt/kvm/arm/arch_timer.c | 9 |
3 files changed, 13 insertions, 10 deletions
diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h index bef6e9243c63..d201d4b396d1 100644 --- a/arch/arm64/include/asm/kvm_arm.h +++ b/arch/arm64/include/asm/kvm_arm.h | |||
@@ -107,8 +107,6 @@ | |||
107 | #define TCR_EL2_MASK (TCR_EL2_TG0 | TCR_EL2_SH0 | \ | 107 | #define TCR_EL2_MASK (TCR_EL2_TG0 | TCR_EL2_SH0 | \ |
108 | TCR_EL2_ORGN0 | TCR_EL2_IRGN0 | TCR_EL2_T0SZ) | 108 | TCR_EL2_ORGN0 | TCR_EL2_IRGN0 | TCR_EL2_T0SZ) |
109 | 109 | ||
110 | #define TCR_EL2_FLAGS (TCR_EL2_RES1 | TCR_EL2_PS_40B) | ||
111 | |||
112 | /* VTCR_EL2 Registers bits */ | 110 | /* VTCR_EL2 Registers bits */ |
113 | #define VTCR_EL2_RES1 (1 << 31) | 111 | #define VTCR_EL2_RES1 (1 << 31) |
114 | #define VTCR_EL2_PS_MASK (7 << 16) | 112 | #define VTCR_EL2_PS_MASK (7 << 16) |
diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S index 3e568dcd907b..d073b5a216f7 100644 --- a/arch/arm64/kvm/hyp-init.S +++ b/arch/arm64/kvm/hyp-init.S | |||
@@ -64,7 +64,7 @@ __do_hyp_init: | |||
64 | mrs x4, tcr_el1 | 64 | mrs x4, tcr_el1 |
65 | ldr x5, =TCR_EL2_MASK | 65 | ldr x5, =TCR_EL2_MASK |
66 | and x4, x4, x5 | 66 | and x4, x4, x5 |
67 | ldr x5, =TCR_EL2_FLAGS | 67 | mov x5, #TCR_EL2_RES1 |
68 | orr x4, x4, x5 | 68 | orr x4, x4, x5 |
69 | 69 | ||
70 | #ifndef CONFIG_ARM64_VA_BITS_48 | 70 | #ifndef CONFIG_ARM64_VA_BITS_48 |
@@ -85,15 +85,17 @@ __do_hyp_init: | |||
85 | ldr_l x5, idmap_t0sz | 85 | ldr_l x5, idmap_t0sz |
86 | bfi x4, x5, TCR_T0SZ_OFFSET, TCR_TxSZ_WIDTH | 86 | bfi x4, x5, TCR_T0SZ_OFFSET, TCR_TxSZ_WIDTH |
87 | #endif | 87 | #endif |
88 | msr tcr_el2, x4 | ||
89 | |||
90 | ldr x4, =VTCR_EL2_FLAGS | ||
91 | /* | 88 | /* |
92 | * Read the PARange bits from ID_AA64MMFR0_EL1 and set the PS bits in | 89 | * Read the PARange bits from ID_AA64MMFR0_EL1 and set the PS bits in |
93 | * VTCR_EL2. | 90 | * TCR_EL2 and VTCR_EL2. |
94 | */ | 91 | */ |
95 | mrs x5, ID_AA64MMFR0_EL1 | 92 | mrs x5, ID_AA64MMFR0_EL1 |
96 | bfi x4, x5, #16, #3 | 93 | bfi x4, x5, #16, #3 |
94 | |||
95 | msr tcr_el2, x4 | ||
96 | |||
97 | ldr x4, =VTCR_EL2_FLAGS | ||
98 | bfi x4, x5, #16, #3 | ||
97 | /* | 99 | /* |
98 | * Read the VMIDBits bits from ID_AA64MMFR1_EL1 and set the VS bit in | 100 | * Read the VMIDBits bits from ID_AA64MMFR1_EL1 and set the VS bit in |
99 | * VTCR_EL2. | 101 | * VTCR_EL2. |
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c index 69bca185c471..ea6064696fe4 100644 --- a/virt/kvm/arm/arch_timer.c +++ b/virt/kvm/arm/arch_timer.c | |||
@@ -143,7 +143,7 @@ static void kvm_timer_update_irq(struct kvm_vcpu *vcpu, bool new_level) | |||
143 | * Check if there was a change in the timer state (should we raise or lower | 143 | * Check if there was a change in the timer state (should we raise or lower |
144 | * the line level to the GIC). | 144 | * the line level to the GIC). |
145 | */ | 145 | */ |
146 | static void kvm_timer_update_state(struct kvm_vcpu *vcpu) | 146 | static int kvm_timer_update_state(struct kvm_vcpu *vcpu) |
147 | { | 147 | { |
148 | struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; | 148 | struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; |
149 | 149 | ||
@@ -154,10 +154,12 @@ static void kvm_timer_update_state(struct kvm_vcpu *vcpu) | |||
154 | * until we call this function from kvm_timer_flush_hwstate. | 154 | * until we call this function from kvm_timer_flush_hwstate. |
155 | */ | 155 | */ |
156 | if (!vgic_initialized(vcpu->kvm)) | 156 | if (!vgic_initialized(vcpu->kvm)) |
157 | return; | 157 | return -ENODEV; |
158 | 158 | ||
159 | if (kvm_timer_should_fire(vcpu) != timer->irq.level) | 159 | if (kvm_timer_should_fire(vcpu) != timer->irq.level) |
160 | kvm_timer_update_irq(vcpu, !timer->irq.level); | 160 | kvm_timer_update_irq(vcpu, !timer->irq.level); |
161 | |||
162 | return 0; | ||
161 | } | 163 | } |
162 | 164 | ||
163 | /* | 165 | /* |
@@ -218,7 +220,8 @@ void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu) | |||
218 | bool phys_active; | 220 | bool phys_active; |
219 | int ret; | 221 | int ret; |
220 | 222 | ||
221 | kvm_timer_update_state(vcpu); | 223 | if (kvm_timer_update_state(vcpu)) |
224 | return; | ||
222 | 225 | ||
223 | /* | 226 | /* |
224 | * If we enter the guest with the virtual input level to the VGIC | 227 | * If we enter the guest with the virtual input level to the VGIC |