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 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 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