| /* |
| * This file is subject to the terms and conditions of the GNU General Public |
| * License. See the file "COPYING" in the main directory of this archive |
| * for more details. |
| * |
| * KVM/MIPS: Interrupt delivery |
| * |
| * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. |
| * Authors: Sanjay Lal <sanjayl@kymasys.com> |
| */ |
| |
| #include <linux/errno.h> |
| #include <linux/err.h> |
| #include <linux/vmalloc.h> |
| #include <linux/fs.h> |
| #include <linux/memblock.h> |
| #include <asm/page.h> |
| #include <asm/cacheflush.h> |
| |
| #include <linux/kvm_host.h> |
| |
| #include "interrupt.h" |
| |
| void kvm_mips_deliver_interrupts(struct kvm_vcpu *vcpu, u32 cause) |
| { |
| unsigned long *pending = &vcpu->arch.pending_exceptions; |
| unsigned long *pending_clr = &vcpu->arch.pending_exceptions_clr; |
| unsigned int priority; |
| |
| if (!(*pending) && !(*pending_clr)) |
| return; |
| |
| priority = __ffs(*pending_clr); |
| while (priority <= MIPS_EXC_MAX) { |
| kvm_mips_callbacks->irq_clear(vcpu, priority, cause); |
| |
| priority = find_next_bit(pending_clr, |
| BITS_PER_BYTE * sizeof(*pending_clr), |
| priority + 1); |
| } |
| |
| priority = __ffs(*pending); |
| while (priority <= MIPS_EXC_MAX) { |
| kvm_mips_callbacks->irq_deliver(vcpu, priority, cause); |
| |
| priority = find_next_bit(pending, |
| BITS_PER_BYTE * sizeof(*pending), |
| priority + 1); |
| } |
| |
| } |
| |
| int kvm_mips_pending_timer(struct kvm_vcpu *vcpu) |
| { |
| return test_bit(MIPS_EXC_INT_TIMER, &vcpu->arch.pending_exceptions); |
| } |