Showing error 821

User: Jiri Slaby
Error type: Resource Leak
Error type description: The code omits to put the resource to the system for reuse
File location: arch/x86/xen/irq.c
Line in file: 64
Project: Linux Kernel
Project version: 2.6.28
Tools: Stanse (1.2)
Entered: 2011-11-07 22:40:13 UTC


Source:

  1#include <linux/hardirq.h>
  2
  3#include <xen/interface/xen.h>
  4#include <xen/interface/sched.h>
  5#include <xen/interface/vcpu.h>
  6
  7#include <asm/xen/hypercall.h>
  8#include <asm/xen/hypervisor.h>
  9
 10#include "xen-ops.h"
 11
 12/*
 13 * Force a proper event-channel callback from Xen after clearing the
 14 * callback mask. We do this in a very simple manner, by making a call
 15 * down into Xen. The pending flag will be checked by Xen on return.
 16 */
 17void xen_force_evtchn_callback(void)
 18{
 19        (void)HYPERVISOR_xen_version(0, NULL);
 20}
 21
 22static void __init __xen_init_IRQ(void)
 23{
 24        int i;
 25
 26        /* Create identity vector->irq map */
 27        for(i = 0; i < NR_VECTORS; i++) {
 28                int cpu;
 29
 30                for_each_possible_cpu(cpu)
 31                        per_cpu(vector_irq, cpu)[i] = i;
 32        }
 33
 34        xen_init_IRQ();
 35}
 36
 37static unsigned long xen_save_fl(void)
 38{
 39        struct vcpu_info *vcpu;
 40        unsigned long flags;
 41
 42        vcpu = x86_read_percpu(xen_vcpu);
 43
 44        /* flag has opposite sense of mask */
 45        flags = !vcpu->evtchn_upcall_mask;
 46
 47        /* convert to IF type flag
 48           -0 -> 0x00000000
 49           -1 -> 0xffffffff
 50        */
 51        return (-flags) & X86_EFLAGS_IF;
 52}
 53
 54static void xen_restore_fl(unsigned long flags)
 55{
 56        struct vcpu_info *vcpu;
 57
 58        /* convert from IF type flag */
 59        flags = !(flags & X86_EFLAGS_IF);
 60
 61        /* There's a one instruction preempt window here.  We need to
 62           make sure we're don't switch CPUs between getting the vcpu
 63           pointer and updating the mask. */
 64        preempt_disable();
 65        vcpu = x86_read_percpu(xen_vcpu);
 66        vcpu->evtchn_upcall_mask = flags;
 67        preempt_enable_no_resched();
 68
 69        /* Doesn't matter if we get preempted here, because any
 70           pending event will get dealt with anyway. */
 71
 72        if (flags == 0) {
 73                preempt_check_resched();
 74                barrier(); /* unmask then check (avoid races) */
 75                if (unlikely(vcpu->evtchn_upcall_pending))
 76                        xen_force_evtchn_callback();
 77        }
 78}
 79
 80static void xen_irq_disable(void)
 81{
 82        /* There's a one instruction preempt window here.  We need to
 83           make sure we're don't switch CPUs between getting the vcpu
 84           pointer and updating the mask. */
 85        preempt_disable();
 86        x86_read_percpu(xen_vcpu)->evtchn_upcall_mask = 1;
 87        preempt_enable_no_resched();
 88}
 89
 90static void xen_irq_enable(void)
 91{
 92        struct vcpu_info *vcpu;
 93
 94        /* We don't need to worry about being preempted here, since
 95           either a) interrupts are disabled, so no preemption, or b)
 96           the caller is confused and is trying to re-enable interrupts
 97           on an indeterminate processor. */
 98
 99        vcpu = x86_read_percpu(xen_vcpu);
100        vcpu->evtchn_upcall_mask = 0;
101
102        /* Doesn't matter if we get preempted here, because any
103           pending event will get dealt with anyway. */
104
105        barrier(); /* unmask then check (avoid races) */
106        if (unlikely(vcpu->evtchn_upcall_pending))
107                xen_force_evtchn_callback();
108}
109
110static void xen_safe_halt(void)
111{
112        /* Blocking includes an implicit local_irq_enable(). */
113        if (HYPERVISOR_sched_op(SCHEDOP_block, NULL) != 0)
114                BUG();
115}
116
117static void xen_halt(void)
118{
119        if (irqs_disabled())
120                HYPERVISOR_vcpu_op(VCPUOP_down, smp_processor_id(), NULL);
121        else
122                xen_safe_halt();
123}
124
125static const struct pv_irq_ops xen_irq_ops __initdata = {
126        .init_IRQ = __xen_init_IRQ,
127        .save_fl = xen_save_fl,
128        .restore_fl = xen_restore_fl,
129        .irq_disable = xen_irq_disable,
130        .irq_enable = xen_irq_enable,
131        .safe_halt = xen_safe_halt,
132        .halt = xen_halt,
133#ifdef CONFIG_X86_64
134        .adjust_exception_frame = xen_adjust_exception_frame,
135#endif
136};
137
138void __init xen_init_irq_ops()
139{
140        pv_irq_ops = xen_irq_ops;
141}