system_call value is different each time when I use rdmsrl(MSR_LSTAR, system_call) - linux

I'm writing a lkm to get sys_call_table address and I'm trying to get it by IDT (I have tested other methods and they work). The problem is that when I use rdmsrl to get register MSR_LSTAR, it's different each time.
I have tried function rdmsrl (MSR_LSTAR) and asm sentences in Ubuntu 18.04.1 with kernel 4.15.0-51.
asm("rdmsr" : "=a" (low), "=d" (high) : "c" (IA32_LSTAR));
system_call = (void*)(((long)high<<32) | low);
printk(KERN_INFO "system_call: 0x%llx", system_call);
rdmsrl(MSR_LSTAR, sct_off);
printk("sct_off: %016llx\n", sct_off);
The result is as follows:
system_call: 0xfffffe0000006000
system_call: 0xfffffe000008a000
system_call: 0xfffffe0000032000

Do you have CONFIG_RETPOLINE=y enabled? (check via cat /usr/src/`uname -r`/.config | grep RETPOLINE). If so, for CPUs where Kernel Page Table Isolation is enabled MSR_LSTAR holds the trampoline per-cpu entry SYSCALL64_entry_trampoline instead of the standard entry_SYSCALL_64 for your kernel version.

Related

Linux kernel does not see all components on my at91sam9g20 board

