Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 220981
Collapse All | Expand All

(-)linux-2.6.18.noarch.orig/arch/ia64/kernel/gate.lds.S (-8 lines)
Lines 48-61 SECTIONS Link Here
48
				    __start_gate_running_on_xen_patchlist = .;
48
				    __start_gate_running_on_xen_patchlist = .;
49
				    *(.data.patch.running_on_xen)
49
				    *(.data.patch.running_on_xen)
50
				    __end_gate_running_on_xen_patchlist = .;
50
				    __end_gate_running_on_xen_patchlist = .;
51
52
				    __start_gate_brl_xen_ssm_i_0_patchlist = .;
53
				    *(.data.patch.brl_xen_ssm_i_0)
54
				    __end_gate_brl_xen_ssm_i_0_patchlist = .;
55
56
				    __start_gate_brl_xen_ssm_i_1_patchlist = .;
57
				    *(.data.patch.brl_xen_ssm_i_1)
58
				    __end_gate_brl_xen_ssm_i_1_patchlist = .;
59
#endif
51
#endif
60
  }									:readable
52
  }									:readable
61
  .IA_64.unwind_info		: { *(.IA_64.unwind_info*) }
53
  .IA_64.unwind_info		: { *(.IA_64.unwind_info*) }
(-)linux-2.6.18.noarch.orig/arch/ia64/kernel/gate.S (-43 / +21 lines)
Lines 35-51 Link Here
35
	.xdata4 ".data.patch.brl_fsys_bubble_down", 1b-.
35
	.xdata4 ".data.patch.brl_fsys_bubble_down", 1b-.
36
36
37
#ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT
37
#ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT
38
	// The page in which hyperprivop lives must be pinned by ITR.
39
	// However vDSO area isn't pinned. So issuing hyperprivop
40
	// from vDSO page causes trouble that Kevin pointed out.
41
	// After clearing vpsr.ic, the vcpu is pre-empted and the itlb
42
	// is flushed. Then vcpu get cpu again, tlb miss fault occures.
43
	// However it results in nested dtlb fault because vpsr.ic is off.
44
	// To avoid such a situation, we jump into the kernel text area
45
	// which is pinned, and then issue hyperprivop and return back
46
	// to vDSO page.
47
	// This is Dan Magenheimer's idea.
48
49
	// Currently is_running_on_xen() is defined as running_on_xen.
38
	// Currently is_running_on_xen() is defined as running_on_xen.
50
	// If is_running_on_xen() is a real function, we must update
39
	// If is_running_on_xen() is a real function, we must update
51
	// according to it.
40
	// according to it.
Lines 55-72 Link Here
55
[1:]	movl reg=0;					\
44
[1:]	movl reg=0;					\
56
	.xdata4 ".data.patch.running_on_xen", 1b-.
45
	.xdata4 ".data.patch.running_on_xen", 1b-.
57
46
58
	.section ".data.patch.brl_xen_ssm_i_0", "a"
47
#endif /* CONFIG_XEN_IA64_VDSO_PARAVIRT */
59
	.previous
60
#define BRL_COND_XEN_SSM_I_0(pr)			\
61
[1:](pr)brl.cond.sptk 0;				\
62
	.xdata4 ".data.patch.brl_xen_ssm_i_0", 1b-.
63
64
	.section ".data.patch.brl_xen_ssm_i_1", "a"
65
	.previous
66
#define BRL_COND_XEN_SSM_I_1(pr)			\
67
[1:](pr)brl.cond.sptk 0;				\
68
	.xdata4 ".data.patch.brl_xen_ssm_i_1", 1b-.
69
#endif
70
48
71
GLOBAL_ENTRY(__kernel_syscall_via_break)
49
GLOBAL_ENTRY(__kernel_syscall_via_break)
72
	.prologue
50
	.prologue
Lines 111-121 GLOBAL_ENTRY(__kernel_syscall_via_epc) Link Here
111
	mov r10=0				// A    default to successful syscall execution
89
	mov r10=0				// A    default to successful syscall execution
112
	epc					// B	causes split-issue
90
	epc					// B	causes split-issue
113
}
91
}
114
	;;
115
#ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT
92
#ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT
116
	// r20 = 1
93
	// r20 = 1
117
	// r22 = &vcpu->vcpu_info->evtchn_upcall_mask
