diff mbox

x86/kvmclock: set pvti_cpu0_va after enabling kvmclock

Message ID 20180621150645.GB8203@flask (mailing list archive)
State New, archived
Headers show

Commit Message

Radim Krčmář June 21, 2018, 3:06 p.m. UTC
2018-06-21 08:13-0400, mpagano@gentoo.org:
> From: Mike Pagano <mpagano@gentoo.org>
> 
> setup_vsyscall_timeinfo() is only defined for x86_64, thus
> clock_set_pvti_cpu0_va() does not get called resulting in
> the failure of ptp_kvm initialization for Linux X86_32 guests.
> The result of this being that the 32 bit guest userspace has
> no /dev/ptp0 device.
> 
> See Gentoo bug 658544 located at the following link:
> https://bugs.gentoo.org/658544
> 
> Signed-off-by: Mike Pagano <mpagano@gentoo.org>
> Signed-off-by: Andreas Steinmetz <ast@domdv.de>
> ---
>  arch/x86/kernel/kvmclock.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c
> index bf8d1eb7fca3..6aee5c6265b3 100644
> --- a/arch/x86/kernel/kvmclock.c
> +++ b/arch/x86/kernel/kvmclock.c
> @@ -350,7 +350,7 @@ void __init kvmclock_init(void)
>  
>  int __init kvm_setup_vsyscall_timeinfo(void)
>  {
> -#ifdef CONFIG_X86_64
> +#ifdef CONFIG_X86_64 || defined(CONFIG_X86_32)

The code should actually read "#if defined(...", or be omitted as we
have only these two x86 variants.  The correct variant might cause
unexpected bugs by enabling the vsyscall on 32 bit kernels.

Please check that the following patch fixes your problem as well,

thanks.

---8<---
pvti_cpu0_va is the address of shared kvmclock data structure.

pvti_cpu0_va is currently kept unset (1) on 32 bit systems, (2) when
kvmclock vsyscall is disabled, and (3) if kvmclock is not stable.
This poses a problem, because kvm_ptp needs pvti_cpu0_va, but (1) can
work on 32 bit, (2) has little relation to the vsyscall, and (3) does
not need stable kvmclock (although kvmclock won't be used for system
clock if it's not stable, so kvm_ptp is pointless in that case).

Expose pvti_cpu0_va whenever kvmclock is enabled to allow all users to
work with it.

This fixes a regression found on Gentoo: https://bugs.gentoo.org/658544.

Fixes: 9f08890ab906 ("x86/pvclock: add setter for pvclock_pvti_cpu0_va")
Reported-by: Andreas Steinmetz <ast@domdv.de>
Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
---
 arch/x86/kernel/kvmclock.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

Comments

Mike Pagano June 27, 2018, 2:02 p.m. UTC | #1
On Thu, Jun 21, 2018 at 05:06:48PM +0200, Radim Krčmář wrote:
> 2018-06-21 08:13-0400, mpagano@gentoo.org:
> > From: Mike Pagano <mpagano@gentoo.org>
> > 
> 
> Please check that the following patch fixes your problem as well,
> 
> thanks.
> 

Thank-you. Our user reports this patch as fixing his issue.
See: https://bugs.gentoo.org/show_bug.cgi?id=658544
Paolo Bonzini July 15, 2018, 3:44 p.m. UTC | #2
On 21/06/2018 17:06, Radim Krčmář wrote:
>> Signed-off-by: Andreas Steinmetz <ast@domdv.de>
>> ---
>>  arch/x86/kernel/kvmclock.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c
>> index bf8d1eb7fca3..6aee5c6265b3 100644
>> --- a/arch/x86/kernel/kvmclock.c
>> +++ b/arch/x86/kernel/kvmclock.c
>> @@ -350,7 +350,7 @@ void __init kvmclock_init(void)
>>  
>>  int __init kvm_setup_vsyscall_timeinfo(void)
>>  {
>> -#ifdef CONFIG_X86_64
>> +#ifdef CONFIG_X86_64 || defined(CONFIG_X86_32)
> 
> The code should actually read "#if defined(...", or be omitted as we
> have only these two x86 variants.  The correct variant might cause
> unexpected bugs by enabling the vsyscall on 32 bit kernels.
> 
> Please check that the following patch fixes your problem as well,
> 
> thanks.

Thanks Radim, I queued your patch.

Paolo

> ---8<---
> pvti_cpu0_va is the address of shared kvmclock data structure.
> 
> pvti_cpu0_va is currently kept unset (1) on 32 bit systems, (2) when
> kvmclock vsyscall is disabled, and (3) if kvmclock is not stable.
> This poses a problem, because kvm_ptp needs pvti_cpu0_va, but (1) can
> work on 32 bit, (2) has little relation to the vsyscall, and (3) does
> not need stable kvmclock (although kvmclock won't be used for system
> clock if it's not stable, so kvm_ptp is pointless in that case).
> 
> Expose pvti_cpu0_va whenever kvmclock is enabled to allow all users to
> work with it.
> 
> This fixes a regression found on Gentoo: https://bugs.gentoo.org/658544.
> 
> Fixes: 9f08890ab906 ("x86/pvclock: add setter for pvclock_pvti_cpu0_va")
> Reported-by: Andreas Steinmetz <ast@domdv.de>
> Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
> ---
>  arch/x86/kernel/kvmclock.c | 11 +++++------
>  1 file changed, 5 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c
> index bf8d1eb7fca3..46ffa8327563 100644
> --- a/arch/x86/kernel/kvmclock.c
> +++ b/arch/x86/kernel/kvmclock.c
> @@ -319,6 +319,8 @@ void __init kvmclock_init(void)
>  	printk(KERN_INFO "kvm-clock: Using msrs %x and %x",
>  		msr_kvm_system_time, msr_kvm_wall_clock);
>  
> +	pvclock_set_pvti_cpu0_va(hv_clock);
> +
>  	if (kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE_STABLE_BIT))
>  		pvclock_set_flags(PVCLOCK_TSC_STABLE_BIT);
>  
> @@ -366,14 +368,11 @@ int __init kvm_setup_vsyscall_timeinfo(void)
>  	vcpu_time = &hv_clock[cpu].pvti;
>  	flags = pvclock_read_flags(vcpu_time);
>  
> -	if (!(flags & PVCLOCK_TSC_STABLE_BIT)) {
> -		put_cpu();
> -		return 1;
> -	}
> -
> -	pvclock_set_pvti_cpu0_va(hv_clock);
>  	put_cpu();
>  
> +	if (!(flags & PVCLOCK_TSC_STABLE_BIT))
> +		return 1;
> +
>  	kvm_clock.archdata.vclock_mode = VCLOCK_PVCLOCK;
>  #endif
>  	return 0;
>
diff mbox

Patch

diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c
index bf8d1eb7fca3..46ffa8327563 100644
--- a/arch/x86/kernel/kvmclock.c
+++ b/arch/x86/kernel/kvmclock.c
@@ -319,6 +319,8 @@  void __init kvmclock_init(void)
 	printk(KERN_INFO "kvm-clock: Using msrs %x and %x",
 		msr_kvm_system_time, msr_kvm_wall_clock);
 
+	pvclock_set_pvti_cpu0_va(hv_clock);
+
 	if (kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE_STABLE_BIT))
 		pvclock_set_flags(PVCLOCK_TSC_STABLE_BIT);
 
@@ -366,14 +368,11 @@  int __init kvm_setup_vsyscall_timeinfo(void)
 	vcpu_time = &hv_clock[cpu].pvti;
 	flags = pvclock_read_flags(vcpu_time);
 
-	if (!(flags & PVCLOCK_TSC_STABLE_BIT)) {
-		put_cpu();
-		return 1;
-	}
-
-	pvclock_set_pvti_cpu0_va(hv_clock);
 	put_cpu();
 
+	if (!(flags & PVCLOCK_TSC_STABLE_BIT))
+		return 1;
+
 	kvm_clock.archdata.vclock_mode = VCLOCK_PVCLOCK;
 #endif
 	return 0;