I am working with a Stamp9g20 embedded chip. It is based on the Atmel at91sam9g20 platform. For a client I need to upgrade the kernel to a newer version. After a bit of research, I landed on the Linux4SAM pages and their additional yocto layer, complete with a 4.14 kernel!
However, when I compile that kernel, I don't see all of my devices, for example, I can write onto the NAND memory and mount an USB device, but I cannot see nor mount any mmc/mci devices. I have tried checking how the Stamp9g20 really differs from the AT91SAM9G20EK, but I couldn't find a definitive clue to an answer there.
The Linux4SAM repo supports slightly different versions of the AT91SAM9 family, but I got it working for the 4.14 kernel, using the at91sam9g20ek.dts as an input for the board. Had to add my machine to the compatible machine list, so it will compile for the 9g20 versions as well.
COMPATIBLE_MACHINE += 'at91sam9g20ek'
and my machine.conf looks like:
##Name: ATMEL AT91SAM9G20EK
##DESCRIPTION: Machine configuration for Atmel's evaluation board
#
# define SOC_FAMILY (we are the family of ...)
SOC_FAMILY = "atsam9"
# Add arm926ejs to the DEFAULTTUNE, so it will be selected in our environment
DEFAULTTUNE = "arm926ejs"
# http://lists.openembedded.org/pipermail/openembedded-core/2019-January/277527.html
#TUNE_CCARGS .= "${#bb.utils.contains('TUNE_FEATURES', 'armv5', ' -march=armv5t${ARMPKGSFX_DSP}', '', d)}"
TUNE_CCARGS = "${#bb.utils.contains('TUNE_FEATURES', 'armv5', ' -march=armv5t${ARMPKGSFX_DSP}', '', d)}"
# We rely on the generic meta-atmel layer
require conf/machine/include/at91sam9.inc
MACHINE_FEATURES = "apm ext2 ext3 ext4 usbhost usbgadget vfat jffs2"
# This device tree is available in the kernel
KERNEL_DEVICETREE = " \
at91sam9g20ek.dtb \
"
# Create filesystems tar.gz and jffs2
IMAGE_FSTYPES += " tar.gz jffs2 tar"
# UNTESTED IMAGES (both bootstrap and uboot)
UBOOT_MACHINE ?= "at91sam9g20ek_nandflash_defconfig"
UBOOT_ENTRYPOINT = "0x20008000"
UBOOT_LOADADDRESS = "0x20008000"
AT91BOOTSTRAP_MACHINE ?= "at91sam9g20ek"
When the kernel launches, it shows that it registers a device driver onto the address 0xffff8000, but it doesn't see a block device.
bus: 'mmc': add driver mmcblk
bus: 'sdio': add driver sdio_uart
bus: 'platform': add driver atmel_mci
bus: 'platform': driver_probe_device: matched device fffa8000.mmc with driver atmel_mci
bus: 'platform': really_probe: probing driver atmel_mci with device fffa8000.mmc
atmel_mci fffa8000.mmc: no init pinctrl state
atmel_mci fffa8000.mmc: version: 0x210
atmel_mci fffa8000.mmc: using PDC
device: 'mmc0': device_add
atmel_mci fffa8000.mmc: Atmel MCI controller at 0xfffa8000 irq 30, 1 slots
driver: 'atmel_mci': driver_bound: bound to device 'fffa8000.mmc'
bus: 'platform': really_probe: bound device fffa8000.mmc to driver atmel_mci
I have tried this board with the 2.6.x version where it works as expected.
How can I make the block device mmcblk available in the system? Do I need to change the .dts (currently I am using the at91sam9g20ek.dts as a template with a minor change to the NAND memory). Or what can I do to get more information as to why the kernel doesn't interact with the mmc device?
Also, if I compare the source code from before the dts structure, I don't see significant differences in the mcc part of the code:
https://elixir.bootlin.com/linux/v3.6.9/source/arch/arm/mach-at91/board-sam9g20ek.c
https://elixir.bootlin.com/linux/v3.6.9/source/arch/arm/mach-at91/board-stamp9g20.c
The only difference I found,
at91sam9g20ek board:
.slot_b = 1, /* Only one slot so use slot B */
stamp9g20 board:
.slot_b = 0,
so I tried changing the reg<> property in the dts to 1, but to no avail...
Found it! All I had to do was change the mmc slot (was 1) in the dts to slot 0:
--- a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
+++ b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi
## -39,8 +39,8 ##
};
- mmc0_slot1 {
- pinctrl_board_mmc0_slot1: mmc0_slot1-board {
+ mmc0_slot0 {
+ pinctrl_board_mmc0_slot0: mmc0_slot0-board {
atmel,pins =
<AT91_PIOC 9 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; /* PC9 gpio CD pin pull up and deglitch */
};
## -90,15 +90,14 ##
mmc0: mmc#fffa8000 {
pinctrl-0 = <
- &pinctrl_board_mmc0_slot1
+ &pinctrl_board_mmc0_slot0
&pinctrl_mmc0_clk
- &pinctrl_mmc0_slot1_cmd_dat0
- &pinctrl_mmc0_slot1_dat1_3>;
+ &pinctrl_mmc0_slot0_cmd_dat0
+ &pinctrl_mmc0_slot0_dat1_3>;
status = "okay";
- slot#1 {
- reg = <1>;
+ slot#0 {
+ reg = <0>;
bus-width = <4>;
- cd-gpios = <&pioC 9 GPIO_ACTIVE_HIGH>;
};
};

Pin Muxing in linux kernel

I want to do following pin muxing.
i.e USART Tx -> to GPIO -> Back to USART Tx pin inside Linux kernel for some purpose.
I tried to make the PIN as GPIO using gpio_request and gpio_direction_output, so i am able to make that pin as GPIO . But as i want to switch back from GPIO to USART Tx pin, it is not working, I tried following at91_set_A_periph to that pin, still no luck.
Working on kernel : 3.18 and at91 atmel board.
You can have a look at the i2c-imx driver. It does exactly that.
You need to use pinctrl_lookup_state to retrieve the different pinctrl states (one of those being USART Tx and the other one GPIO). Then you can switch between both with pinctrl_select_state.
To sum it up, you'd have something like that in your uart node:
usart3: serial#fc00c000 {
pinctrl-names = "default","gpio";
pinctrl-0 = <&pinctrl_usart3>;
pinctrl-1 = <&pinctrl_usart3_gpio>;
tx-gpio = <&pioE 4 GPIO_ACTIVE_LOW>;
status = "okay";
};
In the driver code:
pinctrl_pins_default = pinctrl_lookup_state(pinctrl, PINCTRL_STATE_DEFAULT);
pinctrl_pins_gpio = pinctrl_lookup_state(pinctrl, "gpio");
tx_gpio = of_get_named_gpio(pdev->dev.of_node, "tx-gpio", 0);
Then, you can use pinctrl_select_state to switch back and forth between pinctrl_pins_default and pinctrl_pins_gpio. tx_gpio is your gpio.

