1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
/******************************************************************************
* event.h
*
* A nice interface for passing asynchronous events to guest OSes.
*
* Copyright (c) 2002-2006, K A Fraser
*/
#ifndef __XEN_EVENT_H__
#define __XEN_EVENT_H__
#include <xen/sched.h>
#include <xen/smp.h>
#include <xen/softirq.h>
#include <xen/bitops.h>
#include <asm/event.h>
/*
* send_guest_vcpu_virq: Notify guest via a per-VCPU VIRQ.
* @v: VCPU to which virtual IRQ should be sent
* @virq: Virtual IRQ number (VIRQ_*)
*/
void send_guest_vcpu_virq(struct vcpu *v, uint32_t virq);
/*
* send_global_virq: Notify the domain handling a global VIRQ.
* @virq: Virtual IRQ number (VIRQ_*)
*/
void send_global_virq(uint32_t virq);
/*
* sent_global_virq_handler: Set a global VIRQ handler.
* @d: New target domain for this VIRQ
* @virq: Virtual IRQ number (VIRQ_*), must be global
*/
int set_global_virq_handler(struct domain *d, uint32_t virq);
/*
* send_guest_pirq:
* @d: Domain to which physical IRQ should be sent
* @pirq: Physical IRQ number
*/
void send_guest_pirq(struct domain *, const struct pirq *);
/* Send a notification from a given domain's event-channel port. */
int evtchn_send(struct domain *d, unsigned int lport);
/* Bind a local event-channel port to the specified VCPU. */
long evtchn_bind_vcpu(unsigned int port, unsigned int vcpu_id);
/* Unmask a local event-channel port. */
int evtchn_unmask(unsigned int port);
/* Move all PIRQs after a vCPU was moved to another pCPU. */
void evtchn_move_pirqs(struct vcpu *v);
/* Allocate/free a Xen-attached event channel port. */
typedef void (*xen_event_channel_notification_t)(
struct vcpu *v, unsigned int port);
int alloc_unbound_xen_event_channel(
struct vcpu *local_vcpu, domid_t remote_domid,
xen_event_channel_notification_t notification_fn);
void free_xen_event_channel(
struct vcpu *local_vcpu, int port);
/* Query if event channel is in use by the guest */
int guest_enabled_event(struct vcpu *v, uint32_t virq);
/* Notify remote end of a Xen-attached event channel.*/
void notify_via_xen_event_channel(struct domain *ld, int lport);
/* Internal event channel object accessors */
#define bucket_from_port(d,p) \
((d)->evtchn[(p)/EVTCHNS_PER_BUCKET])
#define port_is_valid(d,p) \
(((p) >= 0) && ((p) < MAX_EVTCHNS(d)) && \
(bucket_from_port(d,p) != NULL))
#define evtchn_from_port(d,p) \
(&(bucket_from_port(d,p))[(p)&(EVTCHNS_PER_BUCKET-1)])
/* Wait on a Xen-attached event channel. */
#define wait_on_xen_event_channel(port, condition) \
do { \
if ( condition ) \
break; \
set_bit(_VPF_blocked_in_xen, ¤t->pause_flags); \
smp_mb(); /* set blocked status /then/ re-evaluate condition */ \
if ( condition ) \
{ \
clear_bit(_VPF_blocked_in_xen, ¤t->pause_flags); \
break; \
} \
raise_softirq(SCHEDULE_SOFTIRQ); \
do_softirq(); \
} while ( 0 )
#define prepare_wait_on_xen_event_channel(port) \
do { \
set_bit(_VPF_blocked_in_xen, ¤t->pause_flags); \
raise_softirq(SCHEDULE_SOFTIRQ); \
smp_mb(); /* set blocked status /then/ caller does his work */ \
} while ( 0 )
#endif /* __XEN_EVENT_H__ */
|