1bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata/******************************************************************************
2bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata * linux/arch/ia64/xen/paravirt_patch.c
3bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata *
4bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
5bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata *                    VA Linux Systems Japan K.K.
6bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata *
7bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata * This program is free software; you can redistribute it and/or modify
8bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata * it under the terms of the GNU General Public License as published by
9bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata * the Free Software Foundation; either version 2 of the License, or
10bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata * (at your option) any later version.
11bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata *
12bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata * This program is distributed in the hope that it will be useful,
13bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata * but WITHOUT ANY WARRANTY; without even the implied warranty of
14bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata * GNU General Public License for more details.
16bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata *
17bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata * You should have received a copy of the GNU General Public License
18bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata * along with this program; if not, write to the Free Software
19bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata *
21bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata */
22bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
23bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata#include <linux/init.h>
24bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata#include <asm/intrinsics.h>
25bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata#include <asm/kprobes.h>
26bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata#include <asm/paravirt.h>
27bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata#include <asm/paravirt_patch.h>
28bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
29bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahatatypedef union ia64_inst {
30bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata        struct {
31bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		unsigned long long qp : 6;
32bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		unsigned long long : 31;
33bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		unsigned long long opcode : 4;
34bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		unsigned long long reserved : 23;
35bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata        } generic;
36bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata        unsigned long long l;
37bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata} ia64_inst_t;
38bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
39bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata/*
40bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata * flush_icache_range() can't be used here.
41bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata * we are here before cpu_init() which initializes
42bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata * ia64_i_cache_stride_shift. flush_icache_range() uses it.
43bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata */
44bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahatavoid __init_or_module
45bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahataparavirt_flush_i_cache_range(const void *instr, unsigned long size)
46bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata{
47bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	extern void paravirt_fc_i(const void *addr);
48bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	unsigned long i;
49bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
50bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	for (i = 0; i < size; i += sizeof(bundle_t))
51bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		paravirt_fc_i(instr + i);
52bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata}
53bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
54bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahatabundle_t* __init_or_module
55bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahataparavirt_get_bundle(unsigned long tag)
56bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata{
57bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	return (bundle_t *)(tag & ~3UL);
58bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata}
59bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
60bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahataunsigned long __init_or_module
61bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahataparavirt_get_slot(unsigned long tag)
62bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata{
63bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	return tag & 3UL;
64bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata}
65bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
66bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahataunsigned long __init_or_module
67bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahataparavirt_get_num_inst(unsigned long stag, unsigned long etag)
68bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata{
69bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	bundle_t *sbundle = paravirt_get_bundle(stag);
70bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	unsigned long sslot = paravirt_get_slot(stag);
71bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	bundle_t *ebundle = paravirt_get_bundle(etag);
72bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	unsigned long eslot = paravirt_get_slot(etag);
73bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
74bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	return (ebundle - sbundle) * 3 + eslot - sslot + 1;
75bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata}
76bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
77bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahataunsigned long __init_or_module
78bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahataparavirt_get_next_tag(unsigned long tag)
79bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata{
80bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	unsigned long slot = paravirt_get_slot(tag);
81bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
82bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	switch (slot) {
83bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	case 0:
84bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	case 1:
85bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		return tag + 1;
86bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	case 2: {
87bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		bundle_t *bundle = paravirt_get_bundle(tag);
88bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		return (unsigned long)(bundle + 1);
89bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	}
90bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	default:
91bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		BUG();
92bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	}
93bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	/* NOTREACHED */
94bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata}
95bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
96bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahataia64_inst_t __init_or_module
97bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahataparavirt_read_slot0(const bundle_t *bundle)
98bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata{
99bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	ia64_inst_t inst;
100bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	inst.l = bundle->quad0.slot0;
101bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	return inst;
102bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata}
103bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
104bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahataia64_inst_t __init_or_module
105bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahataparavirt_read_slot1(const bundle_t *bundle)
106bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata{
107bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	ia64_inst_t inst;
108bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	inst.l = bundle->quad0.slot1_p0 |
109bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		((unsigned long long)bundle->quad1.slot1_p1 << 18UL);
110bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	return inst;
111bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata}
112bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
113bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahataia64_inst_t __init_or_module
114bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahataparavirt_read_slot2(const bundle_t *bundle)
115bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata{
116bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	ia64_inst_t inst;
117bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	inst.l = bundle->quad1.slot2;
118bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	return inst;
119bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata}
120bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
121bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahataia64_inst_t __init_or_module
122bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahataparavirt_read_inst(unsigned long tag)
123bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata{
124bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	bundle_t *bundle = paravirt_get_bundle(tag);
125bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	unsigned long slot = paravirt_get_slot(tag);
126bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
127bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	switch (slot) {
128bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	case 0:
129bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		return paravirt_read_slot0(bundle);
130bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	case 1:
131bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		return paravirt_read_slot1(bundle);
132bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	case 2:
133bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		return paravirt_read_slot2(bundle);
134bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	default:
135bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		BUG();
136bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	}
137bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	/* NOTREACHED */
138bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata}
139bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
140bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahatavoid __init_or_module
141bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahataparavirt_write_slot0(bundle_t *bundle, ia64_inst_t inst)
142bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata{
143bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	bundle->quad0.slot0 = inst.l;
144bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata}
145bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
146bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahatavoid __init_or_module
147bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahataparavirt_write_slot1(bundle_t *bundle, ia64_inst_t inst)
148bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata{
149bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	bundle->quad0.slot1_p0 = inst.l;
150bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	bundle->quad1.slot1_p1 = inst.l >> 18UL;
151bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata}
152bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
153bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahatavoid __init_or_module
154bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahataparavirt_write_slot2(bundle_t *bundle, ia64_inst_t inst)
155bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata{
156bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	bundle->quad1.slot2 = inst.l;
157bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata}
158bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
159bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahatavoid __init_or_module
160bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahataparavirt_write_inst(unsigned long tag, ia64_inst_t inst)
161bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata{
162bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	bundle_t *bundle = paravirt_get_bundle(tag);
163bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	unsigned long slot = paravirt_get_slot(tag);
164bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
165bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	switch (slot) {
166bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	case 0:
167bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		paravirt_write_slot0(bundle, inst);
168bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		break;
169bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	case 1:
170bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		paravirt_write_slot1(bundle, inst);
171bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		break;
172bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	case 2:
173bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		paravirt_write_slot2(bundle, inst);
174bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		break;
175bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	default:
176bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		BUG();
177bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		break;
178bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	}
179bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	paravirt_flush_i_cache_range(bundle, sizeof(*bundle));
180bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata}
181bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
182bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata/* for debug */
183bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahatavoid
184bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahataparavirt_print_bundle(const bundle_t *bundle)
185bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata{
186bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	const unsigned long *quad = (const unsigned long *)bundle;
187bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	ia64_inst_t slot0 = paravirt_read_slot0(bundle);
188bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	ia64_inst_t slot1 = paravirt_read_slot1(bundle);
189bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	ia64_inst_t slot2 = paravirt_read_slot2(bundle);
190bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
191bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	printk(KERN_DEBUG
192bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	       "bundle 0x%p 0x%016lx 0x%016lx\n", bundle, quad[0], quad[1]);
193bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	printk(KERN_DEBUG
194bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	       "bundle template 0x%x\n",
195bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	       bundle->quad0.template);
196bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	printk(KERN_DEBUG
197bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	       "slot0 0x%lx slot1_p0 0x%lx slot1_p1 0x%lx slot2 0x%lx\n",
198bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	       (unsigned long)bundle->quad0.slot0,
199bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	       (unsigned long)bundle->quad0.slot1_p0,
200bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	       (unsigned long)bundle->quad1.slot1_p1,
201bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	       (unsigned long)bundle->quad1.slot2);
202bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	printk(KERN_DEBUG
203bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	       "slot0 0x%016llx slot1 0x%016llx slot2 0x%016llx\n",
204bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	       slot0.l, slot1.l, slot2.l);
205bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata}
206bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
207bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahatastatic int noreplace_paravirt __init_or_module = 0;
208bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
209bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahatastatic int __init setup_noreplace_paravirt(char *str)
210bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata{
211bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	noreplace_paravirt = 1;
212bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	return 1;
213bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata}
214bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata__setup("noreplace-paravirt", setup_noreplace_paravirt);
215bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
216bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata#ifdef ASM_SUPPORTED
217bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahatastatic void __init_or_module
218bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahatafill_nop_bundle(void *sbundle, void *ebundle)
219bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata{
220bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	extern const char paravirt_nop_bundle[];
221bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	extern const unsigned long paravirt_nop_bundle_size;
222bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
223bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	void *bundle = sbundle;
224bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
225bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	BUG_ON((((unsigned long)sbundle) % sizeof(bundle_t)) != 0);
226bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	BUG_ON((((unsigned long)ebundle) % sizeof(bundle_t)) != 0);
227bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
228bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	while (bundle < ebundle) {
229bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		memcpy(bundle, paravirt_nop_bundle, paravirt_nop_bundle_size);
230bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
231bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		bundle += paravirt_nop_bundle_size;
232bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	}
233bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata}
234bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
235bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata/* helper function */
236bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahataunsigned long __init_or_module
237bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata__paravirt_patch_apply_bundle(void *sbundle, void *ebundle, unsigned long type,
238bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata			      const struct paravirt_patch_bundle_elem *elems,
239bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata			      unsigned long nelems,
240bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata			      const struct paravirt_patch_bundle_elem **found)
241bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata{
242bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	unsigned long used = 0;
243bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	unsigned long i;
244bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
245bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	BUG_ON((((unsigned long)sbundle) % sizeof(bundle_t)) != 0);
246bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	BUG_ON((((unsigned long)ebundle) % sizeof(bundle_t)) != 0);
247bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
248bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	found = NULL;
249bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	for (i = 0; i < nelems; i++) {
250bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		const struct paravirt_patch_bundle_elem *p = &elems[i];
251bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		if (p->type == type) {
252bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata			unsigned long need = p->ebundle - p->sbundle;
253bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata			unsigned long room = ebundle - sbundle;
254bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
255bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata			if (found != NULL)
256bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata				*found = p;
257bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
258bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata			if (room < need) {
259bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata				/* no room to replace. skip it */
260bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata				printk(KERN_DEBUG
261bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata				       "the space is too small to put "
262bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata				       "bundles. type %ld need %ld room %ld\n",
263bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata				       type, need, room);
264bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata				break;
265bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata			}
266bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
267bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata			used = need;
268bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata			memcpy(sbundle, p->sbundle, used);
269bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata			break;
270bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		}
271bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	}
272bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
273bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	return used;
274bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata}
275bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
276bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahatavoid __init_or_module
277bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahataparavirt_patch_apply_bundle(const struct paravirt_patch_site_bundle *start,
278bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata			    const struct paravirt_patch_site_bundle *end)
279bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata{
280bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	const struct paravirt_patch_site_bundle *p;
281bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
282bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	if (noreplace_paravirt)
283bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		return;
284bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	if (pv_init_ops.patch_bundle == NULL)
285bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		return;
286bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
287bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	for (p = start; p < end; p++) {
288bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		unsigned long used;
289bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
290bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		used = (*pv_init_ops.patch_bundle)(p->sbundle, p->ebundle,
291bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata						   p->type);
292bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		if (used == 0)
293bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata			continue;
294bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
295bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		fill_nop_bundle(p->sbundle + used, p->ebundle);
296bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		paravirt_flush_i_cache_range(p->sbundle,
297bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata					     p->ebundle - p->sbundle);
298bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	}
299bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	ia64_sync_i();
300bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	ia64_srlz_i();
301bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata}
302bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
303bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata/*
304bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata * nop.i, nop.m, nop.f instruction are same format.
305bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata * but nop.b has differennt format.
306bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata * This doesn't support nop.b for now.
307bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata */
308bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahatastatic void __init_or_module
309bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahatafill_nop_inst(unsigned long stag, unsigned long etag)
310bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata{
311bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	extern const bundle_t paravirt_nop_mfi_inst_bundle[];
312bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	unsigned long tag;
313bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	const ia64_inst_t nop_inst =
314bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		paravirt_read_slot0(paravirt_nop_mfi_inst_bundle);
315bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
316bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	for (tag = stag; tag < etag; tag = paravirt_get_next_tag(tag))
317bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		paravirt_write_inst(tag, nop_inst);
318bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata}
319bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
320bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahatavoid __init_or_module
321bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahataparavirt_patch_apply_inst(const struct paravirt_patch_site_inst *start,
322bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata			  const struct paravirt_patch_site_inst *end)
323bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata{
324bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	const struct paravirt_patch_site_inst *p;
325bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
326bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	if (noreplace_paravirt)
327bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		return;
328bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	if (pv_init_ops.patch_inst == NULL)
329bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		return;
330bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
331bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	for (p = start; p < end; p++) {
332bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		unsigned long tag;
333bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		bundle_t *sbundle;
334bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		bundle_t *ebundle;
335bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
336bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		tag = (*pv_init_ops.patch_inst)(p->stag, p->etag, p->type);
337bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		if (tag == p->stag)
338bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata			continue;
339bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
340bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		fill_nop_inst(tag, p->etag);
341bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		sbundle = paravirt_get_bundle(p->stag);
342bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		ebundle = paravirt_get_bundle(p->etag) + 1;
343bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		paravirt_flush_i_cache_range(sbundle, (ebundle - sbundle) *
344bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata					     sizeof(bundle_t));
345bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	}
346bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	ia64_sync_i();
347bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	ia64_srlz_i();
348bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata}
349bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata#endif /* ASM_SUPPOTED */
350bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
351bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata/* brl.cond.sptk.many <target64> X3 */
352bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahatatypedef union inst_x3_op {
353bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	ia64_inst_t inst;
354bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	struct {
355bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		unsigned long qp: 6;
356bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		unsigned long btyp: 3;
357bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		unsigned long unused: 3;
358bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		unsigned long p: 1;
359bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		unsigned long imm20b: 20;
360bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		unsigned long wh: 2;
361bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		unsigned long d: 1;
362bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		unsigned long i: 1;
363bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		unsigned long opcode: 4;
364bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	};
365bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	unsigned long l;
366bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata} inst_x3_op_t;
367bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
368bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahatatypedef union inst_x3_imm {
369bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	ia64_inst_t inst;
370bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	struct {
371bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		unsigned long unused: 2;
372bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		unsigned long imm39: 39;
373bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	};
374bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	unsigned long l;
375bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata} inst_x3_imm_t;
376bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
377bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahatavoid __init_or_module
378bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahataparavirt_patch_reloc_brl(unsigned long tag, const void *target)
379bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata{
380bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	unsigned long tag_op = paravirt_get_next_tag(tag);
381bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	unsigned long tag_imm = tag;
382bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	bundle_t *bundle = paravirt_get_bundle(tag);
383bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
384bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	ia64_inst_t inst_op = paravirt_read_inst(tag_op);
385bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	ia64_inst_t inst_imm = paravirt_read_inst(tag_imm);
386bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
387bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	inst_x3_op_t inst_x3_op = { .l = inst_op.l };
388bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	inst_x3_imm_t inst_x3_imm = { .l = inst_imm.l };
389bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
390bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	unsigned long imm60 =
391bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		((unsigned long)target - (unsigned long)bundle) >> 4;
392bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
393bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	BUG_ON(paravirt_get_slot(tag) != 1); /* MLX */
394bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	BUG_ON(((unsigned long)target & (sizeof(bundle_t) - 1)) != 0);
395bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
396bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	/* imm60[59] 1bit */
397bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	inst_x3_op.i = (imm60 >> 59) & 1;
398bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	/* imm60[19:0] 20bit */
399bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	inst_x3_op.imm20b = imm60 & ((1UL << 20) - 1);
400bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	/* imm60[58:20] 39bit */
401bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	inst_x3_imm.imm39 = (imm60 >> 20) & ((1UL << 39) - 1);
402bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
403bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	inst_op.l = inst_x3_op.l;
404bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	inst_imm.l = inst_x3_imm.l;
405bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
406bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	paravirt_write_inst(tag_op, inst_op);
407bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	paravirt_write_inst(tag_imm, inst_imm);
408bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata}
409bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
410bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata/* br.cond.sptk.many <target25>	B1 */
411bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahatatypedef union inst_b1 {
412bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	ia64_inst_t inst;
413bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	struct {
414bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		unsigned long qp: 6;
415bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		unsigned long btype: 3;
416bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		unsigned long unused: 3;
417bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		unsigned long p: 1;
418bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		unsigned long imm20b: 20;
419bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		unsigned long wh: 2;
420bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		unsigned long d: 1;
421bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		unsigned long s: 1;
422bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		unsigned long opcode: 4;
423bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	};
424bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	unsigned long l;
425bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata} inst_b1_t;
426bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
427bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahatavoid __init
428bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahataparavirt_patch_reloc_br(unsigned long tag, const void *target)
429bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata{
430bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	bundle_t *bundle = paravirt_get_bundle(tag);
431bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	ia64_inst_t inst = paravirt_read_inst(tag);
432bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	unsigned long target25 = (unsigned long)target - (unsigned long)bundle;
433bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	inst_b1_t inst_b1;
434bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
435bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	BUG_ON(((unsigned long)target & (sizeof(bundle_t) - 1)) != 0);
436bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
437bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	inst_b1.l = inst.l;
438bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	if (target25 & (1UL << 63))
439bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		inst_b1.s = 1;
440bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	else
441bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		inst_b1.s = 0;
442bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
443bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	inst_b1.imm20b = target25 >> 4;
444bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	inst.l = inst_b1.l;
445bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
446bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	paravirt_write_inst(tag, inst);
447bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata}
448bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
449bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahatavoid __init
450bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata__paravirt_patch_apply_branch(
451bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	unsigned long tag, unsigned long type,
452bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	const struct paravirt_patch_branch_target *entries,
453bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	unsigned int nr_entries)
454bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata{
455bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	unsigned int i;
456bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	for (i = 0; i < nr_entries; i++) {
457bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		if (entries[i].type == type) {
458bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata			paravirt_patch_reloc_br(tag, entries[i].entry);
459bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata			break;
460bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		}
461bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	}
462bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata}
463bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
464bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahatastatic void __init
465bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahataparavirt_patch_apply_branch(const struct paravirt_patch_site_branch *start,
466bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata			    const struct paravirt_patch_site_branch *end)
467bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata{
468bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	const struct paravirt_patch_site_branch *p;
469bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
470bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	if (noreplace_paravirt)
471bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		return;
472bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	if (pv_init_ops.patch_branch == NULL)
473bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		return;
474bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
475bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	for (p = start; p < end; p++)
476bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata		(*pv_init_ops.patch_branch)(p->tag, p->type);
477bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
478bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	ia64_sync_i();
479bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	ia64_srlz_i();
480bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata}
481bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
482bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahatavoid __init
483bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahataparavirt_patch_apply(void)
484bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata{
485bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	extern const char __start_paravirt_bundles[];
486bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	extern const char __stop_paravirt_bundles[];
487bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	extern const char __start_paravirt_insts[];
488bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	extern const char __stop_paravirt_insts[];
489bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	extern const char __start_paravirt_branches[];
490bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	extern const char __stop_paravirt_branches[];
491bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
492bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	paravirt_patch_apply_bundle((const struct paravirt_patch_site_bundle *)
493bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata				    __start_paravirt_bundles,
494bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata				    (const struct paravirt_patch_site_bundle *)
495bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata				    __stop_paravirt_bundles);
496bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	paravirt_patch_apply_inst((const struct paravirt_patch_site_inst *)
497bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata				  __start_paravirt_insts,
498bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata				  (const struct paravirt_patch_site_inst *)
499bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata				  __stop_paravirt_insts);
500bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata	paravirt_patch_apply_branch((const struct paravirt_patch_site_branch *)
501bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata				    __start_paravirt_branches,
502bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata				    (const struct paravirt_patch_site_branch *)
503bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata				    __stop_paravirt_branches);
504bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata}
505bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata
506bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata/*
507bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata * Local variables:
508bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata * mode: C
509bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata * c-set-style: "linux"
510bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata * c-basic-offset: 8
511bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata * tab-width: 8
512bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata * indent-tabs-mode: t
513bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata * End:
514bf7ab02f620c1020c869fc71a2c855918b6a5375Isaku Yamahata */
515