1 | /* |
2 | * This file is subject to the terms and conditions of the GNU General Public |
3 | * License. See the file "COPYING" in the main directory of this archive |
4 | * for more details. |
5 | * |
6 | * KVM/MIPS: Interrupt delivery |
7 | * |
8 | * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. |
9 | * Authors: Sanjay Lal <sanjayl@kymasys.com> |
10 | */ |
11 | |
12 | #include <linux/errno.h> |
13 | #include <linux/err.h> |
14 | #include <linux/vmalloc.h> |
15 | #include <linux/fs.h> |
16 | #include <linux/memblock.h> |
17 | #include <asm/page.h> |
18 | #include <asm/cacheflush.h> |
19 | |
20 | #include <linux/kvm_host.h> |
21 | |
22 | #include "interrupt.h" |
23 | |
24 | void kvm_mips_deliver_interrupts(struct kvm_vcpu *vcpu, u32 cause) |
25 | { |
26 | unsigned long *pending = &vcpu->arch.pending_exceptions; |
27 | unsigned long *pending_clr = &vcpu->arch.pending_exceptions_clr; |
28 | unsigned int priority; |
29 | |
30 | if (!(*pending) && !(*pending_clr)) |
31 | return; |
32 | |
33 | priority = __ffs(*pending_clr); |
34 | while (priority <= MIPS_EXC_MAX) { |
35 | kvm_mips_callbacks->irq_clear(vcpu, priority, cause); |
36 | |
37 | priority = find_next_bit(addr: pending_clr, |
38 | BITS_PER_BYTE * sizeof(*pending_clr), |
39 | offset: priority + 1); |
40 | } |
41 | |
42 | priority = __ffs(*pending); |
43 | while (priority <= MIPS_EXC_MAX) { |
44 | kvm_mips_callbacks->irq_deliver(vcpu, priority, cause); |
45 | |
46 | priority = find_next_bit(addr: pending, |
47 | BITS_PER_BYTE * sizeof(*pending), |
48 | offset: priority + 1); |
49 | } |
50 | |
51 | } |
52 | |
53 | int kvm_mips_pending_timer(struct kvm_vcpu *vcpu) |
54 | { |
55 | return test_bit(MIPS_EXC_INT_TIMER, &vcpu->arch.pending_exceptions); |
56 | } |
57 | |