summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-08-28 13:37:21 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-08-28 13:37:21 -0400
commit9cf6b756cdf2cd38b8b0dac2567f7c6daf5e79d5 (patch)
treeeb8af4cbe71eb8b6b8428a078abcbff8cc27a29e
parent9e8312f5e160ade069e131d54ab8652cf0e86e1a (diff)
parent82e40f558de566fdee214bec68096bbd5e64a6a4 (diff)
Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
Pull arm64 fixes from Will Deacon: "Hot on the heels of our last set of fixes are a few more for -rc7. Two of them are fixing issues with our virtual interrupt controller implementation in KVM/arm, while the other is a longstanding but straightforward kallsyms fix which was been acked by Masami and resolves an initialisation failure in kprobes observed on arm64. - Fix GICv2 emulation bug (KVM) - Fix deadlock in virtual GIC interrupt injection code (KVM) - Fix kprobes blacklist init failure due to broken kallsyms lookup" * tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: KVM: arm/arm64: vgic-v2: Handle SGI bits in GICD_I{S,C}PENDR0 as WI KVM: arm/arm64: vgic: Fix potential deadlock when ap_list is long kallsyms: Don't let kallsyms_lookup_size_offset() fail on retrieving the first symbol
-rw-r--r--kernel/kallsyms.c6
-rw-r--r--virt/kvm/arm/vgic/vgic-mmio.c18
-rw-r--r--virt/kvm/arm/vgic/vgic-v2.c5
-rw-r--r--virt/kvm/arm/vgic/vgic-v3.c5
-rw-r--r--virt/kvm/arm/vgic/vgic.c7
5 files changed, 37 insertions, 4 deletions
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
index 95a260f9214b..136ce049c4ad 100644
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -263,8 +263,10 @@ int kallsyms_lookup_size_offset(unsigned long addr, unsigned long *symbolsize,
263{ 263{
264 char namebuf[KSYM_NAME_LEN]; 264 char namebuf[KSYM_NAME_LEN];
265 265
266 if (is_ksym_addr(addr)) 266 if (is_ksym_addr(addr)) {
267 return !!get_symbol_pos(addr, symbolsize, offset); 267 get_symbol_pos(addr, symbolsize, offset);
268 return 1;
269 }
268 return !!module_address_lookup(addr, symbolsize, offset, NULL, namebuf) || 270 return !!module_address_lookup(addr, symbolsize, offset, NULL, namebuf) ||
269 !!__bpf_address_lookup(addr, symbolsize, offset, namebuf); 271 !!__bpf_address_lookup(addr, symbolsize, offset, namebuf);
270} 272}
diff --git a/virt/kvm/arm/vgic/vgic-mmio.c b/virt/kvm/arm/vgic/vgic-mmio.c
index 44efc2ff863f..0d090482720d 100644
--- a/virt/kvm/arm/vgic/vgic-mmio.c
+++ b/virt/kvm/arm/vgic/vgic-mmio.c
@@ -211,6 +211,12 @@ static void vgic_hw_irq_spending(struct kvm_vcpu *vcpu, struct vgic_irq *irq,
211 vgic_irq_set_phys_active(irq, true); 211 vgic_irq_set_phys_active(irq, true);
212} 212}
213 213
214static bool is_vgic_v2_sgi(struct kvm_vcpu *vcpu, struct vgic_irq *irq)
215{
216 return (vgic_irq_is_sgi(irq->intid) &&
217 vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V2);
218}
219
214void vgic_mmio_write_spending(struct kvm_vcpu *vcpu, 220void vgic_mmio_write_spending(struct kvm_vcpu *vcpu,
215 gpa_t addr, unsigned int len, 221 gpa_t addr, unsigned int len,
216 unsigned long val) 222 unsigned long val)
@@ -223,6 +229,12 @@ void vgic_mmio_write_spending(struct kvm_vcpu *vcpu,
223 for_each_set_bit(i, &val, len * 8) { 229 for_each_set_bit(i, &val, len * 8) {
224 struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); 230 struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
225 231
232 /* GICD_ISPENDR0 SGI bits are WI */
233 if (is_vgic_v2_sgi(vcpu, irq)) {
234 vgic_put_irq(vcpu->kvm, irq);
235 continue;
236 }
237
226 raw_spin_lock_irqsave(&irq->irq_lock, flags); 238 raw_spin_lock_irqsave(&irq->irq_lock, flags);
227 if (irq->hw) 239 if (irq->hw)
228 vgic_hw_irq_spending(vcpu, irq, is_uaccess); 240 vgic_hw_irq_spending(vcpu, irq, is_uaccess);
@@ -270,6 +282,12 @@ void vgic_mmio_write_cpending(struct kvm_vcpu *vcpu,
270 for_each_set_bit(i, &val, len * 8) { 282 for_each_set_bit(i, &val, len * 8) {
271 struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); 283 struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
272 284
285 /* GICD_ICPENDR0 SGI bits are WI */
286 if (is_vgic_v2_sgi(vcpu, irq)) {
287 vgic_put_irq(vcpu->kvm, irq);
288 continue;
289 }
290
273 raw_spin_lock_irqsave(&irq->irq_lock, flags); 291 raw_spin_lock_irqsave(&irq->irq_lock, flags);
274 292
275 if (irq->hw) 293 if (irq->hw)
diff --git a/virt/kvm/arm/vgic/vgic-v2.c b/virt/kvm/arm/vgic/vgic-v2.c
index 96aab77d0471..b00aa304c260 100644
--- a/virt/kvm/arm/vgic/vgic-v2.c
+++ b/virt/kvm/arm/vgic/vgic-v2.c
@@ -184,7 +184,10 @@ void vgic_v2_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr)
184 if (vgic_irq_is_sgi(irq->intid)) { 184 if (vgic_irq_is_sgi(irq->intid)) {
185 u32 src = ffs(irq->source); 185 u32 src = ffs(irq->source);
186 186
187 BUG_ON(!src); 187 if (WARN_RATELIMIT(!src, "No SGI source for INTID %d\n",
188 irq->intid))
189 return;
190
188 val |= (src - 1) << GICH_LR_PHYSID_CPUID_SHIFT; 191 val |= (src - 1) << GICH_LR_PHYSID_CPUID_SHIFT;
189 irq->source &= ~(1 << (src - 1)); 192 irq->source &= ~(1 << (src - 1));
190 if (irq->source) { 193 if (irq->source) {
diff --git a/virt/kvm/arm/vgic/vgic-v3.c b/virt/kvm/arm/vgic/vgic-v3.c
index 0c653a1e5215..a4ad431c92a9 100644
--- a/virt/kvm/arm/vgic/vgic-v3.c
+++ b/virt/kvm/arm/vgic/vgic-v3.c
@@ -167,7 +167,10 @@ void vgic_v3_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr)
167 model == KVM_DEV_TYPE_ARM_VGIC_V2) { 167 model == KVM_DEV_TYPE_ARM_VGIC_V2) {
168 u32 src = ffs(irq->source); 168 u32 src = ffs(irq->source);
169 169
170 BUG_ON(!src); 170 if (WARN_RATELIMIT(!src, "No SGI source for INTID %d\n",
171 irq->intid))
172 return;
173
171 val |= (src - 1) << GICH_LR_PHYSID_CPUID_SHIFT; 174 val |= (src - 1) << GICH_LR_PHYSID_CPUID_SHIFT;
172 irq->source &= ~(1 << (src - 1)); 175 irq->source &= ~(1 << (src - 1));
173 if (irq->source) { 176 if (irq->source) {
diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c
index 13d4b38a94ec..e7bde65ba67c 100644
--- a/virt/kvm/arm/vgic/vgic.c
+++ b/virt/kvm/arm/vgic/vgic.c
@@ -254,6 +254,13 @@ static int vgic_irq_cmp(void *priv, struct list_head *a, struct list_head *b)
254 bool penda, pendb; 254 bool penda, pendb;
255 int ret; 255 int ret;
256 256
257 /*
258 * list_sort may call this function with the same element when
259 * the list is fairly long.
260 */
261 if (unlikely(irqa == irqb))
262 return 0;
263
257 raw_spin_lock(&irqa->irq_lock); 264 raw_spin_lock(&irqa->irq_lock);
258 raw_spin_lock_nested(&irqb->irq_lock, SINGLE_DEPTH_NESTING); 265 raw_spin_lock_nested(&irqb->irq_lock, SINGLE_DEPTH_NESTING);
259 266