aboutsummaryrefslogtreecommitdiffstats
path: root/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/setup_arch_post.h
blob: e21d4ee6f21cfcf72bf38abc55459b5b8fb7af9e (plain)
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
/**
 * machine_specific_* - Hooks for machine specific setup.
 *
 * Description:
 *	This is included late in kernel/setup.c so that it can make
 *	use of all of the static functions.
 **/

#include <xen/interface/callback.h>

extern void hypervisor_callback(void);
extern void failsafe_callback(void);
extern void nmi(void);

static void __init machine_specific_arch_setup(void)
{
	int ret;
	struct callback_register event = {
		.type = CALLBACKTYPE_event,
		.address = (unsigned long) hypervisor_callback,
	};
	struct callback_register failsafe = {
		.type = CALLBACKTYPE_failsafe,
		.address = (unsigned long)failsafe_callback,
	};
	struct callback_register syscall = {
		.type = CALLBACKTYPE_syscall,
		.address = (unsigned long)system_call,
	};
#ifdef CONFIG_X86_LOCAL_APIC
	struct callback_register nmi_cb = {
		.type = CALLBACKTYPE_nmi,
		.address = (unsigned long)nmi,
	};
#endif

	ret = HYPERVISOR_callback_op(CALLBACKOP_register, &event);
	if (ret == 0)
		ret = HYPERVISOR_callback_op(CALLBACKOP_register, &failsafe);
	if (ret == 0)
		ret = HYPERVISOR_callback_op(CALLBACKOP_register, &syscall);
	if (ret == -ENOSYS)
		ret = HYPERVISOR_set_callbacks(
			event.address,
			failsafe.address,
			syscall.address);
	BUG_ON(ret);

#ifdef CONFIG_X86_LOCAL_APIC
	ret = HYPERVISOR_callback_op(CALLBACKOP_register, &nmi_cb);
	if (ret == -ENOSYS) {
		struct xennmi_callback cb;

		cb.handler_address = nmi_cb.address;
		HYPERVISOR_nmi_op(XENNMI_register_callback, &cb);
	}
#endif
}