* KVM: pvmmu breakage with gcc 4.3.0 @ 2008-06-26 2:10 Marcelo Tosatti 2008-06-26 3:10 ` Anthony Liguori 2008-06-26 11:43 ` Avi Kivity 0 siblings, 2 replies; 13+ messages in thread From: Marcelo Tosatti @ 2008-06-26 2:10 UTC (permalink / raw) To: Avi Kivity, Anthony Liguori; +Cc: Alexandre Oliva, kvm-devel Some pvmmu functions store their commands on stack, and newer GCC versions conclude that these commands are unused. So stick an inline asm statement to convince the compiler otherwise. Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index 8b7a3cf..c892752 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c @@ -55,6 +55,12 @@ static void kvm_mmu_op(void *buffer, unsigned len) int r; unsigned long a1, a2; + /* + * GCC 4.3.0 concludes that on-stack kvm_mmu_op* is unused and + * optimizes its initialization away. + */ + asm ("" : : "p" (buffer)); + do { a1 = __pa(buffer); a2 = 0; /* on i386 __pa() always returns <4G */ ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: KVM: pvmmu breakage with gcc 4.3.0 2008-06-26 2:10 KVM: pvmmu breakage with gcc 4.3.0 Marcelo Tosatti @ 2008-06-26 3:10 ` Anthony Liguori 2008-06-26 13:18 ` Christian Borntraeger 2008-06-26 18:06 ` Alexandre Oliva 2008-06-26 11:43 ` Avi Kivity 1 sibling, 2 replies; 13+ messages in thread From: Anthony Liguori @ 2008-06-26 3:10 UTC (permalink / raw) To: Marcelo Tosatti; +Cc: Avi Kivity, Anthony Liguori, Alexandre Oliva, kvm-devel [-- Attachment #1: Type: text/plain, Size: 1269 bytes --] Marcelo Tosatti wrote: > Some pvmmu functions store their commands on stack, and newer GCC > versions conclude that these commands are unused. > > So stick an inline asm statement to convince the compiler otherwise. > I think a better fix is to add a "memory " clobber to the hypercalls. This isn't really a GCC bug since it doesn't realize that hypercalls can touch memory. See the attached patch. Avi: please push this for 2.6.26 if possible. Regards, Anthony Liguori > Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> > > > diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c > index 8b7a3cf..c892752 100644 > --- a/arch/x86/kernel/kvm.c > +++ b/arch/x86/kernel/kvm.c > @@ -55,6 +55,12 @@ static void kvm_mmu_op(void *buffer, unsigned len) > int r; > unsigned long a1, a2; > > + /* > + * GCC 4.3.0 concludes that on-stack kvm_mmu_op* is unused and > + * optimizes its initialization away. > + */ > + asm ("" : : "p" (buffer)); > + > do { > a1 = __pa(buffer); > a2 = 0; /* on i386 __pa() always returns <4G */ > -- > To unsubscribe from this list: send the line "unsubscribe kvm" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > [-- Attachment #2: hypercall-memory-clobber.patch --] [-- Type: application/mbox, Size: 1866 bytes --] ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: KVM: pvmmu breakage with gcc 4.3.0 2008-06-26 3:10 ` Anthony Liguori @ 2008-06-26 13:18 ` Christian Borntraeger 2008-06-26 18:06 ` Alexandre Oliva 1 sibling, 0 replies; 13+ messages in thread From: Christian Borntraeger @ 2008-06-26 13:18 UTC (permalink / raw) To: Anthony Liguori Cc: Marcelo Tosatti, Avi Kivity, Anthony Liguori, Alexandre Oliva, kvm-devel Am Donnerstag, 26. Juni 2008 schrieb Anthony Liguori: > Marcelo Tosatti wrote: > > Some pvmmu functions store their commands on stack, and newer GCC > > versions conclude that these commands are unused. > > > > So stick an inline asm statement to convince the compiler otherwise. > > > > I think a better fix is to add a "memory " clobber to the hypercalls. > This isn't really a GCC bug since it doesn't realize that hypercalls can > touch memory. Thats what we do on asm-s390/kvm_para.h. Our hypercalls do have a memory clobber. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: KVM: pvmmu breakage with gcc 4.3.0 2008-06-26 3:10 ` Anthony Liguori 2008-06-26 13:18 ` Christian Borntraeger @ 2008-06-26 18:06 ` Alexandre Oliva 2008-06-29 8:56 ` Avi Kivity 1 sibling, 1 reply; 13+ messages in thread From: Alexandre Oliva @ 2008-06-26 18:06 UTC (permalink / raw) To: Anthony Liguori; +Cc: Marcelo Tosatti, Avi Kivity, Anthony Liguori, kvm-devel On Jun 26, 2008, Anthony Liguori <anthony@codemonkey.ws> wrote: > I think a better fix is to add a "memory " clobber to the hypercalls. This should definitely be done, but I don't see that this is a sure way to get that initializers that are otherwise unreferenced to be stored in their locations. IOW, it appears to me that GCC might still decide to optimize them away, because it doesn't see that the values can be used. Now, Marcelo's patch appears to have been the result of a misunderstanding. I meant to tell him that a simpler "p" notation was *not* enough to make the problem go away. I thought a better approach was to have __pa do something along the lines of ({ char *__buf = (char*)buffer; asm ("" : : "o"(*__buf)); ... }) to make it clear that physical addresses are used. Anyhow, for now, it appears that a "memory" clobber is not only required for correct semantics, but also enough to fix the problem. Let's just hope GCC doesn't get too smart. -- Alexandre Oliva http://www.lsd.ic.unicamp.br/~oliva/ Free Software Evangelist oliva@{lsd.ic.unicamp.br, gnu.org} FSFLA Board Member ¡Sé Libre! => http://www.fsfla.org/ Red Hat Compiler Engineer aoliva@{redhat.com, gcc.gnu.org} ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: KVM: pvmmu breakage with gcc 4.3.0 2008-06-26 18:06 ` Alexandre Oliva @ 2008-06-29 8:56 ` Avi Kivity 0 siblings, 0 replies; 13+ messages in thread From: Avi Kivity @ 2008-06-29 8:56 UTC (permalink / raw) To: Alexandre Oliva Cc: Anthony Liguori, Marcelo Tosatti, Anthony Liguori, kvm-devel Alexandre Oliva wrote: > I thought a better approach > was to have __pa do something along the lines of > > ({ char *__buf = (char*)buffer; asm ("" : : "o"(*__buf)); ... }) > > to make it clear that physical addresses are used. > > I agree, I think such a patch is important for future-proofing Linux against increasing gcc optimization capabilities. -- error compiling committee.c: too many arguments to function ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: KVM: pvmmu breakage with gcc 4.3.0 2008-06-26 2:10 KVM: pvmmu breakage with gcc 4.3.0 Marcelo Tosatti 2008-06-26 3:10 ` Anthony Liguori @ 2008-06-26 11:43 ` Avi Kivity 2008-06-26 12:47 ` Anthony Liguori 2008-06-26 15:08 ` Christian Borntraeger 1 sibling, 2 replies; 13+ messages in thread From: Avi Kivity @ 2008-06-26 11:43 UTC (permalink / raw) To: Marcelo Tosatti; +Cc: Anthony Liguori, Alexandre Oliva, kvm-devel Marcelo Tosatti wrote: > Some pvmmu functions store their commands on stack, and newer GCC > versions conclude that these commands are unused. > > So stick an inline asm statement to convince the compiler otherwise. > > Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> > > > diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c > index 8b7a3cf..c892752 100644 > --- a/arch/x86/kernel/kvm.c > +++ b/arch/x86/kernel/kvm.c > @@ -55,6 +55,12 @@ static void kvm_mmu_op(void *buffer, unsigned len) > int r; > unsigned long a1, a2; > > + /* > + * GCC 4.3.0 concludes that on-stack kvm_mmu_op* is unused and > + * optimizes its initialization away. > + */ > + asm ("" : : "p" (buffer)); > + > I don't think "p" should force the contents into memory? Perhaps "m"(*(char *)buffer)? Anthony, I don't see why a memory clobber would tell gcc that the variables is actually used. The problem is with the void * -> unsigned long cast (__pa), once that happens gcc loses track. It's probably needed anyway since hypercalls _do_ clobber memory. -- Do not meddle in the internals of kernels, for they are subtle and quick to panic. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: KVM: pvmmu breakage with gcc 4.3.0 2008-06-26 11:43 ` Avi Kivity @ 2008-06-26 12:47 ` Anthony Liguori 2008-06-27 16:11 ` Bill Davidsen 2008-06-26 15:08 ` Christian Borntraeger 1 sibling, 1 reply; 13+ messages in thread From: Anthony Liguori @ 2008-06-26 12:47 UTC (permalink / raw) To: Avi Kivity; +Cc: Marcelo Tosatti, Anthony Liguori, Alexandre Oliva, kvm-devel Avi Kivity wrote: > Marcelo Tosatti wrote: >> Some pvmmu functions store their commands on stack, and newer GCC >> versions conclude that these commands are unused. >> >> So stick an inline asm statement to convince the compiler otherwise. >> >> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> >> >> >> diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c >> index 8b7a3cf..c892752 100644 >> --- a/arch/x86/kernel/kvm.c >> +++ b/arch/x86/kernel/kvm.c >> @@ -55,6 +55,12 @@ static void kvm_mmu_op(void *buffer, unsigned len) >> int r; >> unsigned long a1, a2; >> >> + /* >> + * GCC 4.3.0 concludes that on-stack kvm_mmu_op* is unused and >> + * optimizes its initialization away. >> + */ >> + asm ("" : : "p" (buffer)); >> + >> > > I don't think "p" should force the contents into memory? Perhaps > "m"(*(char *)buffer)? > > Anthony, I don't see why a memory clobber would tell gcc that the > variables is actually used. It doesn't, but it seems to me that it should force GCC to assume everything is live. It's a big stick to hit the problem with but it seems like the right thing semantically. > The problem is with the void * -> unsigned long cast (__pa), once > that happens gcc loses track. It's probably needed anyway since > hypercalls _do_ clobber memory. Right, it's not telling GCC that we touch a particular variable, but rather that we may have touched any variable. Regards, Anthony Liguori ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: KVM: pvmmu breakage with gcc 4.3.0 2008-06-26 12:47 ` Anthony Liguori @ 2008-06-27 16:11 ` Bill Davidsen 0 siblings, 0 replies; 13+ messages in thread From: Bill Davidsen @ 2008-06-27 16:11 UTC (permalink / raw) To: kvm Cc: Avi Kivity, Marcelo Tosatti, Anthony Liguori, Alexandre Oliva, kvm-devel Anthony Liguori wrote: > Avi Kivity wrote: >> Marcelo Tosatti wrote: >>> Some pvmmu functions store their commands on stack, and newer GCC >>> versions conclude that these commands are unused. >>> >>> So stick an inline asm statement to convince the compiler otherwise. >>> >>> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> >>> >>> >>> diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c >>> index 8b7a3cf..c892752 100644 >>> --- a/arch/x86/kernel/kvm.c >>> +++ b/arch/x86/kernel/kvm.c >>> @@ -55,6 +55,12 @@ static void kvm_mmu_op(void *buffer, unsigned len) >>> int r; >>> unsigned long a1, a2; >>> >>> + /* >>> + * GCC 4.3.0 concludes that on-stack kvm_mmu_op* is unused and >>> + * optimizes its initialization away. >>> + */ >>> + asm ("" : : "p" (buffer)); >>> + >>> >> >> I don't think "p" should force the contents into memory? Perhaps >> "m"(*(char *)buffer)? >> >> Anthony, I don't see why a memory clobber would tell gcc that the >> variables is actually used. > > It doesn't, but it seems to me that it should force GCC to assume > everything is live. It's a big stick to hit the problem with but it > seems like the right thing semantically. > In general the right stick to hit a compiler with is 'volatile,' which should tell the compiler that outside forces are in play. Without really digging into the code I don't want to suggest just where this should be used, but clearly Christian had the same thought. >> The problem is with the void * -> unsigned long cast (__pa), once >> that happens gcc loses track. It's probably needed anyway since >> hypercalls _do_ clobber memory. > > Right, it's not telling GCC that we touch a particular variable, but > rather that we may have touched any variable. > -- Bill Davidsen <davidsen@tmr.com> "We have more to fear from the bungling of the incompetent than from the machinations of the wicked." - from Slashdot ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: KVM: pvmmu breakage with gcc 4.3.0 2008-06-26 11:43 ` Avi Kivity 2008-06-26 12:47 ` Anthony Liguori @ 2008-06-26 15:08 ` Christian Borntraeger 2008-06-26 15:21 ` Anthony Liguori ` (2 more replies) 1 sibling, 3 replies; 13+ messages in thread From: Christian Borntraeger @ 2008-06-26 15:08 UTC (permalink / raw) To: Avi Kivity; +Cc: Marcelo Tosatti, Anthony Liguori, Alexandre Oliva, kvm-devel Am Donnerstag, 26. Juni 2008 schrieb Avi Kivity: > I don't think "p" should force the contents into memory? Perhaps > "m"(*(char *)buffer)? > > Anthony, I don't see why a memory clobber would tell gcc that the > variables is actually used. The problem is with the void * -> unsigned > long cast (__pa), once that happens gcc loses track. It's probably > needed anyway since hypercalls _do_ clobber memory. I I think about that again, the correct solution should be to use 2 input constraints for parameters together with the memory clobber on hypercall. I think something like the following covers all cases: static inline long kvm_hypercall1(unsigned int nr, unsigned long p1) { long ret; asm volatile(KVM_HYPERCALL : "=a"(ret) : "a"(nr), "b"(p1), "m"(*(char *) p1) : "memory" ); return ret; } The address and the memory content of p1 (if it is a pointer) is not ommitted by gcc. Furthermore, the memory clobbering nature of a hypercall is specified as well. Christian ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: KVM: pvmmu breakage with gcc 4.3.0 2008-06-26 15:08 ` Christian Borntraeger @ 2008-06-26 15:21 ` Anthony Liguori 2008-06-26 15:41 ` Anthony Liguori 2008-06-29 10:16 ` Avi Kivity 2 siblings, 0 replies; 13+ messages in thread From: Anthony Liguori @ 2008-06-26 15:21 UTC (permalink / raw) To: Christian Borntraeger Cc: Avi Kivity, Marcelo Tosatti, Alexandre Oliva, kvm-devel Christian Borntraeger wrote: > Am Donnerstag, 26. Juni 2008 schrieb Avi Kivity: > >> I don't think "p" should force the contents into memory? Perhaps >> "m"(*(char *)buffer)? >> >> Anthony, I don't see why a memory clobber would tell gcc that the >> variables is actually used. The problem is with the void * -> unsigned >> long cast (__pa), once that happens gcc loses track. It's probably >> needed anyway since hypercalls _do_ clobber memory. >> > > I I think about that again, the correct solution should be to use 2 input > constraints for parameters together with the memory clobber on hypercall. > > I think something like the following covers all cases: > > static inline long kvm_hypercall1(unsigned int nr, unsigned long p1) > { > long ret; > asm volatile(KVM_HYPERCALL > : "=a"(ret) > : "a"(nr), "b"(p1), "m"(*(char *) p1) > : "memory" ); > return ret; > } > > > The address and the memory content of p1 (if it is a pointer) is not ommitted > by gcc. Furthermore, the memory clobbering nature of a hypercall is specified > as well. > Isn't that redundant though? Shouldn't a memory clobber force GCC to assume that anything that's reachable is live? Regards, Anthony Liguori > Christian > ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: KVM: pvmmu breakage with gcc 4.3.0 2008-06-26 15:08 ` Christian Borntraeger 2008-06-26 15:21 ` Anthony Liguori @ 2008-06-26 15:41 ` Anthony Liguori 2008-06-26 16:34 ` Christian Borntraeger 2008-06-29 10:16 ` Avi Kivity 2 siblings, 1 reply; 13+ messages in thread From: Anthony Liguori @ 2008-06-26 15:41 UTC (permalink / raw) To: Christian Borntraeger Cc: Avi Kivity, Marcelo Tosatti, Anthony Liguori, Alexandre Oliva, kvm-devel Christian Borntraeger wrote: > Am Donnerstag, 26. Juni 2008 schrieb Avi Kivity: > >> I don't think "p" should force the contents into memory? Perhaps >> "m"(*(char *)buffer)? >> >> Anthony, I don't see why a memory clobber would tell gcc that the >> variables is actually used. The problem is with the void * -> unsigned >> long cast (__pa), once that happens gcc loses track. It's probably >> needed anyway since hypercalls _do_ clobber memory. >> > > I I think about that again, the correct solution should be to use 2 input > constraints for parameters together with the memory clobber on hypercall. > > I think something like the following covers all cases: > > static inline long kvm_hypercall1(unsigned int nr, unsigned long p1) > { > long ret; > asm volatile(KVM_HYPERCALL > : "=a"(ret) > : "a"(nr), "b"(p1), "m"(*(char *) p1) > : "memory" ); > return ret; > } > I don't know exactly what the rules are when you cast from pointer to unsigned long. What I'm concerned about is that if there are a few layers of indirection, GCC won't be able to propagate the liveness of the pointer p1. It has to be able to figure out that p1 here was really that point on the stack. From the perspective of being conservative, it certainly can't hurt, but I'm not sure it solves the problem by itself. This is why I think the "memory" constraint is really the right solution. That should force GCC to be very conservative about syncing everything to memory. Regards, Anthony Liguori > The address and the memory content of p1 (if it is a pointer) is not ommitted > by gcc. Furthermore, the memory clobbering nature of a hypercall is specified > as well. > > Christian > -- > To unsubscribe from this list: send the line "unsubscribe kvm" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: KVM: pvmmu breakage with gcc 4.3.0 2008-06-26 15:41 ` Anthony Liguori @ 2008-06-26 16:34 ` Christian Borntraeger 0 siblings, 0 replies; 13+ messages in thread From: Christian Borntraeger @ 2008-06-26 16:34 UTC (permalink / raw) To: Anthony Liguori Cc: Avi Kivity, Marcelo Tosatti, Anthony Liguori, Alexandre Oliva, kvm-devel Am Donnerstag, 26. Juni 2008 schrieb Anthony Liguori: > Christian Borntraeger wrote: > > Am Donnerstag, 26. Juni 2008 schrieb Avi Kivity: > > > >> I don't think "p" should force the contents into memory? Perhaps > >> "m"(*(char *)buffer)? > >> > >> Anthony, I don't see why a memory clobber would tell gcc that the > >> variables is actually used. The problem is with the void * -> unsigned > >> long cast (__pa), once that happens gcc loses track. It's probably > >> needed anyway since hypercalls _do_ clobber memory. > >> > > > > I I think about that again, the correct solution should be to use 2 input > > constraints for parameters together with the memory clobber on hypercall. > > > > I think something like the following covers all cases: > > > > static inline long kvm_hypercall1(unsigned int nr, unsigned long p1) > > { > > long ret; > > asm volatile(KVM_HYPERCALL > > : "=a"(ret) > > : "a"(nr), "b"(p1), "m"(*(char *) p1) > > : "memory" ); > > return ret; > > } > > > > I don't know exactly what the rules are when you cast from pointer to > unsigned long. What I'm concerned about is that if there are a few > layers of indirection, GCC won't be able to propagate the liveness of > the pointer p1. It has to be able to figure out that p1 here was really > that point on the stack. From the perspective of being conservative, it > certainly can't hurt, but I'm not sure it solves the problem by itself. > > This is why I think the "memory" constraint is really the right > solution. That should force GCC to be very conservative about syncing > everything to memory. The thing is, that your patch has "memory" in the clobber list. I dont know if clobber constraints give any guarantees about input constraints. Thats why I think that "b" plus "m" as input constraints are better. Does gcc actually accept "memory" as input contraint? I think I have to ask our compiler developers, but in 5 minutes I will be offline until monday... ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: KVM: pvmmu breakage with gcc 4.3.0 2008-06-26 15:08 ` Christian Borntraeger 2008-06-26 15:21 ` Anthony Liguori 2008-06-26 15:41 ` Anthony Liguori @ 2008-06-29 10:16 ` Avi Kivity 2 siblings, 0 replies; 13+ messages in thread From: Avi Kivity @ 2008-06-29 10:16 UTC (permalink / raw) To: Christian Borntraeger Cc: Marcelo Tosatti, Anthony Liguori, Alexandre Oliva, kvm-devel Christian Borntraeger wrote: > Am Donnerstag, 26. Juni 2008 schrieb Avi Kivity: > >> I don't think "p" should force the contents into memory? Perhaps >> "m"(*(char *)buffer)? >> >> Anthony, I don't see why a memory clobber would tell gcc that the >> variables is actually used. The problem is with the void * -> unsigned >> long cast (__pa), once that happens gcc loses track. It's probably >> needed anyway since hypercalls _do_ clobber memory. >> > > I I think about that again, the correct solution should be to use 2 input > constraints for parameters together with the memory clobber on hypercall. > > I think something like the following covers all cases: > > static inline long kvm_hypercall1(unsigned int nr, unsigned long p1) > { > long ret; > asm volatile(KVM_HYPERCALL > : "=a"(ret) > : "a"(nr), "b"(p1), "m"(*(char *) p1) > : "memory" ); > return ret; > } > > > The address and the memory content of p1 (if it is a pointer) is not ommitted > by gcc. Furthermore, the memory clobbering nature of a hypercall is specified > as well. > That only works if p1 is a virtual address. x86 (and ppc) hypercalls use physical addresses. -- error compiling committee.c: too many arguments to function ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2008-06-29 10:16 UTC | newest] Thread overview: 13+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-06-26 2:10 KVM: pvmmu breakage with gcc 4.3.0 Marcelo Tosatti 2008-06-26 3:10 ` Anthony Liguori 2008-06-26 13:18 ` Christian Borntraeger 2008-06-26 18:06 ` Alexandre Oliva 2008-06-29 8:56 ` Avi Kivity 2008-06-26 11:43 ` Avi Kivity 2008-06-26 12:47 ` Anthony Liguori 2008-06-27 16:11 ` Bill Davidsen 2008-06-26 15:08 ` Christian Borntraeger 2008-06-26 15:21 ` Anthony Liguori 2008-06-26 15:41 ` Anthony Liguori 2008-06-26 16:34 ` Christian Borntraeger 2008-06-29 10:16 ` Avi Kivity
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox