mirror of
https://github.com/torvalds/linux.git
synced 2026-05-26 16:12:59 +02:00
RISC-V: KVM: Expose APLIC registers as attributes of AIA irqchip
We expose APLIC registers as KVM device attributes of the in-kernel AIA irqchip device. This will allow KVM user-space to save/restore APLIC state using KVM device ioctls(). Signed-off-by: Anup Patel <apatel@ventanamicro.com> Reviewed-by: Atish Patra <atishp@rivosinc.com> Signed-off-by: Anup Patel <anup@brainfault.org>
This commit is contained in:
parent
74967aa208
commit
289a007b98
|
|
@ -129,6 +129,9 @@ static inline void kvm_riscv_vcpu_aia_imsic_cleanup(struct kvm_vcpu *vcpu)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int kvm_riscv_aia_aplic_set_attr(struct kvm *kvm, unsigned long type, u32 v);
|
||||||
|
int kvm_riscv_aia_aplic_get_attr(struct kvm *kvm, unsigned long type, u32 *v);
|
||||||
|
int kvm_riscv_aia_aplic_has_attr(struct kvm *kvm, unsigned long type);
|
||||||
int kvm_riscv_aia_aplic_inject(struct kvm *kvm, u32 source, bool level);
|
int kvm_riscv_aia_aplic_inject(struct kvm *kvm, u32 source, bool level);
|
||||||
int kvm_riscv_aia_aplic_init(struct kvm *kvm);
|
int kvm_riscv_aia_aplic_init(struct kvm *kvm);
|
||||||
void kvm_riscv_aia_aplic_cleanup(struct kvm *kvm);
|
void kvm_riscv_aia_aplic_cleanup(struct kvm *kvm);
|
||||||
|
|
|
||||||
|
|
@ -249,6 +249,12 @@ enum KVM_RISCV_SBI_EXT_ID {
|
||||||
#define KVM_DEV_RISCV_AIA_GRP_CTRL 2
|
#define KVM_DEV_RISCV_AIA_GRP_CTRL 2
|
||||||
#define KVM_DEV_RISCV_AIA_CTRL_INIT 0
|
#define KVM_DEV_RISCV_AIA_CTRL_INIT 0
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The device attribute type contains the memory mapped offset of the
|
||||||
|
* APLIC register (range 0x0000-0x3FFF) and it must be 4-byte aligned.
|
||||||
|
*/
|
||||||
|
#define KVM_DEV_RISCV_AIA_GRP_APLIC 3
|
||||||
|
|
||||||
/* One single KVM irqchip, ie. the AIA */
|
/* One single KVM irqchip, ie. the AIA */
|
||||||
#define KVM_NR_IRQCHIPS 1
|
#define KVM_NR_IRQCHIPS 1
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -501,6 +501,49 @@ static struct kvm_io_device_ops aplic_iodoev_ops = {
|
||||||
.write = aplic_mmio_write,
|
.write = aplic_mmio_write,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int kvm_riscv_aia_aplic_set_attr(struct kvm *kvm, unsigned long type, u32 v)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (!kvm->arch.aia.aplic_state)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
rc = aplic_mmio_write_offset(kvm, type, v);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int kvm_riscv_aia_aplic_get_attr(struct kvm *kvm, unsigned long type, u32 *v)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (!kvm->arch.aia.aplic_state)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
rc = aplic_mmio_read_offset(kvm, type, v);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int kvm_riscv_aia_aplic_has_attr(struct kvm *kvm, unsigned long type)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
if (!kvm->arch.aia.aplic_state)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
rc = aplic_mmio_read_offset(kvm, type, &val);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int kvm_riscv_aia_aplic_init(struct kvm *kvm)
|
int kvm_riscv_aia_aplic_init(struct kvm *kvm)
|
||||||
{
|
{
|
||||||
int i, ret = 0;
|
int i, ret = 0;
|
||||||
|
|
|
||||||
|
|
@ -365,6 +365,15 @@ static int aia_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case KVM_DEV_RISCV_AIA_GRP_APLIC:
|
||||||
|
if (copy_from_user(&nr, uaddr, sizeof(nr)))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
mutex_lock(&dev->kvm->lock);
|
||||||
|
r = kvm_riscv_aia_aplic_set_attr(dev->kvm, type, nr);
|
||||||
|
mutex_unlock(&dev->kvm->lock);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -412,6 +421,20 @@ static int aia_get_attr(struct kvm_device *dev, struct kvm_device_attr *attr)
|
||||||
if (copy_to_user(uaddr, &addr, sizeof(addr)))
|
if (copy_to_user(uaddr, &addr, sizeof(addr)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case KVM_DEV_RISCV_AIA_GRP_APLIC:
|
||||||
|
if (copy_from_user(&nr, uaddr, sizeof(nr)))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
mutex_lock(&dev->kvm->lock);
|
||||||
|
r = kvm_riscv_aia_aplic_get_attr(dev->kvm, type, &nr);
|
||||||
|
mutex_unlock(&dev->kvm->lock);
|
||||||
|
if (r)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (copy_to_user(uaddr, &nr, sizeof(nr)))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -448,6 +471,8 @@ static int aia_has_attr(struct kvm_device *dev, struct kvm_device_attr *attr)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case KVM_DEV_RISCV_AIA_GRP_APLIC:
|
||||||
|
return kvm_riscv_aia_aplic_has_attr(dev->kvm, attr->attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user