arch/mips/kvm/loongson_ipi.c

Source file repositories/reference/linux-study-clean/arch/mips/kvm/loongson_ipi.c

File Facts

System
Linux kernel
Corpus path
arch/mips/kvm/loongson_ipi.c
Extension
.c
Size
5133 bytes
Lines
217
Domain
Architecture Layer
Bucket
arch/mips
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 (!s->status) {
			irq.cpu = id;
			irq.irq = -6;
			kvm_vcpu_ioctl_interrupt(kvm_get_vcpu(kvm, id), &irq);
		}
		break;

	case CORE0_BUF_20 ... CORE0_BUF_38:
		pbuf = (void *)s->buf + (offset - 0x20);
		if (len == 8)
			*(uint64_t *)pbuf = (uint64_t)data;
		else /* Assume len == 4 */
			*(uint32_t *)pbuf = (uint32_t)data;
		break;

	default:
		pr_notice("%s with unknown addr %llx\n", __func__, addr);
		break;
	}

	return 0;
}

static int kvm_ipi_read(struct kvm_vcpu *vcpu, struct kvm_io_device *dev,
			gpa_t addr, int len, void *val)
{
	unsigned long flags;
	struct loongson_kvm_ipi *ipi;
	struct ipi_io_device *ipi_device;

	ipi_device = container_of(dev, struct ipi_io_device, device);
	ipi = ipi_device->ipi;

	spin_lock_irqsave(&ipi->lock, flags);
	loongson_vipi_read(ipi, addr, len, val);
	spin_unlock_irqrestore(&ipi->lock, flags);

	return 0;
}

static int kvm_ipi_write(struct kvm_vcpu *vcpu, struct kvm_io_device *dev,
			gpa_t addr, int len, const void *val)
{
	unsigned long flags;
	struct loongson_kvm_ipi *ipi;
	struct ipi_io_device *ipi_device;

	ipi_device = container_of(dev, struct ipi_io_device, device);
	ipi = ipi_device->ipi;

	spin_lock_irqsave(&ipi->lock, flags);
	loongson_vipi_write(ipi, addr, len, val);
	spin_unlock_irqrestore(&ipi->lock, flags);

	return 0;
}

static const struct kvm_io_device_ops kvm_ipi_ops = {
	.read     = kvm_ipi_read,
	.write    = kvm_ipi_write,
};

void kvm_init_loongson_ipi(struct kvm *kvm)
{
	int i;
	unsigned long addr;
	struct loongson_kvm_ipi *s;
	struct kvm_io_device *device;

	s = &kvm->arch.ipi;
	s->kvm = kvm;
	spin_lock_init(&s->lock);

	/*
	 * Initialize IPI device
	 */
	for (i = 0; i < 4; i++) {
		device = &s->dev_ipi[i].device;
		kvm_iodevice_init(device, &kvm_ipi_ops);
		addr = (((unsigned long)i) << 44) + IPI_BASE;
		mutex_lock(&kvm->slots_lock);
		kvm_io_bus_register_dev(kvm, KVM_MMIO_BUS, addr, 0x400, device);
		mutex_unlock(&kvm->slots_lock);
		s->dev_ipi[i].ipi = s;
		s->dev_ipi[i].node_id = i;
	}
}

Annotation

Implementation Notes