diff options
author | Christoffer Dall <c.dall@virtualopensystems.com> | 2013-01-20 18:28:10 -0500 |
---|---|---|
committer | Christoffer Dall <c.dall@virtualopensystems.com> | 2013-01-23 13:29:14 -0500 |
commit | 1138245ccf9652429630c09fb068e9b12c56c3d3 (patch) | |
tree | f4ef6b0be9f30ee57e7044a5311bf6487bb8bfa1 /arch/arm/kvm/guest.c | |
parent | 5b3e5e5bf230f56309706dfc05fc0cb173cc83aa (diff) |
KVM: ARM: User space API for getting/setting co-proc registers
The following three ioctls are implemented:
- KVM_GET_REG_LIST
- KVM_GET_ONE_REG
- KVM_SET_ONE_REG
Now we have a table for all the cp15 registers, we can drive a generic
API.
The register IDs carry the following encoding:
ARM registers are mapped using the lower 32 bits. The upper 16 of that
is the register group type, or coprocessor number:
ARM 32-bit CP15 registers have the following id bit patterns:
0x4002 0000 000F <zero:1> <crn:4> <crm:4> <opc1:4> <opc2:3>
ARM 64-bit CP15 registers have the following id bit patterns:
0x4003 0000 000F <zero:1> <zero:4> <crm:4> <opc1:4> <zero:3>
For futureproofing, we need to tell QEMU about the CP15 registers the
host lets the guest access.
It will need this information to restore a current guest on a future
CPU or perhaps a future KVM which allow some of these to be changed.
We use a separate table for these, as they're only for the userspace API.
Reviewed-by: Will Deacon <will.deacon@arm.com>
Reviewed-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Christoffer Dall <c.dall@virtualopensystems.com>
Diffstat (limited to 'arch/arm/kvm/guest.c')
-rw-r--r-- | arch/arm/kvm/guest.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/arch/arm/kvm/guest.c b/arch/arm/kvm/guest.c index a12eb229021d..2339d9609d36 100644 --- a/arch/arm/kvm/guest.c +++ b/arch/arm/kvm/guest.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <asm/kvm.h> | 26 | #include <asm/kvm.h> |
27 | #include <asm/kvm_asm.h> | 27 | #include <asm/kvm_asm.h> |
28 | #include <asm/kvm_emulate.h> | 28 | #include <asm/kvm_emulate.h> |
29 | #include <asm/kvm_coproc.h> | ||
29 | 30 | ||
30 | #define VM_STAT(x) { #x, offsetof(struct kvm, stat.x), KVM_STAT_VM } | 31 | #define VM_STAT(x) { #x, offsetof(struct kvm, stat.x), KVM_STAT_VM } |
31 | #define VCPU_STAT(x) { #x, offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU } | 32 | #define VCPU_STAT(x) { #x, offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU } |
@@ -119,7 +120,7 @@ static unsigned long num_core_regs(void) | |||
119 | */ | 120 | */ |
120 | unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu) | 121 | unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu) |
121 | { | 122 | { |
122 | return num_core_regs(); | 123 | return num_core_regs() + kvm_arm_num_coproc_regs(vcpu); |
123 | } | 124 | } |
124 | 125 | ||
125 | /** | 126 | /** |
@@ -138,7 +139,7 @@ int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) | |||
138 | uindices++; | 139 | uindices++; |
139 | } | 140 | } |
140 | 141 | ||
141 | return 0; | 142 | return kvm_arm_copy_coproc_indices(vcpu, uindices); |
142 | } | 143 | } |
143 | 144 | ||
144 | int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) | 145 | int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) |
@@ -151,7 +152,7 @@ int kvm_arm_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) | |||
151 | if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE) | 152 | if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE) |
152 | return get_core_reg(vcpu, reg); | 153 | return get_core_reg(vcpu, reg); |
153 | 154 | ||
154 | return -EINVAL; | 155 | return kvm_arm_coproc_get_reg(vcpu, reg); |
155 | } | 156 | } |
156 | 157 | ||
157 | int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) | 158 | int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) |
@@ -164,7 +165,7 @@ int kvm_arm_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) | |||
164 | if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE) | 165 | if ((reg->id & KVM_REG_ARM_COPROC_MASK) == KVM_REG_ARM_CORE) |
165 | return set_core_reg(vcpu, reg); | 166 | return set_core_reg(vcpu, reg); |
166 | 167 | ||
167 | return -EINVAL; | 168 | return kvm_arm_coproc_set_reg(vcpu, reg); |
168 | } | 169 | } |
169 | 170 | ||
170 | int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, | 171 | int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, |