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