paravirt_patch.c 12 KB

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