diff options
Diffstat (limited to 'virt')
-rw-r--r-- | virt/kvm/arm/mmu.c | 36 | ||||
-rw-r--r-- | virt/kvm/eventfd.c | 2 | ||||
-rw-r--r-- | virt/kvm/kvm_main.c | 24 |
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 | ||
1457 | static 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 | */ |
186 | static int | 186 | static int |
187 | irqfd_wakeup(wait_queue_t *wait, unsigned mode, int sync, void *key) | 187 | irqfd_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 | ||
190 | static 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 | |||
190 | bool kvm_make_all_cpus_request(struct kvm *kvm, unsigned int req) | 202 | bool 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; |