* Why exported const value modified by another driver not updated in original driver
@ 2012-09-04 9:30 Manavendra Nath Manav
2012-09-04 10:28 ` Manavendra Nath Manav
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Manavendra Nath Manav @ 2012-09-04 9:30 UTC (permalink / raw)
To: kernelnewbies
Hi,
I have declared a static const int variable in one driver and exported
that variable symbol. In another driver i am modifying that variable.
The other driver prints the modified value but the original driver
retains the original value. When both virtual and physical addresses
of the variable as seen by both drivers are same, how is this even
possible. Is it a kernel bug?
[root at localhost bug]# uname -a
Linux localhost.localdomain 3.5.3 #3 SMP Mon Sep 3 21:52:12 IST 2012
i686 i686 i386 GNU/Linux
================================
[root at localhost bug]# cat driver.c
#include <linux/module.h>
static const int value = 123;
int init_module()
{
printk("Base driver (init): value = %d\n", value);
printk("Base driver (init): virtual address of value = %p\n", (void *)&value);
printk("Base driver (init): physical address of value = %p\n", (void
*)__pa(&value));
return 0;
}
void cleanup_module()
{
printk("Base driver (exit): value = %d\n", value);
printk("Base driver (exit): virtual address of value = %p\n", (void *)&value);
printk("Base driver (exit): physical address of value = %p\n", (void
*)__pa(&value));
}
EXPORT_SYMBOL(value);
==============================================
[root at localhost bug]# cat hacker.c
#include <linux/module.h>
extern int value;
int init_module()
{
value = 987;
printk("Hacker driver (init): value = %d\n", value);
printk("Hacker Base driver (init): virtual address of value = %p\n",
(void *)&value);
printk("Hacker Base driver (init): physical address of value = %p\n",
(void *)__pa(&value));
return 0;
}
void cleanup_module()
{
printk("Hacker driver (exit): value = %d\n", value);
printk("Hacker driver (exit): virtual address of value = %p\n",
(void *)&value);
printk("Hacker driver (exit): physical address of value = %p\n",
(void *)__pa(&value));
return;
}
=========================================
[root at localhost bug]# insmod driver.ko
Base driver (init): value = 123
Base driver (init): virtual address of value = f89d61c8
Base driver (init): physical address of value = 389d61c8
[root at localhost bug]# insmod hacker.ko
Hacker driver (init): value = 987
Hacker Base driver (init): virtual address of value = f89d61c8
Hacker Base driver (init): physical address of value = 389d61c8
[root at localhost bug]# rmmod hacker.ko
Hacker driver (exit): value = 987
Hacker driver (exit): virtual address of value = f89d61c8
Hacker driver (exit): physical address of value = 389d61c8
[root at localhost bug]# rmmod driver.ko
Base driver (exit): value = 123
Base driver (exit): virtual address of value = f89d61c8
Base driver (exit): physical address of value = 389d61c8
[root at localhost bug]# cat /proc/kallsyms | grep value
f89f91c8 R value [driver]
f89f9088 r __ksymtab_value [driver]
f89f91cc r __kstrtab_value [driver]
Interestingly, when i change the declaration of variable to "volatile"
in driver.c as "static const volatile int" then the driver.ko prints
modified value "987" during rmmod and the original value "123" is
lost. What is the difference between this and previous declaration?
Please forgive if you find this question silly?
--
Manavendra Nath Manav
^ permalink raw reply [flat|nested] 6+ messages in thread* Why exported const value modified by another driver not updated in original driver
2012-09-04 9:30 Why exported const value modified by another driver not updated in original driver Manavendra Nath Manav
@ 2012-09-04 10:28 ` Manavendra Nath Manav
[not found] ` <20120904103905.GA21953@jak-linux.org>
[not found] ` <20120904122544.GC19396@mwanda>
2012-09-04 10:46 ` Alan Cox
2012-09-04 12:06 ` Bernd Petrovitsch
2 siblings, 2 replies; 6+ messages in thread
From: Manavendra Nath Manav @ 2012-09-04 10:28 UTC (permalink / raw)
To: kernelnewbies
On Tue, Sep 4, 2012 at 3:00 PM, Manavendra Nath Manav
<mnm.kernel@gmail.com> wrote:
> Hi,
>
> I have declared a static const int variable in one driver and exported
> that variable symbol. In another driver i am modifying that variable.
> The other driver prints the modified value but the original driver
> retains the original value. When both virtual and physical addresses
> of the variable as seen by both drivers are same, how is this even
> possible. Is it a kernel bug?
>
> [root at localhost bug]# uname -a
> Linux localhost.localdomain 3.5.3 #3 SMP Mon Sep 3 21:52:12 IST 2012
> i686 i686 i386 GNU/Linux
>
> ================================
> [root at localhost bug]# cat driver.c
> #include <linux/module.h>
>
> static const int value = 123;
>
> int init_module()
> {
> printk("Base driver (init): value = %d\n", value);
> printk("Base driver (init): virtual address of value = %p\n", (void *)&value);
> printk("Base driver (init): physical address of value = %p\n", (void
> *)__pa(&value));
> return 0;
> }
>
> void cleanup_module()
> {
> printk("Base driver (exit): value = %d\n", value);
> printk("Base driver (exit): virtual address of value = %p\n", (void *)&value);
> printk("Base driver (exit): physical address of value = %p\n", (void
> *)__pa(&value));
> }
> EXPORT_SYMBOL(value);
>
> ==============================================
> [root at localhost bug]# cat hacker.c
> #include <linux/module.h>
>
> extern int value;
>
> int init_module()
> {
> value = 987;
> printk("Hacker driver (init): value = %d\n", value);
> printk("Hacker Base driver (init): virtual address of value = %p\n",
> (void *)&value);
> printk("Hacker Base driver (init): physical address of value = %p\n",
> (void *)__pa(&value));
> return 0;
> }
>
> void cleanup_module()
> {
> printk("Hacker driver (exit): value = %d\n", value);
> printk("Hacker driver (exit): virtual address of value = %p\n",
> (void *)&value);
> printk("Hacker driver (exit): physical address of value = %p\n",
> (void *)__pa(&value));
> return;
> }
>
> =========================================
> [root at localhost bug]# insmod driver.ko
> Base driver (init): value = 123
> Base driver (init): virtual address of value = f89d61c8
> Base driver (init): physical address of value = 389d61c8
>
> [root at localhost bug]# insmod hacker.ko
> Hacker driver (init): value = 987
> Hacker Base driver (init): virtual address of value = f89d61c8
> Hacker Base driver (init): physical address of value = 389d61c8
>
> [root at localhost bug]# rmmod hacker.ko
> Hacker driver (exit): value = 987
> Hacker driver (exit): virtual address of value = f89d61c8
> Hacker driver (exit): physical address of value = 389d61c8
>
> [root at localhost bug]# rmmod driver.ko
> Base driver (exit): value = 123
> Base driver (exit): virtual address of value = f89d61c8
> Base driver (exit): physical address of value = 389d61c8
>
> [root at localhost bug]# cat /proc/kallsyms | grep value
> f89f91c8 R value [driver]
> f89f9088 r __ksymtab_value [driver]
> f89f91cc r __kstrtab_value [driver]
>
> Interestingly, when i change the declaration of variable to "volatile"
> in driver.c as "static const volatile int" then the driver.ko prints
> modified value "987" during rmmod and the original value "123" is
> lost. What is the difference between this and previous declaration?
> Please forgive if you find this question silly?
> --
> Manavendra Nath Manav
Is the above a genuine kernel bug, or i am missing something out here. Pls help.
Thanks,
Manavendra Nath Manav
^ permalink raw reply [flat|nested] 6+ messages in thread* Why exported const value modified by another driver not updated in original driver
2012-09-04 9:30 Why exported const value modified by another driver not updated in original driver Manavendra Nath Manav
2012-09-04 10:28 ` Manavendra Nath Manav
@ 2012-09-04 10:46 ` Alan Cox
2012-09-04 12:06 ` Bernd Petrovitsch
2 siblings, 0 replies; 6+ messages in thread
From: Alan Cox @ 2012-09-04 10:46 UTC (permalink / raw)
To: kernelnewbies
On Tue, 4 Sep 2012 15:00:16 +0530
Manavendra Nath Manav <mnm.kernel@gmail.com> wrote:
> Hi,
>
> I have declared a static const int variable in one driver and exported
> that variable symbol. In another driver i am modifying that variable.
> The other driver prints the modified value but the original driver
> retains the original value. When both virtual and physical addresses
> of the variable as seen by both drivers are same, how is this even
> possible. Is it a kernel bug?
It's const, why is it even a surprise. If you don't understand what is
going on then I suggest you disassemble the code. That will I think let
you understand what is going on.
Alan
^ permalink raw reply [flat|nested] 6+ messages in thread
* Why exported const value modified by another driver not updated in original driver
2012-09-04 9:30 Why exported const value modified by another driver not updated in original driver Manavendra Nath Manav
2012-09-04 10:28 ` Manavendra Nath Manav
2012-09-04 10:46 ` Alan Cox
@ 2012-09-04 12:06 ` Bernd Petrovitsch
2 siblings, 0 replies; 6+ messages in thread
From: Bernd Petrovitsch @ 2012-09-04 12:06 UTC (permalink / raw)
To: kernelnewbies
Hi!
On Die, 2012-09-04 at 15:00 +0530, Manavendra Nath Manav wrote:
[....]
> I have declared a static const int variable in one driver and exported
> that variable symbol.
Exporting a "static" variable makes conceptually no sense whatsoever -
either you want it exported (so you should remove the "static") or you
want it not exported - which is precisely the definition of "static".
> retains the original value. When both virtual and physical addresses
> of the variable as seen by both drivers are same, how is this even
> possible. Is it a kernel bug?
It's a bug in your drivers.
The C compiler sees an initialized "static const" variable. So the C
compiler knows that it is not accessible from other compilation units
(because it is "static") and the variable isn't changing within the
current compilation unit (because the variable as such is "const" and
their is no non-const pointer to it or similar).
Since this is the only compilation unit, it knows that no one will/can
change it's value.
So the C compiler happily replaces all references to the variable with
it's value - just as if you would have #define'd that value.
Obviously, later on it is exported and the variable actually exists and
you can change it in the other file. But since the value has been
replaced literally by "123" at compile (more precise: optimizer time),
you don't see a change in the printk()s.
> Interestingly, when i change the declaration of variable to "volatile"
> in driver.c as "static const volatile int" then the driver.ko prints
> modified value "987" during rmmod and the original value "123" is
> lost. What is the difference between this and previous declaration?
"volatile" tells the C compiler that a variable may change it's value
without explicit code.
A typical use case are hardware registers which are changed by the
underlying hardware.
In user space, variables may be modified by signal handlers (which can
occur at any time in a program - unless specifcally blocked).
So the optimizer must not accesses to "volatile" variables because they
may change their value at any time.
> Please forgive if you find this question silly?
That all is actually pure (K&R-)C and has nothing to do with the kernel.
> static const int value = 123;
[...]
> EXPORT_SYMBOL(value);
I wonder if we can modify EXPORT_SYMBOL() so that it compile-time-fails
for "static" variables.
And if we actually want that.
Bernd
--
Bernd Petrovitsch Email : bernd at petrovitsch.priv.at
LUGA : http://www.luga.at
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2012-09-05 8:27 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-09-04 9:30 Why exported const value modified by another driver not updated in original driver Manavendra Nath Manav
2012-09-04 10:28 ` Manavendra Nath Manav
[not found] ` <20120904103905.GA21953@jak-linux.org>
2012-09-04 10:59 ` Manavendra Nath Manav
[not found] ` <20120904122544.GC19396@mwanda>
2012-09-05 8:27 ` Manavendra Nath Manav
2012-09-04 10:46 ` Alan Cox
2012-09-04 12:06 ` Bernd Petrovitsch
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).