aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Hildenbrand <dahi@linux.vnet.ibm.com>2016-02-15 03:40:12 -0500
committerChristian Borntraeger <borntraeger@de.ibm.com>2016-03-08 07:57:52 -0500
commit4287f247f6cfaea0ed73b5104e94cd737e1ac0ae (patch)
tree9a5859846ffe67c80946b70d7fc956f6d5fea481
parent01a745ac8b6c5d323a37194c242f7c77f3402469 (diff)
KVM: s390: abstract access to the VCPU cpu timer
We want to manually step the cpu timer in certain scenarios in the future. Let's abstract any access to the cpu timer, so we can hide the complexity internally. Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
-rw-r--r--arch/s390/kvm/interrupt.c5
-rw-r--r--arch/s390/kvm/kvm-s390.c31
-rw-r--r--arch/s390/kvm/kvm-s390.h2
3 files changed, 28 insertions, 10 deletions
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index 87e2d1a89d74..4604e9accc65 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -182,8 +182,9 @@ static int cpu_timer_interrupts_enabled(struct kvm_vcpu *vcpu)
182 182
183static int cpu_timer_irq_pending(struct kvm_vcpu *vcpu) 183static int cpu_timer_irq_pending(struct kvm_vcpu *vcpu)
184{ 184{
185 return (vcpu->arch.sie_block->cputm >> 63) && 185 if (!cpu_timer_interrupts_enabled(vcpu))
186 cpu_timer_interrupts_enabled(vcpu); 186 return 0;
187 return kvm_s390_get_cpu_timer(vcpu) >> 63;
187} 188}
188 189
189static inline int is_ioirq(unsigned long irq_type) 190static inline int is_ioirq(unsigned long irq_type)
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index bd5edb138479..2118a2250ac7 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -1429,6 +1429,18 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
1429 return 0; 1429 return 0;
1430} 1430}
1431 1431
1432/* set the cpu timer - may only be called from the VCPU thread itself */
1433void kvm_s390_set_cpu_timer(struct kvm_vcpu *vcpu, __u64 cputm)
1434{
1435 vcpu->arch.sie_block->cputm = cputm;
1436}
1437
1438/* get the cpu timer - can also be called from other VCPU threads */
1439__u64 kvm_s390_get_cpu_timer(struct kvm_vcpu *vcpu)
1440{
1441 return vcpu->arch.sie_block->cputm;
1442}
1443
1432void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) 1444void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
1433{ 1445{
1434 /* Save host register state */ 1446 /* Save host register state */
@@ -1476,7 +1488,7 @@ static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu)
1476 vcpu->arch.sie_block->gpsw.mask = 0UL; 1488 vcpu->arch.sie_block->gpsw.mask = 0UL;
1477 vcpu->arch.sie_block->gpsw.addr = 0UL; 1489 vcpu->arch.sie_block->gpsw.addr = 0UL;
1478 kvm_s390_set_prefix(vcpu, 0); 1490 kvm_s390_set_prefix(vcpu, 0);
1479 vcpu->arch.sie_block->cputm = 0UL; 1491 kvm_s390_set_cpu_timer(vcpu, 0);
1480 vcpu->arch.sie_block->ckc = 0UL; 1492 vcpu->arch.sie_block->ckc = 0UL;
1481 vcpu->arch.sie_block->todpr = 0; 1493 vcpu->arch.sie_block->todpr = 0;
1482 memset(vcpu->arch.sie_block->gcr, 0, 16 * sizeof(__u64)); 1494 memset(vcpu->arch.sie_block->gcr, 0, 16 * sizeof(__u64));
@@ -1723,7 +1735,7 @@ static int kvm_arch_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu,
1723 (u64 __user *)reg->addr); 1735 (u64 __user *)reg->addr);
1724 break; 1736 break;
1725 case KVM_REG_S390_CPU_TIMER: 1737 case KVM_REG_S390_CPU_TIMER:
1726 r = put_user(vcpu->arch.sie_block->cputm, 1738 r = put_user(kvm_s390_get_cpu_timer(vcpu),
1727 (u64 __user *)reg->addr); 1739 (u64 __user *)reg->addr);
1728 break; 1740 break;
1729 case KVM_REG_S390_CLOCK_COMP: 1741 case KVM_REG_S390_CLOCK_COMP:
@@ -1761,6 +1773,7 @@ static int kvm_arch_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu,
1761 struct kvm_one_reg *reg) 1773 struct kvm_one_reg *reg)
1762{ 1774{
1763 int r = -EINVAL; 1775 int r = -EINVAL;
1776 __u64 val;
1764 1777
1765 switch (reg->id) { 1778 switch (reg->id) {
1766 case KVM_REG_S390_TODPR: 1779 case KVM_REG_S390_TODPR:
@@ -1772,8 +1785,9 @@ static int kvm_arch_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu,
1772 (u64 __user *)reg->addr); 1785 (u64 __user *)reg->addr);
1773 break; 1786 break;
1774 case KVM_REG_S390_CPU_TIMER: 1787 case KVM_REG_S390_CPU_TIMER:
1775 r = get_user(vcpu->arch.sie_block->cputm, 1788 r = get_user(val, (u64 __user *)reg->addr);
1776 (u64 __user *)reg->addr); 1789 if (!r)
1790 kvm_s390_set_cpu_timer(vcpu, val);
1777 break; 1791 break;
1778 case KVM_REG_S390_CLOCK_COMP: 1792 case KVM_REG_S390_CLOCK_COMP:
1779 r = get_user(vcpu->arch.sie_block->ckc, 1793 r = get_user(vcpu->arch.sie_block->ckc,
@@ -2290,7 +2304,7 @@ static void sync_regs(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
2290 kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu); 2304 kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu);
2291 } 2305 }
2292 if (kvm_run->kvm_dirty_regs & KVM_SYNC_ARCH0) { 2306 if (kvm_run->kvm_dirty_regs & KVM_SYNC_ARCH0) {
2293 vcpu->arch.sie_block->cputm = kvm_run->s.regs.cputm; 2307 kvm_s390_set_cpu_timer(vcpu, kvm_run->s.regs.cputm);
2294 vcpu->arch.sie_block->ckc = kvm_run->s.regs.ckc; 2308 vcpu->arch.sie_block->ckc = kvm_run->s.regs.ckc;
2295 vcpu->arch.sie_block->todpr = kvm_run->s.regs.todpr; 2309 vcpu->arch.sie_block->todpr = kvm_run->s.regs.todpr;
2296 vcpu->arch.sie_block->pp = kvm_run->s.regs.pp; 2310 vcpu->arch.sie_block->pp = kvm_run->s.regs.pp;
@@ -2312,7 +2326,7 @@ static void store_regs(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
2312 kvm_run->psw_addr = vcpu->arch.sie_block->gpsw.addr; 2326 kvm_run->psw_addr = vcpu->arch.sie_block->gpsw.addr;
2313 kvm_run->s.regs.prefix = kvm_s390_get_prefix(vcpu); 2327 kvm_run->s.regs.prefix = kvm_s390_get_prefix(vcpu);
2314 memcpy(&kvm_run->s.regs.crs, &vcpu->arch.sie_block->gcr, 128); 2328 memcpy(&kvm_run->s.regs.crs, &vcpu->arch.sie_block->gcr, 128);
2315 kvm_run->s.regs.cputm = vcpu->arch.sie_block->cputm; 2329 kvm_run->s.regs.cputm = kvm_s390_get_cpu_timer(vcpu);
2316 kvm_run->s.regs.ckc = vcpu->arch.sie_block->ckc; 2330 kvm_run->s.regs.ckc = vcpu->arch.sie_block->ckc;
2317 kvm_run->s.regs.todpr = vcpu->arch.sie_block->todpr; 2331 kvm_run->s.regs.todpr = vcpu->arch.sie_block->todpr;
2318 kvm_run->s.regs.pp = vcpu->arch.sie_block->pp; 2332 kvm_run->s.regs.pp = vcpu->arch.sie_block->pp;
@@ -2383,7 +2397,7 @@ int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long gpa)
2383 unsigned char archmode = 1; 2397 unsigned char archmode = 1;
2384 freg_t fprs[NUM_FPRS]; 2398 freg_t fprs[NUM_FPRS];
2385 unsigned int px; 2399 unsigned int px;
2386 u64 clkcomp; 2400 u64 clkcomp, cputm;
2387 int rc; 2401 int rc;
2388 2402
2389 px = kvm_s390_get_prefix(vcpu); 2403 px = kvm_s390_get_prefix(vcpu);
@@ -2417,8 +2431,9 @@ int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long gpa)
2417 &vcpu->run->s.regs.fpc, 4); 2431 &vcpu->run->s.regs.fpc, 4);
2418 rc |= write_guest_abs(vcpu, gpa + __LC_TOD_PROGREG_SAVE_AREA, 2432 rc |= write_guest_abs(vcpu, gpa + __LC_TOD_PROGREG_SAVE_AREA,
2419 &vcpu->arch.sie_block->todpr, 4); 2433 &vcpu->arch.sie_block->todpr, 4);
2434 cputm = kvm_s390_get_cpu_timer(vcpu);
2420 rc |= write_guest_abs(vcpu, gpa + __LC_CPU_TIMER_SAVE_AREA, 2435 rc |= write_guest_abs(vcpu, gpa + __LC_CPU_TIMER_SAVE_AREA,
2421 &vcpu->arch.sie_block->cputm, 8); 2436 &cputm, 8);
2422 clkcomp = vcpu->arch.sie_block->ckc >> 8; 2437 clkcomp = vcpu->arch.sie_block->ckc >> 8;
2423 rc |= write_guest_abs(vcpu, gpa + __LC_CLOCK_COMP_SAVE_AREA, 2438 rc |= write_guest_abs(vcpu, gpa + __LC_CLOCK_COMP_SAVE_AREA,
2424 &clkcomp, 8); 2439 &clkcomp, 8);
diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h
index 1c756c7dd0c2..9787299d9a29 100644
--- a/arch/s390/kvm/kvm-s390.h
+++ b/arch/s390/kvm/kvm-s390.h
@@ -263,6 +263,8 @@ int kvm_s390_vcpu_setup_cmma(struct kvm_vcpu *vcpu);
263void kvm_s390_vcpu_unsetup_cmma(struct kvm_vcpu *vcpu); 263void kvm_s390_vcpu_unsetup_cmma(struct kvm_vcpu *vcpu);
264unsigned long kvm_s390_fac_list_mask_size(void); 264unsigned long kvm_s390_fac_list_mask_size(void);
265extern unsigned long kvm_s390_fac_list_mask[]; 265extern unsigned long kvm_s390_fac_list_mask[];
266void kvm_s390_set_cpu_timer(struct kvm_vcpu *vcpu, __u64 cputm);
267__u64 kvm_s390_get_cpu_timer(struct kvm_vcpu *vcpu);
266 268
267/* implemented in diag.c */ 269/* implemented in diag.c */
268int kvm_s390_handle_diag(struct kvm_vcpu *vcpu); 270int kvm_s390_handle_diag(struct kvm_vcpu *vcpu);