How to check if given page is a ZERO_PAGE in a kernel module? - linux

I am writing a kernel module, where, inside a function I need to check if passed
struct page* maps to ZERO_PAGE or not.
I came up with following code to check the condition.
foo (struct page *pp, ..) {
if(pp == ZERO_PAGE(0)) {
//say, prefault the page.
}
}
When I try to compile this , I get following warning message:
WARNING: "phys_base" [<path_to_'.ko'] undefined!
when I try to 'insmod' the '.ko' , It gives error "Unknown symbol".and prints
"Unknown symbol phys_base" in log buffer.
My Makefile:
obj-m :=zero_page.o
KDIR=/lib/modules/`uname -r`/build
all:
make -C $(KDIR) M=`pwd` modules
The kernel version for which I am writing the module:
2.6.18-398.el5 (rhel 5.11)
I tried to find some other 'interfaces' inside kernel to check if page is ZERO_PAGE, but no luck.
Can some tell me how to get rid of this error.OR any other way to check this condition ?
NOTE: I came across this kernelnewbie thread which addressed the same issue. included <asm/pgtable.h> but no help.

I was able to come up with a fix for this.
After browsing some kernel code , I found out , for ZERO_PAGE address_space ptr is NULL.
Hence fix looks something like this :
if(page->mapping == NULL) {
// Its a ZERO_PAGE.
}
Thank you.

Related

Android Kernel - Unable to activate CONFIG_USB_ETH=y in the kernel dot config

