arch/riscv/kvm/aia_device.c

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

File Facts

System
Linux kernel
Corpus path
arch/riscv/kvm/aia_device.c
Extension
.c
Size
15761 bytes
Lines
651
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

if (write) {
			switch (*nr) {
			case KVM_DEV_RISCV_AIA_MODE_EMUL:
				break;
			case KVM_DEV_RISCV_AIA_MODE_HWACCEL:
			case KVM_DEV_RISCV_AIA_MODE_AUTO:
				/*
				 * HW Acceleration and Auto modes only
				 * supported on host with non-zero guest
				 * external interrupts (i.e. non-zero
				 * VS-level IMSIC pages).
				 */
				if (!atomic_read(&kvm_riscv_aia_nr_hgei))
					return -EINVAL;
				break;
			default:
				return -EINVAL;
			}
			aia->mode = *nr;
		} else
			*nr = aia->mode;
		break;
	case KVM_DEV_RISCV_AIA_CONFIG_IDS:
		if (write) {
			if ((*nr < KVM_DEV_RISCV_AIA_IDS_MIN) ||
			    (*nr >= KVM_DEV_RISCV_AIA_IDS_MAX) ||
			    ((*nr & KVM_DEV_RISCV_AIA_IDS_MIN) !=
			     KVM_DEV_RISCV_AIA_IDS_MIN) ||
			    (kvm_riscv_aia_max_ids <= *nr))
				return -EINVAL;
			aia->nr_ids = *nr;
		} else
			*nr = aia->nr_ids;
		break;
	case KVM_DEV_RISCV_AIA_CONFIG_SRCS:
		if (write) {
			if ((*nr >= KVM_DEV_RISCV_AIA_SRCS_MAX) ||
			    (*nr >= kvm_riscv_aia_max_ids))
				return -EINVAL;
			aia->nr_sources = *nr;
		} else
			*nr = aia->nr_sources;
		break;
	case KVM_DEV_RISCV_AIA_CONFIG_GROUP_BITS:
		if (write) {
			if (*nr >= KVM_DEV_RISCV_AIA_GROUP_BITS_MAX)
				return -EINVAL;
			aia->nr_group_bits = *nr;
		} else
			*nr = aia->nr_group_bits;
		break;
	case KVM_DEV_RISCV_AIA_CONFIG_GROUP_SHIFT:
		if (write) {
			if ((*nr < KVM_DEV_RISCV_AIA_GROUP_SHIFT_MIN) ||
			    (*nr >= KVM_DEV_RISCV_AIA_GROUP_SHIFT_MAX))
				return -EINVAL;
			aia->nr_group_shift = *nr;
		} else
			*nr = aia->nr_group_shift;
		break;
	case KVM_DEV_RISCV_AIA_CONFIG_HART_BITS:
		if (write) {
			if (*nr >= KVM_DEV_RISCV_AIA_HART_BITS_MAX)
				return -EINVAL;
			aia->nr_hart_bits = *nr;
		} else
			*nr = aia->nr_hart_bits;
		break;
	case KVM_DEV_RISCV_AIA_CONFIG_GUEST_BITS:
		if (write) {
			if (*nr >= KVM_DEV_RISCV_AIA_GUEST_BITS_MAX)
				return -EINVAL;
			aia->nr_guest_bits = *nr;
		} else
			*nr = aia->nr_guest_bits;
		break;
	default:
		return -ENXIO;
	}

	return 0;
}

static int aia_aplic_addr(struct kvm *kvm, u64 *addr, bool write)
{
	struct kvm_aia *aia = &kvm->arch.aia;

	if (write) {
		/* Writes can only be done before irqchip is initialized */
		if (kvm_riscv_aia_initialized(kvm))

Annotation

Implementation Notes