94
	// r22 = &vcpu->vcpu_info->evtchn_upcall_mask
118
	// r23 = &vpsr.ic
119
	// r24 = &vcpu->vcpu_info->evtchn_upcall_pending
95
	// r24 = &vcpu->vcpu_info->evtchn_upcall_pending
120
	// r25 = tmp
96
	// r25 = tmp
121
	// r28 = &running_on_xen
97
	// r28 = &running_on_xen
Lines 130-151 GLOBAL_ENTRY(__kernel_syscall_via_epc) Link Here
130
#define isRaw	p13
106
#define isRaw	p13
131
	LOAD_RUNNING_ON_XEN(r28)
107
	LOAD_RUNNING_ON_XEN(r28)
132
	movl r22=XSI_PSR_I_ADDR
108
	movl r22=XSI_PSR_I_ADDR
133
	;;
134
	ld8 r22=[r22]
135
	;;
136
	movl r23=XSI_PSR_IC
137
	adds r24=-1,r22
138
	mov r20=1
109
	mov r20=1
139
	;;
110
	;;
140
	ld4 r30=[r28]
111
	ld4 r30=[r28]
141
	;;
112
	;;
142
	cmp.ne isXen,isRaw=r0,r30
113
	cmp.ne isXen,isRaw=r0,r30
143
	;;
114
	;;
115
(isXen)	ld8 r22=[r22]
116
	;; 
144
(isRaw)	rsm psr.be | psr.i
117
(isRaw)	rsm psr.be | psr.i
118
(isXen)	adds r24=-1,r22
145
(isXen)	st1 [r22]=r20
119
(isXen)	st1 [r22]=r20
146
(isXen)	rum psr.be
120
(isXen)	rum psr.be
147
	;;
148
#else
121
#else
122
	;;
149
	rsm psr.be | psr.i			// M2 (5 cyc to srlz.d)
123
	rsm psr.be | psr.i			// M2 (5 cyc to srlz.d)
150
#endif
124
#endif
151
	LOAD_FSYSCALL_TABLE(r14)		// X
125
	LOAD_FSYSCALL_TABLE(r14)		// X
Lines 177-191 GLOBAL_ENTRY(__kernel_syscall_via_epc) Link Here
177
	nop.m 0
151
	nop.m 0
178
(p6)	tbit.z.unc p8,p0=r18,0			// I0 (dual-issues with "mov b7=r18"!)
152
(p6)	tbit.z.unc p8,p0=r18,0			// I0 (dual-issues with "mov b7=r18"!)
179
#ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT
153
#ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT
180
	;;
154
	
155
#define XEN_SET_PSR_I(pred)		\
156
(pred)	ld1 r31=[r22];			\
157
	;; ;				\
158
(pred)	st1 [r22]=r0;			\
159
(pred)	cmp.ne.unc p14,p0=r0,r31;	\
160
	;; ;				\
161
(p14)	ld1 r25=[r24];			\
162
	;; ;				\
163
(p14)	cmp.ne.unc p11,p0=r0,r25;	\
164
	;; ;				\
165
(p11)	XEN_HYPER_SSM_I;
166
167
	;; 
181
	// p14 = running_on_xen && p8
168
	// p14 = running_on_xen && p8
182
	// p15 = !running_on_xen && p8
169
	// p15 = !running_on_xen && p8
183
(p8)	cmp.ne.unc p14,p15=r0,r30
170
(p8)	cmp.ne.unc p14,p15=r0,r30
184
	;;
171
	;;
185
(p15)	ssm psr.i
172
(p15)	ssm psr.i
186
	BRL_COND_XEN_SSM_I_0(p14)
173
	XEN_SET_PSR_I(p14)
187
	.global .vdso_ssm_i_0_ret
188
.vdso_ssm_i_0_ret:
189
#else
174
#else
190
	nop.i 0
175
	nop.i 0
191
	;;
176
	;;
Lines 213-231 GLOBAL_ENTRY(__kernel_syscall_via_epc) Link Here
213
#endif
198
#endif
214
#ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT
199
#ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT
215
(isRaw)	ssm psr.i
200
(isRaw)	ssm psr.i
216
	BRL_COND_XEN_SSM_I_1(isXen)
201
	XEN_SET_PSR_I(isXen)
217
	.global .vdso_ssm_i_1_ret
