<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=us-ascii"><meta name=Generator content="Microsoft Word 15 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:"Malgun Gothic";
panose-1:2 11 5 3 2 0 0 2 0 4;}
@font-face
{font-family:"Malgun Gothic";
panose-1:2 11 5 3 2 0 0 2 0 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0cm;
margin-bottom:.0001pt;
text-align:justify;
text-justify:inter-ideograph;
text-autospace:none;
word-break:break-hangul;
font-size:10.0pt;
font-family:"Malgun Gothic";}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:#0563C1;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-priority:99;
color:#954F72;
text-decoration:underline;}
span.EmailStyle17
{mso-style-type:personal-compose;
font-family:"Malgun Gothic";
color:windowtext;}
.MsoChpDefault
{mso-style-type:export-only;
font-family:"Malgun Gothic";}
/* Page Definitions */
@page WordSection1
{size:612.0pt 792.0pt;
margin:3.0cm 72.0pt 72.0pt 72.0pt;}
div.WordSection1
{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]--></head><body lang=KO link="#0563C1" vlink="#954F72"><div class=WordSection1><p class=MsoNormal><span lang=EN-US>Hi, all, <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>I’m testing a simple character driver on qemu arm64 virtual machine.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>I have uint64_t args[32] array and I pass args to the ioctl data.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>By the way args[2] contains the address of test_val which is set to 77. I want to change this value to 78 in the driver using kernel virtual address.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>(ultimately I want to get the physical address of test_val and pass it to the qemu hardware model).<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>I read I can change user virtual address to kernel land virtual address using get_user_pages function and then I can use virt_to_phys function to get the physical address from kernel land virtual address.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>(please correct me if I’m wrong)<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>When I try to write 78 at the kernel virtual address for test_val, trap occurs.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>## app.c ## <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> uint64_t __attribute__(( aligned(64) )) args[32]; <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> uint64_t test_val = 77;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> args[2] = (uint64_t) &test_val; // let's see it's changed to 78<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> </span><span lang=DE>printf("app : args[2] = %p, *args[2] = %lld\n", args[2], *(uint64_t *)args[2]);<o:p></o:p></span></p><p class=MsoNormal><span lang=DE> </span><span lang=EN-US>ioctl(fd, CallSetBareMetalMode, (uint64_t)args);<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>### driver.c ###<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US> static long my_ioctl(struct file *file, unsigned int cmd, unsigned long arg)<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> {<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> switch(cmd) {<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> case CallSetBareMetalMode:<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> printk("driver:cmd = %x, arg = %lx\n", cmd, arg);<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> copy_from_user(&args, (void __user *)arg, 8*3);<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> printk("args[2] = %llx\n", args[2]);<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> offs = args[2] % 4096;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US> down_read(¤t->mm->mmap_sem);<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> res = get_user_pages( (unsigned long)args[2], 1, 1, &pages, NULL);<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> printk("get_user_pages done! args[2] = %px\n", args[2]);<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US> if (res) {<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> printk(KERN_INFO "Got mmaped.\n");<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> kvpaddr = kmap(pages);<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> printk("kmap done!\n");<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> printk(KERN_INFO "kvpaddr = %px, ofs = %x\n", kvpaddr, offs);<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> printk("xx = %llx\n", ((unsigned long long int)(kvpaddr)+offs));<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> *(uint64_t *)((unsigned long long int)(kvpaddr)+offs) = 78;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> printk(KERN_INFO "changed value : %lld\n",\<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> *(uint64_t *)((unsigned int)(kvpaddr)+offs));<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> put_page(pages); //page_cache_release(page);<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> printk("put_page done!\n");<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> }<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> else {<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> printk("get_user_pages failed!\n");<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> }<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> up_read(¤t->mm->mmap_sem);<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>### run output ### <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US> args = 0x442f40<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> app : args[0] = 0x443040<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> </span><span lang=DE>app : args[2] = 0xffffd2e44d98, *args[2] = 77<o:p></o:p></span></p><p class=MsoNormal><span lang=DE> [85194.544029] driver:cmd = 40086142, arg = 442f40<o:p></o:p></span></p><p class=MsoNormal><span lang=DE> </span><span lang=EN-US>[85194.544822] args[2] = ffffd2e44d98<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> [85194.545613] get_user_pages done! args[2] = 0000ffffd2e44d98<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> [85194.546004] Got mmaped.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> [85194.546248] kmap done!<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> [85194.546536] kvpaddr = ffff00001f7c0000, ofs = d98<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> [85194.546976] kvaddr = ffff00001f7c0d98<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> [85194.548645] Unable to handle kernel paging request at virtual address 000000001f7c0d98<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>[85194.549245] Mem abort info:<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> [85194.549513] ESR = 0x96000006<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> [85194.549929] EC = 0x25: DABT (current EL), IL = 32 bits<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> [85194.550364] SET = 0, FnV = 0<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> [85194.550719] EA = 0, S1PTW = 0<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> [85194.551008] Data abort info:<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> [85194.551555] ISV = 0, ISS = 0x00000006<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> [85194.551938] CM = 0, WnR = 0<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> [85194.552609] user pgtable: 4k pages, 48-bit VAs, pgdp=00000000568fb000<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> [85194.553441] [000000001f7c0d98] pgd=0000000056209003, pud=0000000047b97003, pmd=0000000000000000<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> [85194.555783] Internal error: Oops: 96000006 [#16] SMP<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> [85194.556761] Modules linked in: chr_drv_ex1(OE) nls_iso8859_1 dm_multipath scsi_dh_rdac scsi_dh_emc scsi_dh_alua qemu_fw_cfg sch_fq_codel ppdev lp parport drm ip_tables x_tables autofs4 btrfs zstd_compress raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor async_tx xor xor_neon raid6_pq libcrc32c raid1 raid0 multipath linear crct10dif_ce ghash_ce sm4_ce sm4_generic sm3_ce sm3_generic sha3_ce sha3_generic sha512_ce sha512_arm64 sha2_ce sha256_arm64 sha1_ce virtio_net net_failover virtio_blk failover aes_neon_bs aes_neon_blk aes_ce_blk crypto_simd cryptd aes_ce_cipher [last unloaded: chr_drv_ex1]<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> [85194.563741] CPU: 2 PID: 4258 Comm: test_axpu_app Tainted: G D W OE 5.4.0-77-generic #86-Ubuntu<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> [85194.564638] Hardware name: QEMU QEMU Ab21q Virtual Machine, BIOS 0.0.0 02/06/2015<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> [85194.565687] pstate: 60400005 (nZCv daif +PAN -UAO)<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> [85194.568143] pc : my_ioctl+0x310/0x370 [chr_drv_ex1]<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> [85194.568854] lr : my_ioctl+0x300/0x370 [chr_drv_ex1]<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> [85194.569473] sp : ffff80001372bd30<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> [85194.569838] x29: ffff80001372bd30 x28: ffff000009f7bc00 <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> </span><span lang=DE>[85194.570354] x27: 0000000000000000 x26: 0000000000000000 <o:p></o:p></span></p><p class=MsoNormal><span lang=DE> [85194.570796] x25: 0000000056000000 x24: ffff00000d3c35e0 <o:p></o:p></span></p><p class=MsoNormal><span lang=DE> [85194.571308] x23: ffff000016875600 x22: 0000000000000d98 <o:p></o:p></span></p><p class=MsoNormal><span lang=DE> </span><span lang=EN-US>[85194.571870] x21: 000000001f7c0d98 x20: 0000000000442f40 <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> [85194.572273] x19: ffff00001f7c0000 x18: 0000000000000010 <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> [85194.572669] x17: 0000000000000000 x16: 0000000000000000 <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> [85194.573126] x15: ffff000009f7c128 x14: ffffffffffffffff <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> [85194.573632] x13: ffff80009372ba77 x12: ffff80001372ba7f <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> </span><span lang=DE>[85194.574127] x11: ffff800011b9e000 x10: 0000000000000000 <o:p></o:p></span></p><p class=MsoNormal><span lang=DE> [85194.574578] x9 : ffff800011db4000 x8 : 00000000000005f2 <o:p></o:p></span></p><p class=MsoNormal><span lang=DE> </span><span lang=EN-US>[85194.575193] x7 : 0000000000000017 x6 : ffff800011db39d4 <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> [85194.575700] x5 : 0000000000000000 x4 : ffff00001feb5250 <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> [85194.576139] x3 : ffff00001fec56c8 x2 : 0000000000000000 <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> [85194.576550] x1 : 0000000000000000 x0 : ffff80000924b220 <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> [85194.577379] Call trace:<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> [85194.577805] my_ioctl+0x310/0x370 [chr_drv_ex1]<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> [85194.579423] do_vfs_ioctl+0xc64/0xe60<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> [85194.579846] ksys_ioctl+0x88/0xb8<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> [85194.580116] __arm64_sys_ioctl+0x2c/0x228<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> [85194.580479] el0_svc_common.constprop.0+0xe4/0x1f0<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> </span><span lang=DE>[85194.580929] el0_svc_handler+0x38/0xa8<o:p></o:p></span></p><p class=MsoNormal><span lang=DE> [85194.581293] el0_svc+0x10/0x2c8<o:p></o:p></span></p><p class=MsoNormal><span lang=DE> </span><span lang=EN-US>[85194.582065] Code: d28009c0 f8336ac0 b0000000 91088000 (f94002a1) <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> [85194.583646] ---[ end trace bd1ac75ca265aec2 ]---<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> [85194.590696] Device File closed..<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> Segmentation fault (core dumped)<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>I thought I changed the user virtual address to kernel virtual address, but writing to the kernel virtual address causes trap. <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>Can anyone help me with finding what is wrong here?<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>Thank you for reading.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>Chan Kim<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p></div></body></html>