xref: /openbmc/linux/arch/mips/kvm/interrupt.c (revision 8be98d2f2a0a262f8bf8a0bc1fdf522b3c7aab17)
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