218
.vdso_ssm_i_1_ret:
219
#else
202
#else
220
	ssm psr.i
203
	ssm psr.i
221
#endif
204
#endif
222
	mov r10=-1
205
	mov r10=-1
223
(p10)	mov r8=EINVAL
206
(p10)	mov r8=EINVAL
224
#ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT
225
	dv_serialize_data // shut up gas warning.
226
		          // we know xen_hyper_ssm_i_0 or xen_hyper_ssm_i_1
227
		          // doesn't change p9 and p10
228
#endif
229
(p9)	mov r8=ENOSYS
207
(p9)	mov r8=ENOSYS
230
	FSYS_RETURN
208
	FSYS_RETURN
231
END(__kernel_syscall_via_epc)
209
END(__kernel_syscall_via_epc)
(-)linux-2.6.18.noarch.orig/arch/ia64/kernel/patch.c (-39 lines)
Lines 205-250 patch_running_on_xen(unsigned long start Link Here
205
	ia64_srlz_i();
205
	ia64_srlz_i();
206
}
206
}
207
207
208
static void __init
209
patch_brl_symaddr(unsigned long start, unsigned long end,
210
                  unsigned long symaddr)
211
{
212
	s32 *offp = (s32 *)start;
213
	u64 ip;
214
215
	while (offp < (s32 *)end) {
216
		ip = (u64)offp + *offp;
217
		ia64_patch_imm60((u64)ia64_imva((void *)ip),
218
				 (u64)(symaddr - (ip & -16)) / 16);
219
		ia64_fc((void *)ip);
220
		++offp;
221
	}
222
	ia64_sync_i();
223
	ia64_srlz_i();
224
}
225
226
#define EXTERN_PATCHLIST(name)					\
227
	extern char __start_gate_brl_##name##_patchlist[];	\
228
	extern char __end_gate_brl_##name##_patchlist[];	\
229
	extern char name[]
230
231
#define PATCH_BRL_SYMADDR(name)						\
232
	patch_brl_symaddr((unsigned long)__start_gate_brl_##name##_patchlist, \
233
	                  (unsigned long)__end_gate_brl_##name##_patchlist,   \
234
	                  (unsigned long)name)
235
236
static void __init
237
patch_brl_in_vdso(void)
238
{
239
	EXTERN_PATCHLIST(xen_ssm_i_0);
240
	EXTERN_PATCHLIST(xen_ssm_i_1);
241
242
	PATCH_BRL_SYMADDR(xen_ssm_i_0);
243
	PATCH_BRL_SYMADDR(xen_ssm_i_1);
244
}
245
#else
208
#else
246
#define patch_running_on_xen(start, end)	do { } while (0)
209
#define patch_running_on_xen(start, end)	do { } while (0)
247
#define patch_brl_in_vdso()			do { } while (0)
248
#endif
210
#endif
249
211
250
void __init
212
void __init
Lines 257-263 ia64_patch_gate (void) Link Here
257
	patch_brl_fsys_bubble_down(START(brl_fsys_bubble_down), END(brl_fsys_bubble_down));
219
	patch_brl_fsys_bubble_down(START(brl_fsys_bubble_down), END(brl_fsys_bubble_down));
258
#ifdef CONFIG_XEN
220
#ifdef CONFIG_XEN
259
	patch_running_on_xen(START(running_on_xen), END(running_on_xen));
221
	patch_running_on_xen(START(running_on_xen), END(running_on_xen));
260
	patch_brl_in_vdso();
261
#endif
222
#endif
262
	ia64_patch_vtop(START(vtop), END(vtop));
223
	ia64_patch_vtop(START(vtop), END(vtop));
263
	ia64_patch_mckinley_e9(START(mckinley_e9), END(mckinley_e9));
224
	ia64_patch_mckinley_e9(START(mckinley_e9), END(mckinley_e9));
(-)linux-2.6.18.noarch.orig/arch/ia64/xen/hypercall.S (-37 lines)
Lines 125-170 GLOBAL_ENTRY(xen_send_ipi) Link Here
125
        ;;
125
        ;;
126
END(xen_send_ipi)
126
END(xen_send_ipi)
127
127
128
#ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT
129
// Those are vdso specialized.
130
// In fsys mode, call, ret can't be used.
131
132
	// see xen_ssm_i() in privop.h
133
	// r22 = &vcpu->vcpu_info->evtchn_upcall_mask
