/* * The default value of gcsr_flag[CSR] is 0, and we use this * function to set the flag to 1 (SW_GCSR) or 2 (HW_GCSR) if the * gcsr is software or hardware. It will be used by get/set_gcsr, * if gcsr_flag is HW we should use gcsrrd/gcsrwr to access it, * else use software csr to emulate it.
*/ staticvoid kvm_init_gcsr_flag(void)
{
set_gcsr_hw_flag(LOONGARCH_CSR_CRMD);
set_gcsr_hw_flag(LOONGARCH_CSR_PRMD);
set_gcsr_hw_flag(LOONGARCH_CSR_EUEN);
set_gcsr_hw_flag(LOONGARCH_CSR_MISC);
set_gcsr_hw_flag(LOONGARCH_CSR_ECFG);
set_gcsr_hw_flag(LOONGARCH_CSR_ESTAT);
set_gcsr_hw_flag(LOONGARCH_CSR_ERA);
set_gcsr_hw_flag(LOONGARCH_CSR_BADV);
set_gcsr_hw_flag(LOONGARCH_CSR_BADI);
set_gcsr_hw_flag(LOONGARCH_CSR_EENTRY);
set_gcsr_hw_flag(LOONGARCH_CSR_TLBIDX);
set_gcsr_hw_flag(LOONGARCH_CSR_TLBEHI);
set_gcsr_hw_flag(LOONGARCH_CSR_TLBELO0);
set_gcsr_hw_flag(LOONGARCH_CSR_TLBELO1);
set_gcsr_hw_flag(LOONGARCH_CSR_ASID);
set_gcsr_hw_flag(LOONGARCH_CSR_PGDL);
set_gcsr_hw_flag(LOONGARCH_CSR_PGDH);
set_gcsr_hw_flag(LOONGARCH_CSR_PGD);
set_gcsr_hw_flag(LOONGARCH_CSR_PWCTL0);
set_gcsr_hw_flag(LOONGARCH_CSR_PWCTL1);
set_gcsr_hw_flag(LOONGARCH_CSR_STLBPGSIZE);
set_gcsr_hw_flag(LOONGARCH_CSR_RVACFG);
set_gcsr_hw_flag(LOONGARCH_CSR_CPUID);
set_gcsr_hw_flag(LOONGARCH_CSR_PRCFG1);
set_gcsr_hw_flag(LOONGARCH_CSR_PRCFG2);
set_gcsr_hw_flag(LOONGARCH_CSR_PRCFG3);
set_gcsr_hw_flag(LOONGARCH_CSR_KS0);
set_gcsr_hw_flag(LOONGARCH_CSR_KS1);
set_gcsr_hw_flag(LOONGARCH_CSR_KS2);
set_gcsr_hw_flag(LOONGARCH_CSR_KS3);
set_gcsr_hw_flag(LOONGARCH_CSR_KS4);
set_gcsr_hw_flag(LOONGARCH_CSR_KS5);
set_gcsr_hw_flag(LOONGARCH_CSR_KS6);
set_gcsr_hw_flag(LOONGARCH_CSR_KS7);
set_gcsr_hw_flag(LOONGARCH_CSR_TMID);
set_gcsr_hw_flag(LOONGARCH_CSR_TCFG);
set_gcsr_hw_flag(LOONGARCH_CSR_TVAL);
set_gcsr_hw_flag(LOONGARCH_CSR_TINTCLR);
set_gcsr_hw_flag(LOONGARCH_CSR_CNTC);
set_gcsr_hw_flag(LOONGARCH_CSR_LLBCTL);
set_gcsr_hw_flag(LOONGARCH_CSR_TLBRENTRY);
set_gcsr_hw_flag(LOONGARCH_CSR_TLBRBADV);
set_gcsr_hw_flag(LOONGARCH_CSR_TLBRERA);
set_gcsr_hw_flag(LOONGARCH_CSR_TLBRSAVE);
set_gcsr_hw_flag(LOONGARCH_CSR_TLBRELO0);
set_gcsr_hw_flag(LOONGARCH_CSR_TLBRELO1);
set_gcsr_hw_flag(LOONGARCH_CSR_TLBREHI);
set_gcsr_hw_flag(LOONGARCH_CSR_TLBRPRMD);
set_gcsr_hw_flag(LOONGARCH_CSR_DMWIN0);
set_gcsr_hw_flag(LOONGARCH_CSR_DMWIN1);
set_gcsr_hw_flag(LOONGARCH_CSR_DMWIN2);
set_gcsr_hw_flag(LOONGARCH_CSR_DMWIN3);
cpu = smp_processor_id(); /* * Are we entering guest context on a different CPU to last time? * If so, the vCPU's guest TLB state on this CPU may be stale.
*/
context = per_cpu_ptr(vcpu->kvm->arch.vmcs, cpu);
migrated = (vcpu->cpu != cpu);
/* * Check if our vpid is of an older version * * We also discard the stored vpid if we've executed on * another CPU, as the guest mappings may have changed without * hypervisor knowledge.
*/
ver = vcpu->arch.vpid & ~vpid_mask;
old = context->vpid_cache & ~vpid_mask; if (migrated || (ver != old)) {
kvm_update_vpid(vcpu, cpu);
trace_kvm_vpid_change(vcpu, vcpu->arch.vpid);
vcpu->cpu = cpu;
kvm_clear_request(KVM_REQ_TLB_FLUSH_GPA, vcpu);
/* * LLBCTL is a separated guest CSR register from host, a general * exception ERET instruction clears the host LLBCTL register in * host mode, and clears the guest LLBCTL register in guest mode. * ERET in tlb refill exception does not clear LLBCTL register. * * When secondary mmu mapping is changed, guest OS does not know * even if the content is changed after mapping is changed. * * Here clear WCLLB of the guest LLBCTL register when mapping is * changed. Otherwise, if mmu mapping is changed while guest is * executing LL/SC pair, LL loads with the old address and set * the LLBCTL flag, SC checks the LLBCTL flag and will store the * new address successfully since LLBCTL_WCLLB is on, even if * memory with new address is changed on other VCPUs.
*/
set_gcsr_llbctl(CSR_LLBCTL_WCLLB);
}
int kvm_arch_enable_virtualization_cpu(void)
{ unsignedlong env, gcfg = 0;
env = read_csr_gcfg();
/* First init gcfg, gstat, gintc, gtlbc. All guest use the same config */
write_csr_gcfg(0);
write_csr_gstat(0);
write_csr_gintc(0);
clear_csr_gtlbc(CSR_GTLBC_USETGID | CSR_GTLBC_TOTI);
/* * Enable virtualization features granting guest direct control of * certain features: * GCI=2: Trap on init or unimplemented cache instruction. * TORU=0: Trap on Root Unimplement. * CACTRL=1: Root control cache. * TOP=0: Trap on Privilege. * TOE=0: Trap on Exception. * TIT=0: Trap on Timer.
*/ if (env & CSR_GCFG_GCIP_SECURE)
gcfg |= CSR_GCFG_GCI_SECURE; if (env & CSR_GCFG_MATP_ROOT)
gcfg |= CSR_GCFG_MATC_ROOT;
/* * HW Guest CSR registers are lost after CPU suspend and resume. * Clear last_vcpu so that Guest CSR registers forced to reload * from vCPU SW state.
*/
this_cpu_ptr(vmcs)->last_vcpu = NULL;
/* * PGD register is shared between root kernel and kvm hypervisor. * So world switch entry should be in DMW area rather than TLB area * to avoid page fault reenter. * * In future if hardware pagetable walking is supported, we won't * need to copy world switch code to DMW area.
*/
order = get_order(kvm_exception_size + kvm_enter_guest_size);
addr = (void *)__get_free_pages(GFP_KERNEL, order); if (!addr) {
free_percpu(vmcs);
vmcs = NULL;
kfree(kvm_loongarch_ops);
kvm_loongarch_ops = NULL; return -ENOMEM;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.