Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * RISC-V code
0004  *
0005  * Copyright (C) 2021 Western Digital Corporation or its affiliates.
0006  */
0007 
0008 #include <linux/compiler.h>
0009 #include <assert.h>
0010 
0011 #include "kvm_util.h"
0012 #include "processor.h"
0013 
0014 #define DEFAULT_RISCV_GUEST_STACK_VADDR_MIN 0xac0000
0015 
0016 static uint64_t page_align(struct kvm_vm *vm, uint64_t v)
0017 {
0018     return (v + vm->page_size) & ~(vm->page_size - 1);
0019 }
0020 
0021 static uint64_t pte_addr(struct kvm_vm *vm, uint64_t entry)
0022 {
0023     return ((entry & PGTBL_PTE_ADDR_MASK) >> PGTBL_PTE_ADDR_SHIFT) <<
0024         PGTBL_PAGE_SIZE_SHIFT;
0025 }
0026 
0027 static uint64_t ptrs_per_pte(struct kvm_vm *vm)
0028 {
0029     return PGTBL_PAGE_SIZE / sizeof(uint64_t);
0030 }
0031 
0032 static uint64_t pte_index_mask[] = {
0033     PGTBL_L0_INDEX_MASK,
0034     PGTBL_L1_INDEX_MASK,
0035     PGTBL_L2_INDEX_MASK,
0036     PGTBL_L3_INDEX_MASK,
0037 };
0038 
0039 static uint32_t pte_index_shift[] = {
0040     PGTBL_L0_INDEX_SHIFT,
0041     PGTBL_L1_INDEX_SHIFT,
0042     PGTBL_L2_INDEX_SHIFT,
0043     PGTBL_L3_INDEX_SHIFT,
0044 };
0045 
0046 static uint64_t pte_index(struct kvm_vm *vm, vm_vaddr_t gva, int level)
0047 {
0048     TEST_ASSERT(level > -1,
0049         "Negative page table level (%d) not possible", level);
0050     TEST_ASSERT(level < vm->pgtable_levels,
0051         "Invalid page table level (%d)", level);
0052 
0053     return (gva & pte_index_mask[level]) >> pte_index_shift[level];
0054 }
0055 
0056 void virt_arch_pgd_alloc(struct kvm_vm *vm)
0057 {
0058     if (!vm->pgd_created) {
0059         vm_paddr_t paddr = vm_phy_pages_alloc(vm,
0060             page_align(vm, ptrs_per_pte(vm) * 8) / vm->page_size,
0061             KVM_GUEST_PAGE_TABLE_MIN_PADDR, 0);
0062         vm->pgd = paddr;
0063         vm->pgd_created = true;
0064     }
0065 }
0066 
0067 void virt_arch_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr)
0068 {
0069     uint64_t *ptep, next_ppn;
0070     int level = vm->pgtable_levels - 1;
0071 
0072     TEST_ASSERT((vaddr % vm->page_size) == 0,
0073         "Virtual address not on page boundary,\n"
0074         "  vaddr: 0x%lx vm->page_size: 0x%x", vaddr, vm->page_size);
0075     TEST_ASSERT(sparsebit_is_set(vm->vpages_valid,
0076         (vaddr >> vm->page_shift)),
0077         "Invalid virtual address, vaddr: 0x%lx", vaddr);
0078     TEST_ASSERT((paddr % vm->page_size) == 0,
0079         "Physical address not on page boundary,\n"
0080         "  paddr: 0x%lx vm->page_size: 0x%x", paddr, vm->page_size);
0081     TEST_ASSERT((paddr >> vm->page_shift) <= vm->max_gfn,
0082         "Physical address beyond maximum supported,\n"
0083         "  paddr: 0x%lx vm->max_gfn: 0x%lx vm->page_size: 0x%x",
0084         paddr, vm->max_gfn, vm->page_size);
0085 
0086     ptep = addr_gpa2hva(vm, vm->pgd) + pte_index(vm, vaddr, level) * 8;
0087     if (!*ptep) {
0088         next_ppn = vm_alloc_page_table(vm) >> PGTBL_PAGE_SIZE_SHIFT;
0089         *ptep = (next_ppn << PGTBL_PTE_ADDR_SHIFT) |
0090             PGTBL_PTE_VALID_MASK;
0091     }
0092     level--;
0093 
0094     while (level > -1) {
0095         ptep = addr_gpa2hva(vm, pte_addr(vm, *ptep)) +
0096                pte_index(vm, vaddr, level) * 8;
0097         if (!*ptep && level > 0) {
0098             next_ppn = vm_alloc_page_table(vm) >>
0099                    PGTBL_PAGE_SIZE_SHIFT;
0100             *ptep = (next_ppn << PGTBL_PTE_ADDR_SHIFT) |
0101                 PGTBL_PTE_VALID_MASK;
0102         }
0103         level--;
0104     }
0105 
0106     paddr = paddr >> PGTBL_PAGE_SIZE_SHIFT;
0107     *ptep = (paddr << PGTBL_PTE_ADDR_SHIFT) |
0108         PGTBL_PTE_PERM_MASK | PGTBL_PTE_VALID_MASK;
0109 }
0110 
0111 vm_paddr_t addr_arch_gva2gpa(struct kvm_vm *vm, vm_vaddr_t gva)
0112 {
0113     uint64_t *ptep;
0114     int level = vm->pgtable_levels - 1;
0115 
0116     if (!vm->pgd_created)
0117         goto unmapped_gva;
0118 
0119     ptep = addr_gpa2hva(vm, vm->pgd) + pte_index(vm, gva, level) * 8;
0120     if (!ptep)
0121         goto unmapped_gva;
0122     level--;
0123 
0124     while (level > -1) {
0125         ptep = addr_gpa2hva(vm, pte_addr(vm, *ptep)) +
0126                pte_index(vm, gva, level) * 8;
0127         if (!ptep)
0128             goto unmapped_gva;
0129         level--;
0130     }
0131 
0132     return pte_addr(vm, *ptep) + (gva & (vm->page_size - 1));
0133 
0134 unmapped_gva:
0135     TEST_FAIL("No mapping for vm virtual address gva: 0x%lx level: %d",
0136           gva, level);
0137     exit(1);
0138 }
0139 
0140 static void pte_dump(FILE *stream, struct kvm_vm *vm, uint8_t indent,
0141              uint64_t page, int level)
0142 {
0143 #ifdef DEBUG
0144     static const char *const type[] = { "pte", "pmd", "pud", "p4d"};
0145     uint64_t pte, *ptep;
0146 
0147     if (level < 0)
0148         return;
0149 
0150     for (pte = page; pte < page + ptrs_per_pte(vm) * 8; pte += 8) {
0151         ptep = addr_gpa2hva(vm, pte);
0152         if (!*ptep)
0153             continue;
0154         fprintf(stream, "%*s%s: %lx: %lx at %p\n", indent, "",
0155             type[level], pte, *ptep, ptep);
0156         pte_dump(stream, vm, indent + 1,
0157              pte_addr(vm, *ptep), level - 1);
0158     }
0159 #endif
0160 }
0161 
0162 void virt_arch_dump(FILE *stream, struct kvm_vm *vm, uint8_t indent)
0163 {
0164     int level = vm->pgtable_levels - 1;
0165     uint64_t pgd, *ptep;
0166 
0167     if (!vm->pgd_created)
0168         return;
0169 
0170     for (pgd = vm->pgd; pgd < vm->pgd + ptrs_per_pte(vm) * 8; pgd += 8) {
0171         ptep = addr_gpa2hva(vm, pgd);
0172         if (!*ptep)
0173             continue;
0174         fprintf(stream, "%*spgd: %lx: %lx at %p\n", indent, "",
0175             pgd, *ptep, ptep);
0176         pte_dump(stream, vm, indent + 1,
0177              pte_addr(vm, *ptep), level - 1);
0178     }
0179 }
0180 
0181 void riscv_vcpu_mmu_setup(struct kvm_vcpu *vcpu)
0182 {
0183     struct kvm_vm *vm = vcpu->vm;
0184     unsigned long satp;
0185 
0186     /*
0187      * The RISC-V Sv48 MMU mode supports 56-bit physical address
0188      * for 48-bit virtual address with 4KB last level page size.
0189      */
0190     switch (vm->mode) {
0191     case VM_MODE_P52V48_4K:
0192     case VM_MODE_P48V48_4K:
0193     case VM_MODE_P40V48_4K:
0194         break;
0195     default:
0196         TEST_FAIL("Unknown guest mode, mode: 0x%x", vm->mode);
0197     }
0198 
0199     satp = (vm->pgd >> PGTBL_PAGE_SIZE_SHIFT) & SATP_PPN;
0200     satp |= SATP_MODE_48;
0201 
0202     vcpu_set_reg(vcpu, RISCV_CSR_REG(satp), satp);
0203 }
0204 
0205 void vcpu_arch_dump(FILE *stream, struct kvm_vcpu *vcpu, uint8_t indent)
0206 {
0207     struct kvm_riscv_core core;
0208 
0209     vcpu_get_reg(vcpu, RISCV_CORE_REG(mode), &core.mode);
0210     vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.pc), &core.regs.pc);
0211     vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.ra), &core.regs.ra);
0212     vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.sp), &core.regs.sp);
0213     vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.gp), &core.regs.gp);
0214     vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.tp), &core.regs.tp);
0215     vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t0), &core.regs.t0);
0216     vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t1), &core.regs.t1);
0217     vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t2), &core.regs.t2);
0218     vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s0), &core.regs.s0);
0219     vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s1), &core.regs.s1);
0220     vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a0), &core.regs.a0);
0221     vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a1), &core.regs.a1);
0222     vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a2), &core.regs.a2);
0223     vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a3), &core.regs.a3);
0224     vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a4), &core.regs.a4);
0225     vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a5), &core.regs.a5);
0226     vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a6), &core.regs.a6);
0227     vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.a7), &core.regs.a7);
0228     vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s2), &core.regs.s2);
0229     vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s3), &core.regs.s3);
0230     vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s4), &core.regs.s4);
0231     vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s5), &core.regs.s5);
0232     vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s6), &core.regs.s6);
0233     vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s7), &core.regs.s7);
0234     vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s8), &core.regs.s8);
0235     vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s9), &core.regs.s9);
0236     vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s10), &core.regs.s10);
0237     vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.s11), &core.regs.s11);
0238     vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t3), &core.regs.t3);
0239     vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t4), &core.regs.t4);
0240     vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t5), &core.regs.t5);
0241     vcpu_get_reg(vcpu, RISCV_CORE_REG(regs.t6), &core.regs.t6);
0242 
0243     fprintf(stream,
0244         " MODE:  0x%lx\n", core.mode);
0245     fprintf(stream,
0246         " PC: 0x%016lx   RA: 0x%016lx SP: 0x%016lx GP: 0x%016lx\n",
0247         core.regs.pc, core.regs.ra, core.regs.sp, core.regs.gp);
0248     fprintf(stream,
0249         " TP: 0x%016lx   T0: 0x%016lx T1: 0x%016lx T2: 0x%016lx\n",
0250         core.regs.tp, core.regs.t0, core.regs.t1, core.regs.t2);
0251     fprintf(stream,
0252         " S0: 0x%016lx   S1: 0x%016lx A0: 0x%016lx A1: 0x%016lx\n",
0253         core.regs.s0, core.regs.s1, core.regs.a0, core.regs.a1);
0254     fprintf(stream,
0255         " A2: 0x%016lx   A3: 0x%016lx A4: 0x%016lx A5: 0x%016lx\n",
0256         core.regs.a2, core.regs.a3, core.regs.a4, core.regs.a5);
0257     fprintf(stream,
0258         " A6: 0x%016lx   A7: 0x%016lx S2: 0x%016lx S3: 0x%016lx\n",
0259         core.regs.a6, core.regs.a7, core.regs.s2, core.regs.s3);
0260     fprintf(stream,
0261         " S4: 0x%016lx   S5: 0x%016lx S6: 0x%016lx S7: 0x%016lx\n",
0262         core.regs.s4, core.regs.s5, core.regs.s6, core.regs.s7);
0263     fprintf(stream,
0264         " S8: 0x%016lx   S9: 0x%016lx S10: 0x%016lx S11: 0x%016lx\n",
0265         core.regs.s8, core.regs.s9, core.regs.s10, core.regs.s11);
0266     fprintf(stream,
0267         " T3: 0x%016lx   T4: 0x%016lx T5: 0x%016lx T6: 0x%016lx\n",
0268         core.regs.t3, core.regs.t4, core.regs.t5, core.regs.t6);
0269 }
0270 
0271 static void __aligned(16) guest_unexp_trap(void)
0272 {
0273     sbi_ecall(KVM_RISCV_SELFTESTS_SBI_EXT,
0274           KVM_RISCV_SELFTESTS_SBI_UNEXP,
0275           0, 0, 0, 0, 0, 0);
0276 }
0277 
0278 struct kvm_vcpu *vm_arch_vcpu_add(struct kvm_vm *vm, uint32_t vcpu_id,
0279                   void *guest_code)
0280 {
0281     int r;
0282     size_t stack_size = vm->page_size == 4096 ?
0283                     DEFAULT_STACK_PGS * vm->page_size :
0284                     vm->page_size;
0285     unsigned long stack_vaddr = vm_vaddr_alloc(vm, stack_size,
0286                     DEFAULT_RISCV_GUEST_STACK_VADDR_MIN);
0287     unsigned long current_gp = 0;
0288     struct kvm_mp_state mps;
0289     struct kvm_vcpu *vcpu;
0290 
0291     vcpu = __vm_vcpu_add(vm, vcpu_id);
0292     riscv_vcpu_mmu_setup(vcpu);
0293 
0294     /*
0295      * With SBI HSM support in KVM RISC-V, all secondary VCPUs are
0296      * powered-off by default so we ensure that all secondary VCPUs
0297      * are powered-on using KVM_SET_MP_STATE ioctl().
0298      */
0299     mps.mp_state = KVM_MP_STATE_RUNNABLE;
0300     r = __vcpu_ioctl(vcpu, KVM_SET_MP_STATE, &mps);
0301     TEST_ASSERT(!r, "IOCTL KVM_SET_MP_STATE failed (error %d)", r);
0302 
0303     /* Setup global pointer of guest to be same as the host */
0304     asm volatile (
0305         "add %0, gp, zero" : "=r" (current_gp) : : "memory");
0306     vcpu_set_reg(vcpu, RISCV_CORE_REG(regs.gp), current_gp);
0307 
0308     /* Setup stack pointer and program counter of guest */
0309     vcpu_set_reg(vcpu, RISCV_CORE_REG(regs.sp), stack_vaddr + stack_size);
0310     vcpu_set_reg(vcpu, RISCV_CORE_REG(regs.pc), (unsigned long)guest_code);
0311 
0312     /* Setup default exception vector of guest */
0313     vcpu_set_reg(vcpu, RISCV_CSR_REG(stvec), (unsigned long)guest_unexp_trap);
0314 
0315     return vcpu;
0316 }
0317 
0318 void vcpu_args_set(struct kvm_vcpu *vcpu, unsigned int num, ...)
0319 {
0320     va_list ap;
0321     uint64_t id = RISCV_CORE_REG(regs.a0);
0322     int i;
0323 
0324     TEST_ASSERT(num >= 1 && num <= 8, "Unsupported number of args,\n"
0325             "  num: %u\n", num);
0326 
0327     va_start(ap, num);
0328 
0329     for (i = 0; i < num; i++) {
0330         switch (i) {
0331         case 0:
0332             id = RISCV_CORE_REG(regs.a0);
0333             break;
0334         case 1:
0335             id = RISCV_CORE_REG(regs.a1);
0336             break;
0337         case 2:
0338             id = RISCV_CORE_REG(regs.a2);
0339             break;
0340         case 3:
0341             id = RISCV_CORE_REG(regs.a3);
0342             break;
0343         case 4:
0344             id = RISCV_CORE_REG(regs.a4);
0345             break;
0346         case 5:
0347             id = RISCV_CORE_REG(regs.a5);
0348             break;
0349         case 6:
0350             id = RISCV_CORE_REG(regs.a6);
0351             break;
0352         case 7:
0353             id = RISCV_CORE_REG(regs.a7);
0354             break;
0355         }
0356         vcpu_set_reg(vcpu, id, va_arg(ap, uint64_t));
0357     }
0358 
0359     va_end(ap);
0360 }
0361 
0362 void assert_on_unhandled_exception(struct kvm_vcpu *vcpu)
0363 {
0364 }