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