summaryrefslogtreecommitdiffstats
path: root/virt
diff options
context:
space:
mode:
Diffstat (limited to 'virt')
-rw-r--r--virt/kvm/arm/mmu.c36
-rw-r--r--virt/kvm/eventfd.c2
-rw-r--r--virt/kvm/kvm_main.c24
3 files changed, 49 insertions, 13 deletions
diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
index f2d5b6cf06ae..0e1fc75f3585 100644
--- a/virt/kvm/arm/mmu.c
+++ b/virt/kvm/arm/mmu.c
@@ -30,6 +30,7 @@
30#include <asm/kvm_asm.h> 30#include <asm/kvm_asm.h>
31#include <asm/kvm_emulate.h> 31#include <asm/kvm_emulate.h>
32#include <asm/virt.h> 32#include <asm/virt.h>
33#include <asm/system_misc.h>
33 34
34#include "trace.h" 35#include "trace.h"
35 36
@@ -1453,6 +1454,25 @@ out:
1453 kvm_set_pfn_accessed(pfn); 1454 kvm_set_pfn_accessed(pfn);
1454} 1455}
1455 1456
1457static bool is_abort_sea(unsigned long fault_status)
1458{
1459 switch (fault_status) {
1460 case FSC_SEA:
1461 case FSC_SEA_TTW0:
1462 case FSC_SEA_TTW1:
1463 case FSC_SEA_TTW2:
1464 case FSC_SEA_TTW3:
1465 case FSC_SECC:
1466 case FSC_SECC_TTW0:
1467 case FSC_SECC_TTW1:
1468 case FSC_SECC_TTW2:
1469 case FSC_SECC_TTW3:
1470 return true;
1471 default:
1472 return false;
1473 }
1474}
1475
1456/** 1476/**
1457 * kvm_handle_guest_abort - handles all 2nd stage aborts 1477 * kvm_handle_guest_abort - handles all 2nd stage aborts
1458 * @vcpu: the VCPU pointer 1478 * @vcpu: the VCPU pointer
@@ -1475,19 +1495,29 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run)
1475 gfn_t gfn; 1495 gfn_t gfn;
1476 int ret, idx; 1496 int ret, idx;
1477 1497
1498 fault_status = kvm_vcpu_trap_get_fault_type(vcpu);
1499
1500 fault_ipa = kvm_vcpu_get_fault_ipa(vcpu);
1501
1502 /*
1503 * The host kernel will handle the synchronous external abort. There
1504 * is no need to pass the error into the guest.
1505 */
1506 if (is_abort_sea(fault_status)) {
1507 if (!handle_guest_sea(fault_ipa, kvm_vcpu_get_hsr(vcpu)))
1508 return 1;
1509 }
1510
1478 is_iabt = kvm_vcpu_trap_is_iabt(vcpu); 1511 is_iabt = kvm_vcpu_trap_is_iabt(vcpu);
1479 if (unlikely(!is_iabt && kvm_vcpu_dabt_isextabt(vcpu))) { 1512 if (unlikely(!is_iabt && kvm_vcpu_dabt_isextabt(vcpu))) {
1480 kvm_inject_vabt(vcpu); 1513 kvm_inject_vabt(vcpu);
1481 return 1; 1514 return 1;
1482 } 1515 }
1483 1516
1484 fault_ipa = kvm_vcpu_get_fault_ipa(vcpu);
1485
1486 trace_kvm_guest_fault(*vcpu_pc(vcpu), kvm_vcpu_get_hsr(vcpu), 1517 trace_kvm_guest_fault(*vcpu_pc(vcpu), kvm_vcpu_get_hsr(vcpu),
1487 kvm_vcpu_get_hfar(vcpu), fault_ipa); 1518 kvm_vcpu_get_hfar(vcpu), fault_ipa);
1488 1519
1489 /* Check the stage-2 fault is trans. fault or write fault */ 1520 /* Check the stage-2 fault is trans. fault or write fault */
1490 fault_status = kvm_vcpu_trap_get_fault_type(vcpu);
1491 if (fault_status != FSC_FAULT && fault_status != FSC_PERM && 1521 if (fault_status != FSC_FAULT && fault_status != FSC_PERM &&
1492 fault_status != FSC_ACCESS) { 1522 fault_status != FSC_ACCESS) {
1493 kvm_err("Unsupported FSC: EC=%#x xFSC=%#lx ESR_EL2=%#lx\n", 1523 kvm_err("Unsupported FSC: EC=%#x xFSC=%#lx ESR_EL2=%#lx\n",
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
index d016aadd5fbb..f2ac53ab8243 100644
--- a/virt/kvm/eventfd.c
+++ b/virt/kvm/eventfd.c
@@ -184,7 +184,7 @@ int __attribute__((weak)) kvm_arch_set_irq_inatomic(
184 * Called with wqh->lock held and interrupts disabled 184 * Called with wqh->lock held and interrupts disabled
185 */ 185 */
186static int 186static int
187irqfd_wakeup(wait_queue_t *wait, unsigned mode, int sync, void *key) 187irqfd_wakeup(wait_queue_entry_t *wait, unsigned mode, int sync, void *key)
188{ 188{
189 struct kvm_kernel_irqfd *irqfd = 189 struct kvm_kernel_irqfd *irqfd =
190 container_of(wait, struct kvm_kernel_irqfd, wait); 190 container_of(wait, struct kvm_kernel_irqfd, wait);
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 6e6d4edf0e92..7766c2b52797 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -187,12 +187,23 @@ static void ack_flush(void *_completed)
187{ 187{
188} 188}
189 189
190static inline bool kvm_kick_many_cpus(const struct cpumask *cpus, bool wait)
191{
192 if (unlikely(!cpus))
193 cpus = cpu_online_mask;
194
195 if (cpumask_empty(cpus))
196 return false;
197
198 smp_call_function_many(cpus, ack_flush, NULL, wait);
199 return true;
200}
201
190bool kvm_make_all_cpus_request(struct kvm *kvm, unsigned int req) 202bool kvm_make_all_cpus_request(struct kvm *kvm, unsigned int req)
191{ 203{
192 int i, cpu, me; 204 int i, cpu, me;
193 cpumask_var_t cpus; 205 cpumask_var_t cpus;
194 bool called = true; 206 bool called;
195 bool wait = req & KVM_REQUEST_WAIT;
196 struct kvm_vcpu *vcpu; 207 struct kvm_vcpu *vcpu;
197 208
198 zalloc_cpumask_var(&cpus, GFP_ATOMIC); 209 zalloc_cpumask_var(&cpus, GFP_ATOMIC);
@@ -207,14 +218,9 @@ bool kvm_make_all_cpus_request(struct kvm *kvm, unsigned int req)
207 218
208 if (cpus != NULL && cpu != -1 && cpu != me && 219 if (cpus != NULL && cpu != -1 && cpu != me &&
209 kvm_request_needs_ipi(vcpu, req)) 220 kvm_request_needs_ipi(vcpu, req))
210 cpumask_set_cpu(cpu, cpus); 221 __cpumask_set_cpu(cpu, cpus);
211 } 222 }
212 if (unlikely(cpus == NULL)) 223 called = kvm_kick_many_cpus(cpus, !!(req & KVM_REQUEST_WAIT));
213 smp_call_function_many(cpu_online_mask, ack_flush, NULL, wait);
214 else if (!cpumask_empty(cpus))
215 smp_call_function_many(cpus, ack_flush, NULL, wait);
216 else
217 called = false;
218 put_cpu(); 224 put_cpu();
219 free_cpumask_var(cpus); 225 free_cpumask_var(cpus);
220 return called; 226 return called;