| @@ -1142,6 +1142,7 @@ struct pvclock_gtod_data { · 1141 unmodified lines |
| 1142 | | 1142 | |
| 1143 | u64 boot_ns; | 1143 | u64 boot_ns; |
| 1144 | u64 nsec_base; | 1144 | u64 nsec_base; |
| | 1145 | u64 wall_time_sec; |
| 1145 | }; | 1146 | }; |
| 1146 | | 1147 | |
| 1147 | static struct pvclock_gtod_data pvclock_gtod_data; | 1148 | static struct pvclock_gtod_data pvclock_gtod_data; |
| @@ -1165,6 +1166,8 @@ static void update_pvclock_gtod(struct timekeeper *tk) · 17 unmodified lines |
| 1165 | vdata->boot_ns = boot_ns; | 1166 | vdata->boot_ns = boot_ns; |
| 1166 | vdata->nsec_base = tk->tkr_mono.xtime_nsec; | 1167 | vdata->nsec_base = tk->tkr_mono.xtime_nsec; |
| 1167 | | 1168 | |
| | 1169 | vdata->wall_time_sec = tk->xtime_sec; |
| | 1170 | |
| 1168 | write_seqcount_end(&vdata->seq); | 1171 | write_seqcount_end(&vdata->seq); |
| 1169 | } | 1172 | } |
| 1170 | #endif | 1173 | #endif |
| @@ -1626,6 +1629,28 @@ static int do_monotonic_boot(s64 *t, u64 *cycle_now) · 455 unmodified lines |
| 1626 | return mode; | 1629 | return mode; |
| 1627 | } | 1630 | } |
| 1628 | | 1631 | |
| | 1632 | static int do_realtime(struct timespec *ts, u64 *cycle_now) |
| | 1633 | { |
| | 1634 | struct pvclock_gtod_data *gtod = &pvclock_gtod_data; |
| | 1635 | unsigned long seq; |
| | 1636 | int mode; |
| | 1637 | u64 ns; |
| | 1638 | |
| | 1639 | do { |
| | 1640 | seq = read_seqcount_begin(>od->seq); |
| | 1641 | mode = gtod->clock.vclock_mode; |
| | 1642 | ts->tv_sec = gtod->wall_time_sec; |
| | 1643 | ns = gtod->nsec_base; |
| | 1644 | ns += vgettsc(cycle_now); |
| | 1645 | ns >>= gtod->clock.shift; |
| | 1646 | } while (unlikely(read_seqcount_retry(>od->seq, seq))); |
| | 1647 | |
| | 1648 | ts->tv_sec += __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns); |
| | 1649 | ts->tv_nsec = ns; |
| | 1650 | |
| | 1651 | return mode; |
| | 1652 | } |
| | 1653 | |
| 1629 | /* returns true if host is using tsc clocksource */ | 1654 | /* returns true if host is using tsc clocksource */ |
| 1630 | static bool kvm_get_time_and_clockread(s64 *kernel_ns, u64 *cycle_now) | 1655 | static bool kvm_get_time_and_clockread(s64 *kernel_ns, u64 *cycle_now) |
| 1631 | { | 1656 | { |
| @@ -1635,6 +1660,17 @@ static bool kvm_get_time_and_clockread(s64 *kernel_ns, u64 *cycle_now) · 3 unmodified lines |
| 1635 | | 1660 | |
| 1636 | return do_monotonic_boot(kernel_ns, cycle_now) == VCLOCK_TSC; | 1661 | return do_monotonic_boot(kernel_ns, cycle_now) == VCLOCK_TSC; |
| 1637 | } | 1662 | } |
| | 1663 | |
| | 1664 | /* returns true if host is using tsc clocksource */ |
| | 1665 | static bool kvm_get_walltime_and_clockread(struct timespec *ts, |
| | 1666 | u64 *cycle_now) |
| | 1667 | { |
| | 1668 | /* checked again under seqlock below */ |
| | 1669 | if (pvclock_gtod_data.clock.vclock_mode != VCLOCK_TSC) |
| | 1670 | return false; |
| | 1671 | |
| | 1672 | return do_realtime(ts, cycle_now) == VCLOCK_TSC; |
| | 1673 | } |
| 1638 | #endif | 1674 | #endif |
| 1639 | | 1675 | |
| 1640 | /* | 1676 | /* |
| @@ -6112,6 +6148,33 @@ int kvm_emulate_halt(struct kvm_vcpu *vcpu) · 4471 unmodified lines |
| 6112 | } | 6148 | } |
| 6113 | EXPORT_SYMBOL_GPL(kvm_emulate_halt); | 6149 | EXPORT_SYMBOL_GPL(kvm_emulate_halt); |
| 6114 | | 6150 | |
| | 6151 | static int kvm_pv_clock_pairing(struct kvm_vcpu *vcpu, gpa_t paddr, |
| | 6152 | unsigned long clock_type) |
| | 6153 | { |
| | 6154 | struct kvm_clock_pairing clock_pairing; |
| | 6155 | struct timespec ts; |
| | 6156 | cycle_t cycle; |
| | 6157 | int ret; |
| | 6158 | |
| | 6159 | if (clock_type != KVM_CLOCK_PAIRING_WALLCLOCK) |
| | 6160 | return -KVM_EOPNOTSUPP; |
| | 6161 | |
| | 6162 | if (kvm_get_walltime_and_clockread(&ts, &cycle) == false) |
| | 6163 | return -KVM_EOPNOTSUPP; |
| | 6164 | |
| | 6165 | clock_pairing.sec = ts.tv_sec; |
| | 6166 | clock_pairing.nsec = ts.tv_nsec; |
| | 6167 | clock_pairing.tsc = kvm_read_l1_tsc(vcpu, cycle); |
| | 6168 | clock_pairing.flags = 0; |
| | 6169 | |
| | 6170 | ret = 0; |
| | 6171 | if (kvm_write_guest(vcpu->kvm, paddr, &clock_pairing, |
| | 6172 | sizeof(struct kvm_clock_pairing))) |
| | 6173 | ret = -KVM_EFAULT; |
| | 6174 | |
| | 6175 | return ret; |
| | 6176 | } |
| | 6177 | |
| 6115 | /* | 6178 | /* |
| 6116 | * kvm_pv_kick_cpu_op: Kick a vcpu. | 6179 | * kvm_pv_kick_cpu_op: Kick a vcpu. |
| 6117 | * | 6180 | * |
| @@ -6176,6 +6239,9 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu) · 58 unmodified lines |
| 6176 | kvm_pv_kick_cpu_op(vcpu->kvm, a0, a1); | 6239 | kvm_pv_kick_cpu_op(vcpu->kvm, a0, a1); |
| 6177 | ret = 0; | 6240 | ret = 0; |
| 6178 | break; | 6241 | break; |
| | 6242 | case KVM_HC_CLOCK_PAIRING: |
| | 6243 | ret = kvm_pv_clock_pairing(vcpu, a0, a1); |
| | 6244 | break; |
| 6179 | default: | 6245 | default: |
| 6180 | ret = -KVM_ENOSYS; | 6246 | ret = -KVM_ENOSYS; |
| 6181 | break; | 6247 | break; |