arch/riscv/kvm/tlb.c

Source file repositories/reference/linux-study-clean/arch/riscv/kvm/tlb.c

File Facts

System
Linux kernel
Corpus path
arch/riscv/kvm/tlb.c
Extension
.c
Size
12448 bytes
Lines
468
Domain
Architecture Layer
Bucket
arch/riscv
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

switch (d.type) {
		case KVM_RISCV_HFENCE_UNKNOWN:
			break;
		case KVM_RISCV_HFENCE_GVMA_VMID_GPA:
			if (kvm_riscv_nacl_available())
				nacl_hfence_gvma_vmid(nacl_shmem(), d.vmid,
						      d.addr, d.size, d.order);
			else
				kvm_riscv_local_hfence_gvma_vmid_gpa(d.vmid, d.addr,
								     d.size, d.order);
			break;
		case KVM_RISCV_HFENCE_GVMA_VMID_ALL:
			if (kvm_riscv_nacl_available())
				nacl_hfence_gvma_vmid_all(nacl_shmem(), d.vmid);
			else
				kvm_riscv_local_hfence_gvma_vmid_all(d.vmid);
			break;
		case KVM_RISCV_HFENCE_VVMA_ASID_GVA:
			kvm_riscv_vcpu_pmu_incr_fw(vcpu, SBI_PMU_FW_HFENCE_VVMA_ASID_RCVD);
			if (kvm_riscv_nacl_available())
				nacl_hfence_vvma_asid(nacl_shmem(), d.vmid, d.asid,
						      d.addr, d.size, d.order);
			else
				kvm_riscv_local_hfence_vvma_asid_gva(d.vmid, d.asid, d.addr,
								     d.size, d.order);
			break;
		case KVM_RISCV_HFENCE_VVMA_ASID_ALL:
			kvm_riscv_vcpu_pmu_incr_fw(vcpu, SBI_PMU_FW_HFENCE_VVMA_ASID_RCVD);
			if (kvm_riscv_nacl_available())
				nacl_hfence_vvma_asid_all(nacl_shmem(), d.vmid, d.asid);
			else
				kvm_riscv_local_hfence_vvma_asid_all(d.vmid, d.asid);
			break;
		case KVM_RISCV_HFENCE_VVMA_GVA:
			kvm_riscv_vcpu_pmu_incr_fw(vcpu, SBI_PMU_FW_HFENCE_VVMA_RCVD);
			if (kvm_riscv_nacl_available())
				nacl_hfence_vvma(nacl_shmem(), d.vmid,
						 d.addr, d.size, d.order);
			else
				kvm_riscv_local_hfence_vvma_gva(d.vmid, d.addr,
								d.size, d.order);
			break;
		case KVM_RISCV_HFENCE_VVMA_ALL:
			kvm_riscv_vcpu_pmu_incr_fw(vcpu, SBI_PMU_FW_HFENCE_VVMA_RCVD);
			if (kvm_riscv_nacl_available())
				nacl_hfence_vvma_all(nacl_shmem(), d.vmid);
			else
				kvm_riscv_local_hfence_vvma_all(d.vmid);
			break;
		default:
			break;
		}
	}
}

static void make_xfence_request(struct kvm *kvm,
				unsigned long hbase, unsigned long hmask,
				unsigned int req, unsigned int fallback_req,
				const struct kvm_riscv_hfence *data)
{
	unsigned long i;
	struct kvm_vcpu *vcpu;
	unsigned int actual_req = req;
	DECLARE_BITMAP(vcpu_mask, KVM_MAX_VCPUS);

	bitmap_zero(vcpu_mask, KVM_MAX_VCPUS);
	kvm_for_each_vcpu(i, vcpu, kvm) {
		if (hbase != -1UL) {
			if (vcpu->vcpu_id < hbase ||
				vcpu->vcpu_id >= hbase + BITS_PER_LONG)
				continue;
			if (!(hmask & (1UL << (vcpu->vcpu_id - hbase))))
				continue;
		}

		bitmap_set(vcpu_mask, i, 1);

		if (!data || !data->type)
			continue;

		/*
		 * Enqueue hfence data to VCPU hfence queue. If we don't
		 * have space in the VCPU hfence queue then fallback to
		 * a more conservative hfence request.
		 */
		if (!vcpu_hfence_enqueue(vcpu, data))
			actual_req = fallback_req;
	}

	kvm_make_vcpus_request_mask(kvm, actual_req, vcpu_mask);

Annotation

Implementation Notes