aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorJes Sorensen <jes@sgi.com>2008-12-16 10:45:47 -0500
committerAvi Kivity <avi@redhat.com>2008-12-31 09:55:47 -0500
commit042b26edf0bc1b0f03238a71aed71cca4593848c (patch)
treecc80cc9e7e097f53837d0eff67cb5186abcd6a17 /arch
parent4531220b71f0399e71cda0c4cf749e7281a7416a (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')
-rw-r--r--arch/ia64/include/asm/kvm.h6
-rw-r--r--arch/ia64/kvm/kvm-ia64.c40
2 files changed, 14 insertions, 32 deletions
diff --git a/arch/ia64/include/asm/kvm.h b/arch/ia64/include/asm/kvm.h
index f38472ac2267..68aa6da807c1 100644
--- a/arch/ia64/include/asm/kvm.h
+++ b/arch/ia64/include/asm/kvm.h
@@ -166,8 +166,6 @@ struct saved_vpd {
166}; 166};
167 167
168struct kvm_regs { 168struct kvm_regs {
169 char *saved_guest;
170 char *saved_stack;
171 struct saved_vpd vpd; 169 struct saved_vpd vpd;
172 /*Arch-regs*/ 170 /*Arch-regs*/
173 int mp_state; 171 int mp_state;
@@ -200,6 +198,10 @@ struct kvm_regs {
200 unsigned long fp_psr; /*used for lazy float register */ 198 unsigned long fp_psr; /*used for lazy float register */
201 unsigned long saved_gp; 199 unsigned long saved_gp;
202 /*for phycial emulation */ 200 /*for phycial emulation */
201
202 union context saved_guest;
203
204 unsigned long reserved[64]; /* for future use */
203}; 205};
204 206
205struct kvm_sregs { 207struct kvm_sregs {
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
832int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) 832int 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, &regs->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
899out: 887 return 0;
900 return r;
901} 888}
902 889
903long kvm_arch_vm_ioctl(struct file *filp, 890long kvm_arch_vm_ioctl(struct file *filp,
@@ -1378,9 +1365,9 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
1378 1365
1379int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) 1366int 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(&regs->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;
1435out:
1436 return r;
1437} 1417}
1438 1418
1439void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) 1419void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)