processor.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * AArch64 code
  4. *
  5. * Copyright (C) 2018, Red Hat, Inc.
  6. */
  7. #include <linux/compiler.h>
  8. #include <assert.h>
  9. #include "guest_modes.h"
  10. #include "kvm_util.h"
  11. #include "processor.h"
  12. #include "ucall_common.h"
  13. #include <linux/bitfield.h>
  14. #include <linux/sizes.h>
  15. #define DEFAULT_ARM64_GUEST_STACK_VADDR_MIN 0xac0000
  16. static vm_vaddr_t exception_handlers;
  17. static uint64_t page_align(struct kvm_vm *vm, uint64_t v)
  18. {
  19. return (v + vm->page_size) & ~(vm->page_size - 1);
  20. }
  21. static uint64_t pgd_index(struct kvm_vm *vm, vm_vaddr_t gva)
  22. {
  23. unsigned int shift = (vm->pgtable_levels - 1) * (vm->page_shift - 3) + vm->page_shift;
  24. uint64_t mask = (1UL << (vm->va_bits - shift)) - 1;
  25. return (gva >> shift) & mask;
  26. }
  27. static uint64_t pud_index(struct kvm_vm *vm, vm_vaddr_t gva)
  28. {
  29. unsigned int shift = 2 * (vm->page_shift - 3) + vm->page_shift;
  30. uint64_t mask = (1UL << (vm->page_shift - 3)) - 1;
  31. TEST_ASSERT(vm->pgtable_levels == 4,
  32. "Mode %d does not have 4 page table levels", vm->mode);
  33. return (gva >> shift) & mask;
  34. }
  35. static uint64_t pmd_index(struct kvm_vm *vm, vm_vaddr_t gva)
  36. {
  37. unsigned int shift = (vm->page_shift - 3) + vm->page_shift;
  38. uint64_t mask = (1UL << (vm->page_shift - 3)) - 1;
  39. TEST_ASSERT(vm->pgtable_levels >= 3,
  40. "Mode %d does not have >= 3 page table levels", vm->mode);
  41. return (gva >> shift) & mask;
  42. }
  43. static uint64_t pte_index(struct kvm_vm *vm, vm_vaddr_t gva)
  44. {
  45. uint64_t mask = (1UL << (vm->page_shift - 3)) - 1;
  46. return (gva >> vm->page_shift) & mask;
  47. }
  48. static inline bool use_lpa2_pte_format(struct kvm_vm *vm)
  49. {
  50. return (vm->page_size == SZ_4K || vm->page_size == SZ_16K) &&
  51. (vm->pa_bits > 48 || vm->va_bits > 48);
  52. }
  53. static uint64_t addr_pte(struct kvm_vm *vm, uint64_t pa, uint64_t attrs)
  54. {
  55. uint64_t pte;
  56. if (use_lpa2_pte_format(vm)) {
  57. pte = pa & GENMASK(49, vm->page_shift);
  58. pte |= FIELD_GET(GENMASK(51, 50), pa) << 8;
  59. attrs &= ~GENMASK(9, 8);
  60. } else {
  61. pte = pa & GENMASK(47, vm->page_shift);
  62. if (vm->page_shift == 16)
  63. pte |= FIELD_GET(GENMASK(51, 48), pa) << 12;
  64. }
  65. pte |= attrs;
  66. return pte;
  67. }
  68. static uint64_t pte_addr(struct kvm_vm *vm, uint64_t pte)
  69. {
  70. uint64_t pa;
  71. if (use_lpa2_pte_format(vm)) {
  72. pa = pte & GENMASK(49, vm->page_shift);
  73. pa |= FIELD_GET(GENMASK(9, 8), pte) << 50;
  74. } else {
  75. pa = pte & GENMASK(47, vm->page_shift);
  76. if (vm->page_shift == 16)
  77. pa |= FIELD_GET(GENMASK(15, 12), pte) << 48;
  78. }
  79. return pa;
  80. }
  81. static uint64_t ptrs_per_pgd(struct kvm_vm *vm)
  82. {
  83. unsigned int shift = (vm->pgtable_levels - 1) * (vm->page_shift - 3) + vm->page_shift;
  84. return 1 << (vm->va_bits - shift);
  85. }
  86. static uint64_t __maybe_unused ptrs_per_pte(struct kvm_vm *vm)
  87. {
  88. return 1 << (vm->page_shift - 3);
  89. }
  90. void virt_arch_pgd_alloc(struct kvm_vm *vm)
  91. {
  92. size_t nr_pages = page_align(vm, ptrs_per_pgd(vm) * 8) / vm->page_size;
  93. if (vm->pgd_created)
  94. return;
  95. vm->pgd = vm_phy_pages_alloc(vm, nr_pages,
  96. KVM_GUEST_PAGE_TABLE_MIN_PADDR,
  97. vm->memslots[MEM_REGION_PT]);
  98. vm->pgd_created = true;
  99. }
  100. static void _virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr,
  101. uint64_t flags)
  102. {
  103. uint8_t attr_idx = flags & 7;
  104. uint64_t *ptep;
  105. TEST_ASSERT((vaddr % vm->page_size) == 0,
  106. "Virtual address not on page boundary,\n"
  107. " vaddr: 0x%lx vm->page_size: 0x%x", vaddr, vm->page_size);
  108. TEST_ASSERT(sparsebit_is_set(vm->vpages_valid,
  109. (vaddr >> vm->page_shift)),
  110. "Invalid virtual address, vaddr: 0x%lx", vaddr);
  111. TEST_ASSERT((paddr % vm->page_size) == 0,
  112. "Physical address not on page boundary,\n"
  113. " paddr: 0x%lx vm->page_size: 0x%x", paddr, vm->page_size);
  114. TEST_ASSERT((paddr >> vm->page_shift) <= vm->max_gfn,
  115. "Physical address beyond beyond maximum supported,\n"
  116. " paddr: 0x%lx vm->max_gfn: 0x%lx vm->page_size: 0x%x",
  117. paddr, vm->max_gfn, vm->page_size);
  118. ptep = addr_gpa2hva(vm, vm->pgd) + pgd_index(vm, vaddr) * 8;
  119. if (!*ptep)
  120. *ptep = addr_pte(vm, vm_alloc_page_table(vm), 3);
  121. switch (vm->pgtable_levels) {
  122. case 4:
  123. ptep = addr_gpa2hva(vm, pte_addr(vm, *ptep)) + pud_index(vm, vaddr) * 8;
  124. if (!*ptep)
  125. *ptep = addr_pte(vm, vm_alloc_page_table(vm), 3);
  126. /* fall through */
  127. case 3:
  128. ptep = addr_gpa2hva(vm, pte_addr(vm, *ptep)) + pmd_index(vm, vaddr) * 8;
  129. if (!*ptep)
  130. *ptep = addr_pte(vm, vm_alloc_page_table(vm), 3);
  131. /* fall through */
  132. case 2:
  133. ptep = addr_gpa2hva(vm, pte_addr(vm, *ptep)) + pte_index(vm, vaddr) * 8;
  134. break;
  135. default:
  136. TEST_FAIL("Page table levels must be 2, 3, or 4");
  137. }
  138. *ptep = addr_pte(vm, paddr, (attr_idx << 2) | (1 << 10) | 3); /* AF */
  139. }
  140. void virt_arch_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr)
  141. {
  142. uint64_t attr_idx = MT_NORMAL;
  143. _virt_pg_map(vm, vaddr, paddr, attr_idx);
  144. }
  145. uint64_t *virt_get_pte_hva(struct kvm_vm *vm, vm_vaddr_t gva)
  146. {
  147. uint64_t *ptep;
  148. if (!vm->pgd_created)
  149. goto unmapped_gva;
  150. ptep = addr_gpa2hva(vm, vm->pgd) + pgd_index(vm, gva) * 8;
  151. if (!ptep)
  152. goto unmapped_gva;
  153. switch (vm->pgtable_levels) {
  154. case 4:
  155. ptep = addr_gpa2hva(vm, pte_addr(vm, *ptep)) + pud_index(vm, gva) * 8;
  156. if (!ptep)
  157. goto unmapped_gva;
  158. /* fall through */
  159. case 3:
  160. ptep = addr_gpa2hva(vm, pte_addr(vm, *ptep)) + pmd_index(vm, gva) * 8;
  161. if (!ptep)
  162. goto unmapped_gva;
  163. /* fall through */
  164. case 2:
  165. ptep = addr_gpa2hva(vm, pte_addr(vm, *ptep)) + pte_index(vm, gva) * 8;
  166. if (!ptep)
  167. goto unmapped_gva;
  168. break;
  169. default:
  170. TEST_FAIL("Page table levels must be 2, 3, or 4");
  171. }
  172. return ptep;
  173. unmapped_gva:
  174. TEST_FAIL("No mapping for vm virtual address, gva: 0x%lx", gva);
  175. exit(EXIT_FAILURE);
  176. }
  177. vm_paddr_t addr_arch_gva2gpa(struct kvm_vm *vm, vm_vaddr_t gva)
  178. {
  179. uint64_t *ptep = virt_get_pte_hva(vm, gva);
  180. return pte_addr(vm, *ptep) + (gva & (vm->page_size - 1));
  181. }
  182. static void pte_dump(FILE *stream, struct kvm_vm *vm, uint8_t indent, uint64_t page, int level)
  183. {
  184. #ifdef DEBUG
  185. static const char * const type[] = { "", "pud", "pmd", "pte" };
  186. uint64_t pte, *ptep;
  187. if (level == 4)
  188. return;
  189. for (pte = page; pte < page + ptrs_per_pte(vm) * 8; pte += 8) {
  190. ptep = addr_gpa2hva(vm, pte);
  191. if (!*ptep)
  192. continue;
  193. fprintf(stream, "%*s%s: %lx: %lx at %p\n", indent, "", type[level], pte, *ptep, ptep);
  194. pte_dump(stream, vm, indent + 1, pte_addr(vm, *ptep), level + 1);
  195. }
  196. #endif
  197. }
  198. void virt_arch_dump(FILE *stream, struct kvm_vm *vm, uint8_t indent)
  199. {
  200. int level = 4 - (vm->pgtable_levels - 1);
  201. uint64_t pgd, *ptep;
  202. if (!vm->pgd_created)
  203. return;
  204. for (pgd = vm->pgd; pgd < vm->pgd + ptrs_per_pgd(vm) * 8; pgd += 8) {
  205. ptep = addr_gpa2hva(vm, pgd);
  206. if (!*ptep)
  207. continue;
  208. fprintf(stream, "%*spgd: %lx: %lx at %p\n", indent, "", pgd, *ptep, ptep);
  209. pte_dump(stream, vm, indent + 1, pte_addr(vm, *ptep), level);
  210. }
  211. }
  212. void aarch64_vcpu_setup(struct kvm_vcpu *vcpu, struct kvm_vcpu_init *init)
  213. {
  214. struct kvm_vcpu_init default_init = { .target = -1, };
  215. struct kvm_vm *vm = vcpu->vm;
  216. uint64_t sctlr_el1, tcr_el1, ttbr0_el1;
  217. if (!init)
  218. init = &default_init;
  219. if (init->target == -1) {
  220. struct kvm_vcpu_init preferred;
  221. vm_ioctl(vm, KVM_ARM_PREFERRED_TARGET, &preferred);
  222. init->target = preferred.target;
  223. }
  224. vcpu_ioctl(vcpu, KVM_ARM_VCPU_INIT, init);
  225. /*
  226. * Enable FP/ASIMD to avoid trapping when accessing Q0-Q15
  227. * registers, which the variable argument list macros do.
  228. */
  229. vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(SYS_CPACR_EL1), 3 << 20);
  230. vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_SCTLR_EL1), &sctlr_el1);
  231. vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_TCR_EL1), &tcr_el1);
  232. /* Configure base granule size */
  233. switch (vm->mode) {
  234. case VM_MODE_PXXV48_4K:
  235. TEST_FAIL("AArch64 does not support 4K sized pages "
  236. "with ANY-bit physical address ranges");
  237. case VM_MODE_P52V48_64K:
  238. case VM_MODE_P48V48_64K:
  239. case VM_MODE_P40V48_64K:
  240. case VM_MODE_P36V48_64K:
  241. tcr_el1 |= 1ul << 14; /* TG0 = 64KB */
  242. break;
  243. case VM_MODE_P52V48_16K:
  244. case VM_MODE_P48V48_16K:
  245. case VM_MODE_P40V48_16K:
  246. case VM_MODE_P36V48_16K:
  247. case VM_MODE_P36V47_16K:
  248. tcr_el1 |= 2ul << 14; /* TG0 = 16KB */
  249. break;
  250. case VM_MODE_P52V48_4K:
  251. case VM_MODE_P48V48_4K:
  252. case VM_MODE_P40V48_4K:
  253. case VM_MODE_P36V48_4K:
  254. tcr_el1 |= 0ul << 14; /* TG0 = 4KB */
  255. break;
  256. default:
  257. TEST_FAIL("Unknown guest mode, mode: 0x%x", vm->mode);
  258. }
  259. ttbr0_el1 = vm->pgd & GENMASK(47, vm->page_shift);
  260. /* Configure output size */
  261. switch (vm->mode) {
  262. case VM_MODE_P52V48_4K:
  263. case VM_MODE_P52V48_16K:
  264. case VM_MODE_P52V48_64K:
  265. tcr_el1 |= 6ul << 32; /* IPS = 52 bits */
  266. ttbr0_el1 |= FIELD_GET(GENMASK(51, 48), vm->pgd) << 2;
  267. break;
  268. case VM_MODE_P48V48_4K:
  269. case VM_MODE_P48V48_16K:
  270. case VM_MODE_P48V48_64K:
  271. tcr_el1 |= 5ul << 32; /* IPS = 48 bits */
  272. break;
  273. case VM_MODE_P40V48_4K:
  274. case VM_MODE_P40V48_16K:
  275. case VM_MODE_P40V48_64K:
  276. tcr_el1 |= 2ul << 32; /* IPS = 40 bits */
  277. break;
  278. case VM_MODE_P36V48_4K:
  279. case VM_MODE_P36V48_16K:
  280. case VM_MODE_P36V48_64K:
  281. case VM_MODE_P36V47_16K:
  282. tcr_el1 |= 1ul << 32; /* IPS = 36 bits */
  283. break;
  284. default:
  285. TEST_FAIL("Unknown guest mode, mode: 0x%x", vm->mode);
  286. }
  287. sctlr_el1 |= (1 << 0) | (1 << 2) | (1 << 12) /* M | C | I */;
  288. /* TCR_EL1 |= IRGN0:WBWA | ORGN0:WBWA | SH0:Inner-Shareable */;
  289. tcr_el1 |= (1 << 8) | (1 << 10) | (3 << 12);
  290. tcr_el1 |= (64 - vm->va_bits) /* T0SZ */;
  291. if (use_lpa2_pte_format(vm))
  292. tcr_el1 |= (1ul << 59) /* DS */;
  293. vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(SYS_SCTLR_EL1), sctlr_el1);
  294. vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(SYS_TCR_EL1), tcr_el1);
  295. vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(SYS_MAIR_EL1), DEFAULT_MAIR_EL1);
  296. vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(SYS_TTBR0_EL1), ttbr0_el1);
  297. vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(SYS_TPIDR_EL1), vcpu->id);
  298. }
  299. void vcpu_arch_dump(FILE *stream, struct kvm_vcpu *vcpu, uint8_t indent)
  300. {
  301. uint64_t pstate, pc;
  302. vcpu_get_reg(vcpu, ARM64_CORE_REG(regs.pstate), &pstate);
  303. vcpu_get_reg(vcpu, ARM64_CORE_REG(regs.pc), &pc);
  304. fprintf(stream, "%*spstate: 0x%.16lx pc: 0x%.16lx\n",
  305. indent, "", pstate, pc);
  306. }
  307. void vcpu_arch_set_entry_point(struct kvm_vcpu *vcpu, void *guest_code)
  308. {
  309. vcpu_set_reg(vcpu, ARM64_CORE_REG(regs.pc), (uint64_t)guest_code);
  310. }
  311. static struct kvm_vcpu *__aarch64_vcpu_add(struct kvm_vm *vm, uint32_t vcpu_id,
  312. struct kvm_vcpu_init *init)
  313. {
  314. size_t stack_size;
  315. uint64_t stack_vaddr;
  316. struct kvm_vcpu *vcpu = __vm_vcpu_add(vm, vcpu_id);
  317. stack_size = vm->page_size == 4096 ? DEFAULT_STACK_PGS * vm->page_size :
  318. vm->page_size;
  319. stack_vaddr = __vm_vaddr_alloc(vm, stack_size,
  320. DEFAULT_ARM64_GUEST_STACK_VADDR_MIN,
  321. MEM_REGION_DATA);
  322. aarch64_vcpu_setup(vcpu, init);
  323. vcpu_set_reg(vcpu, ARM64_CORE_REG(sp_el1), stack_vaddr + stack_size);
  324. return vcpu;
  325. }
  326. struct kvm_vcpu *aarch64_vcpu_add(struct kvm_vm *vm, uint32_t vcpu_id,
  327. struct kvm_vcpu_init *init, void *guest_code)
  328. {
  329. struct kvm_vcpu *vcpu = __aarch64_vcpu_add(vm, vcpu_id, init);
  330. vcpu_arch_set_entry_point(vcpu, guest_code);
  331. return vcpu;
  332. }
  333. struct kvm_vcpu *vm_arch_vcpu_add(struct kvm_vm *vm, uint32_t vcpu_id)
  334. {
  335. return __aarch64_vcpu_add(vm, vcpu_id, NULL);
  336. }
  337. void vcpu_args_set(struct kvm_vcpu *vcpu, unsigned int num, ...)
  338. {
  339. va_list ap;
  340. int i;
  341. TEST_ASSERT(num >= 1 && num <= 8, "Unsupported number of args,\n"
  342. " num: %u", num);
  343. va_start(ap, num);
  344. for (i = 0; i < num; i++) {
  345. vcpu_set_reg(vcpu, ARM64_CORE_REG(regs.regs[i]),
  346. va_arg(ap, uint64_t));
  347. }
  348. va_end(ap);
  349. }
  350. void kvm_exit_unexpected_exception(int vector, uint64_t ec, bool valid_ec)
  351. {
  352. ucall(UCALL_UNHANDLED, 3, vector, ec, valid_ec);
  353. while (1)
  354. ;
  355. }
  356. void assert_on_unhandled_exception(struct kvm_vcpu *vcpu)
  357. {
  358. struct ucall uc;
  359. if (get_ucall(vcpu, &uc) != UCALL_UNHANDLED)
  360. return;
  361. if (uc.args[2]) /* valid_ec */ {
  362. assert(VECTOR_IS_SYNC(uc.args[0]));
  363. TEST_FAIL("Unexpected exception (vector:0x%lx, ec:0x%lx)",
  364. uc.args[0], uc.args[1]);
  365. } else {
  366. assert(!VECTOR_IS_SYNC(uc.args[0]));
  367. TEST_FAIL("Unexpected exception (vector:0x%lx)",
  368. uc.args[0]);
  369. }
  370. }
  371. struct handlers {
  372. handler_fn exception_handlers[VECTOR_NUM][ESR_EC_NUM];
  373. };
  374. void vcpu_init_descriptor_tables(struct kvm_vcpu *vcpu)
  375. {
  376. extern char vectors;
  377. vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(SYS_VBAR_EL1), (uint64_t)&vectors);
  378. }
  379. void route_exception(struct ex_regs *regs, int vector)
  380. {
  381. struct handlers *handlers = (struct handlers *)exception_handlers;
  382. bool valid_ec;
  383. int ec = 0;
  384. switch (vector) {
  385. case VECTOR_SYNC_CURRENT:
  386. case VECTOR_SYNC_LOWER_64:
  387. ec = (read_sysreg(esr_el1) >> ESR_EC_SHIFT) & ESR_EC_MASK;
  388. valid_ec = true;
  389. break;
  390. case VECTOR_IRQ_CURRENT:
  391. case VECTOR_IRQ_LOWER_64:
  392. case VECTOR_FIQ_CURRENT:
  393. case VECTOR_FIQ_LOWER_64:
  394. case VECTOR_ERROR_CURRENT:
  395. case VECTOR_ERROR_LOWER_64:
  396. ec = 0;
  397. valid_ec = false;
  398. break;
  399. default:
  400. valid_ec = false;
  401. goto unexpected_exception;
  402. }
  403. if (handlers && handlers->exception_handlers[vector][ec])
  404. return handlers->exception_handlers[vector][ec](regs);
  405. unexpected_exception:
  406. kvm_exit_unexpected_exception(vector, ec, valid_ec);
  407. }
  408. void vm_init_descriptor_tables(struct kvm_vm *vm)
  409. {
  410. vm->handlers = __vm_vaddr_alloc(vm, sizeof(struct handlers),
  411. vm->page_size, MEM_REGION_DATA);
  412. *(vm_vaddr_t *)addr_gva2hva(vm, (vm_vaddr_t)(&exception_handlers)) = vm->handlers;
  413. }
  414. void vm_install_sync_handler(struct kvm_vm *vm, int vector, int ec,
  415. void (*handler)(struct ex_regs *))
  416. {
  417. struct handlers *handlers = addr_gva2hva(vm, vm->handlers);
  418. assert(VECTOR_IS_SYNC(vector));
  419. assert(vector < VECTOR_NUM);
  420. assert(ec < ESR_EC_NUM);
  421. handlers->exception_handlers[vector][ec] = handler;
  422. }
  423. void vm_install_exception_handler(struct kvm_vm *vm, int vector,
  424. void (*handler)(struct ex_regs *))
  425. {
  426. struct handlers *handlers = addr_gva2hva(vm, vm->handlers);
  427. assert(!VECTOR_IS_SYNC(vector));
  428. assert(vector < VECTOR_NUM);
  429. handlers->exception_handlers[vector][0] = handler;
  430. }
  431. uint32_t guest_get_vcpuid(void)
  432. {
  433. return read_sysreg(tpidr_el1);
  434. }
  435. static uint32_t max_ipa_for_page_size(uint32_t vm_ipa, uint32_t gran,
  436. uint32_t not_sup_val, uint32_t ipa52_min_val)
  437. {
  438. if (gran == not_sup_val)
  439. return 0;
  440. else if (gran >= ipa52_min_val && vm_ipa >= 52)
  441. return 52;
  442. else
  443. return min(vm_ipa, 48U);
  444. }
  445. void aarch64_get_supported_page_sizes(uint32_t ipa, uint32_t *ipa4k,
  446. uint32_t *ipa16k, uint32_t *ipa64k)
  447. {
  448. struct kvm_vcpu_init preferred_init;
  449. int kvm_fd, vm_fd, vcpu_fd, err;
  450. uint64_t val;
  451. uint32_t gran;
  452. struct kvm_one_reg reg = {
  453. .id = KVM_ARM64_SYS_REG(SYS_ID_AA64MMFR0_EL1),
  454. .addr = (uint64_t)&val,
  455. };
  456. kvm_fd = open_kvm_dev_path_or_exit();
  457. vm_fd = __kvm_ioctl(kvm_fd, KVM_CREATE_VM, (void *)(unsigned long)ipa);
  458. TEST_ASSERT(vm_fd >= 0, KVM_IOCTL_ERROR(KVM_CREATE_VM, vm_fd));
  459. vcpu_fd = ioctl(vm_fd, KVM_CREATE_VCPU, 0);
  460. TEST_ASSERT(vcpu_fd >= 0, KVM_IOCTL_ERROR(KVM_CREATE_VCPU, vcpu_fd));
  461. err = ioctl(vm_fd, KVM_ARM_PREFERRED_TARGET, &preferred_init);
  462. TEST_ASSERT(err == 0, KVM_IOCTL_ERROR(KVM_ARM_PREFERRED_TARGET, err));
  463. err = ioctl(vcpu_fd, KVM_ARM_VCPU_INIT, &preferred_init);
  464. TEST_ASSERT(err == 0, KVM_IOCTL_ERROR(KVM_ARM_VCPU_INIT, err));
  465. err = ioctl(vcpu_fd, KVM_GET_ONE_REG, &reg);
  466. TEST_ASSERT(err == 0, KVM_IOCTL_ERROR(KVM_GET_ONE_REG, vcpu_fd));
  467. gran = FIELD_GET(ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_TGRAN4), val);
  468. *ipa4k = max_ipa_for_page_size(ipa, gran, ID_AA64MMFR0_EL1_TGRAN4_NI,
  469. ID_AA64MMFR0_EL1_TGRAN4_52_BIT);
  470. gran = FIELD_GET(ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_TGRAN64), val);
  471. *ipa64k = max_ipa_for_page_size(ipa, gran, ID_AA64MMFR0_EL1_TGRAN64_NI,
  472. ID_AA64MMFR0_EL1_TGRAN64_IMP);
  473. gran = FIELD_GET(ARM64_FEATURE_MASK(ID_AA64MMFR0_EL1_TGRAN16), val);
  474. *ipa16k = max_ipa_for_page_size(ipa, gran, ID_AA64MMFR0_EL1_TGRAN16_NI,
  475. ID_AA64MMFR0_EL1_TGRAN16_52_BIT);
  476. close(vcpu_fd);
  477. close(vm_fd);
  478. close(kvm_fd);
  479. }
  480. #define __smccc_call(insn, function_id, arg0, arg1, arg2, arg3, arg4, arg5, \
  481. arg6, res) \
  482. asm volatile("mov w0, %w[function_id]\n" \
  483. "mov x1, %[arg0]\n" \
  484. "mov x2, %[arg1]\n" \
  485. "mov x3, %[arg2]\n" \
  486. "mov x4, %[arg3]\n" \
  487. "mov x5, %[arg4]\n" \
  488. "mov x6, %[arg5]\n" \
  489. "mov x7, %[arg6]\n" \
  490. #insn "#0\n" \
  491. "mov %[res0], x0\n" \
  492. "mov %[res1], x1\n" \
  493. "mov %[res2], x2\n" \
  494. "mov %[res3], x3\n" \
  495. : [res0] "=r"(res->a0), [res1] "=r"(res->a1), \
  496. [res2] "=r"(res->a2), [res3] "=r"(res->a3) \
  497. : [function_id] "r"(function_id), [arg0] "r"(arg0), \
  498. [arg1] "r"(arg1), [arg2] "r"(arg2), [arg3] "r"(arg3), \
  499. [arg4] "r"(arg4), [arg5] "r"(arg5), [arg6] "r"(arg6) \
  500. : "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7")
  501. void smccc_hvc(uint32_t function_id, uint64_t arg0, uint64_t arg1,
  502. uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5,
  503. uint64_t arg6, struct arm_smccc_res *res)
  504. {
  505. __smccc_call(hvc, function_id, arg0, arg1, arg2, arg3, arg4, arg5,
  506. arg6, res);
  507. }
  508. void smccc_smc(uint32_t function_id, uint64_t arg0, uint64_t arg1,
  509. uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5,
  510. uint64_t arg6, struct arm_smccc_res *res)
  511. {
  512. __smccc_call(smc, function_id, arg0, arg1, arg2, arg3, arg4, arg5,
  513. arg6, res);
  514. }
  515. void kvm_selftest_arch_init(void)
  516. {
  517. /*
  518. * arm64 doesn't have a true default mode, so start by computing the
  519. * available IPA space and page sizes early.
  520. */
  521. guest_modes_append_default();
  522. }
  523. void vm_vaddr_populate_bitmap(struct kvm_vm *vm)
  524. {
  525. /*
  526. * arm64 selftests use only TTBR0_EL1, meaning that the valid VA space
  527. * is [0, 2^(64 - TCR_EL1.T0SZ)).
  528. */
  529. sparsebit_set_num(vm->vpages_valid, 0,
  530. (1ULL << vm->va_bits) >> vm->page_shift);
  531. }
  532. /* Helper to call wfi instruction. */
  533. void wfi(void)
  534. {
  535. asm volatile("wfi");
  536. }