user-exec.c 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290
  1. /*
  2. * User emulator execution
  3. *
  4. * Copyright (c) 2003-2005 Fabrice Bellard
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "qemu/osdep.h"
  20. #include "hw/core/tcg-cpu-ops.h"
  21. #include "disas/disas.h"
  22. #include "exec/exec-all.h"
  23. #include "tcg/tcg.h"
  24. #include "qemu/bitops.h"
  25. #include "qemu/rcu.h"
  26. #include "exec/cpu_ldst.h"
  27. #include "qemu/main-loop.h"
  28. #include "exec/translate-all.h"
  29. #include "exec/page-protection.h"
  30. #include "exec/helper-proto.h"
  31. #include "qemu/atomic128.h"
  32. #include "trace/trace-root.h"
  33. #include "tcg/tcg-ldst.h"
  34. #include "internal-common.h"
  35. #include "internal-target.h"
  36. __thread uintptr_t helper_retaddr;
  37. //#define DEBUG_SIGNAL
  38. void cpu_interrupt(CPUState *cpu, int mask)
  39. {
  40. g_assert(bql_locked());
  41. cpu->interrupt_request |= mask;
  42. qatomic_set(&cpu->neg.icount_decr.u16.high, -1);
  43. }
  44. /*
  45. * Adjust the pc to pass to cpu_restore_state; return the memop type.
  46. */
  47. MMUAccessType adjust_signal_pc(uintptr_t *pc, bool is_write)
  48. {
  49. switch (helper_retaddr) {
  50. default:
  51. /*
  52. * Fault during host memory operation within a helper function.
  53. * The helper's host return address, saved here, gives us a
  54. * pointer into the generated code that will unwind to the
  55. * correct guest pc.
  56. */
  57. *pc = helper_retaddr;
  58. break;
  59. case 0:
  60. /*
  61. * Fault during host memory operation within generated code.
  62. * (Or, a unrelated bug within qemu, but we can't tell from here).
  63. *
  64. * We take the host pc from the signal frame. However, we cannot
  65. * use that value directly. Within cpu_restore_state_from_tb, we
  66. * assume PC comes from GETPC(), as used by the helper functions,
  67. * so we adjust the address by -GETPC_ADJ to form an address that
  68. * is within the call insn, so that the address does not accidentally
  69. * match the beginning of the next guest insn. However, when the
  70. * pc comes from the signal frame it points to the actual faulting
  71. * host memory insn and not the return from a call insn.
  72. *
  73. * Therefore, adjust to compensate for what will be done later
  74. * by cpu_restore_state_from_tb.
  75. */
  76. *pc += GETPC_ADJ;
  77. break;
  78. case 1:
  79. /*
  80. * Fault during host read for translation, or loosely, "execution".
  81. *
  82. * The guest pc is already pointing to the start of the TB for which
  83. * code is being generated. If the guest translator manages the
  84. * page crossings correctly, this is exactly the correct address
  85. * (and if the translator doesn't handle page boundaries correctly
  86. * there's little we can do about that here). Therefore, do not
  87. * trigger the unwinder.
  88. */
  89. *pc = 0;
  90. return MMU_INST_FETCH;
  91. }
  92. return is_write ? MMU_DATA_STORE : MMU_DATA_LOAD;
  93. }
  94. /**
  95. * handle_sigsegv_accerr_write:
  96. * @cpu: the cpu context
  97. * @old_set: the sigset_t from the signal ucontext_t
  98. * @host_pc: the host pc, adjusted for the signal
  99. * @guest_addr: the guest address of the fault
  100. *
  101. * Return true if the write fault has been handled, and should be re-tried.
  102. *
  103. * Note that it is important that we don't call page_unprotect() unless
  104. * this is really a "write to nonwritable page" fault, because
  105. * page_unprotect() assumes that if it is called for an access to
  106. * a page that's writable this means we had two threads racing and
  107. * another thread got there first and already made the page writable;
  108. * so we will retry the access. If we were to call page_unprotect()
  109. * for some other kind of fault that should really be passed to the
  110. * guest, we'd end up in an infinite loop of retrying the faulting access.
  111. */
  112. bool handle_sigsegv_accerr_write(CPUState *cpu, sigset_t *old_set,
  113. uintptr_t host_pc, abi_ptr guest_addr)
  114. {
  115. switch (page_unprotect(guest_addr, host_pc)) {
  116. case 0:
  117. /*
  118. * Fault not caused by a page marked unwritable to protect
  119. * cached translations, must be the guest binary's problem.
  120. */
  121. return false;
  122. case 1:
  123. /*
  124. * Fault caused by protection of cached translation; TBs
  125. * invalidated, so resume execution.
  126. */
  127. return true;
  128. case 2:
  129. /*
  130. * Fault caused by protection of cached translation, and the
  131. * currently executing TB was modified and must be exited immediately.
  132. */
  133. sigprocmask(SIG_SETMASK, old_set, NULL);
  134. cpu_loop_exit_noexc(cpu);
  135. /* NORETURN */
  136. default:
  137. g_assert_not_reached();
  138. }
  139. }
  140. typedef struct PageFlagsNode {
  141. struct rcu_head rcu;
  142. IntervalTreeNode itree;
  143. int flags;
  144. } PageFlagsNode;
  145. static IntervalTreeRoot pageflags_root;
  146. static PageFlagsNode *pageflags_find(target_ulong start, target_ulong last)
  147. {
  148. IntervalTreeNode *n;
  149. n = interval_tree_iter_first(&pageflags_root, start, last);
  150. return n ? container_of(n, PageFlagsNode, itree) : NULL;
  151. }
  152. static PageFlagsNode *pageflags_next(PageFlagsNode *p, target_ulong start,
  153. target_ulong last)
  154. {
  155. IntervalTreeNode *n;
  156. n = interval_tree_iter_next(&p->itree, start, last);
  157. return n ? container_of(n, PageFlagsNode, itree) : NULL;
  158. }
  159. int walk_memory_regions(void *priv, walk_memory_regions_fn fn)
  160. {
  161. IntervalTreeNode *n;
  162. int rc = 0;
  163. mmap_lock();
  164. for (n = interval_tree_iter_first(&pageflags_root, 0, -1);
  165. n != NULL;
  166. n = interval_tree_iter_next(n, 0, -1)) {
  167. PageFlagsNode *p = container_of(n, PageFlagsNode, itree);
  168. rc = fn(priv, n->start, n->last + 1, p->flags);
  169. if (rc != 0) {
  170. break;
  171. }
  172. }
  173. mmap_unlock();
  174. return rc;
  175. }
  176. static int dump_region(void *priv, target_ulong start,
  177. target_ulong end, unsigned long prot)
  178. {
  179. FILE *f = (FILE *)priv;
  180. fprintf(f, TARGET_FMT_lx"-"TARGET_FMT_lx" "TARGET_FMT_lx" %c%c%c\n",
  181. start, end, end - start,
  182. ((prot & PAGE_READ) ? 'r' : '-'),
  183. ((prot & PAGE_WRITE) ? 'w' : '-'),
  184. ((prot & PAGE_EXEC) ? 'x' : '-'));
  185. return 0;
  186. }
  187. /* dump memory mappings */
  188. void page_dump(FILE *f)
  189. {
  190. const int length = sizeof(target_ulong) * 2;
  191. fprintf(f, "%-*s %-*s %-*s %s\n",
  192. length, "start", length, "end", length, "size", "prot");
  193. walk_memory_regions(f, dump_region);
  194. }
  195. int page_get_flags(target_ulong address)
  196. {
  197. PageFlagsNode *p = pageflags_find(address, address);
  198. /*
  199. * See util/interval-tree.c re lockless lookups: no false positives but
  200. * there are false negatives. If we find nothing, retry with the mmap
  201. * lock acquired.
  202. */
  203. if (p) {
  204. return p->flags;
  205. }
  206. if (have_mmap_lock()) {
  207. return 0;
  208. }
  209. mmap_lock();
  210. p = pageflags_find(address, address);
  211. mmap_unlock();
  212. return p ? p->flags : 0;
  213. }
  214. /* A subroutine of page_set_flags: insert a new node for [start,last]. */
  215. static void pageflags_create(target_ulong start, target_ulong last, int flags)
  216. {
  217. PageFlagsNode *p = g_new(PageFlagsNode, 1);
  218. p->itree.start = start;
  219. p->itree.last = last;
  220. p->flags = flags;
  221. interval_tree_insert(&p->itree, &pageflags_root);
  222. }
  223. /* A subroutine of page_set_flags: remove everything in [start,last]. */
  224. static bool pageflags_unset(target_ulong start, target_ulong last)
  225. {
  226. bool inval_tb = false;
  227. while (true) {
  228. PageFlagsNode *p = pageflags_find(start, last);
  229. target_ulong p_last;
  230. if (!p) {
  231. break;
  232. }
  233. if (p->flags & PAGE_EXEC) {
  234. inval_tb = true;
  235. }
  236. interval_tree_remove(&p->itree, &pageflags_root);
  237. p_last = p->itree.last;
  238. if (p->itree.start < start) {
  239. /* Truncate the node from the end, or split out the middle. */
  240. p->itree.last = start - 1;
  241. interval_tree_insert(&p->itree, &pageflags_root);
  242. if (last < p_last) {
  243. pageflags_create(last + 1, p_last, p->flags);
  244. break;
  245. }
  246. } else if (p_last <= last) {
  247. /* Range completely covers node -- remove it. */
  248. g_free_rcu(p, rcu);
  249. } else {
  250. /* Truncate the node from the start. */
  251. p->itree.start = last + 1;
  252. interval_tree_insert(&p->itree, &pageflags_root);
  253. break;
  254. }
  255. }
  256. return inval_tb;
  257. }
  258. /*
  259. * A subroutine of page_set_flags: nothing overlaps [start,last],
  260. * but check adjacent mappings and maybe merge into a single range.
  261. */
  262. static void pageflags_create_merge(target_ulong start, target_ulong last,
  263. int flags)
  264. {
  265. PageFlagsNode *next = NULL, *prev = NULL;
  266. if (start > 0) {
  267. prev = pageflags_find(start - 1, start - 1);
  268. if (prev) {
  269. if (prev->flags == flags) {
  270. interval_tree_remove(&prev->itree, &pageflags_root);
  271. } else {
  272. prev = NULL;
  273. }
  274. }
  275. }
  276. if (last + 1 != 0) {
  277. next = pageflags_find(last + 1, last + 1);
  278. if (next) {
  279. if (next->flags == flags) {
  280. interval_tree_remove(&next->itree, &pageflags_root);
  281. } else {
  282. next = NULL;
  283. }
  284. }
  285. }
  286. if (prev) {
  287. if (next) {
  288. prev->itree.last = next->itree.last;
  289. g_free_rcu(next, rcu);
  290. } else {
  291. prev->itree.last = last;
  292. }
  293. interval_tree_insert(&prev->itree, &pageflags_root);
  294. } else if (next) {
  295. next->itree.start = start;
  296. interval_tree_insert(&next->itree, &pageflags_root);
  297. } else {
  298. pageflags_create(start, last, flags);
  299. }
  300. }
  301. /*
  302. * Allow the target to decide if PAGE_TARGET_[12] may be reset.
  303. * By default, they are not kept.
  304. */
  305. #ifndef PAGE_TARGET_STICKY
  306. #define PAGE_TARGET_STICKY 0
  307. #endif
  308. #define PAGE_STICKY (PAGE_ANON | PAGE_PASSTHROUGH | PAGE_TARGET_STICKY)
  309. /* A subroutine of page_set_flags: add flags to [start,last]. */
  310. static bool pageflags_set_clear(target_ulong start, target_ulong last,
  311. int set_flags, int clear_flags)
  312. {
  313. PageFlagsNode *p;
  314. target_ulong p_start, p_last;
  315. int p_flags, merge_flags;
  316. bool inval_tb = false;
  317. restart:
  318. p = pageflags_find(start, last);
  319. if (!p) {
  320. if (set_flags) {
  321. pageflags_create_merge(start, last, set_flags);
  322. }
  323. goto done;
  324. }
  325. p_start = p->itree.start;
  326. p_last = p->itree.last;
  327. p_flags = p->flags;
  328. /* Using mprotect on a page does not change sticky bits. */
  329. merge_flags = (p_flags & ~clear_flags) | set_flags;
  330. /*
  331. * Need to flush if an overlapping executable region
  332. * removes exec, or adds write.
  333. */
  334. if ((p_flags & PAGE_EXEC)
  335. && (!(merge_flags & PAGE_EXEC)
  336. || (merge_flags & ~p_flags & PAGE_WRITE))) {
  337. inval_tb = true;
  338. }
  339. /*
  340. * If there is an exact range match, update and return without
  341. * attempting to merge with adjacent regions.
  342. */
  343. if (start == p_start && last == p_last) {
  344. if (merge_flags) {
  345. p->flags = merge_flags;
  346. } else {
  347. interval_tree_remove(&p->itree, &pageflags_root);
  348. g_free_rcu(p, rcu);
  349. }
  350. goto done;
  351. }
  352. /*
  353. * If sticky bits affect the original mapping, then we must be more
  354. * careful about the existing intervals and the separate flags.
  355. */
  356. if (set_flags != merge_flags) {
  357. if (p_start < start) {
  358. interval_tree_remove(&p->itree, &pageflags_root);
  359. p->itree.last = start - 1;
  360. interval_tree_insert(&p->itree, &pageflags_root);
  361. if (last < p_last) {
  362. if (merge_flags) {
  363. pageflags_create(start, last, merge_flags);
  364. }
  365. pageflags_create(last + 1, p_last, p_flags);
  366. } else {
  367. if (merge_flags) {
  368. pageflags_create(start, p_last, merge_flags);
  369. }
  370. if (p_last < last) {
  371. start = p_last + 1;
  372. goto restart;
  373. }
  374. }
  375. } else {
  376. if (start < p_start && set_flags) {
  377. pageflags_create(start, p_start - 1, set_flags);
  378. }
  379. if (last < p_last) {
  380. interval_tree_remove(&p->itree, &pageflags_root);
  381. p->itree.start = last + 1;
  382. interval_tree_insert(&p->itree, &pageflags_root);
  383. if (merge_flags) {
  384. pageflags_create(start, last, merge_flags);
  385. }
  386. } else {
  387. if (merge_flags) {
  388. p->flags = merge_flags;
  389. } else {
  390. interval_tree_remove(&p->itree, &pageflags_root);
  391. g_free_rcu(p, rcu);
  392. }
  393. if (p_last < last) {
  394. start = p_last + 1;
  395. goto restart;
  396. }
  397. }
  398. }
  399. goto done;
  400. }
  401. /* If flags are not changing for this range, incorporate it. */
  402. if (set_flags == p_flags) {
  403. if (start < p_start) {
  404. interval_tree_remove(&p->itree, &pageflags_root);
  405. p->itree.start = start;
  406. interval_tree_insert(&p->itree, &pageflags_root);
  407. }
  408. if (p_last < last) {
  409. start = p_last + 1;
  410. goto restart;
  411. }
  412. goto done;
  413. }
  414. /* Maybe split out head and/or tail ranges with the original flags. */
  415. interval_tree_remove(&p->itree, &pageflags_root);
  416. if (p_start < start) {
  417. p->itree.last = start - 1;
  418. interval_tree_insert(&p->itree, &pageflags_root);
  419. if (p_last < last) {
  420. goto restart;
  421. }
  422. if (last < p_last) {
  423. pageflags_create(last + 1, p_last, p_flags);
  424. }
  425. } else if (last < p_last) {
  426. p->itree.start = last + 1;
  427. interval_tree_insert(&p->itree, &pageflags_root);
  428. } else {
  429. g_free_rcu(p, rcu);
  430. goto restart;
  431. }
  432. if (set_flags) {
  433. pageflags_create(start, last, set_flags);
  434. }
  435. done:
  436. return inval_tb;
  437. }
  438. /*
  439. * Modify the flags of a page and invalidate the code if necessary.
  440. * The flag PAGE_WRITE_ORG is positioned automatically depending
  441. * on PAGE_WRITE. The mmap_lock should already be held.
  442. */
  443. void page_set_flags(target_ulong start, target_ulong last, int flags)
  444. {
  445. bool reset = false;
  446. bool inval_tb = false;
  447. /* This function should never be called with addresses outside the
  448. guest address space. If this assert fires, it probably indicates
  449. a missing call to h2g_valid. */
  450. assert(start <= last);
  451. assert(last <= GUEST_ADDR_MAX);
  452. /* Only set PAGE_ANON with new mappings. */
  453. assert(!(flags & PAGE_ANON) || (flags & PAGE_RESET));
  454. assert_memory_lock();
  455. start &= TARGET_PAGE_MASK;
  456. last |= ~TARGET_PAGE_MASK;
  457. if (!(flags & PAGE_VALID)) {
  458. flags = 0;
  459. } else {
  460. reset = flags & PAGE_RESET;
  461. flags &= ~PAGE_RESET;
  462. if (flags & PAGE_WRITE) {
  463. flags |= PAGE_WRITE_ORG;
  464. }
  465. }
  466. if (!flags || reset) {
  467. page_reset_target_data(start, last);
  468. inval_tb |= pageflags_unset(start, last);
  469. }
  470. if (flags) {
  471. inval_tb |= pageflags_set_clear(start, last, flags,
  472. ~(reset ? 0 : PAGE_STICKY));
  473. }
  474. if (inval_tb) {
  475. tb_invalidate_phys_range(start, last);
  476. }
  477. }
  478. bool page_check_range(target_ulong start, target_ulong len, int flags)
  479. {
  480. target_ulong last;
  481. int locked; /* tri-state: =0: unlocked, +1: global, -1: local */
  482. bool ret;
  483. if (len == 0) {
  484. return true; /* trivial length */
  485. }
  486. last = start + len - 1;
  487. if (last < start) {
  488. return false; /* wrap around */
  489. }
  490. locked = have_mmap_lock();
  491. while (true) {
  492. PageFlagsNode *p = pageflags_find(start, last);
  493. int missing;
  494. if (!p) {
  495. if (!locked) {
  496. /*
  497. * Lockless lookups have false negatives.
  498. * Retry with the lock held.
  499. */
  500. mmap_lock();
  501. locked = -1;
  502. p = pageflags_find(start, last);
  503. }
  504. if (!p) {
  505. ret = false; /* entire region invalid */
  506. break;
  507. }
  508. }
  509. if (start < p->itree.start) {
  510. ret = false; /* initial bytes invalid */
  511. break;
  512. }
  513. missing = flags & ~p->flags;
  514. if (missing & ~PAGE_WRITE) {
  515. ret = false; /* page doesn't match */
  516. break;
  517. }
  518. if (missing & PAGE_WRITE) {
  519. if (!(p->flags & PAGE_WRITE_ORG)) {
  520. ret = false; /* page not writable */
  521. break;
  522. }
  523. /* Asking about writable, but has been protected: undo. */
  524. if (!page_unprotect(start, 0)) {
  525. ret = false;
  526. break;
  527. }
  528. /* TODO: page_unprotect should take a range, not a single page. */
  529. if (last - start < TARGET_PAGE_SIZE) {
  530. ret = true; /* ok */
  531. break;
  532. }
  533. start += TARGET_PAGE_SIZE;
  534. continue;
  535. }
  536. if (last <= p->itree.last) {
  537. ret = true; /* ok */
  538. break;
  539. }
  540. start = p->itree.last + 1;
  541. }
  542. /* Release the lock if acquired locally. */
  543. if (locked < 0) {
  544. mmap_unlock();
  545. }
  546. return ret;
  547. }
  548. bool page_check_range_empty(target_ulong start, target_ulong last)
  549. {
  550. assert(last >= start);
  551. assert_memory_lock();
  552. return pageflags_find(start, last) == NULL;
  553. }
  554. target_ulong page_find_range_empty(target_ulong min, target_ulong max,
  555. target_ulong len, target_ulong align)
  556. {
  557. target_ulong len_m1, align_m1;
  558. assert(min <= max);
  559. assert(max <= GUEST_ADDR_MAX);
  560. assert(len != 0);
  561. assert(is_power_of_2(align));
  562. assert_memory_lock();
  563. len_m1 = len - 1;
  564. align_m1 = align - 1;
  565. /* Iteratively narrow the search region. */
  566. while (1) {
  567. PageFlagsNode *p;
  568. /* Align min and double-check there's enough space remaining. */
  569. min = (min + align_m1) & ~align_m1;
  570. if (min > max) {
  571. return -1;
  572. }
  573. if (len_m1 > max - min) {
  574. return -1;
  575. }
  576. p = pageflags_find(min, min + len_m1);
  577. if (p == NULL) {
  578. /* Found! */
  579. return min;
  580. }
  581. if (max <= p->itree.last) {
  582. /* Existing allocation fills the remainder of the search region. */
  583. return -1;
  584. }
  585. /* Skip across existing allocation. */
  586. min = p->itree.last + 1;
  587. }
  588. }
  589. void page_protect(tb_page_addr_t address)
  590. {
  591. PageFlagsNode *p;
  592. target_ulong start, last;
  593. int host_page_size = qemu_real_host_page_size();
  594. int prot;
  595. assert_memory_lock();
  596. if (host_page_size <= TARGET_PAGE_SIZE) {
  597. start = address & TARGET_PAGE_MASK;
  598. last = start + TARGET_PAGE_SIZE - 1;
  599. } else {
  600. start = address & -host_page_size;
  601. last = start + host_page_size - 1;
  602. }
  603. p = pageflags_find(start, last);
  604. if (!p) {
  605. return;
  606. }
  607. prot = p->flags;
  608. if (unlikely(p->itree.last < last)) {
  609. /* More than one protection region covers the one host page. */
  610. assert(TARGET_PAGE_SIZE < host_page_size);
  611. while ((p = pageflags_next(p, start, last)) != NULL) {
  612. prot |= p->flags;
  613. }
  614. }
  615. if (prot & PAGE_WRITE) {
  616. pageflags_set_clear(start, last, 0, PAGE_WRITE);
  617. mprotect(g2h_untagged(start), last - start + 1,
  618. prot & (PAGE_READ | PAGE_EXEC) ? PROT_READ : PROT_NONE);
  619. }
  620. }
  621. /*
  622. * Called from signal handler: invalidate the code and unprotect the
  623. * page. Return 0 if the fault was not handled, 1 if it was handled,
  624. * and 2 if it was handled but the caller must cause the TB to be
  625. * immediately exited. (We can only return 2 if the 'pc' argument is
  626. * non-zero.)
  627. */
  628. int page_unprotect(target_ulong address, uintptr_t pc)
  629. {
  630. PageFlagsNode *p;
  631. bool current_tb_invalidated;
  632. /*
  633. * Technically this isn't safe inside a signal handler. However we
  634. * know this only ever happens in a synchronous SEGV handler, so in
  635. * practice it seems to be ok.
  636. */
  637. mmap_lock();
  638. p = pageflags_find(address, address);
  639. /* If this address was not really writable, nothing to do. */
  640. if (!p || !(p->flags & PAGE_WRITE_ORG)) {
  641. mmap_unlock();
  642. return 0;
  643. }
  644. current_tb_invalidated = false;
  645. if (p->flags & PAGE_WRITE) {
  646. /*
  647. * If the page is actually marked WRITE then assume this is because
  648. * this thread raced with another one which got here first and
  649. * set the page to PAGE_WRITE and did the TB invalidate for us.
  650. */
  651. #ifdef TARGET_HAS_PRECISE_SMC
  652. TranslationBlock *current_tb = tcg_tb_lookup(pc);
  653. if (current_tb) {
  654. current_tb_invalidated = tb_cflags(current_tb) & CF_INVALID;
  655. }
  656. #endif
  657. } else {
  658. int host_page_size = qemu_real_host_page_size();
  659. target_ulong start, len, i;
  660. int prot;
  661. if (host_page_size <= TARGET_PAGE_SIZE) {
  662. start = address & TARGET_PAGE_MASK;
  663. len = TARGET_PAGE_SIZE;
  664. prot = p->flags | PAGE_WRITE;
  665. pageflags_set_clear(start, start + len - 1, PAGE_WRITE, 0);
  666. current_tb_invalidated = tb_invalidate_phys_page_unwind(start, pc);
  667. } else {
  668. start = address & -host_page_size;
  669. len = host_page_size;
  670. prot = 0;
  671. for (i = 0; i < len; i += TARGET_PAGE_SIZE) {
  672. target_ulong addr = start + i;
  673. p = pageflags_find(addr, addr);
  674. if (p) {
  675. prot |= p->flags;
  676. if (p->flags & PAGE_WRITE_ORG) {
  677. prot |= PAGE_WRITE;
  678. pageflags_set_clear(addr, addr + TARGET_PAGE_SIZE - 1,
  679. PAGE_WRITE, 0);
  680. }
  681. }
  682. /*
  683. * Since the content will be modified, we must invalidate
  684. * the corresponding translated code.
  685. */
  686. current_tb_invalidated |=
  687. tb_invalidate_phys_page_unwind(addr, pc);
  688. }
  689. }
  690. if (prot & PAGE_EXEC) {
  691. prot = (prot & ~PAGE_EXEC) | PAGE_READ;
  692. }
  693. mprotect((void *)g2h_untagged(start), len, prot & PAGE_RWX);
  694. }
  695. mmap_unlock();
  696. /* If current TB was invalidated return to main loop */
  697. return current_tb_invalidated ? 2 : 1;
  698. }
  699. static int probe_access_internal(CPUArchState *env, vaddr addr,
  700. int fault_size, MMUAccessType access_type,
  701. bool nonfault, uintptr_t ra)
  702. {
  703. int acc_flag;
  704. bool maperr;
  705. switch (access_type) {
  706. case MMU_DATA_STORE:
  707. acc_flag = PAGE_WRITE_ORG;
  708. break;
  709. case MMU_DATA_LOAD:
  710. acc_flag = PAGE_READ;
  711. break;
  712. case MMU_INST_FETCH:
  713. acc_flag = PAGE_EXEC;
  714. break;
  715. default:
  716. g_assert_not_reached();
  717. }
  718. if (guest_addr_valid_untagged(addr)) {
  719. int page_flags = page_get_flags(addr);
  720. if (page_flags & acc_flag) {
  721. if ((acc_flag == PAGE_READ || acc_flag == PAGE_WRITE)
  722. && cpu_plugin_mem_cbs_enabled(env_cpu(env))) {
  723. return TLB_MMIO;
  724. }
  725. return 0; /* success */
  726. }
  727. maperr = !(page_flags & PAGE_VALID);
  728. } else {
  729. maperr = true;
  730. }
  731. if (nonfault) {
  732. return TLB_INVALID_MASK;
  733. }
  734. cpu_loop_exit_sigsegv(env_cpu(env), addr, access_type, maperr, ra);
  735. }
  736. int probe_access_flags(CPUArchState *env, vaddr addr, int size,
  737. MMUAccessType access_type, int mmu_idx,
  738. bool nonfault, void **phost, uintptr_t ra)
  739. {
  740. int flags;
  741. g_assert(-(addr | TARGET_PAGE_MASK) >= size);
  742. flags = probe_access_internal(env, addr, size, access_type, nonfault, ra);
  743. *phost = (flags & TLB_INVALID_MASK) ? NULL : g2h(env_cpu(env), addr);
  744. return flags;
  745. }
  746. void *probe_access(CPUArchState *env, vaddr addr, int size,
  747. MMUAccessType access_type, int mmu_idx, uintptr_t ra)
  748. {
  749. int flags;
  750. g_assert(-(addr | TARGET_PAGE_MASK) >= size);
  751. flags = probe_access_internal(env, addr, size, access_type, false, ra);
  752. g_assert((flags & ~TLB_MMIO) == 0);
  753. return size ? g2h(env_cpu(env), addr) : NULL;
  754. }
  755. tb_page_addr_t get_page_addr_code_hostp(CPUArchState *env, vaddr addr,
  756. void **hostp)
  757. {
  758. int flags;
  759. flags = probe_access_internal(env, addr, 1, MMU_INST_FETCH, false, 0);
  760. g_assert(flags == 0);
  761. if (hostp) {
  762. *hostp = g2h_untagged(addr);
  763. }
  764. return addr;
  765. }
  766. #ifdef TARGET_PAGE_DATA_SIZE
  767. /*
  768. * Allocate chunks of target data together. For the only current user,
  769. * if we allocate one hunk per page, we have overhead of 40/128 or 40%.
  770. * Therefore, allocate memory for 64 pages at a time for overhead < 1%.
  771. */
  772. #define TPD_PAGES 64
  773. #define TBD_MASK (TARGET_PAGE_MASK * TPD_PAGES)
  774. typedef struct TargetPageDataNode {
  775. struct rcu_head rcu;
  776. IntervalTreeNode itree;
  777. char data[] __attribute__((aligned));
  778. } TargetPageDataNode;
  779. static IntervalTreeRoot targetdata_root;
  780. void page_reset_target_data(target_ulong start, target_ulong last)
  781. {
  782. IntervalTreeNode *n, *next;
  783. assert_memory_lock();
  784. start &= TARGET_PAGE_MASK;
  785. last |= ~TARGET_PAGE_MASK;
  786. for (n = interval_tree_iter_first(&targetdata_root, start, last),
  787. next = n ? interval_tree_iter_next(n, start, last) : NULL;
  788. n != NULL;
  789. n = next,
  790. next = next ? interval_tree_iter_next(n, start, last) : NULL) {
  791. target_ulong n_start, n_last, p_ofs, p_len;
  792. TargetPageDataNode *t = container_of(n, TargetPageDataNode, itree);
  793. if (n->start >= start && n->last <= last) {
  794. interval_tree_remove(n, &targetdata_root);
  795. g_free_rcu(t, rcu);
  796. continue;
  797. }
  798. if (n->start < start) {
  799. n_start = start;
  800. p_ofs = (start - n->start) >> TARGET_PAGE_BITS;
  801. } else {
  802. n_start = n->start;
  803. p_ofs = 0;
  804. }
  805. n_last = MIN(last, n->last);
  806. p_len = (n_last + 1 - n_start) >> TARGET_PAGE_BITS;
  807. memset(t->data + p_ofs * TARGET_PAGE_DATA_SIZE, 0,
  808. p_len * TARGET_PAGE_DATA_SIZE);
  809. }
  810. }
  811. void *page_get_target_data(target_ulong address)
  812. {
  813. IntervalTreeNode *n;
  814. TargetPageDataNode *t;
  815. target_ulong page, region, p_ofs;
  816. page = address & TARGET_PAGE_MASK;
  817. region = address & TBD_MASK;
  818. n = interval_tree_iter_first(&targetdata_root, page, page);
  819. if (!n) {
  820. /*
  821. * See util/interval-tree.c re lockless lookups: no false positives
  822. * but there are false negatives. If we find nothing, retry with
  823. * the mmap lock acquired. We also need the lock for the
  824. * allocation + insert.
  825. */
  826. mmap_lock();
  827. n = interval_tree_iter_first(&targetdata_root, page, page);
  828. if (!n) {
  829. t = g_malloc0(sizeof(TargetPageDataNode)
  830. + TPD_PAGES * TARGET_PAGE_DATA_SIZE);
  831. n = &t->itree;
  832. n->start = region;
  833. n->last = region | ~TBD_MASK;
  834. interval_tree_insert(n, &targetdata_root);
  835. }
  836. mmap_unlock();
  837. }
  838. t = container_of(n, TargetPageDataNode, itree);
  839. p_ofs = (page - region) >> TARGET_PAGE_BITS;
  840. return t->data + p_ofs * TARGET_PAGE_DATA_SIZE;
  841. }
  842. #else
  843. void page_reset_target_data(target_ulong start, target_ulong last) { }
  844. #endif /* TARGET_PAGE_DATA_SIZE */
  845. /* The system-mode versions of these helpers are in cputlb.c. */
  846. static void *cpu_mmu_lookup(CPUState *cpu, vaddr addr,
  847. MemOp mop, uintptr_t ra, MMUAccessType type)
  848. {
  849. int a_bits = get_alignment_bits(mop);
  850. void *ret;
  851. /* Enforce guest required alignment. */
  852. if (unlikely(addr & ((1 << a_bits) - 1))) {
  853. cpu_loop_exit_sigbus(cpu, addr, type, ra);
  854. }
  855. ret = g2h(cpu, addr);
  856. set_helper_retaddr(ra);
  857. return ret;
  858. }
  859. #include "ldst_atomicity.c.inc"
  860. static uint8_t do_ld1_mmu(CPUState *cpu, vaddr addr, MemOpIdx oi,
  861. uintptr_t ra, MMUAccessType access_type)
  862. {
  863. void *haddr;
  864. uint8_t ret;
  865. cpu_req_mo(TCG_MO_LD_LD | TCG_MO_ST_LD);
  866. haddr = cpu_mmu_lookup(cpu, addr, get_memop(oi), ra, access_type);
  867. ret = ldub_p(haddr);
  868. clear_helper_retaddr();
  869. return ret;
  870. }
  871. static uint16_t do_ld2_mmu(CPUState *cpu, vaddr addr, MemOpIdx oi,
  872. uintptr_t ra, MMUAccessType access_type)
  873. {
  874. void *haddr;
  875. uint16_t ret;
  876. MemOp mop = get_memop(oi);
  877. cpu_req_mo(TCG_MO_LD_LD | TCG_MO_ST_LD);
  878. haddr = cpu_mmu_lookup(cpu, addr, mop, ra, access_type);
  879. ret = load_atom_2(cpu, ra, haddr, mop);
  880. clear_helper_retaddr();
  881. if (mop & MO_BSWAP) {
  882. ret = bswap16(ret);
  883. }
  884. return ret;
  885. }
  886. static uint32_t do_ld4_mmu(CPUState *cpu, vaddr addr, MemOpIdx oi,
  887. uintptr_t ra, MMUAccessType access_type)
  888. {
  889. void *haddr;
  890. uint32_t ret;
  891. MemOp mop = get_memop(oi);
  892. cpu_req_mo(TCG_MO_LD_LD | TCG_MO_ST_LD);
  893. haddr = cpu_mmu_lookup(cpu, addr, mop, ra, access_type);
  894. ret = load_atom_4(cpu, ra, haddr, mop);
  895. clear_helper_retaddr();
  896. if (mop & MO_BSWAP) {
  897. ret = bswap32(ret);
  898. }
  899. return ret;
  900. }
  901. static uint64_t do_ld8_mmu(CPUState *cpu, vaddr addr, MemOpIdx oi,
  902. uintptr_t ra, MMUAccessType access_type)
  903. {
  904. void *haddr;
  905. uint64_t ret;
  906. MemOp mop = get_memop(oi);
  907. cpu_req_mo(TCG_MO_LD_LD | TCG_MO_ST_LD);
  908. haddr = cpu_mmu_lookup(cpu, addr, mop, ra, access_type);
  909. ret = load_atom_8(cpu, ra, haddr, mop);
  910. clear_helper_retaddr();
  911. if (mop & MO_BSWAP) {
  912. ret = bswap64(ret);
  913. }
  914. return ret;
  915. }
  916. static Int128 do_ld16_mmu(CPUState *cpu, abi_ptr addr,
  917. MemOpIdx oi, uintptr_t ra)
  918. {
  919. void *haddr;
  920. Int128 ret;
  921. MemOp mop = get_memop(oi);
  922. tcg_debug_assert((mop & MO_SIZE) == MO_128);
  923. cpu_req_mo(TCG_MO_LD_LD | TCG_MO_ST_LD);
  924. haddr = cpu_mmu_lookup(cpu, addr, mop, ra, MMU_DATA_LOAD);
  925. ret = load_atom_16(cpu, ra, haddr, mop);
  926. clear_helper_retaddr();
  927. if (mop & MO_BSWAP) {
  928. ret = bswap128(ret);
  929. }
  930. return ret;
  931. }
  932. static void do_st1_mmu(CPUState *cpu, vaddr addr, uint8_t val,
  933. MemOpIdx oi, uintptr_t ra)
  934. {
  935. void *haddr;
  936. cpu_req_mo(TCG_MO_LD_ST | TCG_MO_ST_ST);
  937. haddr = cpu_mmu_lookup(cpu, addr, get_memop(oi), ra, MMU_DATA_STORE);
  938. stb_p(haddr, val);
  939. clear_helper_retaddr();
  940. }
  941. static void do_st2_mmu(CPUState *cpu, vaddr addr, uint16_t val,
  942. MemOpIdx oi, uintptr_t ra)
  943. {
  944. void *haddr;
  945. MemOp mop = get_memop(oi);
  946. cpu_req_mo(TCG_MO_LD_ST | TCG_MO_ST_ST);
  947. haddr = cpu_mmu_lookup(cpu, addr, mop, ra, MMU_DATA_STORE);
  948. if (mop & MO_BSWAP) {
  949. val = bswap16(val);
  950. }
  951. store_atom_2(cpu, ra, haddr, mop, val);
  952. clear_helper_retaddr();
  953. }
  954. static void do_st4_mmu(CPUState *cpu, vaddr addr, uint32_t val,
  955. MemOpIdx oi, uintptr_t ra)
  956. {
  957. void *haddr;
  958. MemOp mop = get_memop(oi);
  959. cpu_req_mo(TCG_MO_LD_ST | TCG_MO_ST_ST);
  960. haddr = cpu_mmu_lookup(cpu, addr, mop, ra, MMU_DATA_STORE);
  961. if (mop & MO_BSWAP) {
  962. val = bswap32(val);
  963. }
  964. store_atom_4(cpu, ra, haddr, mop, val);
  965. clear_helper_retaddr();
  966. }
  967. static void do_st8_mmu(CPUState *cpu, vaddr addr, uint64_t val,
  968. MemOpIdx oi, uintptr_t ra)
  969. {
  970. void *haddr;
  971. MemOp mop = get_memop(oi);
  972. cpu_req_mo(TCG_MO_LD_ST | TCG_MO_ST_ST);
  973. haddr = cpu_mmu_lookup(cpu, addr, mop, ra, MMU_DATA_STORE);
  974. if (mop & MO_BSWAP) {
  975. val = bswap64(val);
  976. }
  977. store_atom_8(cpu, ra, haddr, mop, val);
  978. clear_helper_retaddr();
  979. }
  980. static void do_st16_mmu(CPUState *cpu, vaddr addr, Int128 val,
  981. MemOpIdx oi, uintptr_t ra)
  982. {
  983. void *haddr;
  984. MemOpIdx mop = get_memop(oi);
  985. cpu_req_mo(TCG_MO_LD_ST | TCG_MO_ST_ST);
  986. haddr = cpu_mmu_lookup(cpu, addr, mop, ra, MMU_DATA_STORE);
  987. if (mop & MO_BSWAP) {
  988. val = bswap128(val);
  989. }
  990. store_atom_16(cpu, ra, haddr, mop, val);
  991. clear_helper_retaddr();
  992. }
  993. uint32_t cpu_ldub_code(CPUArchState *env, abi_ptr ptr)
  994. {
  995. uint32_t ret;
  996. set_helper_retaddr(1);
  997. ret = ldub_p(g2h_untagged(ptr));
  998. clear_helper_retaddr();
  999. return ret;
  1000. }
  1001. uint32_t cpu_lduw_code(CPUArchState *env, abi_ptr ptr)
  1002. {
  1003. uint32_t ret;
  1004. set_helper_retaddr(1);
  1005. ret = lduw_p(g2h_untagged(ptr));
  1006. clear_helper_retaddr();
  1007. return ret;
  1008. }
  1009. uint32_t cpu_ldl_code(CPUArchState *env, abi_ptr ptr)
  1010. {
  1011. uint32_t ret;
  1012. set_helper_retaddr(1);
  1013. ret = ldl_p(g2h_untagged(ptr));
  1014. clear_helper_retaddr();
  1015. return ret;
  1016. }
  1017. uint64_t cpu_ldq_code(CPUArchState *env, abi_ptr ptr)
  1018. {
  1019. uint64_t ret;
  1020. set_helper_retaddr(1);
  1021. ret = ldq_p(g2h_untagged(ptr));
  1022. clear_helper_retaddr();
  1023. return ret;
  1024. }
  1025. uint8_t cpu_ldb_code_mmu(CPUArchState *env, abi_ptr addr,
  1026. MemOpIdx oi, uintptr_t ra)
  1027. {
  1028. void *haddr;
  1029. uint8_t ret;
  1030. haddr = cpu_mmu_lookup(env_cpu(env), addr, oi, ra, MMU_INST_FETCH);
  1031. ret = ldub_p(haddr);
  1032. clear_helper_retaddr();
  1033. return ret;
  1034. }
  1035. uint16_t cpu_ldw_code_mmu(CPUArchState *env, abi_ptr addr,
  1036. MemOpIdx oi, uintptr_t ra)
  1037. {
  1038. void *haddr;
  1039. uint16_t ret;
  1040. haddr = cpu_mmu_lookup(env_cpu(env), addr, oi, ra, MMU_INST_FETCH);
  1041. ret = lduw_p(haddr);
  1042. clear_helper_retaddr();
  1043. if (get_memop(oi) & MO_BSWAP) {
  1044. ret = bswap16(ret);
  1045. }
  1046. return ret;
  1047. }
  1048. uint32_t cpu_ldl_code_mmu(CPUArchState *env, abi_ptr addr,
  1049. MemOpIdx oi, uintptr_t ra)
  1050. {
  1051. void *haddr;
  1052. uint32_t ret;
  1053. haddr = cpu_mmu_lookup(env_cpu(env), addr, oi, ra, MMU_INST_FETCH);
  1054. ret = ldl_p(haddr);
  1055. clear_helper_retaddr();
  1056. if (get_memop(oi) & MO_BSWAP) {
  1057. ret = bswap32(ret);
  1058. }
  1059. return ret;
  1060. }
  1061. uint64_t cpu_ldq_code_mmu(CPUArchState *env, abi_ptr addr,
  1062. MemOpIdx oi, uintptr_t ra)
  1063. {
  1064. void *haddr;
  1065. uint64_t ret;
  1066. haddr = cpu_mmu_lookup(env_cpu(env), addr, oi, ra, MMU_DATA_LOAD);
  1067. ret = ldq_p(haddr);
  1068. clear_helper_retaddr();
  1069. if (get_memop(oi) & MO_BSWAP) {
  1070. ret = bswap64(ret);
  1071. }
  1072. return ret;
  1073. }
  1074. #include "ldst_common.c.inc"
  1075. /*
  1076. * Do not allow unaligned operations to proceed. Return the host address.
  1077. */
  1078. static void *atomic_mmu_lookup(CPUState *cpu, vaddr addr, MemOpIdx oi,
  1079. int size, uintptr_t retaddr)
  1080. {
  1081. MemOp mop = get_memop(oi);
  1082. int a_bits = get_alignment_bits(mop);
  1083. void *ret;
  1084. /* Enforce guest required alignment. */
  1085. if (unlikely(addr & ((1 << a_bits) - 1))) {
  1086. cpu_loop_exit_sigbus(cpu, addr, MMU_DATA_STORE, retaddr);
  1087. }
  1088. /* Enforce qemu required alignment. */
  1089. if (unlikely(addr & (size - 1))) {
  1090. cpu_loop_exit_atomic(cpu, retaddr);
  1091. }
  1092. ret = g2h(cpu, addr);
  1093. set_helper_retaddr(retaddr);
  1094. return ret;
  1095. }
  1096. #include "atomic_common.c.inc"
  1097. /*
  1098. * First set of functions passes in OI and RETADDR.
  1099. * This makes them callable from other helpers.
  1100. */
  1101. #define ATOMIC_NAME(X) \
  1102. glue(glue(glue(cpu_atomic_ ## X, SUFFIX), END), _mmu)
  1103. #define ATOMIC_MMU_CLEANUP do { clear_helper_retaddr(); } while (0)
  1104. #define DATA_SIZE 1
  1105. #include "atomic_template.h"
  1106. #define DATA_SIZE 2
  1107. #include "atomic_template.h"
  1108. #define DATA_SIZE 4
  1109. #include "atomic_template.h"
  1110. #ifdef CONFIG_ATOMIC64
  1111. #define DATA_SIZE 8
  1112. #include "atomic_template.h"
  1113. #endif
  1114. #if defined(CONFIG_ATOMIC128) || HAVE_CMPXCHG128
  1115. #define DATA_SIZE 16
  1116. #include "atomic_template.h"
  1117. #endif