134
	// r23 = &vpsr.ic
135
	// r24 = &vcpu->vcpu_info->evtchn_upcall_pending
136
	// r25 = tmp
137
	// r31 = tmp
138
	// p11 = tmp
139
	// p14 = tmp
140
#define XEN_SET_PSR_I			\
141
	ld1 r31=[r22];			\
142
	ld1 r25=[r24];			\
143
	;;				\
144
	st1 [r22]=r0;			\
145
	cmp.ne.unc p14,p0=r0,r31;	\
146
	;;				\
147
(p14)	cmp.ne.unc p11,p0=r0,r25;	\
148
	;;				\
149
(p11)	st1 [r22]=r20;			\
150
(p11)	XEN_HYPER_SSM_I;
151
		
152
GLOBAL_ENTRY(xen_ssm_i_0)
153
	XEN_SET_PSR_I
154
	brl.cond.sptk	.vdso_ssm_i_0_ret
155
	;; 
156
END(xen_ssm_i_0)
157
158
GLOBAL_ENTRY(xen_ssm_i_1)
159
	XEN_SET_PSR_I
160
	brl.cond.sptk	.vdso_ssm_i_1_ret
161
	;; 
162
END(xen_ssm_i_1)
163
164
GLOBAL_ENTRY(__hypercall)
128
GLOBAL_ENTRY(__hypercall)
165
	mov r2=r37
129
	mov r2=r37
166
	break 0x1000
130
	break 0x1000
167
	br.ret.sptk.many b0
131
	br.ret.sptk.many b0
168
	;;
132
	;;
169
END(__hypercall)
133
END(__hypercall)
170
#endif
(-)linux-2.6.18.noarch.orig/include/asm-ia64/xen/privop.h (-9 / +9 lines)
Lines 64-71 Link Here
64
#endif
64
#endif
65
65
66
#ifndef __ASSEMBLY__
66
#ifndef __ASSEMBLY__
67
#define	XEN_HYPER_SSM_I		asm("break %0" : : "i" (HYPERPRIVOP_SSM_I))
67
#define	XEN_HYPER_SSM_I		asm ("break %0" : : "i" (HYPERPRIVOP_SSM_I) : "memory")
68
#define	XEN_HYPER_GET_IVR	asm("break %0" : : "i" (HYPERPRIVOP_GET_IVR))
69
68
70
/************************************************/
69
/************************************************/
71
/* Instructions paravirtualized for correctness */
70
/* Instructions paravirtualized for correctness */
Lines 127-133 extern void xen_set_eflag(unsigned long) Link Here
127
126
128
/* turning off interrupts can be paravirtualized simply by writing
127
/* turning off interrupts can be paravirtualized simply by writing
129
 * to a memory-mapped virtual psr.i bit (implemented as a 16-bit bool) */
128
 * to a memory-mapped virtual psr.i bit (implemented as a 16-bit bool) */
130
#define xen_rsm_i()	xen_set_virtual_psr_i(0)
129
#define xen_rsm_i()							\
130
do {	xen_set_virtual_psr_i(0);					\
131
	barrier();							\
132
} while(0)
131
133
132
/* turning on interrupts is a bit more complicated.. write to the
134
/* turning on interrupts is a bit more complicated.. write to the
133
 * memory-mapped virtual psr.i bit first (to avoid race condition),
135
 * memory-mapped virtual psr.i bit first (to avoid race condition),
Lines 136-147 extern void xen_set_eflag(unsigned long) Link Here
136
#define xen_ssm_i()							\
138
#define xen_ssm_i()							\
137
({									\
139
({									\
138
	int old = xen_get_virtual_psr_i();				\
140
	int old = xen_get_virtual_psr_i();				\
139
	if (!old) {							\
141
	xen_set_virtual_psr_i(1);					\
140
		if (xen_get_virtual_pend())				\
142
	barrier();							\
141
			xen_hyper_ssm_i();				\
143
	if (!old && xen_get_virtual_pend())				\
142
		else							\
144
		xen_hyper_ssm_i();					\
143
			xen_set_virtual_psr_i(1);			\
144
	}								\
145
})
145
})
146
146
147
#define xen_ia64_intrin_local_irq_restore(x)				\
147
#define xen_ia64_intrin_local_irq_restore(x)				\

Return to bug 220981