diff options
author | Jes Sorensen <jes@sgi.com> | 2008-12-16 10:45:47 -0500 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2008-12-31 09:55:47 -0500 |
commit | 042b26edf0bc1b0f03238a71aed71cca4593848c (patch) | |
tree | cc80cc9e7e097f53837d0eff67cb5186abcd6a17 /arch/ia64/kvm/kvm-ia64.c | |
parent | 4531220b71f0399e71cda0c4cf749e7281a7416a (diff) |
KVM: ia64: Fix kvm_arch_vcpu_ioctl_[gs]et_regs()
Fix kvm_arch_vcpu_ioctl_[gs]et_regs() to do something meaningful on
ia64. Old versions could never have worked since they required
pointers to be set in the ioctl payload which were never being set by
the ioctl handler for get_regs.
In addition reserve extra space for future extensions.
The change of layout of struct kvm_regs doesn't require adding a new
CAP since get/set regs never worked on ia64 until now.
This version doesn't support copying the KVM kernel stack in/out of
the kernel. This should be implemented in a seperate ioctl call if
ever needed.
Signed-off-by: Jes Sorensen <jes@sgi.com>
Acked-by : Xiantao Zhang <xiantao.zhang@intel.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/ia64/kvm/kvm-ia64.c')
-rw-r--r-- | arch/ia64/kvm/kvm-ia64.c | 40 |
1 files changed, 10 insertions, 30 deletions
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index d2eb9691d61d..0f5ebd948437 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c | |||
@@ -831,9 +831,8 @@ static int kvm_vm_ioctl_set_irqchip(struct kvm *kvm, struct kvm_irqchip *chip) | |||
831 | 831 | ||
832 | int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) | 832 | int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) |
833 | { | 833 | { |
834 | int i; | ||
835 | struct vpd *vpd = to_host(vcpu->kvm, vcpu->arch.vpd); | 834 | struct vpd *vpd = to_host(vcpu->kvm, vcpu->arch.vpd); |
836 | int r; | 835 | int i; |
837 | 836 | ||
838 | vcpu_load(vcpu); | 837 | vcpu_load(vcpu); |
839 | 838 | ||
@@ -850,18 +849,7 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) | |||
850 | 849 | ||
851 | vpd->vpr = regs->vpd.vpr; | 850 | vpd->vpr = regs->vpd.vpr; |
852 | 851 | ||
853 | r = -EFAULT; | 852 | memcpy(&vcpu->arch.guest, ®s->saved_guest, sizeof(union context)); |
854 | r = copy_from_user(&vcpu->arch.guest, regs->saved_guest, | ||
855 | sizeof(union context)); | ||
856 | if (r) | ||
857 | goto out; | ||
858 | r = copy_from_user(vcpu + 1, regs->saved_stack + | ||
859 | sizeof(struct kvm_vcpu), | ||
860 | KVM_STK_OFFSET - sizeof(struct kvm_vcpu)); | ||
861 | if (r) | ||
862 | goto out; | ||
863 | vcpu->arch.exit_data = | ||
864 | ((struct kvm_vcpu *)(regs->saved_stack))->arch.exit_data; | ||
865 | 853 | ||
866 | RESTORE_REGS(mp_state); | 854 | RESTORE_REGS(mp_state); |
867 | RESTORE_REGS(vmm_rr); | 855 | RESTORE_REGS(vmm_rr); |
@@ -895,9 +883,8 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) | |||
895 | set_bit(KVM_REQ_RESUME, &vcpu->requests); | 883 | set_bit(KVM_REQ_RESUME, &vcpu->requests); |
896 | 884 | ||
897 | vcpu_put(vcpu); | 885 | vcpu_put(vcpu); |
898 | r = 0; | 886 | |
899 | out: | 887 | return 0; |
900 | return r; | ||
901 | } | 888 | } |
902 | 889 | ||
903 | long kvm_arch_vm_ioctl(struct file *filp, | 890 | long kvm_arch_vm_ioctl(struct file *filp, |
@@ -1378,9 +1365,9 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | |||
1378 | 1365 | ||
1379 | int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) | 1366 | int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) |
1380 | { | 1367 | { |
1381 | int i; | ||
1382 | int r; | ||
1383 | struct vpd *vpd = to_host(vcpu->kvm, vcpu->arch.vpd); | 1368 | struct vpd *vpd = to_host(vcpu->kvm, vcpu->arch.vpd); |
1369 | int i; | ||
1370 | |||
1384 | vcpu_load(vcpu); | 1371 | vcpu_load(vcpu); |
1385 | 1372 | ||
1386 | for (i = 0; i < 16; i++) { | 1373 | for (i = 0; i < 16; i++) { |
@@ -1395,14 +1382,8 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) | |||
1395 | regs->vpd.vpsr = vpd->vpsr; | 1382 | regs->vpd.vpsr = vpd->vpsr; |
1396 | regs->vpd.vpr = vpd->vpr; | 1383 | regs->vpd.vpr = vpd->vpr; |
1397 | 1384 | ||
1398 | r = -EFAULT; | 1385 | memcpy(®s->saved_guest, &vcpu->arch.guest, sizeof(union context)); |
1399 | r = copy_to_user(regs->saved_guest, &vcpu->arch.guest, | 1386 | |
1400 | sizeof(union context)); | ||
1401 | if (r) | ||
1402 | goto out; | ||
1403 | r = copy_to_user(regs->saved_stack, (void *)vcpu, KVM_STK_OFFSET); | ||
1404 | if (r) | ||
1405 | goto out; | ||
1406 | SAVE_REGS(mp_state); | 1387 | SAVE_REGS(mp_state); |
1407 | SAVE_REGS(vmm_rr); | 1388 | SAVE_REGS(vmm_rr); |
1408 | memcpy(regs->itrs, vcpu->arch.itrs, sizeof(struct thash_data) * NITRS); | 1389 | memcpy(regs->itrs, vcpu->arch.itrs, sizeof(struct thash_data) * NITRS); |
@@ -1430,10 +1411,9 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) | |||
1430 | SAVE_REGS(metaphysical_saved_rr4); | 1411 | SAVE_REGS(metaphysical_saved_rr4); |
1431 | SAVE_REGS(fp_psr); | 1412 | SAVE_REGS(fp_psr); |
1432 | SAVE_REGS(saved_gp); | 1413 | SAVE_REGS(saved_gp); |
1414 | |||
1433 | vcpu_put(vcpu); | 1415 | vcpu_put(vcpu); |
1434 | r = 0; | 1416 | return 0; |
1435 | out: | ||
1436 | return r; | ||
1437 | } | 1417 | } |
1438 | 1418 | ||
1439 | void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) | 1419 | void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) |