aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2016-02-16 12:51:55 -0500
committerPaolo Bonzini <pbonzini@redhat.com>2016-02-16 12:51:55 -0500
commitc53d7a846ee7273c21ca317500480eb7dcdd2c5a (patch)
tree100375bae0a491968cc65d717bf96d1b8b38e840
parentc05235d50f681bf685e7290cae05ab3b4fa493f3 (diff)
parent3c5b1d92b3b02be07873d611a27950addff544d3 (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.h2
-rw-r--r--arch/arm64/kvm/hyp-init.S12
-rw-r--r--virt/kvm/arm/arch_timer.c9
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 */
146static void kvm_timer_update_state(struct kvm_vcpu *vcpu) 146static 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