static void nestedhvm_flushtlb_ipi(void *info) { struct vcpu *v = current; struct domain *d = info; ASSERT(d != NULL); if (v->domain != d) { /* This cpu doesn't belong to the domain */ return; } /* Just flush the ASID (or request a new one). * This is cheaper than flush_tlb_local() and has * the same desired effect. */ hvm_asid_flush_core(); vcpu_nestedhvm(v).nv_p2m = NULL; }
bool_t hvm_asid_handle_vmenter(struct hvm_vcpu_asid *asid) { struct hvm_asid_data *data = &this_cpu(hvm_asid_data); /* On erratum #170 systems we must flush the TLB. * Generation overruns are taken here, too. */ if ( data->disabled ) goto disabled; /* Test if VCPU has valid ASID. */ if ( asid->generation == data->core_asid_generation ) return 0; /* If there are no free ASIDs, need to go to a new generation */ if ( unlikely(data->next_asid > data->max_asid) ) { hvm_asid_flush_core(); data->next_asid = 1; if ( data->disabled ) goto disabled; } /* Now guaranteed to be a free ASID. */ asid->asid = data->next_asid++; asid->generation = data->core_asid_generation; /* * When we assign ASID 1, flush all TLB entries as we are starting a new * generation, and all old ASID allocations are now stale. */ return (asid->asid == 1); disabled: asid->asid = 0; return 0; }