Force lshosts command to return megabytes for "maxmem" and "maxswp" parameters

When I type "lshosts" I am given:
HOST_NAME type model cpuf ncpus maxmem maxswp server RESOURCES
server1 X86_64 Intel_EM 60.0 12 191.9G 159.7G Yes ()
server2 X86_64 Intel_EM 60.0 12 191.9G 191.2G Yes ()
server3 X86_64 Intel_EM 60.0 12 191.9G 191.2G Yes ()
I am trying to return maxmem and maxswp as megabytes, not gigabytes when lshosts is called. I am trying to send Xilinx ISE jobs to my LSF, however the software expects integer, megabyte values for maxmem and maxswp. By doing debugging, it appears that the software grabs these parameters using the lshosts command.
I have already checked in my lsf.conf file that:
LSF_UNIT_FOR_LIMTS=MB
I have tried searching the IBM Knowledge Base, but to no avail.
Do you use a specific command to specify maxmem and maxswp units within the lsf.conf, lsf.shared, or other config files?
Or does LSF force return the most practical unit?
Any way to override this?
LSF_UNIT_FOR_LIMITS should work, if you completely drained the cluster of all running, pending, and finished jobs. According to the docs, MB is the default, so I'm surprised.
That said, you can use something like this to transform the results:
$ cat to_mb.awk
function to_mb(s) {
e = index("KMG", substr(s, length(s)))
m = substr(s, 0, length(s) - 1)
return m * 10^((e-2) * 3)
}
{ print $1 " " to_mb($6) " " to_mb($7) }
$ lshosts | tail -n +2 | awk -f to_mb.awk
server1 191900 159700
server2 191900 191200
server3 191900 191200
The to_mb function should also handle 'K' or 'M' units, should those pop up.
If LSF_UNIT_FOR_LIMITS is defined in lsf.conf, lshosts will always print the output as a floating point number, and in some versions of LSF the parameter is defined as 'KB' in lsf.conf upon installation.
Try searching for any definitions of the parameter in lsf.conf and commenting them all out so that the parameter is left undefined, I think in that case it defaults to printing it out as an integer in megabytes.
(Don't ask me why it works this way)

sbull ldd3 example driver gets stuck

I'm writing a block device driver and started with the sbull example from here:
http://lwn.net/images/pdf/LDD3/ldd3_pdf.tar.bz2
I loaded the sbull driver successfully on my machine with kernel version 3.5.0-23.
When I run this code:
int main(){
int fd;
if ((fd = open("/dev/sbulla",O_RDWR)) < 0)
{
perror("open: ");
exit(1);
}
lseek(fd,4096,SEEK_SET);
write(fd,"yonityoyin",10);
lseek(fd,4096*2,SEEK_SET);
write(fd,"yonityoyin",10);
close(fd);
}
The session gets stuck.
If i open another session on the machine and print dmesg i get this after some time:
[56437.815570] INFO: task a.out:4640 blocked for more than 120 seconds.
[56437.822742] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[56437.831563] a.out D ffffffff8180cbe0 0 4640 4639 0x00000000
[56437.831571] ffff880852715c08 0000000000000082 0000000000000000 0000000000000001
[56437.831580] ffff880852715fd8 ffff880852715fd8 ffff880852715fd8 00000000000139c0
[56437.831588] ffff8808547c0000 ffff880851bc2e00 ffff880852715be8 ffff88085fd74258
[56437.831595] Call Trace:
[56437.831623] [<ffffffff81127220>] ? __lock_page+0x70/0x70
[56437.831638] [<ffffffff8169d8b9>] schedule+0x29/0x70
[56437.831643] [<ffffffff8169d98f>] io_schedule+0x8f/0xd0
[56437.831652] [<ffffffff8112722e>] sleep_on_page+0xe/0x20
[56437.831657] [<ffffffff8169c25f>] __wait_on_bit+0x5f/0x90
[56437.831663] [<ffffffff81127c1b>] ? find_get_pages_tag+0xcb/0x170
[56437.831674] [<ffffffff81127388>] wait_on_page_bit+0x78/0x80
[56437.831682] [<ffffffff81078490>] ? autoremove_wake_function+0x40/0x40
[56437.831691] [<ffffffff8112749c>] filemap_fdatawait_range+0x10c/0x1a0
[56437.831701] [<ffffffff81133000>] ? do_writepages+0x20/0x40
[56437.831706] [<ffffffff8112755b>] filemap_fdatawait+0x2b/0x30
[56437.831711] [<ffffffff811298e4>] filemap_write_and_wait+0x44/0x60
[56437.831718] [<ffffffff811c0091>] __sync_blockdev+0x21/0x40
[56437.831722] [<ffffffff811c00c3>] sync_blockdev+0x13/0x20
[56437.831726] [<ffffffff811c0139>] __blkdev_put+0x69/0x1c0
[56437.831736] [<ffffffff811c02eb>] blkdev_put+0x5b/0x160
[56437.831740] [<ffffffff811c0415>] blkdev_close+0x25/0x30
[56437.831750] [<ffffffff81188afe>] __fput+0xbe/0x240
[56437.831756] [<ffffffff81188ca5>] fput+0x25/0x30
[56437.831761] [<ffffffff81185976>] filp_close+0x66/0x90
[56437.831766] [<ffffffff81185a3e>] sys_close+0x9e/0x110
[56437.831775] [<ffffffff816a7029>] system_call_fastpath+0x16/0x1b
What could be the problem with the driver?
Just to be clear, I get this problem with the original sbull driver.
Please refer the newer example code.
https://github.com/martinezjavier/ldd3

linux softlockup in memory

My system is a embedded linux system(running kernel version 2.6.18). A client process send data to mysql server. The data will be stored in mysql database at a RAID5 assembled by four disks. The IO pressure(wa%) is always above 20% , mysql CPU utilization is very high.
After running 5 or 6 hours, the system run into softlock up stat.
The stack information is about releasing the physical memory, writing cache data to the hard disk.
Any suggestions in this circumstance?**
BUG: soft lockup detected on CPU#0!
[<c043dc1c>] softlockup_tick+0x8f/0xb1
[<c0428cb5>] update_process_times+0x26/0x5c
[<c0411256>] smp_apic_timer_interrupt+0x5d/0x67
[<c04044e7>] apic_timer_interrupt+0x1f/0x24
[<c06fe0b9>] _spin_lock+0x5/0xf
[<c047db2a>] __mark_inode_dirty+0x50/0x176
[<c0424eef>] current_fs_time+0x4d/0x5e
[<c0475ccd>] touch_atime+0x51/0x94
[<c0440926>] do_generic_mapping_read+0x425/0x563
[<c044134b>] __generic_file_aio_read+0xf3/0x267
[<c043fcd0>] file_read_actor+0x0/0xd4
[<c04414fb>] generic_file_aio_read+0x3c/0x4d
[<c045d72d>] do_sync_read+0xc1/0xfd
[<c0431656>] autoremove_wake_function+0x0/0x37
[<c045e0e8>] vfs_read+0xa4/0x167
[<c045d66c>] do_sync_read+0x0/0xfd
[<c045e688>] sys_pread64+0x5e/0x62
[<c0403a27>] syscall_call+0x7/0xb
=======================
BUG: soft lockup detected on CPU#2!
[<c043dc1c>] softlockup_tick+0x8f/0xb1
[<c0428cb5>] update_process_times+0x26/0x5c
[<c0411256>] smp_apic_timer_interrupt+0x5d/0x67
[<c04044e7>] apic_timer_interrupt+0x1f/0x24
[<c06fe0bb>] _spin_lock+0x7/0xf
[<c04aaf17>] journal_try_to_free_buffers+0xf4/0x17b
[<c0442c52>] find_get_pages+0x28/0x5d
[<c049c4b1>] ext3_releasepage+0x0/0x7d
[<c045f0bf>] try_to_release_page+0x2c/0x46
[<c0447894>] invalidate_mapping_pages+0xc9/0x167
[<c04813b0>] drop_pagecache+0x86/0xd2
[<c048144e>] drop_caches_sysctl_handler+0x52/0x64
[<c04813fc>] drop_caches_sysctl_handler+0x0/0x64
[<c042623d>] do_rw_proc+0xe8/0xf4
[<c0426268>] proc_writesys+0x1f/0x24
[<c045df81>] vfs_write+0xa6/0x169
[<c0426249>] proc_writesys+0x0/0x24
[<c045e601>] sys_write+0x41/0x6a
[<c0403a27>] syscall_call+0x7/0xb
=======================
BUG: soft lockup detected on CPU#1!
[<c043dc1c>] softlockup_tick+0x8f/0xb1
[<c0428cb5>] update_process_times+0x26/0x5c
[<c0411256>] smp_apic_timer_interrupt+0x5d/0x67
[<c04044e7>] apic_timer_interrupt+0x1f/0x24
[<c06f007b>] inet_diag_dump+0x804/0x821
[<c06fe0bb>] _spin_lock+0x7/0xf
[<c047db2a>] __mark_inode_dirty+0x50/0x176
[<c043168d>] wake_bit_function+0x0/0x3c
[<c04ae0f6>] __journal_remove_journal_head+0xee/0x1a5
[<c0445ae8>] __set_page_dirty_nobuffers+0x87/0xc6
[<c04a908e>] __journal_unfile_buffer+0x8/0x11
[<c04ab94d>] journal_commit_transaction+0x8e0/0x1103
[<c0431656>] autoremove_wake_function+0x0/0x37
[<c04af690>] kjournald+0xa9/0x1e5
[<c0431656>] autoremove_wake_function+0x0/0x37
[<c04af5e7>] kjournald+0x0/0x1e5
[<c04314da>] kthread+0xde/0xe2
[<c04313fc>] kthread+0x0/0xe2
[<c0404763>] kernel_thread_helper+0x7/0x14
=======================
BUG: soft lockup detected on CPU#3!
[<c043dc1c>] softlockup_tick+0x8f/0xb1
[<c0428cb5>] update_process_times+0x26/0x5c
[<c0411256>] smp_apic_timer_interrupt+0x5d/0x67
[<c04044e7>] apic_timer_interrupt+0x1f/0x24
[<c06fe0bb>] _spin_lock+0x7/0xf
[<c047db2a>] __mark_inode_dirty+0x50/0x176
[<c0424eef>] current_fs_time+0x4d/0x5e
[<c0475ccd>] touch_atime+0x51/0x94
[<c0440926>] do_generic_mapping_read+0x425/0x563
[<c044134b>] __generic_file_aio_read+0xf3/0x267
[<c043fcd0>] file_read_actor+0x0/0xd4
[<c04414fb>] generic_file_aio_read+0x3c/0x4d
[<c045d72d>] do_sync_read+0xc1/0xfd
[<c0431656>] autoremove_wake_function+0x0/0x37
[<c045e0e8>] vfs_read+0xa4/0x167
[<c045d66c>] do_sync_read+0x0/0xfd
[<c045e688>] sys_pread64+0x5e/0x62
[<c0403a27>] syscall_call+0x7/0xb
=======================
Seriously, try something newer. 2.6.18 is >7 years old.
Looks like CPU#1 and CPU#3 are spinning in a spinlock on a inode structure.

Resources