I am trying to configure Android Kernel (msm-4.4)to have USB-CDC Ethernet Support in order to implement USB tethering in the low level. What I want to do is to migrate what's done in the following link to Android: https://developer.ridgerun.com/wiki/index.php/How_to_use_USB_device_networking
The following are already enabled in the .config:
CONFIG_USB=y
CONFIG_SND_USB=y
CONFIG_USB_SUPPORT=y
CONFIG_USB_GADGET=y
CONFIG_USB_CONFIGFS_UEVENT=y
However, when I add the following
CONFIG_USB_ETH=y
CONFIG_USB_ETH_EEM=y
Resulting .config has CONFIG_USB_CONFIGFS_UEVENT disabled:
CONFIG_USB_ETH=y
# CONFIG_USB_CONFIGFS_UEVENT is not set
which results in kernel compilation errors:
In function 'gadgets_make':
error: 'gadget_index' undeclared (first use in this function)
gadget_index++;
^
note: each undeclared identifier is reported only once for each function it appears in
In function 'gadgets_drop':
error: 'struct gadget_info' has no member named 'dev'
if (gi->dev) {
^
When I try to compile CONFIG_USB_ETH as a module, kernel compilation succeeds, but the resulting .config don't have it as enabled:
# CONFIG_USB_ETH is not set
I want to understand why something bizarre like this happens. I searched through the entire Android source code and couldn't find which triggers this blocking behavior.
Please have a look at the following Kconfigs if you require:
https://github.com/android-linux-stable/msm-4.4/blob/5a05099fd7feedfa07a75720669caf5f374810d4/drivers/usb/gadget/legacy/Kconfig
https://github.com/android-linux-stable/msm-4.4/blob/5a05099fd7feedfa07a75720669caf5f374810d4/drivers/usb/gadget/legacy/Kconfig
Any guidance to identify this problem is much appreciated.
You should use CONFIG_USB_NET_CDC_EEM=y instead of CONFIG_USB_ETH=y.
CONFIG_USB_ETH is not compatible with CONFIG_USB_CONFIGFS_UEVENT

Unable to add a custom system call on x86 ubuntu linux

I am new to this and just learning about the kernel, and I am trying to add a custom call to kernel 4.20.4. This is the steps that I did.
First I create the file (kernel/printmsg.c) that contains the code.
#include <linux/kernel.h>
#include <linux/syscalls.h>
SYSCALL_DEFINE1(printmsg, int, i)
{
printk(KERN_DEBUG, "TESTING %d", i);
return 1;
}
Next, I add this file to the kernel/Makefile
obj-y = fork.o exec_domain.o panic.o \
// A few more lines
obj-y += printmsg.o // I added this line
Finally, I add the system call to the syscall table on arch/x86/entry/syscalls/syscall_64.tbl(I'm building this on a 64-bit Ubuntu) by appending this line:
548 64 printmsg sys_printmsg
Now, I proceed to run make. However, it has this error:
arch/x86/entry/syscall_64.o:(.rodata+0x1120): undefined reference to `sys_printmsg'
Makefile:1034: recipe for target 'vmlinux' failed
make: *** [vmlinux] Error 1
I've been scratching my head for a long time for this but I can't seem to realised what went wrong.
Hope that anyone that managed to find a problem can help out a poor soul. Thanks in advance!
Okay, after hours of trial and error, I have finally found the problem. From linux kernel v4.17 onwards, x86_64 system calls may begin with "__x64_sys".
So, instead of using 548 64 printmsg sys_printmsg, I changed it to 548 64 printmsg __x64_sys_printmsg. Then everything works.
Hoped this helped everyone that might have this problem.

Error on dlclose: "shared objects still referenced"

I have the following error on a dlclose()'d .so: "Shared objects still referenced". I didn't find too much information about it. Did you have such a problem before? What kind of programming errors (or compiling options?) can cause this?
The only thing I tried is to find if MY module has successfully released all of the referenced shared objects, but all of them was ok as I see. At least hopefully. I could not really use LD_DEBUG yet.
(Posting re. discussion in the question's comments.)
The following might trigger that error/warning on QNX. We first need two shared libraries:
shared_needs.c
/* References a function defined elsewhere. */
void defined_elsewhere(void);
void f(void) {
defined_elsewhere();
}
shared_has.c
/* Has the function referenced above. */
void defined_elsewhere(void) {}
We compile them as follows (with sonames and other good practice omitted to keep things simple):
$ gcc -shared -fPIC shared_has.c -o shared_has.so
$ gcc -shared -fPIC shared_needs.c -o shared_needs.so
We now load/unload the libraries with the following code (loader.c),
#include <dlfcn.h>
#include <stdio.h>
int main(void) {
void *shared_has;
/* Pass RTLD_GLOBAL so that defined_elsewhere() becomes
available to libraries loaded later. */
shared_has = dlopen("shared_has.so", RTLD_NOW | RTLD_GLOBAL);
if (shared_has == NULL) {
fprintf(stderr, "%s\n", dlerror());
return 1;
}
/* shared_needs.so resolves defined_elsewhere() from
shared_has.so. */
if (dlopen("shared_needs.so", RTLD_NOW) == NULL) {
fprintf(stderr, "%s\n", dlerror());
return 1;
}
/* Might get warning here on QNX, since defined_elsewhere()
is still used. */
if (dlclose(shared_has) != 0) {
fprintf(stderr, "%s\n", dlerror());
return 1;
}
return 0;
}
, which we compile and run as follows:
$ gcc loader.c -ldl -o loader
$ LD_LIBRARY_PATH=. ./loader
The above might print the warning on QNX. It should be safe though (as it is on Linux), as the dlclose() man page on QNX says the following:
An object won't be removed from the address space until all references to that object (via dlopen() or dependencies from other objects) have been closed.
As a side note, you can run objdump -T shared_needs.so to see that shared_needs.so has an undefined reference to defined_elsewhere() (look for **UND**).
I can't find "Shared objects still referenced" error message in Linux or in opensource libraries. This message only mentioned in context of QNX.
This QT patch https://qt.gitorious.org/qt/qtbase/commit/4af257eb3cfeef93adefda5f981742ffb58ba0ad says that this error is informative and can be ignored
On QNX that's only "informative"
Shared objects still referenced" dlerror should actually be treated as "for your information" only, not as an actual error.
We can say more about error only with additional information:
debug logs (DL_DEBUG - http://www.qnx.com/developers/docs/6.5.0/topic/com.qnx.doc.neutrino_lib_ref/d/dlopen.html)
or the source of QNX recent dl libraries (QNX now is closed-source and there should be no source of it and its libs in the Internet; you should ask current QNX owners for support or sources licensing)

Error on building android-ndk-assets

I want load resources from c++ code. And try repeat this way. But when i try build it, i get:
E:\Android\Samples\android-ndk-assets\project>e:\Android\android-ndk-r8b\ndk-build
Gdbserver : [arm-linux-androideabi-4.6] libs/armeabi/gdbserver
Gdbsetup : libs/armeabi/gdb.setup
"Compile thumb : png <= pngrtran.c
jni/libpng/pngrtran.c: In function 'png_do_expand':
jni/libpng/pngrtran.c:3790:1: internal compiler error: in reload, at reload1.c:1061
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.
make: *** [obj/local/armeabi/objs-debug/png/pngrtran.o] Error 1
I just ran into this problem as well. Another workaround is to build the library as ARM code instead of Thumb code by adding the following line to your makefile:
LOCAL_ARM_MODE := arm
There should be no problem using ARM mode... ARM instructions require twice the space of Thumb instructions but are also much more sophisticated and capable of accomplishing a lot more in a single instruction, so depending on the cleverness of the compiler the resultant code may be bigger or smaller as well as more efficient or less efficient, but should execute with the same results.
I had the same error in android-ndk-r8b.
Looks like the bug in GCC. Do you submit bug report already?
I found the code which make error:
if (*(sp - 5) == red_high &&
*(sp - 4) == red_low &&
*(sp - 3) == green_high && //this line make error
*(sp - 2) == green_low && //this line make error
*(sp - 1) == blue_high &&
*(sp ) == blue_low)
{
*dp-- = 0;
*dp-- = 0;
}
I have a similar error in android-ndk-r8b as well. It occurs when calling ndk-build with the NDK_DEBUG flag set:
ndk-build NDK_DEBUG=1 <--- error
Try setting the NDK_BUILD flag to 0. It should compile. Of course it won't be debuggable :(
ndk-build NDK_DEBUG=0 <--- no error

What directory should I use for "error: 'extra_PROGRAMS' is used but 'extradir' is undefined"?

I have a autoconf/automake system that has a stand-alone target called stand. I don't want stand to be normally built, so I have this in my Makefile.am:
bin_PROGRAMS = grace
extra_PROGRAMS = stand
...
stand_SOURCES = stand.cpp barry.cpp ...
This has worked for a while, but automake just got updated on my system and I'm now getting this error:
src/Makefile.am:4: error: 'extra_PROGRAMS' is used but 'extradir' is undefined
src/Makefile.am:66: warning: variable 'stand_SOURCES' is defined but no program or
src/Makefile.am:66: library has 'stand' as canonical name (possible typo)
So I added this:
extradir = .
But that has caused problems.
I don't want the stand program installed. It's just a test program for me. But it's not part of a formal test suite, it's just for my own purposes. What should I do?
We found the bug! It turns out that extra needs to be capitalized, like this:
bin_PROGRAMS = grace
EXTRA_PROGRAMS = stand
...
stand_SOURCES = stand.cpp barry.cpp ...
You could try conditionally building it:
noinst_PROGRAMS=
if BUILD_STAND
noinst_PROGRAMS += stand
endif
stand_SOURCES = stand.cpp barry.cpp ...
This will not install it since it's in noinst_PROGRAMS and others will normally not build it since BUILD_STAND will normally not be defined for them.

Resources