lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <B22E6B1E-9569-4267-87E0-F442B86A49A8@zytor.com>
Date: Tue, 22 Jul 2025 09:53:21 -0700
From: "H. Peter Anvin" <hpa@...or.com>
To: David Laight <david.laight.linux@...il.com>,
        Oleg Nesterov <oleg@...hat.com>
CC: Ingo Molnar <mingo@...hat.com>, Peter Zijlstra <peterz@...radead.org>,
        Thomas Gleixner <tglx@...utronix.de>, Borislav Petkov <bp@...en8.de>,
        Dave Hansen <dave.hansen@...ux.intel.com>,
        "Li,Rongqing" <lirongqing@...du.com>,
        Steven Rostedt <rostedt@...dmis.org>, linux-kernel@...r.kernel.org,
        x86@...nel.org
Subject: Re: [PATCH] x86/math64: handle #DE in mul_u64_u64_div_u64()

On July 22, 2025 5:09:47 AM PDT, David Laight <david.laight.linux@...il.com> wrote:
>On Tue, 22 Jul 2025 12:50:35 +0200
>Oleg Nesterov <oleg@...hat.com> wrote:
>
>> On 07/21, David Laight wrote:
>> >
>> > On Mon, 21 Jul 2025 15:04:22 +0200
>> > Oleg Nesterov <oleg@...hat.com> wrote:
>> >  
>> > > Change mul_u64_u64_div_u64() to return ULONG_MAX if the result doesn't
>> > > fit u64, this matches the generic implementation in lib/math/div64.c.  
>> >
>> > Not quite, the generic version is likely to trap on divide by zero.  
>> 
>> I meant that the generic implementation returns -1ul too if the result
>> doesn't fit into u64.
>> 
>> > I think it would be better to always trap (eg BUG_ON(!div)).  
>> 
>> Well, I don't like adding a BUG_ON(), but OK.
>> 
>> > The trouble there is that (an ignored) ~(u64)0 is likely to cause another
>> > arithmetic overflow with even more consequences.
>> >
>> > So I'm not at all sure what it should look like or whether 0 is a better
>> > error return (esp for div == 0).  
>> 
>> I'm not sure either but x86/generic versions should be consistent. Let's
>> discuss this and possibly change both implementations later?
>
>My thought as well.
>Getting both to agree is a start.
>
>My latest thought is to add another parameter for the return value
>when the result overflows or is infinity/NaN.
>So the calling code can get 0, 1, ~0 (or any other 'safe' value) returned.
>A special 'magic' value could be used to mean BUG().
>
>> 
>> > >  static inline u64 mul_u64_u64_div_u64(u64 a, u64 mul, u64 div)
>> > >  {
>> > > +	int ok = 0;
>> > >  	u64 q;
>> > >
>> > > -	asm ("mulq %2; divq %3" : "=a" (q)
>> > > -				: "a" (a), "rm" (mul), "rm" (div)
>> > > -				: "rdx");
>> > > +	asm ("mulq %3; 1: divq %4; movl $1,%1; 2:\n"  
>> >
>> > The "movl $1,%1" is a 5 byte instruction.
>> > Better to use either 'incl' or get the constraints right for 'movb'  
>> 
>> Agreed, thanks,
>> 
>> > > +	if (ok)
>> > > +		return q;
>> > > +	WARN_ON_ONCE(!div);  
>> >
>> > I think you need to WARN for overflow as well as divide by zero.  
>> 
>> The generic implementation doesn't WARN... OK, I won't argue.
>
>I've a set of patches I need to do a new version of.
>I'll add a WARN_ON_ONCE() to the generic version.
>I'll also put a copy of this patch in my set so that the later patches
>will apply after this is applied without too much hastle.
>
>> How about
>> 
>> 	static inline u64 mul_u64_u64_div_u64(u64 a, u64 mul, u64 div)
>> 	{
>> 		char ok = 0;
>> 		u64 q;
>> 
>> 		asm ("mulq %3; 1: divq %4; movb $1,%1; 2:\n"
>> 			_ASM_EXTABLE(1b, 2b)
>> 			: "=a" (q), "+r" (ok)
>
>That needs to be "+q" (ok)
>
>> 			: "a" (a), "rm" (mul), "rm" (div)
>> 			: "rdx");
>> 
>> 		if (ok)
>> 			return q;
>> 		BUG_ON(!div);
>> 		WARN_ON_ONCE(1);
>
>I know there are are a lot of WARN_ON_ONCE(1) out there,
>but maybe WARN_ON_ONCE("muldiv overflow") would be better?
>(The linker will merge the strings).
>
>	David
>
>> 		return ~(u64)0;
>> 	}
>> 
>> ?
>> 
>> Oleg.
>> 
>

Note that -1 for division by zero (not necessarily for overflow) follows from most natural division algorithms, and so architectures which don't trap on division overflow tend to behave that way.

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