Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
tile
kernel
messaging.c
Go to the documentation of this file.
1
/*
2
* Copyright 2010 Tilera Corporation. All Rights Reserved.
3
*
4
* This program is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU General Public License
6
* as published by the Free Software Foundation, version 2.
7
*
8
* This program is distributed in the hope that it will be useful, but
9
* WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
11
* NON INFRINGEMENT. See the GNU General Public License for
12
* more details.
13
*/
14
15
#include <
linux/percpu.h
>
16
#include <
linux/smp.h
>
17
#include <
linux/hardirq.h
>
18
#include <linux/ptrace.h>
19
#include <
asm/hv_driver.h
>
20
#include <asm/irq_regs.h>
21
#include <asm/traps.h>
22
#include <
hv/hypervisor.h
>
23
#include <
arch/interrupts.h
>
24
25
/* All messages are stored here */
26
static
DEFINE_PER_CPU
(
HV_MsgState
, msg_state);
27
28
void
__cpuinit
init_messaging
(
void
)
29
{
30
/* Allocate storage for messages in kernel space */
31
HV_MsgState
*
state
= &
__get_cpu_var
(msg_state);
32
int
rc
=
hv_register_message_state
(state);
33
if
(rc !=
HV_OK
)
34
panic
(
"hv_register_message_state: error %d"
, rc);
35
36
/* Make sure downcall interrupts will be enabled. */
37
arch_local_irq_unmask
(
INT_INTCTRL_K
);
38
}
39
40
void
hv_message_intr
(
struct
pt_regs
*
regs
,
int
intnum)
41
{
42
/*
43
* We enter with interrupts disabled and leave them disabled,
44
* to match expectations of called functions (e.g.
45
* do_ccupdate_local() in mm/slab.c). This is also consistent
46
* with normal call entry for device interrupts.
47
*/
48
49
int
message
[
HV_MAX_MESSAGE_SIZE
/
sizeof
(
int
)];
50
HV_RcvMsgInfo
rmi;
51
int
nmsgs = 0;
52
53
/* Track time spent here in an interrupt context */
54
struct
pt_regs
*old_regs = set_irq_regs(regs);
55
irq_enter
();
56
57
#ifdef CONFIG_DEBUG_STACKOVERFLOW
58
/* Debugging check for stack overflow: less than 1/8th stack free? */
59
{
60
long
sp
=
stack_pointer
- (
long
)
current_thread_info
();
61
if
(
unlikely
(sp < (
sizeof
(
struct
thread_info
) +
STACK_WARN
))) {
62
pr_emerg
(
"hv_message_intr: "
63
"stack overflow: %ld\n"
,
64
sp -
sizeof
(
struct
thread_info
));
65
dump_stack
();
66
}
67
}
68
#endif
69
70
while
(1) {
71
rmi =
hv_receive_message
(
__get_cpu_var
(msg_state),
72
(
HV_VirtAddr
)
message
,
73
sizeof
(message));
74
if
(rmi.msglen == 0)
75
break
;
76
77
if
(rmi.msglen < 0)
78
panic
(
"hv_receive_message failed: %d"
, rmi.msglen);
79
80
++nmsgs;
81
82
if
(rmi.source ==
HV_MSG_TILE
) {
83
int
tag
;
84
85
/* we just send tags for now */
86
BUG_ON
(rmi.msglen !=
sizeof
(
int
));
87
88
tag = message[0];
89
#ifdef CONFIG_SMP
90
evaluate_message
(message[0]);
91
#else
92
panic
(
"Received IPI message %d in UP mode"
, tag);
93
#endif
94
}
else
if
(rmi.source ==
HV_MSG_INTR
) {
95
HV_IntrMsg
*him = (
HV_IntrMsg
*)message;
96
struct
hv_driver_cb
*
cb
=
97
(
struct
hv_driver_cb
*)him->
intarg
;
98
cb->
callback
(cb, him->
intdata
);
99
__get_cpu_var
(
irq_stat
).irq_hv_msg_count++;
100
}
101
}
102
103
/*
104
* We shouldn't have gotten a message downcall with no
105
* messages available.
106
*/
107
if
(nmsgs == 0)
108
panic
(
"Message downcall invoked with no messages!"
);
109
110
/*
111
* Track time spent against the current process again and
112
* process any softirqs if they are waiting.
113
*/
114
irq_exit
();
115
set_irq_regs(old_regs);
116
}
Generated on Thu Jan 10 2013 13:19:05 for Linux Kernel by
1.8.2