[Xen-devel] [xen-unstable test] 117311: tolerable FAIL
flight 117311 xen-unstable real [real] http://logs.test-lab.xenproject.org/osstest/logs/117311/ Failures :-/ but no regressions. Tests which did not succeed, but are not blocking: test-armhf-armhf-libvirt 14 saverestore-support-checkfail like 117258 test-armhf-armhf-libvirt-xsm 14 saverestore-support-checkfail like 117258 test-armhf-armhf-xl-credit2 16 guest-start/debian.repeatfail like 117258 test-amd64-amd64-xl-qemuu-win7-amd64 17 guest-stopfail like 117258 test-armhf-armhf-libvirt-raw 13 saverestore-support-checkfail like 117258 test-amd64-i386-xl-qemuu-win7-amd64 17 guest-stop fail like 117258 test-amd64-amd64-xl-qemut-win7-amd64 17 guest-stopfail like 117258 test-amd64-i386-xl-qemut-win7-amd64 17 guest-stop fail like 117258 test-amd64-i386-xl-qemuu-ws16-amd64 17 guest-stop fail like 117258 test-amd64-amd64-xl-qemuu-ws16-amd64 17 guest-stopfail like 117258 test-amd64-amd64-xl-qemut-ws16-amd64 17 guest-stopfail like 117258 test-amd64-amd64-xl-pvhv2-intel 12 guest-start fail never pass test-amd64-amd64-xl-pvhv2-amd 12 guest-start fail never pass test-amd64-amd64-libvirt 13 migrate-support-checkfail never pass test-amd64-amd64-libvirt-xsm 13 migrate-support-checkfail never pass test-amd64-i386-libvirt-xsm 13 migrate-support-checkfail never pass test-amd64-i386-libvirt 13 migrate-support-checkfail never pass test-arm64-arm64-xl-xsm 13 migrate-support-checkfail never pass test-arm64-arm64-xl 13 migrate-support-checkfail never pass test-arm64-arm64-xl-xsm 14 saverestore-support-checkfail never pass test-arm64-arm64-xl 14 saverestore-support-checkfail never pass test-arm64-arm64-xl-credit2 13 migrate-support-checkfail never pass test-arm64-arm64-xl-credit2 14 saverestore-support-checkfail never pass test-amd64-amd64-libvirt-qemuu-debianhvm-amd64-xsm 11 migrate-support-check fail never pass test-amd64-i386-libvirt-qemuu-debianhvm-amd64-xsm 11 migrate-support-check fail never pass test-amd64-amd64-libvirt-vhd 12 migrate-support-checkfail never pass test-amd64-amd64-qemuu-nested-amd 17 debian-hvm-install/l1/l2 fail never pass test-armhf-armhf-xl-multivcpu 13 migrate-support-checkfail never pass test-armhf-armhf-xl-multivcpu 14 saverestore-support-checkfail never pass test-armhf-armhf-xl-cubietruck 13 migrate-support-checkfail never pass test-armhf-armhf-xl-cubietruck 14 saverestore-support-checkfail never pass test-armhf-armhf-xl-xsm 13 migrate-support-checkfail never pass test-armhf-armhf-xl-xsm 14 saverestore-support-checkfail never pass test-armhf-armhf-libvirt 13 migrate-support-checkfail never pass test-armhf-armhf-libvirt-xsm 13 migrate-support-checkfail never pass test-armhf-armhf-xl-rtds 13 migrate-support-checkfail never pass test-armhf-armhf-xl-rtds 14 saverestore-support-checkfail never pass test-armhf-armhf-xl-credit2 13 migrate-support-checkfail never pass test-armhf-armhf-xl-credit2 14 saverestore-support-checkfail never pass test-arm64-arm64-libvirt-xsm 13 migrate-support-checkfail never pass test-arm64-arm64-libvirt-xsm 14 saverestore-support-checkfail never pass test-armhf-armhf-libvirt-raw 12 migrate-support-checkfail never pass test-armhf-armhf-xl-vhd 12 migrate-support-checkfail never pass test-armhf-armhf-xl-vhd 13 saverestore-support-checkfail never pass test-armhf-armhf-xl-arndale 13 migrate-support-checkfail never pass test-armhf-armhf-xl-arndale 14 saverestore-support-checkfail never pass test-armhf-armhf-xl 13 migrate-support-checkfail never pass test-armhf-armhf-xl 14 saverestore-support-checkfail never pass test-amd64-i386-xl-qemut-ws16-amd64 17 guest-stop fail never pass test-amd64-i386-xl-qemuu-win10-i386 10 windows-install fail never pass test-amd64-amd64-xl-qemuu-win10-i386 10 windows-installfail never pass test-amd64-amd64-xl-qemut-win10-i386 10 windows-installfail never pass test-amd64-i386-xl-qemut-win10-i386 10 windows-install fail never pass version targeted for testing: xen ec320542e4f4de12305551ef5e3cd4d2ced85771 baseline version: xen ec320542e4f4de12305551ef5e3cd4d2ced85771 Last test of basis 117311 2017-12-19 02:35:18 Z1 days Testing same since (not found) 0 attempts jobs: build-amd64-xsm pass build-arm64-xsm pass build-armhf-xsm pass build-i386-xsm
[Xen-devel] [xen-4.7-testing baseline-only test] 73075: trouble: blocked/broken
This run is configured for baseline tests only. flight 73075 xen-4.7-testing real [real] http://osstest.xs.citrite.net/~osstest/testlogs/logs/73075/ Failures and problems with tests :-( Tests which did not succeed and are blocking, including tests which could not be run: build-amd64 broken build-amd64-prev broken build-i386 broken build-armhf-pvopsbroken build-i386-xsm broken build-amd64-xtf broken build-amd64-xsm broken build-amd64-pvopsbroken build-i386-pvops broken build-armhf-xsm broken build-armhf broken build-i386-prev broken build-armhf 4 host-install(4) broken REGR. vs. 72502 build-armhf-pvops 4 host-install(4) broken REGR. vs. 72502 build-armhf-xsm 4 host-install(4) broken REGR. vs. 72502 build-i3864 host-install(4) broken REGR. vs. 72502 build-amd64 4 host-install(4) broken REGR. vs. 72502 build-i386-prev 4 host-install(4) broken REGR. vs. 72502 build-amd64-xsm 4 host-install(4) broken REGR. vs. 72502 build-i386-pvops 4 host-install(4) broken REGR. vs. 72502 build-i386-xsm4 host-install(4) broken REGR. vs. 72502 build-amd64-pvops 4 host-install(4) broken REGR. vs. 72502 build-amd64-xtf 4 host-install(4) broken REGR. vs. 72502 build-amd64-prev 4 host-install(4) broken REGR. vs. 72502 Tests which did not succeed, but are not blocking: test-amd64-i386-libvirt-qcow2 1 build-check(1) blocked n/a test-amd64-amd64-xl-qemuu-debianhvm-amd64 1 build-check(1)blocked n/a test-amd64-i386-freebsd10-i386 1 build-check(1) blocked n/a test-amd64-amd64-qemuu-nested-intel 1 build-check(1) blocked n/a test-amd64-i386-libvirt-qemuu-debianhvm-amd64-xsm 1 build-check(1) blocked n/a test-xtf-amd64-amd64-11 build-check(1) blocked n/a test-armhf-armhf-xl-midway1 build-check(1) blocked n/a test-armhf-armhf-libvirt 1 build-check(1) blocked n/a test-amd64-i386-xl-qemuu-debianhvm-amd64-xsm 1 build-check(1) blocked n/a test-amd64-i386-xl-qemut-debianhvm-amd64-xsm 1 build-check(1) blocked n/a test-amd64-amd64-migrupgrade 1 build-check(1) blocked n/a test-amd64-i386-xl-qemut-win10-i386 1 build-check(1) blocked n/a test-amd64-amd64-xl-qemut-stubdom-debianhvm-amd64-xsm 1 build-check(1) blocked n/a test-amd64-i386-xl-qemuu-win10-i386 1 build-check(1) blocked n/a test-armhf-armhf-libvirt-raw 1 build-check(1) blocked n/a test-amd64-i386-libvirt-xsm 1 build-check(1) blocked n/a test-amd64-amd64-xl-multivcpu 1 build-check(1) blocked n/a test-amd64-amd64-libvirt 1 build-check(1) blocked n/a test-amd64-i386-xl-qemut-ws16-amd64 1 build-check(1) blocked n/a test-amd64-amd64-xl-qemut-win10-i386 1 build-check(1) blocked n/a test-amd64-i386-xl-qemut-debianhvm-amd64 1 build-check(1) blocked n/a test-amd64-i386-qemut-rhel6hvm-intel 1 build-check(1) blocked n/a test-amd64-i386-freebsd10-amd64 1 build-check(1) blocked n/a test-amd64-amd64-pair 1 build-check(1) blocked n/a test-armhf-armhf-xl-credit2 1 build-check(1) blocked n/a build-i386-rumprun1 build-check(1) blocked n/a test-amd64-amd64-xl-qemuu-win10-i386 1 build-check(1) blocked n/a test-amd64-amd64-xl-qemuu-win7-amd64 1 build-check(1) blocked n/a test-amd64-amd64-libvirt-qemuu-debianhvm-amd64-xsm 1 build-check(1) blocked n/a test-amd64-amd64-pygrub 1 build-check(1) blocked n/a test-amd64-i386-xl-qemuu-ws16-amd64 1 build-check(1) blocked n/a test-amd64-amd64-xl-qcow2 1 build-check(1) blocked n/a test-amd64-amd64-amd64-pvgrub 1 build-check(1) blocked n/a test-xtf-amd64-amd64-21 build-check(1) blocked n/a test-amd64-amd64-xl-qemut-win7-amd64 1 build-check(1) blocked n/a test-amd64-i386-xl-qemuu-debianhvm-amd64 1 build-check(1) blocked n/a test-armhf-armhf-libvirt-xsm 1 build-check(1) blocked n/a build-amd64-rumprun 1 build-check(1) blocked n/a test-amd64-i386-xl1 build-check(1) blocked
[Xen-devel] [linux-linus test] 117305: regressions - FAIL
flight 117305 linux-linus real [real] http://logs.test-lab.xenproject.org/osstest/logs/117305/ Regressions :-( Tests which did not succeed and are blocking, including tests which could not be run: test-amd64-amd64-qemuu-nested-intel 7 xen-boot fail REGR. vs. 115643 test-amd64-i386-qemuu-rhel6hvm-intel 7 xen-boot fail REGR. vs. 115643 test-amd64-amd64-xl-pvhv2-amd 7 xen-bootfail REGR. vs. 115643 test-amd64-amd64-libvirt-vhd 7 xen-boot fail REGR. vs. 115643 test-amd64-amd64-xl-qemuu-ovmf-amd64 7 xen-boot fail REGR. vs. 115643 test-amd64-amd64-libvirt-pair 10 xen-boot/src_host fail REGR. vs. 115643 test-amd64-amd64-pygrub 7 xen-boot fail REGR. vs. 115643 test-amd64-amd64-libvirt-pair 11 xen-boot/dst_host fail REGR. vs. 115643 test-amd64-i386-xl-qemut-debianhvm-amd64 7 xen-boot fail REGR. vs. 115643 test-amd64-i386-xl-raw7 xen-boot fail REGR. vs. 115643 test-amd64-i386-xl-qemuu-debianhvm-amd64 7 xen-boot fail REGR. vs. 115643 test-amd64-i386-libvirt-qemuu-debianhvm-amd64-xsm 7 xen-boot fail REGR. vs. 115643 test-amd64-i386-xl-xsm7 xen-boot fail REGR. vs. 115643 test-amd64-amd64-libvirt-qemuu-debianhvm-amd64-xsm 7 xen-boot fail REGR. vs. 115643 test-amd64-amd64-qemuu-nested-amd 7 xen-bootfail REGR. vs. 115643 test-amd64-i386-xl-qemuu-debianhvm-amd64-xsm 7 xen-boot fail REGR. vs. 115643 test-amd64-amd64-xl-qemuu-win10-i386 7 xen-boot fail REGR. vs. 115643 test-amd64-amd64-xl-qemuu-win7-amd64 7 xen-boot fail REGR. vs. 115643 test-amd64-i386-freebsd10-amd64 7 xen-boot fail REGR. vs. 115643 test-amd64-i386-freebsd10-i386 7 xen-boot fail REGR. vs. 115643 test-amd64-amd64-xl-qcow2 7 xen-boot fail REGR. vs. 115643 test-amd64-amd64-xl-multivcpu 7 xen-bootfail REGR. vs. 115643 test-amd64-i386-examine 8 reboot fail REGR. vs. 115643 test-amd64-i386-xl-qemuu-ovmf-amd64 7 xen-boot fail REGR. vs. 115643 test-amd64-i386-rumprun-i386 7 xen-boot fail REGR. vs. 115643 test-amd64-amd64-amd64-pvgrub 7 xen-bootfail REGR. vs. 115643 test-amd64-i386-qemut-rhel6hvm-amd 7 xen-boot fail REGR. vs. 115643 test-amd64-amd64-xl-xsm 7 xen-boot fail REGR. vs. 115643 test-amd64-i386-qemuu-rhel6hvm-amd 7 xen-boot fail REGR. vs. 115643 test-amd64-amd64-xl 7 xen-boot fail REGR. vs. 115643 test-amd64-i386-libvirt-pair 10 xen-boot/src_hostfail REGR. vs. 115643 test-amd64-i386-pair 10 xen-boot/src_hostfail REGR. vs. 115643 test-amd64-i386-pair 11 xen-boot/dst_hostfail REGR. vs. 115643 test-amd64-i386-libvirt-pair 11 xen-boot/dst_hostfail REGR. vs. 115643 test-amd64-i386-xl-qemut-debianhvm-amd64-xsm 7 xen-boot fail REGR. vs. 115643 test-amd64-i386-xl-qemut-stubdom-debianhvm-amd64-xsm 7 xen-boot fail REGR. vs. 115643 test-amd64-amd64-libvirt-xsm 7 xen-boot fail REGR. vs. 115643 test-amd64-amd64-xl-qemut-debianhvm-amd64 7 xen-bootfail REGR. vs. 115643 test-amd64-amd64-xl-qemut-stubdom-debianhvm-amd64-xsm 7 xen-boot fail REGR. vs. 115643 test-amd64-amd64-pair10 xen-boot/src_hostfail REGR. vs. 115643 test-amd64-amd64-pair11 xen-boot/dst_hostfail REGR. vs. 115643 Regressions which are regarded as allowable (not blocking): test-amd64-amd64-xl-rtds 7 xen-boot fail REGR. vs. 115643 Tests which did not succeed, but are not blocking: test-armhf-armhf-libvirt 14 saverestore-support-checkfail like 115643 test-amd64-amd64-xl-qemut-win7-amd64 17 guest-stopfail like 115643 test-armhf-armhf-libvirt-xsm 14 saverestore-support-checkfail like 115643 test-amd64-i386-xl-qemut-win7-amd64 17 guest-stop fail like 115643 test-amd64-i386-xl-qemuu-win7-amd64 17 guest-stop fail like 115643 test-amd64-amd64-xl-qemut-ws16-amd64 17 guest-stopfail like 115643 test-amd64-amd64-xl-qemuu-ws16-amd64 17 guest-stopfail like 115643 test-armhf-armhf-libvirt-raw 13 saverestore-support-checkfail like 115643 test-amd64-i386-libvirt 13 migrate-support-checkfail never pass test-arm64-arm64-xl-credit2 13 migrate-support-checkfail never pass test-arm64-arm64-libvirt-xsm 13 migrate-support-checkfail never pass test-arm64-arm64-libvirt-xsm 14 saverestore-support-checkfail never pass test-arm64-arm64-xl-credit2 14 saverestore-support-checkfail never pass test-amd64-amd64-libvirt 13 migrate-support-checkfail never pass test-arm64-arm64-xl-xsm 13 migrate-support-checkfail never pass test-arm64-arm64-xl-xsm 14 saverestore-support-checkfail never pass
Re: [Xen-devel] Xen PV DomU running Kernel 4.14.5-1.el7.elrepo.x86_64: xl -v vcpu-set triggers domU kernel WARNING, then domU becomes unresponsive
Just a quick follow-up, same behaviour with: dom0 running CentOS 7 with https://buildlogs.centos.org/centos/7/virt/x86_64/xen/kernel-4.9.70-29.el7.x86_64.rpm domU running CentOS 7 with kernel-ml-4.14.7-1.el7.elrepo.x86_64 dom0 stacktrace: [ 287.710812] [ cut here ] [ 287.710842] WARNING: CPU: 2 PID: 35 at block/blk-mq.c:1144 __blk_mq_run_hw_queue+0x89/0xa0 [ 287.710853] Modules linked in: ip_set_hash_ip ip_set nfnetlink x86_pkg_temp_thermal coretemp crct10dif_pclmul crc32_pclmul ghash_clmulni_intel pcbc aesni_intel crypto_simd glue_helper cryptd intel_rapl_perf pcspkr nfsd auth_rpcgss nfs_acl lockd grace sunrpc ip_tables ext4 mbcache jbd2 xen_netfront xen_blkfront crc32c_intel [ 287.710913] CPU: 2 PID: 35 Comm: kworker/2:1H Not tainted 4.14.7-1.el7.elrepo.x86_64 #1 [ 287.710927] Workqueue: kblockd blk_mq_run_work_fn [ 287.710936] task: 88007c6a task.stack: c90040474000 [ 287.710948] RIP: e030:__blk_mq_run_hw_queue+0x89/0xa0 [ 287.710956] RSP: e02b:c90040477e30 EFLAGS: 00010202 [ 287.710968] RAX: 0001 RBX: 880003aa5400 RCX: 88007d11bca0 [ 287.710977] RDX: 88007c656d98 RSI: 00a0 RDI: 880003aa5400 [ 287.710986] RBP: c90040477e48 R08: R09: [ 287.710996] R10: 7ff0 R11: 018e R12: 88007c57 [ 287.711005] R13: 88007d11bc80 R14: 88007d121b00 R15: 880003aa5448 [ 287.711025] FS: () GS:88007d10() knlGS:88007d10 [ 287.711036] CS: e033 DS: ES: CR0: 80050033 [ 287.711045] CR2: 7f8750908000 CR3: 796a4000 CR4: 00042660 [ 287.711057] Call Trace: [ 287.711071] blk_mq_run_work_fn+0x2c/0x30 [ 287.711086] process_one_work+0x149/0x360 [ 287.711098] worker_thread+0x4d/0x3e0 [ 287.711108] kthread+0x109/0x140 [ 287.79] ? rescuer_thread+0x380/0x380 [ 287.711128] ? kthread_park+0x60/0x60 [ 287.711140] ret_from_fork+0x25/0x30 [ 287.711148] Code: 00 e8 4c e8 45 00 4c 89 e7 e8 34 4a d7 ff 48 89 df 41 89 c5 e8 19 66 00 00 44 89 ee 4c 89 e7 e8 4e 4a d7 ff 5b 41 5c 41 5d 5d c3 <0f> ff eb b4 48 89 df e8 fb 65 00 00 5b 41 5c 41 5d 5d c3 0f ff [ 287.711235] ---[ end trace 7b31b11d076677d1 ]--- --- Adi Pircalabu On 19-12-2017 17:31, Adi Pircalabu wrote: Posted initially to centos-virt mailing list. Please note I'm not subscribed to xen-devel. Running "xl -v vcpu-set " on both CentOS 6 running 4.14.5-1.el6.elrepo.x86_64 and CentOS 7 running 4.14.5-1.el7.elrepo.x86_64 I'm able to trigger this bug where certain commands in the domU stall: top ls -l /var/tmp ls -l /tmp - Stuck in D state on the CentOS 7 domU: root 5 0.0 0.0 0 0 ?D11:20 0:00 [kworker/u8:0] root 316 0.0 0.0 0 0 ?D11:20 0:00 [jbd2/xvda1-8] root 1145 0.0 0.2 116636 4776 ?Ds 11:20 0:00 -bash root 1289 0.0 0.1 25852 2420 ?Ds 11:35 0:00 /usr/bin/systemd-tmpfiles --clean root 1290 0.0 0.1 125248 2696 pts/1D+ 11:44 0:00 ls --color=auto -l /tmp/ root 1293 0.0 0.1 125248 2568 pts/2D+ 11:44 0:00 ls --color=auto -l /var/tmp root 1296 0.0 0.2 116636 4908 pts/3Ds+ 11:44 0:00 -bash root 1358 0.0 0.1 125248 2612 pts/4D+ 11:47 0:00 ls --color=auto -l /var/tmp I couldn't replicate the problem on: - CentOS 6 running kernel-2.6.32-696.16.1.el6.x86_64, kernel-lt-4.4.105-1.el6.elrepo.x86_64 - CentOS 7 running 4.9.67-1.el7.centos.x86_64 dom0 versions tested with similar results in the domU: - 4.6.6-6.el7 on kernel 4.9.63-29.el7.x86_64 - 4.6.3-15.el6 on kernel 4.9.37-29.el6.x86_64 At a first glance it appears the issue is in 4.14.5 kernel. Stack traces follow: -CentOS 6 kernel-ml-4.14.5-1.el6.elrepo.x86_64 start here- [ cut here ] WARNING: CPU: 4 PID: 60 at block/blk-mq.c:1144 __blk_mq_run_hw_queue+0x9e/0xc0 Modules linked in: intel_cstate(-) ipt_REJECT nf_reject_ipv4 nf_conntrack_ipv4 nf_defrag_ipv4 xt_multiport iptable_filter ip_tables ip6t_REJECT nf_reject_ipv6 nf_conntrack_ipv6 nf_defrag_ipv6 xt_state nf_conntrack libcrc32c ip6table_filter ip6_tables dm_mod dax xen_netfront crc32_pclmul crct10dif_pclmul ghash_clmulni_intel crc32c_intel pcbc aesni_intel glue_helper crypto_simd cryptd aes_x86_64 coretemp hwmon x86_pkg_temp_thermal sb_edac intel_rapl_perf pcspkr ext4 jbd2 mbcache xen_blkfront CPU: 4 PID: 60 Comm: kworker/4:1H Not tainted 4.14.5-1.el6.elrepo.x86_64 #1 Workqueue: kblockd blk_mq_run_work_fn task: 8802711a2780 task.stack: c90041af4000 RIP: e030:__blk_mq_run_hw_queue+0x9e/0xc0 RSP: e02b:c90041af7c48 EFLAGS: 00010202 RAX: 0001 RBX: 88027117fa80 RCX: 0001 RDX: 88026b053ee0 RSI: 88027351bca0 RDI: 88026b072800 RBP: c90041af7c68 R08: c90041af7eb8 R09: 8802711a2810 R10: 7ff0 R11: 0001 R12:
Re: [Xen-devel] [Minios-devel] [PATCH RFC 00/16] Save/Restore Support for mini-OS PVH
About patch 16, "Replace xenstore and console pfns with the correspondent mfns" seems exactly contrary to what the code does. Apart from that, Reviewed-by: Samuel ThibaultSamuel ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [Minios-devel] [PATCH RFC 00/16] Save/Restore Support for mini-OS PVH
About patch 15, it seems your terminal is set to see tabs as 4 spaces. Where tabs are used, the mini-os source code assumes 8 spaces. Avoid using tabs, just use spaces :) And, avoid for (list = dev_list; list->next != NULL; list = list->next); better write for (list = dev_list; list->next != NULL; list = list->next) ; to make it explicit that the loop is empty. Also, *ip = malloc(strlen(ldev->ip) + 1); strncpy(*ip, ldev->ip, strlen(ldev->ip) + 1); can be a mere *ip = strdup(ldev->ip), can't it? Apart from that, Reviewed-by: Samuel ThibaultSamuel ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [Minios-devel] [PATCH RFC 13/16] Save/Restore Support: Add suspend/restore support for Grant Tables.
Bruno Alvisio, on mar. 19 déc. 2017 15:42:08 -0800, wrote: > +void suspend_gnttab(void) > +{ > +#ifdef CONFIG_PARAVIRT > +int i; > + > +for (i = 0; i < NR_GRANT_FRAMES; i++) { > +HYPERVISOR_update_va_mapping((unsigned long)(((char *)gnttab_table) > + PAGE_SIZE*i), > +(pte_t){0x0<+} > +#endif > +return; > +} > + > +void resume_gnttab(void) > +{... The initialization in arch_init_gnttab is different for arm, so I'd say this should be arch-specific. Samuel ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [Minios-devel] [PATCH RFC 12/16] Save/Restore Support: Add support for suspend/restore events.
Bruno Alvisio, on mar. 19 déc. 2017 15:42:07 -0800, wrote: > Signed-off-by: Bruno AlvisioReviewed-by: Samuel Thibault > --- > events.c | 5 + > include/events.h | 1 + > kernel.c | 2 ++ > 3 files changed, 8 insertions(+) > > diff --git a/events.c b/events.c > index e8ef8aa..342aead 100644 > --- a/events.c > +++ b/events.c > @@ -183,6 +183,11 @@ void fini_events(void) > arch_fini_events(); > } > > +void suspend_events(void) > +{ > +unbind_all_ports(); > +} > + > void default_handler(evtchn_port_t port, struct pt_regs *regs, void *ignore) > { > printk("[Port %d] - event received\n", port); > diff --git a/include/events.h b/include/events.h > index 89b5997..705ad93 100644 > --- a/include/events.h > +++ b/include/events.h > @@ -55,5 +55,6 @@ static inline int notify_remote_via_evtchn(evtchn_port_t > port) > } > > void fini_events(void); > +void suspend_events(void); > > #endif /* _EVENTS_H_ */ > diff --git a/kernel.c b/kernel.c > index fd1c4c5..c6ff9f3 100644 > --- a/kernel.c > +++ b/kernel.c > @@ -124,6 +124,8 @@ void pre_suspend(void) > suspend_time(); > > suspend_console(); > + > +suspend_events(); > } > > void post_suspend(int canceled) > -- > 2.3.2 (Apple Git-55) > > > ___ > Minios-devel mailing list > minios-de...@lists.xenproject.org > https://lists.xenproject.org/mailman/listinfo/minios-devel -- Samuel X-Favorit-Cartoon: Calvin and Hobbes -+- Mail header of Wim van Dorst -+- ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [Minios-devel] [PATCH RFC 00/16] Save/Restore Support for mini-OS PVH
Again, I didn't find patch 11, so I got it from here Bruno Alvisio, on mar. 19 déc. 2017 15:41:55 -0800, wrote: > https://github.com/balvisio/mini-os/tree/feature/mini-os-suspend-support There are indentation oddities bringing spurious hunks. Apart from that, Reviewed-by: Samuel ThibaultSamuel ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [Minios-devel] [PATCH RFC 10/16] Save/Restore Support: Add suspend/resume support for timers
Bruno Alvisio, on mar. 19 déc. 2017 15:42:05 -0800, wrote: > Signed-off-by: Bruno Alvisio> +void resume_time(void) > +{ > +port = bind_virq(VIRQ_TIMER, _handler, NULL); > +unmask_evtchn(port); > +} I'd say rather factorize it with init_time. (you could even just remove the printf there to avoid having to write yet another function) > diff --git a/include/time.h b/include/time.h > index 5d6ed67..2e06d58 100644 > --- a/include/time.h > +++ b/include/time.h > @@ -55,6 +55,8 @@ typedef long suseconds_t; > /* prototypes */ > void init_time(void); > void fini_time(void); > +void suspend_time(void); > +void resume_time(void); > s_time_t get_s_time(void); > s_time_t get_v_time(void); > uint64_t monotonic_clock(void); > diff --git a/kernel.c b/kernel.c > index 782eb79..a16b1ba 100644 > --- a/kernel.c > +++ b/kernel.c > @@ -120,10 +120,14 @@ void start_kernel(void* par) > void pre_suspend(void) > { > local_irq_disable(); > + > +suspend_time(); > } > > void post_suspend(int canceled) > { > +resume_time(); > + > local_irq_enable(); > } > > -- > 2.3.2 (Apple Git-55) > > > ___ > Minios-devel mailing list > minios-de...@lists.xenproject.org > https://lists.xenproject.org/mailman/listinfo/minios-devel -- Samuel ça gaze ? prout -+- #ens-mim - ouvrez les fenêtres ! -+- ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [Minios-devel] [PATCH RFC 08/16] Save/Restore Support: Add arch_mm_pre|post_suspend
Bruno Alvisio, on mar. 19 déc. 2017 15:42:03 -0800, wrote: > For PV guests the pagetables reference the real MFNs rather than PFNs, so when > the guest is resumed into a different area of a hosts memory, these will need > to > be rewritten. Thus for PV guests the MFNs need to be replaced with PFNs: > canonicalization. > > PVH guests are auto-translated so no memory operation is needed. > > Signed-off-by: Bruno AlvisioReviewed-by: Samuel Thibault > --- > arch/x86/mm.c | 14 ++ > include/x86/arch_mm.h | 3 +++ > 2 files changed, 17 insertions(+) > > diff --git a/arch/x86/mm.c b/arch/x86/mm.c > index 05ad029..1b163ac 100644 > --- a/arch/x86/mm.c > +++ b/arch/x86/mm.c > @@ -848,6 +848,20 @@ void arch_init_p2m(unsigned long max_pfn) > > arch_remap_p2m(max_pfn); > } > + > +void arch_mm_pre_suspend(void) > +{ > +//TODO: Canonicalize pagetables > +} > + > +void arch_mm_post_suspend(int canceled) > +{ > +//TODO: Locate pagetables and 'uncanonicalize' them > +} > +#else > +void arch_mm_pre_suspend(void){ } > + > +void arch_mm_post_suspend(int canceled){ } > #endif > > void arch_init_mm(unsigned long* start_pfn_p, unsigned long* max_pfn_p) > diff --git a/include/x86/arch_mm.h b/include/x86/arch_mm.h > index ab8a53e..cbbeb21 100644 > --- a/include/x86/arch_mm.h > +++ b/include/x86/arch_mm.h > @@ -279,6 +279,9 @@ pgentry_t *need_pgt(unsigned long addr); > void arch_mm_preinit(void *p); > unsigned long alloc_virt_kernel(unsigned n_pages); > > +void arch_mm_pre_suspend(void); > +void arch_mm_post_suspend(int canceled); > + > #ifndef CONFIG_PARAVIRT > void arch_print_memmap(void); > #endif > -- > 2.3.2 (Apple Git-55) > > > ___ > Minios-devel mailing list > minios-de...@lists.xenproject.org > https://lists.xenproject.org/mailman/listinfo/minios-devel -- Samuel J'ai un gros problème: j'ai cet exercice à rendre demain lundi, mais ma TI 89 ne sait pas le faire... Est-ce que quelqu'un pourrait m'aider?? -+- OD In Guide du Neuneu Usenet : Comment ça ! Il faut réfléchir ?-+- ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [Minios-devel] [PATCH RFC 09/16] Save/Restore Support: Disable/enable IRQs during suspend/restore
Bruno Alvisio, on mar. 19 déc. 2017 15:42:04 -0800, wrote: > Signed-off-by: Bruno AlvisioReviewed-by: Samuel Thibault > --- > kernel.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/kernel.c b/kernel.c > index 1cd40e8..782eb79 100644 > --- a/kernel.c > +++ b/kernel.c > @@ -119,12 +119,12 @@ void start_kernel(void* par) > > void pre_suspend(void) > { > - > +local_irq_disable(); > } > > void post_suspend(int canceled) > { > - > +local_irq_enable(); > } > > void stop_kernel(void) > -- > 2.3.2 (Apple Git-55) > > > ___ > Minios-devel mailing list > minios-de...@lists.xenproject.org > https://lists.xenproject.org/mailman/listinfo/minios-devel -- Samuel Q: How do you play religious roulette? A: You stand around in a circle and blaspheme and see who gets struck by lightning first. ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [Minios-devel] [PATCH RFC 07/16] Save/Restore Support: Add unmap_shared_info
Bruno Alvisio, on mar. 19 déc. 2017 15:42:02 -0800, wrote: > This function is necessary as part of the pre-suspend operation. > > Signed-off-by: Bruno Alvisio> --- > +void unmap_shared_info(void) > +{ > +int rc; > + > +if ( (rc = HYPERVISOR_update_va_mapping((unsigned > long)HYPERVISOR_shared_info, For coherency, I'd say use shared_info there too. Apart from that, Reviewed-by: Samuel Thibault > +__pte((virt_to_mfn(shared_info)< UVMF_INVLPG)) ) > +{ > +printk("Failed to unmap shared_info page!! rc=%d\n", rc); > +do_exit(); > +} > +} > + > static void get_cmdline(void *p) > { > start_info_t *si = p; > diff --git a/hypervisor.c b/hypervisor.c > index 1647121..d3857e7 100644 > --- a/hypervisor.c > +++ b/hypervisor.c > @@ -78,6 +78,18 @@ shared_info_t *map_shared_info(void *p) > > return _info; > } > + > +void unmap_shared_info(void) > +{ > +struct xen_remove_from_physmap xrtp; > + > +xrtp.domid = DOMID_SELF; > +xrtp.gpfn = virt_to_pfn(_info); > +if ( HYPERVISOR_memory_op(XENMEM_remove_from_physmap, ) != 0 ) > +BUG(); > + > +return; > +} > #endif > > void do_hypervisor_callback(struct pt_regs *regs) > diff --git a/include/hypervisor.h b/include/hypervisor.h > index f3b1f3c..1d09271 100644 > --- a/include/hypervisor.h > +++ b/include/hypervisor.h > @@ -43,6 +43,7 @@ int hvm_get_parameter(int idx, uint64_t *value); > int hvm_set_parameter(int idx, uint64_t value); > #endif > shared_info_t *map_shared_info(void *p); > +void unmap_shared_info(void); > void force_evtchn_callback(void); > void do_hypervisor_callback(struct pt_regs *regs); > void mask_evtchn(uint32_t port); > -- > 2.3.2 (Apple Git-55) > > > ___ > Minios-devel mailing list > minios-de...@lists.xenproject.org > https://lists.xenproject.org/mailman/listinfo/minios-devel -- Samuel la vraie vie, c'est quand le prompt passe de $ à # ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [Minios-devel] [PATCH RFC 05/16] Save/Restore Support: Add kernel shutdown logic to shutdown.c
Bruno Alvisio, on mar. 19 déc. 2017 15:42:00 -0800, wrote: > + * NEC Europe Ltd. PROPRIETARY INFORMATION > + * > + * This software is supplied under the terms of a license agreement > + * or nondisclosure agreement with NEC Europe Ltd. and may not be > + * copied or disclosed except in accordance with the terms of that > + * agreement. The software and its source code contain valuable trade > + * secrets and confidential information which have to be maintained in > + * confidence. > + * Any unauthorized publication, transfer to third parties or duplication > + * of the object or source code - either totally or in part – is > + * prohibited. > + * > + * Copyright (c) 2014 NEC Europe Ltd. All Rights Reserved. > + * > + * Authors: Filipe Manco> + * > + * NEC Europe Ltd. DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, > + * INCLUDING BUT NOT LIMITED TO IMPLIED WARRANTIES OF MERCHANTABILITY > + * AND FITNESS FOR A PARTICULAR PURPOSE AND THE WARRANTY AGAINST LATENT > + * DEFECTS, WITH RESPECT TO THE PROGRAM AND THE ACCOMPANYING > + * DOCUMENTATION. > + * > + * No Liability For Consequential Damages IN NO EVENT SHALL NEC Europe > + * Ltd., NEC Corporation OR ANY OF ITS SUBSIDIARIES BE LIABLE FOR ANY > + * DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS > + * OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF INFORMATION, OR > + * OTHER PECUNIARY LOSS AND INDIRECT, CONSEQUENTIAL, INCIDENTAL, > + * ECONOMIC OR PUNITIVE DAMAGES) ARISING OUT OF THE USE OF OR INABILITY > + * TO USE THIS PROGRAM, EVEN IF NEC Europe Ltd. HAS BEEN ADVISED OF THE > + * POSSIBILITY OF SUCH DAMAGES. > + * > + * THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY. Err, AIUI, this makes it unusable for mini-os (or whatever free software). Samuel ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [Minios-devel] [PATCH RFC 04/16] Save/Restore Support: Add xenbus_release_wait_for_watch
Bruno Alvisio, on mar. 19 déc. 2017 15:41:59 -0800, wrote: > xenbus_release_wait_for_watch generates a fake event to trigger make > xenbus_wait_for_watch return. This is necessary to wake up waiting threads. Please also document the release_xenbus_id change. > Signed-off-by: Bruno AlvisioReviewed-by: Samuel Thibault > --- > include/xenbus.h | 1 + > xenbus/xenbus.c | 10 +- > 2 files changed, 10 insertions(+), 1 deletion(-) > > diff --git a/include/xenbus.h b/include/xenbus.h > index 12391b9..b2d5072 100644 > --- a/include/xenbus.h > +++ b/include/xenbus.h > @@ -42,6 +42,7 @@ char *xenbus_unwatch_path_token(xenbus_transaction_t xbt, > const char *path, cons > extern struct wait_queue_head xenbus_watch_queue; > void xenbus_wait_for_watch(xenbus_event_queue *queue); > char **xenbus_wait_for_watch_return(xenbus_event_queue *queue); > +void xenbus_release_wait_for_watch(xenbus_event_queue *queue); > char* xenbus_wait_for_value(const char *path, const char *value, > xenbus_event_queue *queue); > char *xenbus_wait_for_state_change(const char* path, XenbusState *state, > xenbus_event_queue *queue); > char *xenbus_switch_state(xenbus_transaction_t xbt, const char* path, > XenbusState state); > diff --git a/xenbus/xenbus.c b/xenbus/xenbus.c > index 636786c..c2d2bd1 100644 > --- a/xenbus/xenbus.c > +++ b/xenbus/xenbus.c > @@ -129,6 +129,14 @@ void xenbus_wait_for_watch(xenbus_event_queue *queue) > printk("unexpected path returned by watch\n"); > } > > +void xenbus_release_wait_for_watch(xenbus_event_queue *queue) > +{ > +struct xenbus_event *event = malloc(sizeof(*event)); > +event->next = *queue; > +*queue = event; > +wake_up(_watch_queue); > +} > + > char* xenbus_wait_for_value(const char* path, const char* value, > xenbus_event_queue *queue) > { > if (!queue) > @@ -318,7 +326,7 @@ static void release_xenbus_id(int id) > req_info[id].in_use = 0; > nr_live_reqs--; > req_info[id].in_use = 0; > -if (nr_live_reqs == NR_REQS - 1) > +if (nr_live_reqs == 0 || nr_live_reqs == NR_REQS - 1) > wake_up(_wq); > spin_unlock(_lock); > } > -- > 2.3.2 (Apple Git-55) > > > ___ > Minios-devel mailing list > minios-de...@lists.xenproject.org > https://lists.xenproject.org/mailman/listinfo/minios-devel -- Samuel "c'est pas nous qui sommes à la rue, c'est la rue qui est à nous" ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [Minios-devel] [PATCH RFC 03/16] Save/Restore Support: Declare kernel and arch pre/post suspend functions
Bruno Alvisio, on mar. 19 déc. 2017 15:41:58 -0800, wrote: > For mini-OS to support suspend and restore, the kernel will have to suspend > different modules such as xenbus, console, irq, etc. During save/restore the > kernel and arch pre_suspend and post_suspend functions will be invoked to > suspend/resume each of the modules. > > Signed-off-by: Bruno AlvisioReviewed-by: Samuel Thibault > --- > arch/x86/setup.c | 10 ++ > include/kernel.h | 2 ++ > include/x86/os.h | 4 ++-- > kernel.c | 10 ++ > 4 files changed, 24 insertions(+), 2 deletions(-) > > diff --git a/arch/x86/setup.c b/arch/x86/setup.c > index 5278227..3dd86f9 100644 > --- a/arch/x86/setup.c > +++ b/arch/x86/setup.c > @@ -204,6 +204,16 @@ arch_init(void *par) > start_kernel(); > } > > +void arch_pre_suspend(void) > +{ > + > +} > + > +void arch_post_suspend(int canceled) > +{ > + > +} > + > void > arch_fini(void) > { > diff --git a/include/kernel.h b/include/kernel.h > index d37ddda..161d757 100644 > --- a/include/kernel.h > +++ b/include/kernel.h > @@ -5,6 +5,8 @@ > extern char cmdline[MAX_CMDLINE_SIZE]; > > void start_kernel(void); > +void pre_suspend(void); > +void post_suspend(int canceled); > void do_exit(void) __attribute__((noreturn)); > void arch_do_exit(void); > void stop_kernel(void); > diff --git a/include/x86/os.h b/include/x86/os.h > index d155914..a73b63e 100644 > --- a/include/x86/os.h > +++ b/include/x86/os.h > @@ -71,10 +71,10 @@ void trap_fini(void); > void xen_callback_vector(void); > #endif > > +void arch_pre_suspend(void); > +void arch_post_suspend(int canceled); > void arch_fini(void); > > - > - > #ifdef CONFIG_PARAVIRT > > /* > diff --git a/kernel.c b/kernel.c > index 0d84a9b..90c865a 100644 > --- a/kernel.c > +++ b/kernel.c > @@ -155,6 +155,16 @@ void start_kernel(void) > run_idle_thread(); > } > > +void pre_suspend(void) > +{ > + > +} > + > +void post_suspend(int canceled) > +{ > + > +} > + > void stop_kernel(void) > { > /* TODO: fs import */ > -- > 2.3.2 (Apple Git-55) > > > ___ > Minios-devel mailing list > minios-de...@lists.xenproject.org > https://lists.xenproject.org/mailman/listinfo/minios-devel -- Samuel r: et la marmotte, elle écrit un papier IPDPS ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [Minios-devel] [PATCH RFC 02/16] Save/Restore Support: Refactor trap_init() and setup vector callbacks
Bruno Alvisio, on mar. 19 déc. 2017 15:41:57 -0800, wrote: > Currently the setup of the IDT and the request to set the HVM vector callbacks > are performed both in the trap_init function. > > As part of the post-suspend operation, the HVM vector callback needs to be > setup > again while the IDT does not. Thus, the trap_init function is split into two > separate functions: trap_init (sets up IDT) and xen_callback_vector (sets the > HVM vector callback). During the post-suspend operations the > xen_callback_vector > function will be invoked. > > Signed-off-by: Bruno AlvisioReviewed-by: Samuel Thibault > --- > arch/x86/traps.c | 17 +++-- > include/x86/os.h | 3 +++ > 2 files changed, 14 insertions(+), 6 deletions(-) > > diff --git a/arch/x86/traps.c b/arch/x86/traps.c > index aa17da3..a7388a5 100644 > --- a/arch/x86/traps.c > +++ b/arch/x86/traps.c > @@ -389,6 +389,16 @@ static void setup_gate(unsigned int entry, void *addr, > unsigned int dpl) > #endif > } > > +void xen_callback_vector(void) > +{ > +if (hvm_set_parameter(HVM_PARAM_CALLBACK_IRQ, > + (2ULL << 56) | TRAP_xen_callback)) > +{ > +xprintk("Request for Xen HVM callback vector failed\n"); > +do_exit(); > +} > +} > + > void trap_init(void) > { > setup_gate(TRAP_divide_error, _error, 0); > @@ -415,12 +425,7 @@ void trap_init(void) > gdt[GDTE_TSS] = (typeof(*gdt))INIT_GDTE((unsigned long), 0x67, 0x89); > asm volatile ("ltr %w0" :: "rm" (GDTE_TSS * 8)); > > -if ( hvm_set_parameter(HVM_PARAM_CALLBACK_IRQ, > - (2ULL << 56) | TRAP_xen_callback) ) > -{ > -xprintk("Request for Xen HVM callback vector failed\n"); > -do_exit(); > -} > +xen_callback_vector(); > } > > void trap_fini(void) > diff --git a/include/x86/os.h b/include/x86/os.h > index fbc2eeb..d155914 100644 > --- a/include/x86/os.h > +++ b/include/x86/os.h > @@ -67,6 +67,9 @@ extern shared_info_t *HYPERVISOR_shared_info; > > void trap_init(void); > void trap_fini(void); > +#ifndef CONFIG_PARAVIRT > +void xen_callback_vector(void); > +#endif > > void arch_fini(void); > > -- > 2.3.2 (Apple Git-55) > > > ___ > Minios-devel mailing list > minios-de...@lists.xenproject.org > https://lists.xenproject.org/mailman/listinfo/minios-devel -- Samuel Ça peut être une madeleine à sous munitions (avec des composants, par exemple) -+- #runtime -+- ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [Minios-devel] [PATCH RFC 01/16] Save/Restore Support: Refactor HYPERVISOR_suspend hypercall
Bruno Alvisio, on mar. 19 déc. 2017 15:41:56 -0800, wrote: > Directly using the SHUTDOWN_suspend macro as a parameter for the schedop > hypercall causes an error in the Xen hypercall handler. Also for consistency, > the SHUTDOWN_suspend param is wrapped in the sched_shutdown struct. > > Signed-off-by: Bruno AlvisioReviewed-by: Samuel Thibault > --- > include/x86/x86_32/hypercall-x86_32.h | 4 ++-- > include/x86/x86_64/hypercall-x86_64.h | 4 ++-- > 2 files changed, 4 insertions(+), 4 deletions(-) > > diff --git a/include/x86/x86_32/hypercall-x86_32.h > b/include/x86/x86_32/hypercall-x86_32.h > index 5c93464..70505a4 100644 > --- a/include/x86/x86_32/hypercall-x86_32.h > +++ b/include/x86/x86_32/hypercall-x86_32.h > @@ -298,8 +298,8 @@ static inline int > HYPERVISOR_suspend( > unsigned long srec) > { > - return _hypercall3(int, sched_op, SCHEDOP_shutdown, > -SHUTDOWN_suspend, srec); > + struct sched_shutdown shutdown = { .reason = SHUTDOWN_suspend }; > + return _hypercall3(int, sched_op, SCHEDOP_shutdown, , srec); > } > > static inline int > diff --git a/include/x86/x86_64/hypercall-x86_64.h > b/include/x86/x86_64/hypercall-x86_64.h > index 6171812..95f8ade 100644 > --- a/include/x86/x86_64/hypercall-x86_64.h > +++ b/include/x86/x86_64/hypercall-x86_64.h > @@ -305,8 +305,8 @@ static inline int > HYPERVISOR_suspend( > unsigned long srec) > { > - return _hypercall3(int, sched_op, SCHEDOP_shutdown, > -SHUTDOWN_suspend, srec); > + struct sched_shutdown shutdown = { .reason = SHUTDOWN_suspend }; > + return _hypercall3(int, sched_op, SCHEDOP_shutdown, , srec); > } > > static inline int > -- > 2.3.2 (Apple Git-55) > > > ___ > Minios-devel mailing list > minios-de...@lists.xenproject.org > https://lists.xenproject.org/mailman/listinfo/minios-devel -- Samuel csp.tar.gz: ascii text -+- #ens-mim - vive les browsers qui prennent des initiatives à la con -+- ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [PATCH RFC 07/16] Save/Restore Support: Add unmap_shared_info
This function is necessary as part of the pre-suspend operation. Signed-off-by: Bruno Alvisio--- arch/x86/setup.c | 12 hypervisor.c | 12 include/hypervisor.h | 1 + 3 files changed, 25 insertions(+) diff --git a/arch/x86/setup.c b/arch/x86/setup.c index 31fa2c6..3eabce4 100644 --- a/arch/x86/setup.c +++ b/arch/x86/setup.c @@ -93,6 +93,18 @@ shared_info_t *map_shared_info(void *p) return (shared_info_t *)shared_info; } +void unmap_shared_info(void) +{ +int rc; + +if ( (rc = HYPERVISOR_update_va_mapping((unsigned long)HYPERVISOR_shared_info, +__pte((virt_to_mfn(shared_info)<
[Xen-devel] [PATCH RFC 14/16] Save/Restore Support: Add suspend/restore support for xenbus
Currently the watch path is not saved in the watch struct when it is registered. During xenbus resume the path is needed so that the watches can be registered again. Thus, 'path' field is added to struct watch so that watches can be re-registered during xenbus resume. Signed-off-by: Bruno Alvisio--- include/xenbus.h | 2 ++ kernel.c | 8 + xenbus/xenbus.c | 106 +++ 3 files changed, 85 insertions(+), 31 deletions(-) diff --git a/include/xenbus.h b/include/xenbus.h index b2d5072..3871f35 100644 --- a/include/xenbus.h +++ b/include/xenbus.h @@ -120,6 +120,8 @@ domid_t xenbus_get_self_id(void); #ifdef CONFIG_XENBUS /* Reset the XenBus system. */ void fini_xenbus(void); +void suspend_xenbus(void); +void resume_xenbus(int canceled); #else static inline void fini_xenbus(void) { diff --git a/kernel.c b/kernel.c index a563f60..bc2394f 100644 --- a/kernel.c +++ b/kernel.c @@ -119,6 +119,10 @@ void start_kernel(void* par) void pre_suspend(void) { +#ifdef CONFIG_XENBUS +suspend_xenbus(); +#endif + local_irq_disable(); suspend_gnttab(); @@ -139,6 +143,10 @@ void post_suspend(int canceled) resume_gnttab(); local_irq_enable(); + +#ifdef CONFIG_XENBUS +resume_xenbus(canceled); +#endif } void stop_kernel(void) diff --git a/xenbus/xenbus.c b/xenbus/xenbus.c index c2d2bd1..4c626fb 100644 --- a/xenbus/xenbus.c +++ b/xenbus/xenbus.c @@ -50,6 +50,7 @@ DECLARE_WAIT_QUEUE_HEAD(xenbus_watch_queue); xenbus_event_queue xenbus_events; static struct watch { char *token; +char *path; xenbus_event_queue *events; struct watch *next; } *watches; @@ -63,6 +64,8 @@ struct xenbus_req_info #define NR_REQS 32 static struct xenbus_req_info req_info[NR_REQS]; +static char *errmsg(struct xsd_sockmsg *rep); + uint32_t xenbus_evtchn; #ifdef CONFIG_PARAVIRT @@ -231,45 +234,39 @@ static void xenbus_thread_func(void *ign) struct xsd_sockmsg msg; unsigned prod = xenstore_buf->rsp_prod; -for (;;) -{ +for (;;) { wait_event(xb_waitq, prod != xenstore_buf->rsp_prod); -while (1) -{ +while (1) { prod = xenstore_buf->rsp_prod; DEBUG("Rsp_cons %d, rsp_prod %d.\n", xenstore_buf->rsp_cons, -xenstore_buf->rsp_prod); + xenstore_buf->rsp_prod); if (xenstore_buf->rsp_prod - xenstore_buf->rsp_cons < sizeof(msg)) break; rmb(); -memcpy_from_ring(xenstore_buf->rsp, -, -MASK_XENSTORE_IDX(xenstore_buf->rsp_cons), -sizeof(msg)); -DEBUG("Msg len %d, %d avail, id %d.\n", -msg.len + sizeof(msg), -xenstore_buf->rsp_prod - xenstore_buf->rsp_cons, -msg.req_id); +memcpy_from_ring(xenstore_buf->rsp, , + MASK_XENSTORE_IDX(xenstore_buf->rsp_cons), + sizeof(msg)); +DEBUG("Msg len %d, %d avail, id %d.\n", msg.len + sizeof(msg), + xenstore_buf->rsp_prod - xenstore_buf->rsp_cons, msg.req_id); + if (xenstore_buf->rsp_prod - xenstore_buf->rsp_cons < -sizeof(msg) + msg.len) +sizeof(msg) + msg.len) break; DEBUG("Message is good.\n"); -if(msg.type == XS_WATCH_EVENT) -{ - struct xenbus_event *event = malloc(sizeof(*event) + msg.len); +if (msg.type == XS_WATCH_EVENT) { + struct xenbus_event *event = malloc(sizeof(*event) + msg.len); xenbus_event_queue *events = NULL; - char *data = (char*)event + sizeof(*event); + char *data = (char*)event + sizeof(*event); struct watch *watch; -memcpy_from_ring(xenstore_buf->rsp, - data, +memcpy_from_ring(xenstore_buf->rsp, data, MASK_XENSTORE_IDX(xenstore_buf->rsp_cons + sizeof(msg)), msg.len); - event->path = data; - event->token = event->path + strlen(event->path) + 1; + event->path = data; + event->token = event->path + strlen(event->path) + 1; mb(); xenstore_buf->rsp_cons += msg.len + sizeof(msg); @@ -288,15 +285,11 @@ static void xenbus_thread_func(void *ign) printk("unexpected watch token %s\n", event->token); free(event); } -} - -else -{ +} else { req_info[msg.req_id].reply = malloc(sizeof(msg) + msg.len); -memcpy_from_ring(xenstore_buf->rsp, -req_info[msg.req_id].reply, -
[Xen-devel] [PATCH RFC 04/16] Save/Restore Support: Add xenbus_release_wait_for_watch
xenbus_release_wait_for_watch generates a fake event to trigger make xenbus_wait_for_watch return. This is necessary to wake up waiting threads. Signed-off-by: Bruno Alvisio--- include/xenbus.h | 1 + xenbus/xenbus.c | 10 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/include/xenbus.h b/include/xenbus.h index 12391b9..b2d5072 100644 --- a/include/xenbus.h +++ b/include/xenbus.h @@ -42,6 +42,7 @@ char *xenbus_unwatch_path_token(xenbus_transaction_t xbt, const char *path, cons extern struct wait_queue_head xenbus_watch_queue; void xenbus_wait_for_watch(xenbus_event_queue *queue); char **xenbus_wait_for_watch_return(xenbus_event_queue *queue); +void xenbus_release_wait_for_watch(xenbus_event_queue *queue); char* xenbus_wait_for_value(const char *path, const char *value, xenbus_event_queue *queue); char *xenbus_wait_for_state_change(const char* path, XenbusState *state, xenbus_event_queue *queue); char *xenbus_switch_state(xenbus_transaction_t xbt, const char* path, XenbusState state); diff --git a/xenbus/xenbus.c b/xenbus/xenbus.c index 636786c..c2d2bd1 100644 --- a/xenbus/xenbus.c +++ b/xenbus/xenbus.c @@ -129,6 +129,14 @@ void xenbus_wait_for_watch(xenbus_event_queue *queue) printk("unexpected path returned by watch\n"); } +void xenbus_release_wait_for_watch(xenbus_event_queue *queue) +{ +struct xenbus_event *event = malloc(sizeof(*event)); +event->next = *queue; +*queue = event; +wake_up(_watch_queue); +} + char* xenbus_wait_for_value(const char* path, const char* value, xenbus_event_queue *queue) { if (!queue) @@ -318,7 +326,7 @@ static void release_xenbus_id(int id) req_info[id].in_use = 0; nr_live_reqs--; req_info[id].in_use = 0; -if (nr_live_reqs == NR_REQS - 1) +if (nr_live_reqs == 0 || nr_live_reqs == NR_REQS - 1) wake_up(_wq); spin_unlock(_lock); } -- 2.3.2 (Apple Git-55) ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [PATCH RFC 15/16] Save/Restore Support: Add suspend/restore support for netfront
Performed an additional cleanup to make the file more syntactically consistent. Signed-off-by: Bruno Alvisio--- include/netfront.h | 8 +- kernel.c | 8 ++ netfront.c | 242 + 3 files changed, 204 insertions(+), 54 deletions(-) diff --git a/include/netfront.h b/include/netfront.h index 2b95da9..1164d50 100644 --- a/include/netfront.h +++ b/include/netfront.h @@ -3,9 +3,15 @@ #include #endif struct netfront_dev; -struct netfront_dev *init_netfront(char *nodename, void (*netif_rx)(unsigned char *data, int len), unsigned char rawmac[6], char **ip); +struct netfront_dev *init_netfront(char *nodename, + void (*netif_rx)(unsigned char *data, +int len, void* arg), + unsigned char rawmac[6], + char **ip); void netfront_xmit(struct netfront_dev *dev, unsigned char* data,int len); void shutdown_netfront(struct netfront_dev *dev); +void suspend_netfront(void); +void resume_netfront(void); #ifdef HAVE_LIBC int netfront_tap_open(char *nodename); ssize_t netfront_receive(struct netfront_dev *dev, unsigned char *data, size_t len); diff --git a/kernel.c b/kernel.c index bc2394f..805539e 100644 --- a/kernel.c +++ b/kernel.c @@ -119,6 +119,10 @@ void start_kernel(void* par) void pre_suspend(void) { +#ifdef CONFIG_NETFRONT +suspend_netfront(); +#endif + #ifdef CONFIG_XENBUS suspend_xenbus(); #endif @@ -147,6 +151,10 @@ void post_suspend(int canceled) #ifdef CONFIG_XENBUS resume_xenbus(canceled); #endif + +#ifdef CONFIG_NETFRONT +resume_netfront(); +#endif } void stop_kernel(void) diff --git a/netfront.c b/netfront.c index b8fac62..9aef42b 100644 --- a/netfront.c +++ b/netfront.c @@ -63,10 +63,29 @@ struct netfront_dev { size_t rlen; #endif -void (*netif_rx)(unsigned char* data, int len); +void (*netif_rx)(unsigned char* data, int len, void* arg); +void *netif_rx_arg; }; +struct netfront_dev_list { + struct netfront_dev *dev; + unsigned char rawmac[6]; + char *ip; + + int refcount; + + struct netfront_dev_list *next; +}; + +static struct netfront_dev_list *dev_list = NULL; + void init_rx_buffers(struct netfront_dev *dev); +static struct netfront_dev *_init_netfront(struct netfront_dev *dev, + unsigned char rawmac[6], char **ip); +static void _shutdown_netfront(struct netfront_dev *dev); +void netfront_set_rx_handler(struct netfront_dev *dev, +void (*thenetif_rx)(unsigned char *data, int len, +void *arg), void *arg); static inline void add_id_to_freelist(unsigned int id,unsigned short* freelist) { @@ -81,7 +100,7 @@ static inline unsigned short get_id_from_freelist(unsigned short* freelist) return id; } -__attribute__((weak)) void netif_rx(unsigned char* data,int len) +__attribute__((weak)) void netif_rx(unsigned char* data, int len, void *arg) { printk("%d bytes incoming at %p\n",len,data); } @@ -134,7 +153,7 @@ moretodo: dobreak = 1; } else #endif - dev->netif_rx(page+rx->offset,rx->status); + dev->netif_rx(page+rx->offset, rx->status, dev->netif_rx_arg); } } dev->rx.rsp_cons=cons; @@ -282,19 +301,16 @@ static void free_netfront(struct netfront_dev *dev) free(dev); } -struct netfront_dev *init_netfront(char *_nodename, void (*thenetif_rx)(unsigned char* data, int len), unsigned char rawmac[6], char **ip) +struct netfront_dev *init_netfront(char *_nodename, + void (*thenetif_rx)(unsigned char* data, + int len, void* arg), + unsigned char rawmac[6], + char **ip) { -xenbus_transaction_t xbt; -char* err; -char* message=NULL; -struct netif_tx_sring *txs; -struct netif_rx_sring *rxs; -int retry=0; -int i; -char* msg = NULL; char nodename[256]; -char path[256]; struct netfront_dev *dev; +struct netfront_dev_list *ldev = NULL; +struct netfront_dev_list *list = NULL; static int netfrontends = 0; if (!_nodename) @@ -303,10 +319,20 @@ struct netfront_dev *init_netfront(char *_nodename, void (*thenetif_rx)(unsigned strncpy(nodename, _nodename, sizeof(nodename) - 1); nodename[sizeof(nodename) - 1] = 0; } -netfrontends++; + +/* Check if the device is already initialized */ +for (list = dev_list; list != NULL; list = list->next) { +if (strcmp(nodename, list->dev->nodename) == 0) { +list->refcount++; +dev = list->dev; +if (thenetif_rx) +
[Xen-devel] [PATCH RFC 09/16] Save/Restore Support: Disable/enable IRQs during suspend/restore
Signed-off-by: Bruno Alvisio--- kernel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel.c b/kernel.c index 1cd40e8..782eb79 100644 --- a/kernel.c +++ b/kernel.c @@ -119,12 +119,12 @@ void start_kernel(void* par) void pre_suspend(void) { - +local_irq_disable(); } void post_suspend(int canceled) { - +local_irq_enable(); } void stop_kernel(void) -- 2.3.2 (Apple Git-55) ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [PATCH RFC 03/16] Save/Restore Support: Declare kernel and arch pre/post suspend functions
For mini-OS to support suspend and restore, the kernel will have to suspend different modules such as xenbus, console, irq, etc. During save/restore the kernel and arch pre_suspend and post_suspend functions will be invoked to suspend/resume each of the modules. Signed-off-by: Bruno Alvisio--- arch/x86/setup.c | 10 ++ include/kernel.h | 2 ++ include/x86/os.h | 4 ++-- kernel.c | 10 ++ 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/arch/x86/setup.c b/arch/x86/setup.c index 5278227..3dd86f9 100644 --- a/arch/x86/setup.c +++ b/arch/x86/setup.c @@ -204,6 +204,16 @@ arch_init(void *par) start_kernel(); } +void arch_pre_suspend(void) +{ + +} + +void arch_post_suspend(int canceled) +{ + +} + void arch_fini(void) { diff --git a/include/kernel.h b/include/kernel.h index d37ddda..161d757 100644 --- a/include/kernel.h +++ b/include/kernel.h @@ -5,6 +5,8 @@ extern char cmdline[MAX_CMDLINE_SIZE]; void start_kernel(void); +void pre_suspend(void); +void post_suspend(int canceled); void do_exit(void) __attribute__((noreturn)); void arch_do_exit(void); void stop_kernel(void); diff --git a/include/x86/os.h b/include/x86/os.h index d155914..a73b63e 100644 --- a/include/x86/os.h +++ b/include/x86/os.h @@ -71,10 +71,10 @@ void trap_fini(void); void xen_callback_vector(void); #endif +void arch_pre_suspend(void); +void arch_post_suspend(int canceled); void arch_fini(void); - - #ifdef CONFIG_PARAVIRT /* diff --git a/kernel.c b/kernel.c index 0d84a9b..90c865a 100644 --- a/kernel.c +++ b/kernel.c @@ -155,6 +155,16 @@ void start_kernel(void) run_idle_thread(); } +void pre_suspend(void) +{ + +} + +void post_suspend(int canceled) +{ + +} + void stop_kernel(void) { /* TODO: fs import */ -- 2.3.2 (Apple Git-55) ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [PATCH RFC 02/16] Save/Restore Support: Refactor trap_init() and setup vector callbacks
Currently the setup of the IDT and the request to set the HVM vector callbacks are performed both in the trap_init function. As part of the post-suspend operation, the HVM vector callback needs to be setup again while the IDT does not. Thus, the trap_init function is split into two separate functions: trap_init (sets up IDT) and xen_callback_vector (sets the HVM vector callback). During the post-suspend operations the xen_callback_vector function will be invoked. Signed-off-by: Bruno Alvisio--- arch/x86/traps.c | 17 +++-- include/x86/os.h | 3 +++ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/arch/x86/traps.c b/arch/x86/traps.c index aa17da3..a7388a5 100644 --- a/arch/x86/traps.c +++ b/arch/x86/traps.c @@ -389,6 +389,16 @@ static void setup_gate(unsigned int entry, void *addr, unsigned int dpl) #endif } +void xen_callback_vector(void) +{ +if (hvm_set_parameter(HVM_PARAM_CALLBACK_IRQ, + (2ULL << 56) | TRAP_xen_callback)) +{ +xprintk("Request for Xen HVM callback vector failed\n"); +do_exit(); +} +} + void trap_init(void) { setup_gate(TRAP_divide_error, _error, 0); @@ -415,12 +425,7 @@ void trap_init(void) gdt[GDTE_TSS] = (typeof(*gdt))INIT_GDTE((unsigned long), 0x67, 0x89); asm volatile ("ltr %w0" :: "rm" (GDTE_TSS * 8)); -if ( hvm_set_parameter(HVM_PARAM_CALLBACK_IRQ, - (2ULL << 56) | TRAP_xen_callback) ) -{ -xprintk("Request for Xen HVM callback vector failed\n"); -do_exit(); -} +xen_callback_vector(); } void trap_fini(void) diff --git a/include/x86/os.h b/include/x86/os.h index fbc2eeb..d155914 100644 --- a/include/x86/os.h +++ b/include/x86/os.h @@ -67,6 +67,9 @@ extern shared_info_t *HYPERVISOR_shared_info; void trap_init(void); void trap_fini(void); +#ifndef CONFIG_PARAVIRT +void xen_callback_vector(void); +#endif void arch_fini(void); -- 2.3.2 (Apple Git-55) ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [PATCH RFC 06/16] Save/Restore Support: Moved shutdown thread to shutdown.c
The shutdown thread present in kernel.c was removed and now the thread in shutdown.c is created instead. Signed-off-by: Bruno Alvisio--- arch/x86/setup.c | 2 +- include/kernel.h | 2 +- kernel.c | 50 ++ 3 files changed, 8 insertions(+), 46 deletions(-) diff --git a/arch/x86/setup.c b/arch/x86/setup.c index 3dd86f9..31fa2c6 100644 --- a/arch/x86/setup.c +++ b/arch/x86/setup.c @@ -201,7 +201,7 @@ arch_init(void *par) memcpy(_info, par, sizeof(start_info)); #endif - start_kernel(); + start_kernel((start_info_t *)par); } void arch_pre_suspend(void) diff --git a/include/kernel.h b/include/kernel.h index 161d757..742abf5 100644 --- a/include/kernel.h +++ b/include/kernel.h @@ -4,7 +4,7 @@ #define MAX_CMDLINE_SIZE 1024 extern char cmdline[MAX_CMDLINE_SIZE]; -void start_kernel(void); +void start_kernel(void* par); void pre_suspend(void); void post_suspend(int canceled); void do_exit(void) __attribute__((noreturn)); diff --git a/kernel.c b/kernel.c index 90c865a..1cd40e8 100644 --- a/kernel.c +++ b/kernel.c @@ -42,6 +42,9 @@ #include #include #include +#ifdef CONFIG_XENBUS +#include +#endif #include #include #include @@ -66,48 +69,6 @@ void setup_xen_features(void) } } -#ifdef CONFIG_XENBUS -/* This should be overridden by the application we are linked against. */ -__attribute__((weak)) void app_shutdown(unsigned reason) -{ -struct sched_shutdown sched_shutdown = { .reason = reason }; -printk("Shutdown requested: %d\n", reason); -HYPERVISOR_sched_op(SCHEDOP_shutdown, _shutdown); -} - -static void shutdown_thread(void *p) -{ -const char *path = "control/shutdown"; -const char *token = path; -xenbus_event_queue events = NULL; -char *shutdown = NULL, *err; -unsigned int shutdown_reason; -xenbus_watch_path_token(XBT_NIL, path, token, ); -while ((err = xenbus_read(XBT_NIL, path, )) != NULL || !strcmp(shutdown, "")) -{ -free(err); -free(shutdown); -shutdown = NULL; -xenbus_wait_for_watch(); -} -err = xenbus_unwatch_path_token(XBT_NIL, path, token); -free(err); -err = xenbus_write(XBT_NIL, path, ""); -free(err); -printk("Shutting down (%s)\n", shutdown); - -if (!strcmp(shutdown, "poweroff")) -shutdown_reason = SHUTDOWN_poweroff; -else if (!strcmp(shutdown, "reboot")) -shutdown_reason = SHUTDOWN_reboot; -else -/* Unknown */ -shutdown_reason = SHUTDOWN_crash; -app_shutdown(shutdown_reason); -free(shutdown); -} -#endif - /* This should be overridden by the application we are linked against. */ __attribute__((weak)) int app_main(void *p) @@ -116,7 +77,7 @@ __attribute__((weak)) int app_main(void *p) return 0; } -void start_kernel(void) +void start_kernel(void* par) { /* Set up events. */ init_events(); @@ -145,7 +106,8 @@ void start_kernel(void) init_xenbus(); #ifdef CONFIG_XENBUS -create_thread("shutdown", shutdown_thread, NULL); +/* Init shutdown thread */ +init_shutdown((start_info_t *)par); #endif /* Call (possibly overridden) app_main() */ -- 2.3.2 (Apple Git-55) ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [PATCH RFC 08/16] Save/Restore Support: Add arch_mm_pre|post_suspend
For PV guests the pagetables reference the real MFNs rather than PFNs, so when the guest is resumed into a different area of a hosts memory, these will need to be rewritten. Thus for PV guests the MFNs need to be replaced with PFNs: canonicalization. PVH guests are auto-translated so no memory operation is needed. Signed-off-by: Bruno Alvisio--- arch/x86/mm.c | 14 ++ include/x86/arch_mm.h | 3 +++ 2 files changed, 17 insertions(+) diff --git a/arch/x86/mm.c b/arch/x86/mm.c index 05ad029..1b163ac 100644 --- a/arch/x86/mm.c +++ b/arch/x86/mm.c @@ -848,6 +848,20 @@ void arch_init_p2m(unsigned long max_pfn) arch_remap_p2m(max_pfn); } + +void arch_mm_pre_suspend(void) +{ +//TODO: Canonicalize pagetables +} + +void arch_mm_post_suspend(int canceled) +{ +//TODO: Locate pagetables and 'uncanonicalize' them +} +#else +void arch_mm_pre_suspend(void){ } + +void arch_mm_post_suspend(int canceled){ } #endif void arch_init_mm(unsigned long* start_pfn_p, unsigned long* max_pfn_p) diff --git a/include/x86/arch_mm.h b/include/x86/arch_mm.h index ab8a53e..cbbeb21 100644 --- a/include/x86/arch_mm.h +++ b/include/x86/arch_mm.h @@ -279,6 +279,9 @@ pgentry_t *need_pgt(unsigned long addr); void arch_mm_preinit(void *p); unsigned long alloc_virt_kernel(unsigned n_pages); +void arch_mm_pre_suspend(void); +void arch_mm_post_suspend(int canceled); + #ifndef CONFIG_PARAVIRT void arch_print_memmap(void); #endif -- 2.3.2 (Apple Git-55) ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [PATCH RFC 13/16] Save/Restore Support: Add suspend/restore support for Grant Tables.
Signed-off-by: Bruno Alvisio--- gnttab.c | 33 + include/gnttab.h | 2 ++ kernel.c | 4 3 files changed, 39 insertions(+) diff --git a/gnttab.c b/gnttab.c index 3f0e35f..a91c2e1 100644 --- a/gnttab.c +++ b/gnttab.c @@ -194,3 +194,36 @@ fini_gnttab(void) HYPERVISOR_grant_table_op(GNTTABOP_setup_table, , 1); } + +void suspend_gnttab(void) +{ +#ifdef CONFIG_PARAVIRT +int i; + +for (i = 0; i < NR_GRANT_FRAMES; i++) { +HYPERVISOR_update_va_mapping((unsigned long)(((char *)gnttab_table) + PAGE_SIZE*i), +(pte_t){0x0<
[Xen-devel] [PATCH RFC 10/16] Save/Restore Support: Add suspend/resume support for timers
Signed-off-by: Bruno Alvisio--- arch/x86/time.c | 13 + include/time.h | 2 ++ kernel.c| 4 3 files changed, 19 insertions(+) diff --git a/arch/x86/time.c b/arch/x86/time.c index 3658142..8f79d69 100644 --- a/arch/x86/time.c +++ b/arch/x86/time.c @@ -244,3 +244,16 @@ void fini_time(void) HYPERVISOR_set_timer_op(0); unbind_evtchn(port); } + +void suspend_time(void) +{ +/* Clear any pending timer */ +HYPERVISOR_set_timer_op(0); +unbind_evtchn(port); +} + +void resume_time(void) +{ +port = bind_virq(VIRQ_TIMER, _handler, NULL); +unmask_evtchn(port); +} diff --git a/include/time.h b/include/time.h index 5d6ed67..2e06d58 100644 --- a/include/time.h +++ b/include/time.h @@ -55,6 +55,8 @@ typedef long suseconds_t; /* prototypes */ void init_time(void); void fini_time(void); +void suspend_time(void); +void resume_time(void); s_time_t get_s_time(void); s_time_t get_v_time(void); uint64_t monotonic_clock(void); diff --git a/kernel.c b/kernel.c index 782eb79..a16b1ba 100644 --- a/kernel.c +++ b/kernel.c @@ -120,10 +120,14 @@ void start_kernel(void* par) void pre_suspend(void) { local_irq_disable(); + +suspend_time(); } void post_suspend(int canceled) { +resume_time(); + local_irq_enable(); } -- 2.3.2 (Apple Git-55) ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [PATCH RFC 12/16] Save/Restore Support: Add support for suspend/restore events.
Signed-off-by: Bruno Alvisio--- events.c | 5 + include/events.h | 1 + kernel.c | 2 ++ 3 files changed, 8 insertions(+) diff --git a/events.c b/events.c index e8ef8aa..342aead 100644 --- a/events.c +++ b/events.c @@ -183,6 +183,11 @@ void fini_events(void) arch_fini_events(); } +void suspend_events(void) +{ +unbind_all_ports(); +} + void default_handler(evtchn_port_t port, struct pt_regs *regs, void *ignore) { printk("[Port %d] - event received\n", port); diff --git a/include/events.h b/include/events.h index 89b5997..705ad93 100644 --- a/include/events.h +++ b/include/events.h @@ -55,5 +55,6 @@ static inline int notify_remote_via_evtchn(evtchn_port_t port) } void fini_events(void); +void suspend_events(void); #endif /* _EVENTS_H_ */ diff --git a/kernel.c b/kernel.c index fd1c4c5..c6ff9f3 100644 --- a/kernel.c +++ b/kernel.c @@ -124,6 +124,8 @@ void pre_suspend(void) suspend_time(); suspend_console(); + +suspend_events(); } void post_suspend(int canceled) -- 2.3.2 (Apple Git-55) ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [PATCH RFC 00/16] Save/Restore Support for mini-OS PVH
Hi all, I have been working on supporting save/restore for mini-os PVH. Some parts of the implementation were taken from the sysml/mini-os repository. The branch can be found at: https://github.com/balvisio/mini-os/tree/feature/mini-os-suspend-support Any feedback would be greatly appreciated. Cheers, Bruno ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [seabios test] 117314: regressions - FAIL
flight 117314 seabios real [real] http://logs.test-lab.xenproject.org/osstest/logs/117314/ Regressions :-( Tests which did not succeed and are blocking, including tests which could not be run: test-amd64-amd64-xl-qemuu-ws16-amd64 17 guest-stop fail REGR. vs. 115539 Tests which did not succeed, but are not blocking: test-amd64-amd64-xl-qemuu-win7-amd64 17 guest-stopfail like 115539 test-amd64-i386-xl-qemuu-win7-amd64 17 guest-stop fail like 115539 test-amd64-i386-xl-qemuu-ws16-amd64 17 guest-stop fail like 115539 test-amd64-i386-libvirt-qemuu-debianhvm-amd64-xsm 11 migrate-support-check fail never pass test-amd64-amd64-libvirt-qemuu-debianhvm-amd64-xsm 11 migrate-support-check fail never pass test-amd64-amd64-qemuu-nested-amd 17 debian-hvm-install/l1/l2 fail never pass test-amd64-i386-xl-qemuu-win10-i386 10 windows-install fail never pass test-amd64-amd64-xl-qemuu-win10-i386 10 windows-installfail never pass version targeted for testing: seabios 844b86464a5cbfffb62b87808632018ca250d867 baseline version: seabios 0ca6d6277dfafc671a5b3718cbeb5c78e2a888ea Last test of basis 115539 2017-11-03 20:48:58 Z 46 days Failing since115733 2017-11-10 17:19:59 Z 39 days 56 attempts Testing same since 117014 2017-12-08 19:11:23 Z 11 days 11 attempts People who touched revisions under test: Kevin O'ConnorPaul Menzel Stefan Berger jobs: build-amd64-xsm pass build-i386-xsm pass build-amd64 pass build-i386 pass build-amd64-libvirt pass build-i386-libvirt pass build-amd64-pvopspass build-i386-pvops pass test-amd64-amd64-libvirt-qemuu-debianhvm-amd64-xsm pass test-amd64-i386-libvirt-qemuu-debianhvm-amd64-xsmpass test-amd64-amd64-xl-qemuu-debianhvm-amd64-xsmpass test-amd64-i386-xl-qemuu-debianhvm-amd64-xsm pass test-amd64-amd64-qemuu-nested-amdfail test-amd64-i386-qemuu-rhel6hvm-amd pass test-amd64-amd64-xl-qemuu-debianhvm-amd64pass test-amd64-i386-xl-qemuu-debianhvm-amd64 pass test-amd64-amd64-xl-qemuu-win7-amd64 fail test-amd64-i386-xl-qemuu-win7-amd64 fail test-amd64-amd64-xl-qemuu-ws16-amd64 fail test-amd64-i386-xl-qemuu-ws16-amd64 fail test-amd64-amd64-xl-qemuu-win10-i386 fail test-amd64-i386-xl-qemuu-win10-i386 fail test-amd64-amd64-qemuu-nested-intel pass test-amd64-i386-qemuu-rhel6hvm-intel pass sg-report-flight on osstest.test-lab.xenproject.org logs: /home/logs/logs images: /home/logs/images Logs, config files, etc. are available at http://logs.test-lab.xenproject.org/osstest/logs Explanation of these reports, and of osstest in general, is at http://xenbits.xen.org/gitweb/?p=osstest.git;a=blob;f=README.email;hb=master http://xenbits.xen.org/gitweb/?p=osstest.git;a=blob;f=README;hb=master Test harness code can be found at http://xenbits.xen.org/gitweb?p=osstest.git;a=summary Not pushing. commit 844b86464a5cbfffb62b87808632018ca250d867 Author: Paul Menzel Date: Mon Oct 2 08:13:13 2017 +0200 docs/Download: Use more secure HTTPS URLs where possible Signed-off-by: Paul Menzel commit df46d10c8a7b88eb82f3ceb2aa31782dee15593d Author: Stefan Berger Date: Tue Nov 14 15:03:47 2017 -0500 tpm: Add support for TPM2 ACPI table Add support for the TPM2 ACPI table. If we find it and its of the appropriate size, we can get the log_area_start_address and log_area_minimum_size from it. The latest version of the spec can be found here: https://trustedcomputinggroup.org/tcg-acpi-specification/ Signed-off-by: Stefan Berger commit 0541f2f0f246e77d7c726926976920e8072d1119 Author: Kevin O'Connor Date: Fri Nov 10 12:20:35 2017 -0500 paravirt: Only enable sercon in NOGRAPHIC mode if no other console specified
Re: [Xen-devel] [RFC PATCH 01/60] hyper_dmabuf: initial working version of hyper_dmabuf drv
I forgot to include this brief information about this patch series. This patch series contains the implementation of a new device driver, hyper_dmabuf, which provides a method for DMA-BUF sharing across different OSes running on the same virtual OS platform powered by a hypervisor. Detailed information about this driver is described in a high-level doc added by the second patch of the series. [RFC PATCH 02/60] hyper_dmabuf: added a doc for hyper_dmabuf sharing I am attaching 'Overview' section here as a summary. -- Section 1. Overview -- Hyper_DMABUF driver is a Linux device driver running on multiple Virtual achines (VMs), which expands DMA-BUF sharing capability to the VM environment where multiple different OS instances need to share same physical data without data-copy across VMs. To share a DMA_BUF across VMs, an instance of the Hyper_DMABUF drv on the exporting VM (so called, “exporter”) imports a local DMA_BUF from the original producer of the buffer, then re-exports it with an unique ID, hyper_dmabuf_id for the buffer to the importing VM (so called, “importer”). Another instance of the Hyper_DMABUF driver on importer registers a hyper_dmabuf_id together with reference information for the shared physical pages associated with the DMA_BUF to its database when the export happens. The actual mapping of the DMA_BUF on the importer’s side is done by the Hyper_DMABUF driver when user space issues the IOCTL command to access the shared DMA_BUF. The Hyper_DMABUF driver works as both an importing and exporting driver as is, that is, no special configuration is required. Consequently, only a single module per VM is needed to enable cross-VM DMA_BUF exchange. -- There is a git repository at github.com where this series of patches are all integrated in Linux kernel tree based on the commit: commit ae64f9bd1d3621b5e60d7363bc20afb46aede215 Author: Linus TorvaldsDate: Sun Dec 3 11:01:47 2017 -0500 Linux 4.15-rc2 https://github.com/downor/linux_hyper_dmabuf.git hyper_dmabuf_integration_v3 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH v2 1/3] x86/crashkernel: avoid Xen image when looking for module/crashkernel position
On Thu, Dec 07, 2017 at 04:39:37PM +0100, Daniel Kiper wrote: > On Thu, Dec 07, 2017 at 04:08:31AM -0700, Jan Beulich wrote: > > >>> On 04.12.17 at 11:24,wrote: > > > --- a/xen/arch/x86/setup.c > > > +++ b/xen/arch/x86/setup.c > > > @@ -653,7 +653,7 @@ void __init noreturn __start_xen(unsigned long mbi_p) > > > module_t *mod = (module_t *)__va(mbi->mods_addr); > > > unsigned long nr_pages, raw_max_page, modules_headroom, *module_map; > > > int i, j, e820_warn = 0, bytes = 0; > > > -bool acpi_boot_table_init_done = false; > > > +bool acpi_boot_table_init_done = false, xen_relocated = false; > > > > I don't see a need for the xen_ prefix here - with that dropped > > (which I guess could be done while committing) > > Reviewed-by: Jan Beulich > > I am OK with that change. Go ahead... I have seen that you have applied this. Great! I have just realized that this patch also fixed another issue which we discovered a few days ago. Machines with less than 4 GiB rebooted mysteriously if Xen was loaded with Multiboot2 and relocated by the bootloader. This happened because relocator chosen to relocate e.g. dom0 kernel over the Xen image. The problem does not appear if Xen is loaded with Multiboot protocol. This happens because end of RAM region (e) occupied by Xen is updated by Xen relocation code. So, one shot and two bugs killed at once! Nice! Daniel ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH v2 3/3] x86/setup: remap Xen image up to PFN_DOWN(__pa(_end))
On Tue, Dec 12, 2017 at 02:42:50AM -0700, Jan Beulich wrote: > >>> On 11.12.17 at 16:12,wrote: > > On Thu, Dec 07, 2017 at 05:02:02AM -0700, Jan Beulich wrote: > >> >>> On 04.12.17 at 11:24, wrote: > >> > Current limit, PFN_DOWN(xen_phys_start), introduced by commit b280442 > >> > (x86: make Xen early boot code relocatable) is not reliable. Potentially > >> > its value may fall below PFN_DOWN(__pa(_end)) > >> > >> Under what (perhaps just theoretical) conditions? It seems to imply > >> to me that we'd be moved Xen downwards if this was to happen, in > >> which case I'd suggest to simply skip the relocation instead (we > >> really only ever want to move Xen upwards). > > > > Not always. If __pa(__image_base__) > xen_phys_start and even > > I'm being increasingly confused: Isn't xen_phys_start identical to > __pa(__image_base__)? Right, it is confusing and condition is incorrect. I should say: NEW_xen_phys_start > __pa_BEFORE_xen_phys_start_CHANGE(__image_base__)... > > if xen_phys_start < __pa(_end) then we are still moving upwards. > > And xen_phys_start always below __pa(_end)? ...and NEW_xen_phys_start < __pa_BEFORE_xen_phys_start_CHANGE(_end). > > That is why we should change the condition. And we have to reference > > to something constant not to the moving one. > > I also don't understand what would be "the moving one" here: > xen_phys_start is being updated just once, before any of the I am referring to this change. And it means that everything between NEW_xen_phys_start and __pa_BEFORE_xen_phys_start_CHANGE(_end) may not be mapped because ramping condition/limit refers to xen_phys_start which may fall below __pa_BEFORE_xen_phys_start_CHANGE(_end) (right now in theory due to lack of relocation if boot loader did it for us). Daniel ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [xen-4.7-testing test] 117289: tolerable FAIL - PUSHED
flight 117289 xen-4.7-testing real [real] http://logs.test-lab.xenproject.org/osstest/logs/117289/ Failures :-/ but no regressions. Tests which did not succeed, but are not blocking: test-amd64-amd64-xl-qemut-win7-amd64 17 guest-stopfail like 116623 test-xtf-amd64-amd64-2 49 xtf/test-hvm64-lbr-tsx-vmentry fail like 116665 test-armhf-armhf-libvirt 14 saverestore-support-checkfail like 116665 test-armhf-armhf-xl-rtds 16 guest-start/debian.repeatfail like 116665 test-armhf-armhf-libvirt-xsm 14 saverestore-support-checkfail like 116665 test-amd64-i386-xl-qemut-ws16-amd64 17 guest-stop fail like 116665 test-amd64-amd64-xl-qemuu-win7-amd64 17 guest-stopfail like 116665 test-amd64-i386-xl-qemut-win7-amd64 17 guest-stop fail like 116665 test-armhf-armhf-libvirt-raw 13 saverestore-support-checkfail like 116665 test-amd64-i386-xl-qemuu-win7-amd64 17 guest-stop fail like 116665 test-amd64-i386-xl-qemuu-ws16-amd64 17 guest-stop fail like 116665 test-amd64-amd64-xl-qemuu-ws16-amd64 17 guest-stopfail like 116665 test-amd64-amd64-xl-qemut-ws16-amd64 17 guest-stopfail like 116665 test-amd64-amd64-libvirt-xsm 13 migrate-support-checkfail never pass test-amd64-i386-libvirt 13 migrate-support-checkfail never pass test-amd64-amd64-libvirt 13 migrate-support-checkfail never pass test-amd64-i386-libvirt-xsm 13 migrate-support-checkfail never pass test-arm64-arm64-xl 13 migrate-support-checkfail never pass test-arm64-arm64-xl 14 saverestore-support-checkfail never pass test-arm64-arm64-xl-credit2 13 migrate-support-checkfail never pass test-arm64-arm64-xl-credit2 14 saverestore-support-checkfail never pass test-arm64-arm64-libvirt-xsm 13 migrate-support-checkfail never pass test-arm64-arm64-libvirt-xsm 14 saverestore-support-checkfail never pass test-amd64-amd64-libvirt-qemuu-debianhvm-amd64-xsm 11 migrate-support-check fail never pass test-amd64-i386-libvirt-qemuu-debianhvm-amd64-xsm 11 migrate-support-check fail never pass test-arm64-arm64-xl-xsm 13 migrate-support-checkfail never pass test-arm64-arm64-xl-xsm 14 saverestore-support-checkfail never pass test-amd64-amd64-libvirt-vhd 12 migrate-support-checkfail never pass test-amd64-amd64-qemuu-nested-amd 17 debian-hvm-install/l1/l2 fail never pass test-armhf-armhf-xl-rtds 13 migrate-support-checkfail never pass test-armhf-armhf-xl-rtds 14 saverestore-support-checkfail never pass test-armhf-armhf-libvirt 13 migrate-support-checkfail never pass test-armhf-armhf-xl-multivcpu 13 migrate-support-checkfail never pass test-armhf-armhf-xl-multivcpu 14 saverestore-support-checkfail never pass test-armhf-armhf-xl-xsm 13 migrate-support-checkfail never pass test-armhf-armhf-xl-xsm 14 saverestore-support-checkfail never pass test-armhf-armhf-xl-cubietruck 13 migrate-support-checkfail never pass test-armhf-armhf-xl-cubietruck 14 saverestore-support-checkfail never pass test-armhf-armhf-xl 13 migrate-support-checkfail never pass test-armhf-armhf-xl 14 saverestore-support-checkfail never pass test-armhf-armhf-xl-credit2 13 migrate-support-checkfail never pass test-armhf-armhf-xl-credit2 14 saverestore-support-checkfail never pass test-armhf-armhf-libvirt-xsm 13 migrate-support-checkfail never pass test-armhf-armhf-libvirt-raw 12 migrate-support-checkfail never pass test-armhf-armhf-xl-vhd 12 migrate-support-checkfail never pass test-armhf-armhf-xl-vhd 13 saverestore-support-checkfail never pass test-armhf-armhf-xl-arndale 13 migrate-support-checkfail never pass test-armhf-armhf-xl-arndale 14 saverestore-support-checkfail never pass test-amd64-amd64-xl-qemut-win10-i386 10 windows-installfail never pass test-amd64-amd64-xl-qemuu-win10-i386 10 windows-installfail never pass test-amd64-i386-xl-qemuu-win10-i386 10 windows-install fail never pass test-amd64-i386-xl-qemut-win10-i386 10 windows-install fail never pass version targeted for testing: xen c3ddeca415a5d1f01f3867e268cbe8a0f331c3b3 baseline version: xen b3981ea9e88ba96ba55c1cd41e7123924d0f69fc Last test of basis 116665 2017-11-29 09:50:32 Z 20 days Testing same since 117100 2017-12-12 14:44:22 Z7 days6 attempts People who touched revisions under test: Andrew CooperJan Beulich jobs: build-amd64-xsm pass build-arm64-xsm
[Xen-devel] [RFC PATCH 50/60] hyper_dmabuf: fix styling err and warns caught by checkpatch.pl
Fixing all styling problems caught by checkpatch.pl Signed-off-by: Dongwon Kim--- drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c| 53 ++-- drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h| 6 +- drivers/xen/hyper_dmabuf/hyper_dmabuf_event.c | 12 +- drivers/xen/hyper_dmabuf/hyper_dmabuf_id.c | 24 +- drivers/xen/hyper_dmabuf/hyper_dmabuf_id.h | 4 +- drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c | 308 +++-- drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.h | 5 +- drivers/xen/hyper_dmabuf/hyper_dmabuf_msg.c| 132 - drivers/xen/hyper_dmabuf/hyper_dmabuf_msg.h| 4 +- drivers/xen/hyper_dmabuf/hyper_dmabuf_ops.c| 58 ++-- drivers/xen/hyper_dmabuf/hyper_dmabuf_query.c | 236 .../xen/hyper_dmabuf/hyper_dmabuf_remote_sync.c| 81 +++--- drivers/xen/hyper_dmabuf/hyper_dmabuf_sgl_proc.c | 15 +- drivers/xen/hyper_dmabuf/hyper_dmabuf_sgl_proc.h | 2 +- drivers/xen/hyper_dmabuf/hyper_dmabuf_struct.h | 78 -- .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c | 154 +-- .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.h | 21 +- .../hyper_dmabuf/xen/hyper_dmabuf_xen_comm_list.c | 21 +- .../hyper_dmabuf/xen/hyper_dmabuf_xen_comm_list.h | 16 +- .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_drv.h| 19 +- .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_shm.c| 128 + .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_shm.h| 15 +- include/uapi/xen/hyper_dmabuf.h| 26 +- 23 files changed, 739 insertions(+), 679 deletions(-) diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c index 525ee78..023d7f4 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c @@ -44,7 +44,6 @@ #ifdef CONFIG_HYPER_DMABUF_XEN #include "xen/hyper_dmabuf_xen_drv.h" -extern struct hyper_dmabuf_backend_ops xen_backend_ops; #endif MODULE_LICENSE("GPL and additional rights"); @@ -52,14 +51,11 @@ MODULE_AUTHOR("Intel Corporation"); struct hyper_dmabuf_private *hy_drv_priv; -long hyper_dmabuf_ioctl(struct file *filp, - unsigned int cmd, unsigned long param); - -static void hyper_dmabuf_force_free(struct exported_sgt_info* exported, - void *attr) +static void hyper_dmabuf_force_free(struct exported_sgt_info *exported, + void *attr) { struct ioctl_hyper_dmabuf_unexport unexport_attr; - struct file *filp = (struct file*) attr; + struct file *filp = (struct file *)attr; if (!filp || !exported) return; @@ -97,7 +93,8 @@ int hyper_dmabuf_release(struct inode *inode, struct file *filp) #ifdef CONFIG_HYPER_DMABUF_EVENT_GEN -unsigned int hyper_dmabuf_event_poll(struct file *filp, struct poll_table_struct *wait) +unsigned int hyper_dmabuf_event_poll(struct file *filp, +struct poll_table_struct *wait) { unsigned int mask = 0; @@ -153,15 +150,17 @@ ssize_t hyper_dmabuf_event_read(struct file *filp, char __user *buffer, mutex_unlock(_drv_priv->event_read_lock); ret = wait_event_interruptible(hy_drv_priv->event_wait, - !list_empty(_drv_priv->event_list)); + !list_empty(_drv_priv->event_list)); if (ret == 0) - ret = mutex_lock_interruptible(_drv_priv->event_read_lock); + ret = mutex_lock_interruptible( + _drv_priv->event_read_lock); if (ret) return ret; } else { - unsigned length = (sizeof(struct hyper_dmabuf_event_hdr) + e->event_data.hdr.size); + unsigned int length = (sizeof(e->event_data.hdr) + + e->event_data.hdr.size); if (length > count - ret) { put_back_event: @@ -172,20 +171,22 @@ ssize_t hyper_dmabuf_event_read(struct file *filp, char __user *buffer, } if (copy_to_user(buffer + ret, >event_data.hdr, -sizeof(struct hyper_dmabuf_event_hdr))) { +sizeof(e->event_data.hdr))) { if (ret == 0) ret = -EFAULT; goto put_back_event; } - ret += sizeof(struct hyper_dmabuf_event_hdr); + ret += sizeof(e->event_data.hdr); - if (copy_to_user(buffer + ret, e->event_data.data, e->event_data.hdr.size))
[Xen-devel] [RFC PATCH 38/60] hyper_dmabuf: preventing self exporting of dma_buf
Adding ID check to make sure a dma-buf is exported externally since hyper_dmabuf only allows to export a dmabuf to a different VM. Signed-off-by: Dongwon Kim--- drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c index 12f7ce4..b77b156 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c @@ -103,6 +103,12 @@ static int hyper_dmabuf_export_remote_ioctl(struct file *filp, void *data) export_remote_attr = (struct ioctl_hyper_dmabuf_export_remote *)data; + if (hyper_dmabuf_private.domid == export_remote_attr->remote_domain) { + dev_err(hyper_dmabuf_private.device, + "exporting to the same VM is not permitted\n"); + return -EINVAL; + } + dma_buf = dma_buf_get(export_remote_attr->dmabuf_fd); if (IS_ERR(dma_buf)) { -- 2.7.4 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [RFC PATCH 08/60] hyper_dmabuf: automatic comm channel initialization using xenstore
From: Mateusz PolrolaThis introduces use of xenstore for creating and managing communication channels between two VMs in the system. When hyper_dmabuf driver is loaded in the service VM (host OS), a new xenstore directory, "/local/domain//data/hyper_dmabuf" is created in xenstore filesystem. Whenever a new guest OS creates and initailizes its own upstream channel the service VM, new directory is created under the main directory created above as shown here: /local/domain//data/hyper_dmabuf//port /local/domain//data/hyper_dmabuf//gref This patch also adds a "xenstore watch" callback is called when a new upstream connection is made from another VM (VM-b). Upon detection, this VM (VM-a) intializes a downstream channel ,paired with detected upstream connection as shown below. VM-a (downstream) <- (upstream) VM-a And as soon as this downstream channel is created, a new upstream channel from VM-a to VM-b is automatically created and initialized via "xenstore watch" call back on VM-b. VM-a (upstream) <- (downstream) VM-b As a result, there will be bi-directional communication channel available between two VMs. When upstream channel is removed (e.g. unloading driver), VM on the other side is notified and "xenstore watch" callback is invoked. Via this callback, VM can remove corresponding downstream channel. Signed-off-by: Dongwon Kim --- drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c| 11 +- drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h| 14 -- drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c | 30 +-- drivers/xen/hyper_dmabuf/hyper_dmabuf_msg.c| 31 +-- drivers/xen/hyper_dmabuf/hyper_dmabuf_msg.h| 2 - .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c | 226 +++-- .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.h | 18 +- .../hyper_dmabuf/xen/hyper_dmabuf_xen_comm_list.c | 22 ++ .../hyper_dmabuf/xen/hyper_dmabuf_xen_comm_list.h | 6 + 9 files changed, 270 insertions(+), 90 deletions(-) diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c index 70b4878..5b5dae44 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c @@ -6,6 +6,7 @@ #include "hyper_dmabuf_conf.h" #include "hyper_dmabuf_list.h" #include "xen/hyper_dmabuf_xen_comm_list.h" +#include "xen/hyper_dmabuf_xen_comm.h" MODULE_LICENSE("Dual BSD/GPL"); MODULE_AUTHOR("IOTG-PED, INTEL"); @@ -43,6 +44,11 @@ static int hyper_dmabuf_drv_init(void) return -EINVAL; } + ret = hyper_dmabuf_setup_data_dir(); + if (ret < 0) { + return -EINVAL; + } + /* interrupt for comm should be registered here: */ return ret; } @@ -52,12 +58,15 @@ static void hyper_dmabuf_drv_exit(void) { /* hash tables for export/import entries and ring_infos */ hyper_dmabuf_table_destroy(); - hyper_dmabuf_ring_table_init(); + + hyper_dmabuf_cleanup_ringbufs(); + hyper_dmabuf_ring_table_destroy(); /* destroy workqueue */ if (hyper_dmabuf_private.work_queue) destroy_workqueue(hyper_dmabuf_private.work_queue); + hyper_dmabuf_destroy_data_dir(); printk( KERN_NOTICE "dma_buf-src_sink model: Exiting" ); unregister_device(); } diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h index 6145d29..7511afb 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h @@ -29,8 +29,6 @@ struct ioctl_hyper_dmabuf_exporter_ring_setup { /* IN parameters */ /* Remote domain id */ uint32_t remote_domain; - grant_ref_t ring_refid; /* assigned by driver, copied to userspace after initialization */ - uint32_t port; /* assigned by driver, copied to userspace after initialization */ }; #define IOCTL_HYPER_DMABUF_IMPORTER_RING_SETUP \ @@ -39,10 +37,6 @@ struct ioctl_hyper_dmabuf_importer_ring_setup { /* IN parameters */ /* Source domain id */ uint32_t source_domain; - /* Ring shared page refid */ - grant_ref_t ring_refid; - /* Port number */ - uint32_t port; }; #define IOCTL_HYPER_DMABUF_EXPORT_REMOTE \ @@ -95,12 +89,4 @@ struct ioctl_hyper_dmabuf_query { uint32_t info; }; -#define IOCTL_HYPER_DMABUF_REMOTE_EXPORTER_RING_SETUP \ -_IOC(_IOC_NONE, 'G', 6, sizeof(struct ioctl_hyper_dmabuf_remote_exporter_ring_setup)) -struct ioctl_hyper_dmabuf_remote_exporter_ring_setup { - /* in parameters */ - uint32_t rdomain; /* id of remote domain where exporter's ring need to be setup */ - uint32_t info; -}; - #endif //__LINUX_PUBLIC_HYPER_DMABUF_DRV_H__ diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c index e4d8316..44a153b 100644 ---
[Xen-devel] [RFC PATCH 37/60] hyper_dmabuf: implementation of query ioctl
List of queries is re-defined. Now it supports following items: enum hyper_dmabuf_query { DMABUF_QUERY_TYPE = 0x10, DMABUF_QUERY_EXPORTER, DMABUF_QUERY_IMPORTER, DMABUF_QUERY_SIZE, DMABUF_QUERY_BUSY, DMABUF_QUERY_UNEXPORTED, DMABUF_QUERY_DELAYED_UNEXPORTED, }; Also, actual querying part of the function is moved to hyper_dmabuf_query.c Signed-off-by: Dongwon Kim--- drivers/xen/hyper_dmabuf/Makefile | 1 + drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c | 111 ++--- drivers/xen/hyper_dmabuf/hyper_dmabuf_query.c | 115 ++ drivers/xen/hyper_dmabuf/hyper_dmabuf_query.h | 38 + include/uapi/xen/hyper_dmabuf.h | 17 5 files changed, 179 insertions(+), 103 deletions(-) create mode 100644 drivers/xen/hyper_dmabuf/hyper_dmabuf_query.c diff --git a/drivers/xen/hyper_dmabuf/Makefile b/drivers/xen/hyper_dmabuf/Makefile index d90cfc3..8865f50 100644 --- a/drivers/xen/hyper_dmabuf/Makefile +++ b/drivers/xen/hyper_dmabuf/Makefile @@ -11,6 +11,7 @@ ifneq ($(KERNELRELEASE),) hyper_dmabuf_msg.o \ hyper_dmabuf_id.o \ hyper_dmabuf_remote_sync.o \ +hyper_dmabuf_query.o \ ifeq ($(CONFIG_XEN), y) $(TARGET_MODULE)-objs += xen/hyper_dmabuf_xen_comm.o \ diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c index 375b664..12f7ce4 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include #include @@ -46,7 +46,7 @@ extern struct hyper_dmabuf_private hyper_dmabuf_private; -static int hyper_dmabuf_tx_ch_setup(struct file *filp, void *data) +static int hyper_dmabuf_tx_ch_setup_ioctl(struct file *filp, void *data) { struct ioctl_hyper_dmabuf_tx_ch_setup *tx_ch_attr; struct hyper_dmabuf_backend_ops *ops = hyper_dmabuf_private.backend_ops; @@ -63,7 +63,7 @@ static int hyper_dmabuf_tx_ch_setup(struct file *filp, void *data) return ret; } -static int hyper_dmabuf_rx_ch_setup(struct file *filp, void *data) +static int hyper_dmabuf_rx_ch_setup_ioctl(struct file *filp, void *data) { struct ioctl_hyper_dmabuf_rx_ch_setup *rx_ch_attr; struct hyper_dmabuf_backend_ops *ops = hyper_dmabuf_private.backend_ops; @@ -81,7 +81,7 @@ static int hyper_dmabuf_rx_ch_setup(struct file *filp, void *data) return ret; } -static int hyper_dmabuf_export_remote(struct file *filp, void *data) +static int hyper_dmabuf_export_remote_ioctl(struct file *filp, void *data) { struct ioctl_hyper_dmabuf_export_remote *export_remote_attr; struct hyper_dmabuf_backend_ops *ops = hyper_dmabuf_private.backend_ops; @@ -514,7 +514,7 @@ static void hyper_dmabuf_delayed_unexport(struct work_struct *work) /* Schedules unexport of dmabuf. */ -static int hyper_dmabuf_unexport(struct file *filp, void *data) +static int hyper_dmabuf_unexport_ioctl(struct file *filp, void *data) { struct ioctl_hyper_dmabuf_unexport *unexport_attr; struct hyper_dmabuf_sgt_info *sgt_info; @@ -554,11 +554,11 @@ static int hyper_dmabuf_unexport(struct file *filp, void *data) return 0; } -static int hyper_dmabuf_query(struct file *filp, void *data) +static int hyper_dmabuf_query_ioctl(struct file *filp, void *data) { struct ioctl_hyper_dmabuf_query *query_attr; - struct hyper_dmabuf_sgt_info *sgt_info; - struct hyper_dmabuf_imported_sgt_info *imported_sgt_info; + struct hyper_dmabuf_sgt_info *sgt_info = NULL; + struct hyper_dmabuf_imported_sgt_info *imported_sgt_info = NULL; int ret = 0; if (!data) { @@ -568,71 +568,46 @@ static int hyper_dmabuf_query(struct file *filp, void *data) query_attr = (struct ioctl_hyper_dmabuf_query *)data; - sgt_info = hyper_dmabuf_find_exported(query_attr->hid); - imported_sgt_info = hyper_dmabuf_find_imported(query_attr->hid); - - /* if dmabuf can't be found in both lists, return */ - if (!(sgt_info && imported_sgt_info)) { - dev_err(hyper_dmabuf_private.device, "can't find entry anywhere\n"); - return -ENOENT; - } - - /* not considering the case where a dmabuf is found on both queues -* in one domain */ - switch (query_attr->item) - { - case DMABUF_QUERY_TYPE_LIST: - if (sgt_info) { - query_attr->info = EXPORTED; - } else { - query_attr->info = IMPORTED; - } - break; - -
[Xen-devel] [RFC PATCH 15/60] hyper_dmabuf: reusing previously released hyper_dmabuf_id
Now, released hyper_dmabuf_ids are stored in a stack - (hyper_dmabuf_private.id_queue) for reuse. This is to prevent overflow of ids for buffers. We also limit maximum number for the id to 1000 for the stability and optimal performance. Signed-off-by: Dongwon Kim--- drivers/xen/hyper_dmabuf/Makefile | 1 + drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c| 5 ++ drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h| 6 ++ drivers/xen/hyper_dmabuf/hyper_dmabuf_id.c | 76 ++ drivers/xen/hyper_dmabuf/hyper_dmabuf_id.h | 24 +++ drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c| 1 + drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c | 15 ++--- .../xen/hyper_dmabuf/hyper_dmabuf_remote_sync.c| 3 + drivers/xen/hyper_dmabuf/hyper_dmabuf_struct.h | 9 --- 9 files changed, 120 insertions(+), 20 deletions(-) create mode 100644 drivers/xen/hyper_dmabuf/hyper_dmabuf_id.c create mode 100644 drivers/xen/hyper_dmabuf/hyper_dmabuf_id.h diff --git a/drivers/xen/hyper_dmabuf/Makefile b/drivers/xen/hyper_dmabuf/Makefile index 3459382..c9b8b7f 100644 --- a/drivers/xen/hyper_dmabuf/Makefile +++ b/drivers/xen/hyper_dmabuf/Makefile @@ -7,6 +7,7 @@ ifneq ($(KERNELRELEASE),) hyper_dmabuf_list.o \ hyper_dmabuf_imp.o \ hyper_dmabuf_msg.o \ +hyper_dmabuf_id.o \ hyper_dmabuf_remote_sync.o \ xen/hyper_dmabuf_xen_comm.o \ xen/hyper_dmabuf_xen_comm_list.o diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c index 5a7cfa5..66d6cb9 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c @@ -5,6 +5,7 @@ #include "hyper_dmabuf_drv.h" #include "hyper_dmabuf_conf.h" #include "hyper_dmabuf_list.h" +#include "hyper_dmabuf_id.h" #include "xen/hyper_dmabuf_xen_comm_list.h" #include "xen/hyper_dmabuf_xen_comm.h" @@ -67,6 +68,10 @@ static void hyper_dmabuf_drv_exit(void) if (hyper_dmabuf_private.work_queue) destroy_workqueue(hyper_dmabuf_private.work_queue); + /* destroy id_queue */ + if (hyper_dmabuf_private.id_queue) + destroy_reusable_list(); + hyper_dmabuf_destroy_data_dir(); printk( KERN_NOTICE "dma_buf-src_sink model: Exiting" ); unregister_device(); diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h index ff883e1..37b0cc1 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h @@ -1,10 +1,16 @@ #ifndef __LINUX_PUBLIC_HYPER_DMABUF_DRV_H__ #define __LINUX_PUBLIC_HYPER_DMABUF_DRV_H__ +struct list_reusable_id { + int id; + struct list_head list; +}; + struct hyper_dmabuf_private { struct device *device; int domid; struct workqueue_struct *work_queue; + struct list_reusable_id *id_queue; }; typedef int (*hyper_dmabuf_ioctl_t)(void *data); diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_id.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_id.c new file mode 100644 index 000..7bbb179 --- /dev/null +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_id.c @@ -0,0 +1,76 @@ +#include +#include +#include "hyper_dmabuf_drv.h" +#include "hyper_dmabuf_id.h" + +extern struct hyper_dmabuf_private hyper_dmabuf_private; + +void store_reusable_id(int id) +{ + struct list_reusable_id *reusable_head = hyper_dmabuf_private.id_queue; + struct list_reusable_id *new_reusable; + + new_reusable = kmalloc(sizeof(*new_reusable), GFP_KERNEL); + new_reusable->id = id; + + list_add(_reusable->list, _head->list); +} + +static int retrieve_reusable_id(void) +{ + struct list_reusable_id *reusable_head = hyper_dmabuf_private.id_queue; + + /* check there is reusable id */ + if (!list_empty(_head->list)) { + reusable_head = list_first_entry(_head->list, +struct list_reusable_id, +list); + + list_del(_head->list); + return reusable_head->id; + } + + return -1; +} + +void destroy_reusable_list(void) +{ + struct list_reusable_id *reusable_head = hyper_dmabuf_private.id_queue; + struct list_reusable_id *temp_head; + + if (reusable_head) { + /* freeing mem space all reusable ids in the stack */ + while (!list_empty(_head->list)) { + temp_head = list_first_entry(_head->list, +struct list_reusable_id, +list); + list_del(_head->list); +
[Xen-devel] [RFC PATCH 58/60] hyper_dmabuf: move device node out of /dev/xen/
From: Mateusz Polrolahyper_dmabuf driver is generic driver that is designed to work with any hypervisor with various backend implementations. So moving out its device node out of /dev/xen. Signed-off-by: Mateusz Polrola Signed-off-by: Dongwon Kim --- drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c index f2731bf..bbb3414 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c @@ -227,7 +227,7 @@ static const struct file_operations hyper_dmabuf_driver_fops = { static struct miscdevice hyper_dmabuf_miscdev = { .minor = MISC_DYNAMIC_MINOR, - .name = "xen/hyper_dmabuf", + .name = "hyper_dmabuf", .fops = _dmabuf_driver_fops, }; -- 2.7.4 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [RFC PATCH 23/60] hyper_dmabuf: use CONFIG_HYPER_DMABUF_XEN instead of CONFIG_XEN
Now, use CONFIG_HYPER_DMABUF_XEN as a configuration option for building hyper_dmabuf for Xen hypervisor. Signed-off-by: Dongwon Kim--- drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c index 4e0ccdd..569b95e 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c @@ -36,7 +36,7 @@ #include "hyper_dmabuf_list.h" #include "hyper_dmabuf_id.h" -#ifdef CONFIG_XEN +#ifdef CONFIG_HYPER_DMABUF_XEN #include "xen/hyper_dmabuf_xen_drv.h" extern struct hyper_dmabuf_backend_ops xen_backend_ops; #endif @@ -61,7 +61,7 @@ static int __init hyper_dmabuf_drv_init(void) return -EINVAL; } -#ifdef CONFIG_XEN +#ifdef CONFIG_HYPER_DMABUF_XEN hyper_dmabuf_private.backend_ops = _backend_ops; #endif -- 2.7.4 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [RFC PATCH 07/60] hyper_dmabuf: message parsing done via workqueue
Use workqueue mechanism to delay message parsing done after exiting from ISR to reduce ISR execution time. Signed-off-by: Dongwon Kim--- drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c| 13 ++ drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h| 5 + drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c | 4 +- drivers/xen/hyper_dmabuf/hyper_dmabuf_msg.c| 155 ++--- .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c | 75 -- .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.h | 7 - 6 files changed, 152 insertions(+), 107 deletions(-) diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c index 0698327..70b4878 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c @@ -1,5 +1,8 @@ #include/* module_init, module_exit */ #include /* version info, MODULE_LICENSE, MODULE_AUTHOR, printk() */ +#include +#include +#include "hyper_dmabuf_drv.h" #include "hyper_dmabuf_conf.h" #include "hyper_dmabuf_list.h" #include "xen/hyper_dmabuf_xen_comm_list.h" @@ -10,6 +13,8 @@ MODULE_AUTHOR("IOTG-PED, INTEL"); int register_device(void); int unregister_device(void); +struct hyper_dmabuf_private hyper_dmabuf_private; + /*===*/ static int hyper_dmabuf_drv_init(void) { @@ -24,6 +29,10 @@ static int hyper_dmabuf_drv_init(void) printk( KERN_NOTICE "initializing database for imported/exported dmabufs\n"); + /* device structure initialization */ + /* currently only does work-queue initialization */ + hyper_dmabuf_private.work_queue = create_workqueue("hyper_dmabuf_wqueue"); + ret = hyper_dmabuf_table_init(); if (ret < 0) { return -EINVAL; @@ -45,6 +54,10 @@ static void hyper_dmabuf_drv_exit(void) hyper_dmabuf_table_destroy(); hyper_dmabuf_ring_table_init(); + /* destroy workqueue */ + if (hyper_dmabuf_private.work_queue) + destroy_workqueue(hyper_dmabuf_private.work_queue); + printk( KERN_NOTICE "dma_buf-src_sink model: Exiting" ); unregister_device(); } diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h index 2dad9a6..6145d29 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h @@ -1,6 +1,11 @@ #ifndef __LINUX_PUBLIC_HYPER_DMABUF_DRV_H__ #define __LINUX_PUBLIC_HYPER_DMABUF_DRV_H__ +struct hyper_dmabuf_private { +struct device *device; + struct workqueue_struct *work_queue; +}; + typedef int (*hyper_dmabuf_ioctl_t)(void *data); struct hyper_dmabuf_ioctl_desc { diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c index af94359..e4d8316 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c @@ -15,9 +15,7 @@ #include "xen/hyper_dmabuf_xen_comm_list.h" #include "hyper_dmabuf_msg.h" -struct hyper_dmabuf_private { - struct device *device; -} hyper_dmabuf_private; +extern struct hyper_dmabuf_private hyper_dmabuf_private; static uint32_t hyper_dmabuf_id_gen(void) { /* TODO: add proper implementation */ diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_msg.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_msg.c index 3237e50..0166e61 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_msg.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_msg.c @@ -3,12 +3,23 @@ #include #include #include +#include +#include +#include "hyper_dmabuf_drv.h" #include "hyper_dmabuf_imp.h" //#include "hyper_dmabuf_remote_sync.h" #include "xen/hyper_dmabuf_xen_comm.h" #include "hyper_dmabuf_msg.h" #include "hyper_dmabuf_list.h" +extern struct hyper_dmabuf_private hyper_dmabuf_private; + +struct cmd_process { + struct work_struct work; + struct hyper_dmabuf_ring_rq *rq; + int domid; +}; + void hyper_dmabuf_create_request(struct hyper_dmabuf_ring_rq *request, enum hyper_dmabuf_command command, int *operands) { @@ -71,18 +82,17 @@ void hyper_dmabuf_create_request(struct hyper_dmabuf_ring_rq *request, } } -int hyper_dmabuf_msg_parse(int domid, struct hyper_dmabuf_ring_rq *req) +void cmd_process_work(struct work_struct *work) { - uint32_t i, ret; struct hyper_dmabuf_imported_sgt_info *imported_sgt_info; - struct hyper_dmabuf_sgt_info *sgt_info; - - /* make sure req is not NULL (may not be needed) */ - if (!req) { - return -EINVAL; - } +struct hyper_dmabuf_sgt_info *sgt_info; + struct cmd_process *proc = container_of(work, struct cmd_process, work); + struct hyper_dmabuf_ring_rq *req; + int domid; + int i; - req->status =
[Xen-devel] [RFC PATCH 55/60] hyper_dmabuf: fixed wrong send_req call
From: Mateusz PolrolaWrong vmid is used in case of sending HYPER_DMABUF_EXPORT_FD_FAILED message. Instead of vmid, hypder dmabuf id is being used. Signed-off-by: Mateusz Polrola Signed-off-by: Dongwon Kim --- drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c index d1970c8..ca6edf2 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c @@ -473,7 +473,7 @@ static int hyper_dmabuf_export_fd_ioctl(struct file *filp, void *data) */ hyper_dmabuf_create_req(req, HYPER_DMABUF_EXPORT_FD_FAILED, [0]); - bknd_ops->send_req(op[0], req, false); + bknd_ops->send_req(HYPER_DMABUF_DOM_ID(imported->hid), req, false); kfree(req); dev_err(hy_drv_priv->dev, "Failed to create sgt or notify exporter\n"); -- 2.7.4 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [RFC PATCH 39/60] hyper_dmabuf: correcting DMA-BUF clean-up order
Reordering clean-up procedure Signed-off-by: Dongwon Kim--- drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c | 37 +-- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c index b77b156..2ff2c145 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c @@ -148,21 +148,24 @@ static int hyper_dmabuf_export_remote_ioctl(struct file *filp, void *data) attachment = dma_buf_attach(dma_buf, hyper_dmabuf_private.device); if (IS_ERR(attachment)) { dev_err(hyper_dmabuf_private.device, "Cannot get attachment\n"); - return PTR_ERR(attachment); + ret = PTR_ERR(attachment); + goto fail_attach; } sgt = dma_buf_map_attachment(attachment, DMA_BIDIRECTIONAL); if (IS_ERR(sgt)) { dev_err(hyper_dmabuf_private.device, "Cannot map attachment\n"); - return PTR_ERR(sgt); + ret = PTR_ERR(sgt); + goto fail_map_attachment; } sgt_info = kcalloc(1, sizeof(*sgt_info), GFP_KERNEL); if(!sgt_info) { dev_err(hyper_dmabuf_private.device, "no more space left\n"); - return -ENOMEM; + ret = -ENOMEM; + goto fail_sgt_info_creation; } sgt_info->hid = hyper_dmabuf_get_hid(); @@ -171,8 +174,8 @@ static int hyper_dmabuf_export_remote_ioctl(struct file *filp, void *data) if(sgt_info->hid.id == -1) { dev_err(hyper_dmabuf_private.device, "exceeds allowed number of dmabuf to be exported\n"); - /* TODO: Cleanup sgt */ - return -ENOMEM; + ret = -ENOMEM; + goto fail_sgt_info_creation; } /* TODO: We might need to consider using port number on event channel? */ @@ -286,6 +289,8 @@ static int hyper_dmabuf_export_remote_ioctl(struct file *filp, void *data) return ret; +/* Clean-up if error occurs */ + fail_send_request: kfree(req); @@ -293,20 +298,26 @@ static int hyper_dmabuf_export_remote_ioctl(struct file *filp, void *data) hyper_dmabuf_remove_exported(sgt_info->hid); fail_export: - dma_buf_unmap_attachment(sgt_info->active_attached->attach, -sgt_info->active_sgts->sgt, -DMA_BIDIRECTIONAL); - dma_buf_detach(sgt_info->dma_buf, sgt_info->active_attached->attach); - dma_buf_put(sgt_info->dma_buf); - kfree(sgt_info->va_vmapped); + fail_map_va_vmapped: kfree(sgt_info->va_kmapped); + fail_map_va_kmapped: - kfree(sgt_info->active_sgts); -fail_map_active_sgts: kfree(sgt_info->active_attached); + fail_map_active_attached: + kfree(sgt_info->active_sgts); + +fail_map_active_sgts: +fail_sgt_info_creation: + dma_buf_unmap_attachment(attachment, sgt, DMA_BIDIRECTIONAL); + +fail_map_attachment: + dma_buf_detach(dma_buf, attachment); + +fail_attach: + dma_buf_put(dma_buf); return ret; } -- 2.7.4 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [RFC PATCH 06/60] hyper_dmabuf: map shared pages only once when importing.
From: Mateusz PolrolaIf shared pages of buffer were already mapped on importer side, do not map them again on next request to export fd. Signed-off-by: Mateusz Polrola Signed-off-by: Dongwon Kim --- drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c | 20 +++- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c index 90e0c65..af94359 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c @@ -203,7 +203,7 @@ static int hyper_dmabuf_export_fd_ioctl(void *data) if (!data) { printk("user data is NULL\n"); - return -1; + return -EINVAL; } export_fd_attr = (struct ioctl_hyper_dmabuf_export_fd *)data; @@ -218,15 +218,17 @@ static int hyper_dmabuf_export_fd_ioctl(void *data) imported_sgt_info->last_len, imported_sgt_info->nents, HYPER_DMABUF_ID_IMPORTER_GET_SDOMAIN_ID(imported_sgt_info->hyper_dmabuf_id)); - imported_sgt_info->sgt = hyper_dmabuf_map_pages(imported_sgt_info->gref, - imported_sgt_info->frst_ofst, - imported_sgt_info->last_len, - imported_sgt_info->nents, - HYPER_DMABUF_ID_IMPORTER_GET_SDOMAIN_ID(imported_sgt_info->hyper_dmabuf_id), - _sgt_info->shared_pages_info); - if (!imported_sgt_info->sgt) { - return -1; + imported_sgt_info->sgt = hyper_dmabuf_map_pages(imported_sgt_info->gref, + imported_sgt_info->frst_ofst, + imported_sgt_info->last_len, + imported_sgt_info->nents, + HYPER_DMABUF_ID_IMPORTER_GET_SDOMAIN_ID(imported_sgt_info->hyper_dmabuf_id), + _sgt_info->shared_pages_info); + if (!imported_sgt_info->sgt) { + printk("Failed to create sgt\n"); + return -EINVAL; + } } export_fd_attr->fd = hyper_dmabuf_export_fd(imported_sgt_info, export_fd_attr->flags); -- 2.7.4 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [RFC PATCH 35/60] hyper_dmabuf: 128bit hyper_dmabuf_id with random keys
The length of hyper_dmabuf_id is increased to 128bit by adding random key (96bit) to the id. This is to prevent possible leak of the id by guessing on importer VM (by unauthorized application). hyper_dmabuf_id_t is now defined as, typedef struct { int id; int rng_key[3]; } hyper_dmabuf_id_t; Signed-off-by: Dongwon Kim--- drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c| 2 +- drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h| 3 +- drivers/xen/hyper_dmabuf/hyper_dmabuf_id.c | 57 -- drivers/xen/hyper_dmabuf/hyper_dmabuf_id.h | 17 +- drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c| 51 +++--- drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c | 199 + drivers/xen/hyper_dmabuf/hyper_dmabuf_list.c | 87 ++--- drivers/xen/hyper_dmabuf/hyper_dmabuf_list.h | 10 +- drivers/xen/hyper_dmabuf/hyper_dmabuf_msg.c| 115 +++- drivers/xen/hyper_dmabuf/hyper_dmabuf_msg.h| 2 +- .../xen/hyper_dmabuf/hyper_dmabuf_remote_sync.c| 21 ++- .../xen/hyper_dmabuf/hyper_dmabuf_remote_sync.h| 2 +- drivers/xen/hyper_dmabuf/hyper_dmabuf_struct.h | 20 ++- .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.h | 2 - include/uapi/xen/hyper_dmabuf.h| 13 +- 15 files changed, 372 insertions(+), 229 deletions(-) diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c index 92d710e..c802c3e 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c @@ -30,9 +30,9 @@ #include #include #include +#include "hyper_dmabuf_drv.h" #include "hyper_dmabuf_conf.h" #include "hyper_dmabuf_msg.h" -#include "hyper_dmabuf_drv.h" #include "hyper_dmabuf_list.h" #include "hyper_dmabuf_id.h" diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h index 91fda04..ffe4d53 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h @@ -26,11 +26,12 @@ #define __LINUX_PUBLIC_HYPER_DMABUF_DRV_H__ #include +#include struct hyper_dmabuf_req; struct list_reusable_id { - int id; + hyper_dmabuf_id_t hid; struct list_head list; }; diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_id.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_id.c index fe95091..f59dee3 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_id.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_id.c @@ -28,13 +28,14 @@ #include #include -#include "hyper_dmabuf_msg.h" +#include #include "hyper_dmabuf_drv.h" #include "hyper_dmabuf_id.h" +#include "hyper_dmabuf_msg.h" extern struct hyper_dmabuf_private hyper_dmabuf_private; -void store_reusable_id(int id) +void store_reusable_hid(hyper_dmabuf_id_t hid) { struct list_reusable_id *reusable_head = hyper_dmabuf_private.id_queue; struct list_reusable_id *new_reusable; @@ -47,15 +48,15 @@ void store_reusable_id(int id) return; } - new_reusable->id = id; + new_reusable->hid = hid; list_add(_reusable->list, _head->list); } -static int retrieve_reusable_id(void) +static hyper_dmabuf_id_t retrieve_reusable_hid(void) { struct list_reusable_id *reusable_head = hyper_dmabuf_private.id_queue; - int id; + hyper_dmabuf_id_t hid = {-1, {0,0,0}}; /* check there is reusable id */ if (!list_empty(_head->list)) { @@ -64,12 +65,11 @@ static int retrieve_reusable_id(void) list); list_del(_head->list); - id = reusable_head->id; + hid = reusable_head->hid; kfree(reusable_head); - return id; } - return -ENOENT; + return hid; } void destroy_reusable_list(void) @@ -92,31 +92,50 @@ void destroy_reusable_list(void) } } -int hyper_dmabuf_get_id(void) +hyper_dmabuf_id_t hyper_dmabuf_get_hid(void) { - static int id = 0; + static int count = 0; + hyper_dmabuf_id_t hid; struct list_reusable_id *reusable_head; - int ret; - /* first cla to hyper_dmabuf_get_id */ - if (id == 0) { + /* first call to hyper_dmabuf_get_id */ + if (count == 0) { reusable_head = kmalloc(sizeof(*reusable_head), GFP_KERNEL); if (!reusable_head) { dev_err(hyper_dmabuf_private.device, "No memory left to be allocated\n"); - return -ENOMEM; + return (hyper_dmabuf_id_t){-1, {0,0,0}}; } - reusable_head->id = -1; /* list head have invalid id */ + reusable_head->hid.id = -1; /* list head has an invalid count */ INIT_LIST_HEAD(_head->list);
[Xen-devel] [RFC PATCH 54/60] hyper_dmabuf: 'backend_ops' reduced to 'bknd_ops' and 'ops' to 'bknd_ops'
To make type's name compact, *_backend_ops is changed to '*_bknd_ops'. Also 'ops' is now changed to 'bknd_ops' to clarify it is a data structure with entry points of 'backend' operations. Signed-off-by: Dongwon Kim--- drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c| 14 +-- drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h| 4 ++-- drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c | 28 +++--- drivers/xen/hyper_dmabuf/hyper_dmabuf_ops.c| 10 drivers/xen/hyper_dmabuf/hyper_dmabuf_sgl_proc.c | 4 ++-- .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_drv.c| 2 +- .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_drv.h| 2 +- 7 files changed, 33 insertions(+), 31 deletions(-) diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c index 387cc63..161fee7 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c @@ -276,13 +276,13 @@ static int __init hyper_dmabuf_drv_init(void) /* currently only supports XEN hypervisor */ #ifdef CONFIG_HYPER_DMABUF_XEN - hy_drv_priv->backend_ops = _backend_ops; + hy_drv_priv->bknd_ops = _bknd_ops; #else - hy_drv_priv->backend_ops = NULL; + hy_drv_priv->bknd_ops = NULL; printk(KERN_ERR "hyper_dmabuf drv currently supports XEN only.\n"); #endif - if (hy_drv_priv->backend_ops == NULL) { + if (hy_drv_priv->bknd_ops == NULL) { printk(KERN_ERR "Hyper_dmabuf: no backend found\n"); return -1; } @@ -301,7 +301,7 @@ static int __init hyper_dmabuf_drv_init(void) ret = hyper_dmabuf_table_init(); if (ret < 0) { dev_err(hy_drv_priv->dev, - "failed to initialize table for exported/imported entries\n"); + "fail to init table for exported/imported entries\n"); mutex_unlock(_drv_priv->lock); kfree(hy_drv_priv); return ret; @@ -330,9 +330,9 @@ static int __init hyper_dmabuf_drv_init(void) hy_drv_priv->pending = 0; #endif - hy_drv_priv->domid = hy_drv_priv->backend_ops->get_vm_id(); + hy_drv_priv->domid = hy_drv_priv->bknd_ops->get_vm_id(); - ret = hy_drv_priv->backend_ops->init_comm_env(); + ret = hy_drv_priv->bknd_ops->init_comm_env(); if (ret < 0) { dev_dbg(hy_drv_priv->dev, "failed to initialize comm-env.\n"); @@ -360,7 +360,7 @@ static void hyper_dmabuf_drv_exit(void) /* hash tables for export/import entries and ring_infos */ hyper_dmabuf_table_destroy(); - hy_drv_priv->backend_ops->destroy_comm(); + hy_drv_priv->bknd_ops->destroy_comm(); /* destroy workqueue */ if (hy_drv_priv->work_queue) diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h index 049c694..4a51f9e 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h @@ -48,7 +48,7 @@ struct hyper_dmabuf_private { struct list_reusable_id *id_queue; /* backend ops - hypervisor specific */ - struct hyper_dmabuf_backend_ops *backend_ops; + struct hyper_dmabuf_bknd_ops *bknd_ops; /* device global lock */ /* TODO: might need a lock per resource (e.g. EXPORT LIST) */ @@ -72,7 +72,7 @@ struct list_reusable_id { struct list_head list; }; -struct hyper_dmabuf_backend_ops { +struct hyper_dmabuf_bknd_ops { /* retreiving id of current virtual machine */ int (*get_vm_id)(void); diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c index d11f609..d1970c8 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c @@ -44,7 +44,7 @@ static int hyper_dmabuf_tx_ch_setup_ioctl(struct file *filp, void *data) { struct ioctl_hyper_dmabuf_tx_ch_setup *tx_ch_attr; - struct hyper_dmabuf_backend_ops *ops = hy_drv_priv->backend_ops; + struct hyper_dmabuf_bknd_ops *bknd_ops = hy_drv_priv->bknd_ops; int ret = 0; if (!data) { @@ -53,7 +53,7 @@ static int hyper_dmabuf_tx_ch_setup_ioctl(struct file *filp, void *data) } tx_ch_attr = (struct ioctl_hyper_dmabuf_tx_ch_setup *)data; - ret = ops->init_tx_ch(tx_ch_attr->remote_domain); + ret = bknd_ops->init_tx_ch(tx_ch_attr->remote_domain); return ret; } @@ -61,7 +61,7 @@ static int hyper_dmabuf_tx_ch_setup_ioctl(struct file *filp, void *data) static int hyper_dmabuf_rx_ch_setup_ioctl(struct file *filp, void *data) { struct ioctl_hyper_dmabuf_rx_ch_setup *rx_ch_attr; - struct hyper_dmabuf_backend_ops *ops = hy_drv_priv->backend_ops; + struct hyper_dmabuf_bknd_ops *bknd_ops = hy_drv_priv->bknd_ops; int ret = 0; if
[Xen-devel] [RFC PATCH 47/60] hyper_dmabuf: fix issues with event-polling
This patch fixes several defects on event handling including: 1. Imported sgt info and exported sgt info now have buffer for private data (priv) with variable size 2. Now user input to export_remote_ioctl contain sz_priv, which specifies size of private data (e.g. meta data) 3. Increased max size of operands to 64 * sizeof(int) to accomodate maximum size of private data 4. Initialize mutexes and spinlock 5. Change max event queue depth to 32 to prevent user app to display too much outdated frames. 6. Frees oldest event if event queue is full to prevent overflow. Signed-off-by: Dongwon Kim--- drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c | 23 ++--- drivers/xen/hyper_dmabuf/hyper_dmabuf_event.c| 8 +-- drivers/xen/hyper_dmabuf/hyper_dmabuf_event.h| 2 +- drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c| 64 ++-- drivers/xen/hyper_dmabuf/hyper_dmabuf_msg.c | 42 +--- drivers/xen/hyper_dmabuf/hyper_dmabuf_msg.h | 2 +- drivers/xen/hyper_dmabuf/hyper_dmabuf_sgl_proc.c | 1 + drivers/xen/hyper_dmabuf/hyper_dmabuf_struct.h | 9 +++- include/uapi/xen/hyper_dmabuf.h | 7 ++- 9 files changed, 131 insertions(+), 27 deletions(-) diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c index 005677d..87ea6ca 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c @@ -74,9 +74,6 @@ int hyper_dmabuf_release(struct inode *inode, struct file *filp) { hyper_dmabuf_foreach_exported(hyper_dmabuf_emergency_release, filp); - /* clean up event queue */ - hyper_dmabuf_events_release(); - return 0; } @@ -98,12 +95,18 @@ ssize_t hyper_dmabuf_event_read(struct file *filp, char __user *buffer, int ret; /* only root can read events */ - if (!capable(CAP_DAC_OVERRIDE)) + if (!capable(CAP_DAC_OVERRIDE)) { + dev_err(hyper_dmabuf_private.device, + "Only root can read events\n"); return -EFAULT; + } /* make sure user buffer can be written */ - if (!access_ok(VERIFY_WRITE, buffer, count)) + if (!access_ok(VERIFY_WRITE, buffer, count)) { + dev_err(hyper_dmabuf_private.device, + "User buffer can't be written.\n"); return -EFAULT; + } ret = mutex_lock_interruptible(_dmabuf_private.event_read_lock); if (ret) @@ -132,7 +135,7 @@ ssize_t hyper_dmabuf_event_read(struct file *filp, char __user *buffer, ret = wait_event_interruptible(hyper_dmabuf_private.event_wait, !list_empty(_dmabuf_private.event_list)); - if (ret >= 0) + if (ret == 0) ret = mutex_lock_interruptible(_dmabuf_private.event_read_lock); if (ret) @@ -174,13 +177,14 @@ ssize_t hyper_dmabuf_event_read(struct file *filp, char __user *buffer, } ret += e->event_data.hdr.size; + hyper_dmabuf_private.curr_num_event--; kfree(e); } } mutex_unlock(_dmabuf_private.event_read_lock); - return 0; + return ret; } static struct file_operations hyper_dmabuf_driver_fops = @@ -233,6 +237,8 @@ static int __init hyper_dmabuf_drv_init(void) printk( KERN_NOTICE "hyper_dmabuf_starting: Initialization started\n"); mutex_init(_dmabuf_private.lock); + mutex_init(_dmabuf_private.event_read_lock); + spin_lock_init(_dmabuf_private.event_lock); ret = register_device(); if (ret < 0) { @@ -329,6 +335,9 @@ static void hyper_dmabuf_drv_exit(void) hyper_dmabuf_private.exited = true; + /* clean up event queue */ + hyper_dmabuf_events_release(); + mutex_unlock(_dmabuf_private.lock); dev_info(hyper_dmabuf_private.device, diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_event.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_event.c index be70e54..8998a7d 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_event.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_event.c @@ -49,11 +49,12 @@ static void hyper_dmabuf_send_event_locked(struct hyper_dmabuf_event *e) /* check current number of event then if it hits the max num allowed * then remove the oldest event in the list */ - if (hyper_dmabuf_private.curr_num_event > MAX_NUMBER_OF_EVENT - 1) { + if (hyper_dmabuf_private.curr_num_event > MAX_DEPTH_EVENT_QUEUE - 1) { oldest = list_first_entry(_dmabuf_private.event_list, struct hyper_dmabuf_event, link); list_del(>link); hyper_dmabuf_private.curr_num_event--; +
[Xen-devel] [RFC PATCH 53/60] hyper_dmabuf: define fastpath_export for exporting existing buffer
To make hyper_dmabuf_export_remote_ioctl more compact and readable, a new function call, 'fastpath_export' is created to replace a routine in hyper_dmabuf_export_remote_ioctl for the case requested buffer for exporting is already in the LIST (exported previously). Signed-off-by: Dongwon Kim--- drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c | 153 +++--- 1 file changed, 87 insertions(+), 66 deletions(-) diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c index b40cf89..d11f609 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c @@ -122,6 +122,82 @@ static int send_export_msg(struct exported_sgt_info *exported, return ret; } +/* Fast path exporting routine in case same buffer is already exported. + * In this function, we skip normal exporting process and just update + * private data on both VMs (importer and exporter) + * + * return '1' if reexport is needed, return '0' if succeeds, return + * Kernel error code if something goes wrong + */ +static int fastpath_export(hyper_dmabuf_id_t hid, int sz_priv, char *priv) +{ + int reexport = 1; + int ret = 0; + struct exported_sgt_info *exported; + + exported = hyper_dmabuf_find_exported(hid); + + if (!exported) + return reexport; + + if (exported->valid == false) + return reexport; + + /* +* Check if unexport is already scheduled for that buffer, +* if so try to cancel it. If that will fail, buffer needs +* to be reexport once again. +*/ + if (exported->unexport_sched) { + if (!cancel_delayed_work_sync(>unexport)) + return reexport; + + exported->unexport_sched = false; + } + + /* if there's any change in size of private data. +* we reallocate space for private data with new size +*/ + if (sz_priv != exported->sz_priv) { + kfree(exported->priv); + + /* truncating size */ + if (sz_priv > MAX_SIZE_PRIV_DATA) + exported->sz_priv = MAX_SIZE_PRIV_DATA; + else + exported->sz_priv = sz_priv; + + exported->priv = kcalloc(1, exported->sz_priv, +GFP_KERNEL); + + if (!exported->priv) { + hyper_dmabuf_remove_exported(exported->hid); + hyper_dmabuf_cleanup_sgt_info(exported, true); + kfree(exported); + return -ENOMEM; + } + } + + /* update private data in sgt_info with new ones */ + ret = copy_from_user(exported->priv, priv, exported->sz_priv); + if (ret) { + dev_err(hy_drv_priv->dev, + "Failed to load a new private data\n"); + ret = -EINVAL; + } else { + /* send an export msg for updating priv in importer */ + ret = send_export_msg(exported, NULL); + + if (ret < 0) { + dev_err(hy_drv_priv->dev, + "Failed to send a new private data\n"); + ret = -EBUSY; + } + } + + return ret; +} + static int hyper_dmabuf_export_remote_ioctl(struct file *filp, void *data) { struct ioctl_hyper_dmabuf_export_remote *export_remote_attr = @@ -153,79 +229,24 @@ static int hyper_dmabuf_export_remote_ioctl(struct file *filp, void *data) */ hid = hyper_dmabuf_find_hid_exported(dma_buf, export_remote_attr->remote_domain); - if (hid.id != -1) { - exported = hyper_dmabuf_find_exported(hid); - if (!exported) - goto reexport; - - if (exported->valid == false) - goto reexport; + if (hid.id != -1) { + ret = fastpath_export(hid, export_remote_attr->sz_priv, + export_remote_attr->priv); - /* -* Check if unexport is already scheduled for that buffer, -* if so try to cancel it. If that will fail, buffer needs -* to be reexport once again. + /* return if fastpath_export succeeds or +* gets some fatal error */ - if (exported->unexport_sched) { - if (!cancel_delayed_work_sync(>unexport)) { - dma_buf_put(dma_buf); - goto reexport; - } - exported->unexport_sched = false; + if (ret <= 0) { + dma_buf_put(dma_buf); + export_remote_attr->hid = hid; +
[Xen-devel] [RFC PATCH 17/60] hyper_dmabuf: use dynamic debug macros for logging
From: Mateusz PolrolaReplaces printk to debug macros Signed-off-by: Dongwon Kim --- drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c| 4 +- drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h| 4 ++ drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c| 46 +- drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c | 50 +-- drivers/xen/hyper_dmabuf/hyper_dmabuf_msg.c| 26 +--- .../xen/hyper_dmabuf/hyper_dmabuf_remote_sync.c| 60 -- .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c | 73 +++--- .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_shm.c| 50 +-- 8 files changed, 206 insertions(+), 107 deletions(-) diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c index ddcc955..9d99769 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c @@ -1,6 +1,7 @@ #include #include #include +#include #include "hyper_dmabuf_conf.h" #include "hyper_dmabuf_msg.h" #include "hyper_dmabuf_drv.h" @@ -36,7 +37,8 @@ static int hyper_dmabuf_drv_init(void) hyper_dmabuf_private.backend_ops = _backend_ops; #endif - printk( KERN_NOTICE "initializing database for imported/exported dmabufs\n"); + dev_info(hyper_dmabuf_private.device, +"initializing database for imported/exported dmabufs\n"); /* device structure initialization */ /* currently only does work-queue initialization */ diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h index 03d77d7..c16e8d4 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h @@ -1,6 +1,10 @@ #ifndef __LINUX_PUBLIC_HYPER_DMABUF_DRV_H__ #define __LINUX_PUBLIC_HYPER_DMABUF_DRV_H__ +#include + +struct hyper_dmabuf_req; + struct list_reusable_id { int id; struct list_head list; diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c index 0f104b9..b61d29a 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c @@ -155,7 +155,7 @@ int hyper_dmabuf_cleanup_sgt_info(struct hyper_dmabuf_sgt_info *sgt_info, int fo struct hyper_dmabuf_backend_ops *ops = hyper_dmabuf_private.backend_ops; if (!sgt_info) { - printk("invalid hyper_dmabuf_id\n"); + dev_err(hyper_dmabuf_private.device, "invalid hyper_dmabuf_id\n"); return -EINVAL; } @@ -168,7 +168,7 @@ int hyper_dmabuf_cleanup_sgt_info(struct hyper_dmabuf_sgt_info *sgt_info, int fo !list_empty(_info->va_vmapped->list) || !list_empty(_info->active_sgts->list) || !list_empty(_info->active_attached->list))) { - printk("dma-buf is used by importer\n"); + dev_warn(hyper_dmabuf_private.device, "dma-buf is used by importer\n"); return -EPERM; } @@ -273,7 +273,8 @@ static int hyper_dmabuf_ops_attach(struct dma_buf* dmabuf, struct device* dev, HYPER_DMABUF_OPS_ATTACH); if (ret < 0) { - printk("hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); + dev_err(hyper_dmabuf_private.device, + "hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); return ret; } @@ -294,7 +295,8 @@ static void hyper_dmabuf_ops_detach(struct dma_buf* dmabuf, struct dma_buf_attac HYPER_DMABUF_OPS_DETACH); if (ret < 0) { - printk("hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); + dev_err(hyper_dmabuf_private.device, + "hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); } } @@ -331,7 +333,8 @@ static struct sg_table* hyper_dmabuf_ops_map(struct dma_buf_attachment *attachme kfree(page_info); if (ret < 0) { - printk("hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); + dev_err(hyper_dmabuf_private.device, + "hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); } return st; @@ -363,7 +366,8 @@ static void hyper_dmabuf_ops_unmap(struct dma_buf_attachment *attachment, HYPER_DMABUF_OPS_UNMAP); if (ret < 0) { - printk("hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); + dev_err(hyper_dmabuf_private.device, + "hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); } } @@ -403,7 +407,8 @@ static void
[Xen-devel] [RFC PATCH 44/60] hyper_dmabuf: proper handling of sgt_info->priv
sgt_info->priv will be used to store user private info passed in ioctl. Data in sgt_info->priv is transfered via comm channel to the importer VM whenever DMA_BUF is exported to keep the private data synchroized across VMs. This patch also adds hyper_dmabuf_send_export_msg that replaces some of export_remote_ioctl to make it more readable and compact. Signed-off-by: Dongwon Kim--- drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c | 110 ++--- drivers/xen/hyper_dmabuf/hyper_dmabuf_struct.h | 6 +- 2 files changed, 65 insertions(+), 51 deletions(-) diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c index 3215003..dfdb889 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c @@ -82,17 +82,64 @@ static int hyper_dmabuf_rx_ch_setup_ioctl(struct file *filp, void *data) return ret; } +static int hyper_dmabuf_send_export_msg(struct hyper_dmabuf_sgt_info *sgt_info, + struct hyper_dmabuf_pages_info *page_info) +{ + struct hyper_dmabuf_backend_ops *ops = hyper_dmabuf_private.backend_ops; + struct hyper_dmabuf_req *req; + int operands[12] = {0}; + int ret, i; + + /* now create request for importer via ring */ + operands[0] = sgt_info->hid.id; + + for (i=0; i<3; i++) + operands[i+1] = sgt_info->hid.rng_key[i]; + + if (page_info) { + operands[4] = page_info->nents; + operands[5] = page_info->frst_ofst; + operands[6] = page_info->last_len; + operands[7] = ops->share_pages (page_info->pages, sgt_info->hyper_dmabuf_rdomain, + page_info->nents, _info->refs_info); + if (operands[7] < 0) { + dev_err(hyper_dmabuf_private.device, "pages sharing failed\n"); + return -1; + } + } + + /* driver/application specific private info, max 4x4 bytes */ + memcpy([8], _info->priv[0], sizeof(unsigned int) * 4); + + req = kcalloc(1, sizeof(*req), GFP_KERNEL); + + if(!req) { + dev_err(hyper_dmabuf_private.device, "no more space left\n"); + return -1; + } + + /* composing a message to the importer */ + hyper_dmabuf_create_request(req, HYPER_DMABUF_EXPORT, [0]); + + ret = ops->send_req(sgt_info->hyper_dmabuf_rdomain, req, false); + + if(ret) { + dev_err(hyper_dmabuf_private.device, "error while communicating\n"); + } + + kfree(req); + + return ret; +} + static int hyper_dmabuf_export_remote_ioctl(struct file *filp, void *data) { struct ioctl_hyper_dmabuf_export_remote *export_remote_attr; - struct hyper_dmabuf_backend_ops *ops = hyper_dmabuf_private.backend_ops; struct dma_buf *dma_buf; struct dma_buf_attachment *attachment; struct sg_table *sgt; struct hyper_dmabuf_pages_info *page_info; struct hyper_dmabuf_sgt_info *sgt_info; - struct hyper_dmabuf_req *req; - int operands[MAX_NUMBER_OF_OPERANDS]; hyper_dmabuf_id_t hid; int i; int ret = 0; @@ -138,6 +185,13 @@ static int hyper_dmabuf_export_remote_ioctl(struct file *filp, void *data) } sgt_info->unexport_scheduled = 0; } + + /* update private data in sgt_info with new ones */ + memcpy(_info->priv[0], _remote_attr->priv[0], sizeof(unsigned int) * 4); + + /* TODO: need to send this private info to the importer so that those +* on importer's side are also updated */ + dma_buf_put(dma_buf); export_remote_attr->hid = hid; return 0; @@ -225,6 +279,9 @@ static int hyper_dmabuf_export_remote_ioctl(struct file *filp, void *data) INIT_LIST_HEAD(_info->va_kmapped->list); INIT_LIST_HEAD(_info->va_vmapped->list); + /* copy private data to sgt_info */ + memcpy(_info->priv[0], _remote_attr->priv[0], sizeof(unsigned int) * 4); + page_info = hyper_dmabuf_ext_pgs(sgt); if (!page_info) { dev_err(hyper_dmabuf_private.device, "failed to construct page_info\n"); @@ -236,53 +293,15 @@ static int hyper_dmabuf_export_remote_ioctl(struct file *filp, void *data) /* now register it to export list */ hyper_dmabuf_register_exported(sgt_info); - page_info->hyper_dmabuf_rdomain = sgt_info->hyper_dmabuf_rdomain; - page_info->hid = sgt_info->hid; /* may not be needed */ - export_remote_attr->hid = sgt_info->hid; - /* now create request
[Xen-devel] [RFC PATCH 46/60] hyper_dmabuf: delay auto initialization of comm_env
Comm env intialization is now scheduled to be done when xenstore is initialized. This scheduling is done in driver's init routine. Also, adding a recursively scheduled routine that monitors any new tx ch setup from other domains and automaticlaly configure rx channel accordingly (every 10 sec). Only limitation is it currently checks domain ID 0 to 10. We could increase this range if needed. With this patch, we don't have to call comm channel setup IOCTL on importer side anymore. For example, we can remove ioctl call in init_hyper_dmabuf from vmdisplay. Signed-off-by: Dongwon Kim--- drivers/xen/hyper_dmabuf/Kconfig | 10 ++ drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c| 64 + drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h| 3 + .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c | 153 - 4 files changed, 199 insertions(+), 31 deletions(-) diff --git a/drivers/xen/hyper_dmabuf/Kconfig b/drivers/xen/hyper_dmabuf/Kconfig index eb1b637..5efcd44 100644 --- a/drivers/xen/hyper_dmabuf/Kconfig +++ b/drivers/xen/hyper_dmabuf/Kconfig @@ -29,4 +29,14 @@ config HYPER_DMABUF_EVENT_GEN shared DMA-BUF is available. Events in the list can be retrieved by read operation. +config HYPER_DMABUF_XEN_AUTO_RX_CH_ADD + bool "Enable automatic rx-ch add with 10 secs interval" + default y + depends on HYPER_DMABUF && HYPER_DMABUF_XEN + help + If enabled, driver reads a node in xenstore every 10 seconds + to check whether there is any tx comm ch configured by another + domain then initialize matched rx comm ch automatically for any + existing tx comm chs. + endmenu diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c index 2845224..005677d 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c @@ -67,27 +67,6 @@ int hyper_dmabuf_open(struct inode *inode, struct file *filp) if (filp->f_flags & O_EXCL) return -EBUSY; - /* -* Initialize backend if needed, -* use mutex to prevent race conditions when -* two userspace apps will open device at the same time -*/ - mutex_lock(_dmabuf_private.lock); - - if (!hyper_dmabuf_private.backend_initialized) { - hyper_dmabuf_private.domid = hyper_dmabuf_private.backend_ops->get_vm_id(); - - ret = hyper_dmabuf_private.backend_ops->init_comm_env(); - if (ret < 0) { - dev_err(hyper_dmabuf_private.device, - "failed to initiailize hypervisor-specific comm env\n"); - } else { - hyper_dmabuf_private.backend_initialized = true; - } - } - - mutex_unlock(_dmabuf_private.lock); - return ret; } @@ -260,17 +239,22 @@ static int __init hyper_dmabuf_drv_init(void) return ret; } +/* currently only supports XEN hypervisor */ + #ifdef CONFIG_HYPER_DMABUF_XEN hyper_dmabuf_private.backend_ops = _backend_ops; +#else + hyper_dmabuf_private.backend_ops = NULL; + printk( KERN_ERR "hyper_dmabuf drv currently supports XEN only.\n"); #endif - /* -* Defer backend setup to first open call. -* Due to fact that some hypervisors eg. Xen, may have dependencies -* to userspace daemons like xenstored, in that case all xenstore -* calls done from kernel will block until that deamon will be -* started, in case where module is built in that will block entire -* kernel initialization. -*/ + + if (hyper_dmabuf_private.backend_ops == NULL) { + printk( KERN_ERR "Hyper_dmabuf: failed to be loaded - no backend found\n"); + return -1; + } + + mutex_lock(_dmabuf_private.lock); + hyper_dmabuf_private.backend_initialized = false; dev_info(hyper_dmabuf_private.device, @@ -301,6 +285,22 @@ static int __init hyper_dmabuf_drv_init(void) init_waitqueue_head(_dmabuf_private.event_wait); hyper_dmabuf_private.curr_num_event = 0; + hyper_dmabuf_private.exited = false; + + hyper_dmabuf_private.domid = hyper_dmabuf_private.backend_ops->get_vm_id(); + + ret = hyper_dmabuf_private.backend_ops->init_comm_env(); + if (ret < 0) { + dev_dbg(hyper_dmabuf_private.device, + "failed to initialize comm-env but it will re-attempt.\n"); + } else { + hyper_dmabuf_private.backend_initialized = true; + } + + mutex_unlock(_dmabuf_private.lock); + + dev_info(hyper_dmabuf_private.device, + "Finishing up initialization of hyper_dmabuf drv\n"); /* interrupt for comm should be registered here: */ return ret; @@ -312,6 +312,8 @@ static void
[Xen-devel] [RFC PATCH 45/60] hyper_dmabuf: adding poll/read for event generation
hyper_dmabuf driver on importing domain now generates event every time new hyper_dmabuf is available (visible) to the importer. Each event comes with 128 byte private data, which can contain any meta data or user data specific to the originator of DMA BUF. Signed-off-by: Dongwon Kim--- drivers/xen/hyper_dmabuf/Kconfig | 10 ++ drivers/xen/hyper_dmabuf/Makefile | 1 + drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c| 120 +++- drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h| 48 ++-- drivers/xen/hyper_dmabuf/hyper_dmabuf_event.c | 125 + drivers/xen/hyper_dmabuf/hyper_dmabuf_event.h | 38 +++ drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c | 23 ++-- drivers/xen/hyper_dmabuf/hyper_dmabuf_list.c | 1 + drivers/xen/hyper_dmabuf/hyper_dmabuf_msg.c| 44 +++- drivers/xen/hyper_dmabuf/hyper_dmabuf_msg.h| 2 +- drivers/xen/hyper_dmabuf/hyper_dmabuf_struct.h | 4 +- .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c | 37 +- include/uapi/xen/hyper_dmabuf.h| 13 ++- 13 files changed, 430 insertions(+), 36 deletions(-) create mode 100644 drivers/xen/hyper_dmabuf/hyper_dmabuf_event.c create mode 100644 drivers/xen/hyper_dmabuf/hyper_dmabuf_event.h diff --git a/drivers/xen/hyper_dmabuf/Kconfig b/drivers/xen/hyper_dmabuf/Kconfig index 185fdf8..eb1b637 100644 --- a/drivers/xen/hyper_dmabuf/Kconfig +++ b/drivers/xen/hyper_dmabuf/Kconfig @@ -19,4 +19,14 @@ config HYPER_DMABUF_SYSFS Expose information about imported and exported buffers using hyper_dmabuf driver +config HYPER_DMABUF_EVENT_GEN + bool "Enable event-generation and polling operation" + default n + depends on HYPER_DMABUF + help + With this config enabled, hyper_dmabuf driver on the importer side + generates events and queue those up in the event list whenever a new + shared DMA-BUF is available. Events in the list can be retrieved by + read operation. + endmenu diff --git a/drivers/xen/hyper_dmabuf/Makefile b/drivers/xen/hyper_dmabuf/Makefile index 5040b9f..1cd7a81 100644 --- a/drivers/xen/hyper_dmabuf/Makefile +++ b/drivers/xen/hyper_dmabuf/Makefile @@ -13,6 +13,7 @@ ifneq ($(KERNELRELEASE),) hyper_dmabuf_id.o \ hyper_dmabuf_remote_sync.o \ hyper_dmabuf_query.o \ +hyper_dmabuf_event.o \ ifeq ($(CONFIG_XEN), y) $(TARGET_MODULE)-objs += xen/hyper_dmabuf_xen_comm.o \ diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c index 8c488d7..2845224 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c @@ -30,7 +30,10 @@ #include #include #include +#include #include +#include +#include #include #include "hyper_dmabuf_drv.h" #include "hyper_dmabuf_conf.h" @@ -38,6 +41,7 @@ #include "hyper_dmabuf_msg.h" #include "hyper_dmabuf_list.h" #include "hyper_dmabuf_id.h" +#include "hyper_dmabuf_event.h" #ifdef CONFIG_HYPER_DMABUF_XEN #include "xen/hyper_dmabuf_xen_drv.h" @@ -64,7 +68,7 @@ int hyper_dmabuf_open(struct inode *inode, struct file *filp) return -EBUSY; /* -* Initialize backend if neededm, +* Initialize backend if needed, * use mutex to prevent race conditions when * two userspace apps will open device at the same time */ @@ -91,6 +95,112 @@ int hyper_dmabuf_release(struct inode *inode, struct file *filp) { hyper_dmabuf_foreach_exported(hyper_dmabuf_emergency_release, filp); + /* clean up event queue */ + hyper_dmabuf_events_release(); + + return 0; +} + +unsigned int hyper_dmabuf_event_poll(struct file *filp, struct poll_table_struct *wait) +{ + unsigned int mask = 0; + + poll_wait(filp, _dmabuf_private.event_wait, wait); + + if (!list_empty(_dmabuf_private.event_list)) + mask |= POLLIN | POLLRDNORM; + + return mask; +} + +ssize_t hyper_dmabuf_event_read(struct file *filp, char __user *buffer, + size_t count, loff_t *offset) +{ + int ret; + + /* only root can read events */ + if (!capable(CAP_DAC_OVERRIDE)) + return -EFAULT; + + /* make sure user buffer can be written */ + if (!access_ok(VERIFY_WRITE, buffer, count)) + return -EFAULT; + + ret = mutex_lock_interruptible(_dmabuf_private.event_read_lock); + if (ret) + return ret; + + while (1) { + struct hyper_dmabuf_event *e = NULL; + + spin_lock_irq(_dmabuf_private.event_lock); + if (!list_empty(_dmabuf_private.event_list)) { + e = list_first_entry(_dmabuf_private.event_list, +
[Xen-devel] [RFC PATCH 24/60] hyper_dmabuf: waits for resp only if WAIT_AFTER_SYNC_REQ == 1
hyper_dmabuf's sync_request (previously hyper_dmabuf_sync_request_ and_wait) now does not wait for the response from exporter if WAIT_AFTER_SYNC_REQ==0. This is to prevent peformance degradation due to the communication latency while doing indirect hyper DMABUF synchronization. This patch also includes some minor changes as followed: 1. hyper_dmabuf_free_sgt is removed. Now we call sg_free_table and kfree directly from all the places where this function was executed. This was done for conciseness. 2. changed hyper_dmabuf_get_domid to hyper_dmabuf_xen_get_domid for consistence in func names in the backend. 3. some minor clean-ups Signed-off-by: Dongwon Kim--- drivers/xen/hyper_dmabuf/hyper_dmabuf_conf.h | 2 - drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c| 91 +++--- drivers/xen/hyper_dmabuf/hyper_dmabuf_msg.c| 2 - .../xen/hyper_dmabuf/hyper_dmabuf_remote_sync.c| 2 +- .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c | 14 ++-- .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.h | 2 +- .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_drv.c| 2 +- .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_shm.c| 21 +++-- 8 files changed, 69 insertions(+), 67 deletions(-) diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_conf.h b/drivers/xen/hyper_dmabuf/hyper_dmabuf_conf.h index ee1886c..d5125f2 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_conf.h +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_conf.h @@ -23,5 +23,3 @@ */ /* configuration */ - -#define CURRENT_TARGET XEN diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c index a017070..d7a35fc 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c @@ -131,7 +131,7 @@ struct hyper_dmabuf_pages_info *hyper_dmabuf_ext_pgs(struct sg_table *sgt) /* create sg_table with given pages and other parameters */ struct sg_table* hyper_dmabuf_create_sgt(struct page **pages, - int frst_ofst, int last_len, int nents) +int frst_ofst, int last_len, int nents) { struct sg_table *sgt; struct scatterlist *sgl; @@ -144,7 +144,11 @@ struct sg_table* hyper_dmabuf_create_sgt(struct page **pages, ret = sg_alloc_table(sgt, nents, GFP_KERNEL); if (ret) { - hyper_dmabuf_free_sgt(sgt); + if (sgt) { + sg_free_table(sgt); + kfree(sgt); + } + return NULL; } @@ -165,15 +169,6 @@ struct sg_table* hyper_dmabuf_create_sgt(struct page **pages, return sgt; } -/* free sg_table */ -void hyper_dmabuf_free_sgt(struct sg_table* sgt) -{ - if (sgt) { - sg_free_table(sgt); - kfree(sgt); - } -} - int hyper_dmabuf_cleanup_sgt_info(struct hyper_dmabuf_sgt_info *sgt_info, int force) { struct sgt_list *sgtl; @@ -264,7 +259,9 @@ int hyper_dmabuf_cleanup_sgt_info(struct hyper_dmabuf_sgt_info *sgt_info, int fo return 0; } -inline int hyper_dmabuf_sync_request_and_wait(int id, int dmabuf_ops) +#define WAIT_AFTER_SYNC_REQ 1 + +inline int hyper_dmabuf_sync_request(int id, int dmabuf_ops) { struct hyper_dmabuf_req *req; struct hyper_dmabuf_backend_ops *ops = hyper_dmabuf_private.backend_ops; @@ -279,7 +276,7 @@ inline int hyper_dmabuf_sync_request_and_wait(int id, int dmabuf_ops) hyper_dmabuf_create_request(req, HYPER_DMABUF_OPS_TO_SOURCE, [0]); /* send request and wait for a response */ - ret = ops->send_req(HYPER_DMABUF_DOM_ID(id), req, true); + ret = ops->send_req(HYPER_DMABUF_DOM_ID(id), req, WAIT_AFTER_SYNC_REQ); kfree(req); @@ -297,8 +294,8 @@ static int hyper_dmabuf_ops_attach(struct dma_buf* dmabuf, struct device* dev, sgt_info = (struct hyper_dmabuf_imported_sgt_info *)attach->dmabuf->priv; - ret = hyper_dmabuf_sync_request_and_wait(sgt_info->hyper_dmabuf_id, -HYPER_DMABUF_OPS_ATTACH); + ret = hyper_dmabuf_sync_request(sgt_info->hyper_dmabuf_id, + HYPER_DMABUF_OPS_ATTACH); if (ret < 0) { dev_err(hyper_dmabuf_private.device, @@ -319,8 +316,8 @@ static void hyper_dmabuf_ops_detach(struct dma_buf* dmabuf, struct dma_buf_attac sgt_info = (struct hyper_dmabuf_imported_sgt_info *)attach->dmabuf->priv; - ret = hyper_dmabuf_sync_request_and_wait(sgt_info->hyper_dmabuf_id, -HYPER_DMABUF_OPS_DETACH); + ret = hyper_dmabuf_sync_request(sgt_info->hyper_dmabuf_id, + HYPER_DMABUF_OPS_DETACH); if (ret < 0) { dev_err(hyper_dmabuf_private.device, @@ -354,8 +351,8 @@ static struct sg_table* hyper_dmabuf_ops_map(struct
[Xen-devel] [RFC PATCH 51/60] hyper_dmabuf: missing mutex_unlock and move spinlock
Added missing mutex_unlock to make sure mutex is unlocked before returning. Also, moved spinlock lock/unlock into hyper_dmabuf_send_event and remove checking on spinlock (with assumption caller does the spinlock in advance) to make it more straight forward. This patch includes a couple of minor modifications, changing type of function calls to static and correcting some of error code. Signed-off-by: Dongwon Kim--- drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c | 38 +-- drivers/xen/hyper_dmabuf/hyper_dmabuf_event.c | 15 +-- drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c | 8 -- 3 files changed, 30 insertions(+), 31 deletions(-) diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c index 023d7f4..76f57c2 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c @@ -73,7 +73,7 @@ static void hyper_dmabuf_force_free(struct exported_sgt_info *exported, } } -int hyper_dmabuf_open(struct inode *inode, struct file *filp) +static int hyper_dmabuf_open(struct inode *inode, struct file *filp) { int ret = 0; @@ -84,7 +84,7 @@ int hyper_dmabuf_open(struct inode *inode, struct file *filp) return ret; } -int hyper_dmabuf_release(struct inode *inode, struct file *filp) +static int hyper_dmabuf_release(struct inode *inode, struct file *filp) { hyper_dmabuf_foreach_exported(hyper_dmabuf_force_free, filp); @@ -93,20 +93,18 @@ int hyper_dmabuf_release(struct inode *inode, struct file *filp) #ifdef CONFIG_HYPER_DMABUF_EVENT_GEN -unsigned int hyper_dmabuf_event_poll(struct file *filp, +static unsigned int hyper_dmabuf_event_poll(struct file *filp, struct poll_table_struct *wait) { - unsigned int mask = 0; - poll_wait(filp, _drv_priv->event_wait, wait); if (!list_empty(_drv_priv->event_list)) - mask |= POLLIN | POLLRDNORM; + return POLLIN | POLLRDNORM; - return mask; + return 0; } -ssize_t hyper_dmabuf_event_read(struct file *filp, char __user *buffer, +static ssize_t hyper_dmabuf_event_read(struct file *filp, char __user *buffer, size_t count, loff_t *offset) { int ret; @@ -115,14 +113,14 @@ ssize_t hyper_dmabuf_event_read(struct file *filp, char __user *buffer, if (!capable(CAP_DAC_OVERRIDE)) { dev_err(hy_drv_priv->dev, "Only root can read events\n"); - return -EFAULT; + return -EPERM; } /* make sure user buffer can be written */ if (!access_ok(VERIFY_WRITE, buffer, count)) { dev_err(hy_drv_priv->dev, "User buffer can't be written.\n"); - return -EFAULT; + return -EINVAL; } ret = mutex_lock_interruptible(_drv_priv->event_read_lock); @@ -143,6 +141,7 @@ ssize_t hyper_dmabuf_event_read(struct file *filp, char __user *buffer, if (!e) { if (ret) break; + if (filp->f_flags & O_NONBLOCK) { ret = -EAGAIN; break; @@ -233,7 +232,7 @@ static struct miscdevice hyper_dmabuf_miscdev = { .fops = _dmabuf_driver_fops, }; -int register_device(void) +static int register_device(void) { int ret = 0; @@ -252,7 +251,7 @@ int register_device(void) return ret; } -void unregister_device(void) +static void unregister_device(void) { dev_info(hy_drv_priv->dev, "hyper_dmabuf: unregister_device() is called\n"); @@ -269,10 +268,8 @@ static int __init hyper_dmabuf_drv_init(void) hy_drv_priv = kcalloc(1, sizeof(struct hyper_dmabuf_private), GFP_KERNEL); - if (!hy_drv_priv) { - printk(KERN_ERR "hyper_dmabuf: Failed to create drv\n"); - return -1; - } + if (!hy_drv_priv) + return -ENOMEM; ret = register_device(); if (ret < 0) @@ -291,7 +288,6 @@ static int __init hyper_dmabuf_drv_init(void) return -1; } - /* initializing mutexes and a spinlock */ mutex_init(_drv_priv->lock); mutex_lock(_drv_priv->lock); @@ -301,14 +297,14 @@ static int __init hyper_dmabuf_drv_init(void) dev_info(hy_drv_priv->dev, "initializing database for imported/exported dmabufs\n"); - /* device structure initialization */ - /* currently only does work-queue initialization */ hy_drv_priv->work_queue = create_workqueue("hyper_dmabuf_wqueue"); ret = hyper_dmabuf_table_init(); if (ret < 0) { dev_err(hy_drv_priv->dev, "failed to initialize table for exported/imported entries\n"); +
[Xen-devel] [RFC PATCH 48/60] hyper_dmabuf: add query items for buffer private info.
From: Mateusz PolrolaThis change adds two query items, 'HYPER_DMABUF_QUERY_PRIV_INFO_SIZE' and 'HYPER_DMABUF_QUERY_PRIV_INFO', for retrieving buffer's private info and its size. 'info' is an address of user-space buffer (user application provides this) ,where private data will be copied in case query item is 'HYPER_DMABUF_QUERY_PRIV_INFO'. Signed-off-by: Dongwon Kim --- drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c | 7 +- drivers/xen/hyper_dmabuf/hyper_dmabuf_event.c | 6 ++ drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c | 12 ++-- drivers/xen/hyper_dmabuf/hyper_dmabuf_query.c | 97 +-- drivers/xen/hyper_dmabuf/hyper_dmabuf_query.h | 6 +- include/uapi/xen/hyper_dmabuf.h | 4 +- 6 files changed, 100 insertions(+), 32 deletions(-) diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c index 87ea6ca..1c35a59 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c @@ -168,8 +168,11 @@ ssize_t hyper_dmabuf_event_read(struct file *filp, char __user *buffer, ret -= sizeof(struct hyper_dmabuf_event_hdr); /* nullifying hdr of the event in user buffer */ - copy_to_user(buffer + ret, _hdr, -sizeof(dummy_hdr)); + if (copy_to_user(buffer + ret, _hdr, +sizeof(dummy_hdr))) { + dev_err(hyper_dmabuf_private.device, + "failed to nullify invalid hdr already in userspace\n"); + } ret = -EFAULT; diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_event.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_event.c index 8998a7d..3e1498c 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_event.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_event.c @@ -104,6 +104,12 @@ int hyper_dmabuf_import_event(hyper_dmabuf_id_t hid) e = kzalloc(sizeof(*e), GFP_KERNEL); + if (!e) { + dev_err(hyper_dmabuf_private.device, + "no space left\n"); + return -ENOMEM; + } + e->event_data.hdr.event_type = HYPER_DMABUF_NEW_IMPORT; e->event_data.hdr.hid = hid; e->event_data.data = (void*)imported_sgt_info->priv; diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c index 06f95ca..15191c2 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c @@ -671,9 +671,8 @@ static int hyper_dmabuf_query_ioctl(struct file *filp, void *data) /* query for exported dmabuf */ sgt_info = hyper_dmabuf_find_exported(query_attr->hid); if (sgt_info) { - ret = hyper_dmabuf_query_exported(sgt_info, query_attr->item); - if (ret != -EINVAL) - query_attr->info = ret; + ret = hyper_dmabuf_query_exported(sgt_info, + query_attr->item, _attr->info); } else { dev_err(hyper_dmabuf_private.device, "DMA BUF {id:%d key:%d %d %d} can't be found in the export list\n", @@ -685,9 +684,8 @@ static int hyper_dmabuf_query_ioctl(struct file *filp, void *data) /* query for imported dmabuf */ imported_sgt_info = hyper_dmabuf_find_imported(query_attr->hid); if (imported_sgt_info) { - ret = hyper_dmabuf_query_imported(imported_sgt_info, query_attr->item); - if (ret != -EINVAL) - query_attr->info = ret; + ret = hyper_dmabuf_query_imported(imported_sgt_info, + query_attr->item, _attr->info); } else { dev_err(hyper_dmabuf_private.device, "DMA BUF {id:%d key:%d %d %d} can't be found in the imported list\n", @@ -697,7 +695,7 @@ static int hyper_dmabuf_query_ioctl(struct file *filp, void *data) } } - return 0; + return ret; } void hyper_dmabuf_emergency_release(struct hyper_dmabuf_sgt_info* sgt_info, diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_query.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_query.c index 2a5201b..39c9dee 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_query.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_query.c @@ -27,6 +27,7 @@ */ #include +#include #include "hyper_dmabuf_drv.h" #include "hyper_dmabuf_struct.h" #include
[Xen-devel] [RFC PATCH 01/60] hyper_dmabuf: initial working version of hyper_dmabuf drv
Upload of intial version of hyper_DMABUF driver enabling DMA_BUF exchange between two different VMs in virtualized platform based on hypervisor such as KVM or XEN. Hyper_DMABUF drv's primary role is to import a DMA_BUF from originator then re-export it to another Linux VM so that it can be mapped and accessed by it. The functionality of this driver highly depends on Hypervisor's native page sharing mechanism and inter-VM communication support. This driver has two layers, one is main hyper_DMABUF framework for scatter-gather list management that handles actual import and export of DMA_BUF. Lower layer is about actual memory sharing and communication between two VMs, which is hypervisor-specific interface. This driver is initially designed to enable DMA_BUF sharing across VMs in Xen environment, so currently working with Xen only. This also adds Kernel configuration for hyper_DMABUF drv under Device Drivers->Xen driver support->hyper_dmabuf options. To give some brief information about each source file, hyper_dmabuf/hyper_dmabuf_conf.h : configuration info hyper_dmabuf/hyper_dmabuf_drv.c : driver interface and initialization hyper_dmabuf/hyper_dmabuf_imp.c : scatter-gather list generation and management. DMA_BUF ops for DMA_BUF reconstructed from hyper_DMABUF hyper_dmabuf/hyper_dmabuf_ioctl.c : IOCTLs calls for export/import and comm channel creation unexport. hyper_dmabuf/hyper_dmabuf_list.c : Database (linked-list) for exported and imported hyper_DMABUF hyper_dmabuf/hyper_dmabuf_msg.c : creation and management of messages between exporter and importer hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c : comm ch management and ISRs for incoming messages. hyper_dmabuf/xen/hyper_dmabuf_xen_comm_list.c : Database (linked-list) for keeping information about existing comm channels among VMs Signed-off-by: Dongwon KimSigned-off-by: Mateusz Polrola --- drivers/xen/Kconfig| 2 + drivers/xen/Makefile | 1 + drivers/xen/hyper_dmabuf/Kconfig | 14 + drivers/xen/hyper_dmabuf/Makefile | 34 + drivers/xen/hyper_dmabuf/hyper_dmabuf_conf.h | 2 + drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c| 54 ++ drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h| 101 +++ drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c| 852 + drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.h| 31 + drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c | 462 +++ drivers/xen/hyper_dmabuf/hyper_dmabuf_list.c | 119 +++ drivers/xen/hyper_dmabuf/hyper_dmabuf_list.h | 40 + drivers/xen/hyper_dmabuf/hyper_dmabuf_msg.c| 212 + drivers/xen/hyper_dmabuf/hyper_dmabuf_msg.h| 45 ++ drivers/xen/hyper_dmabuf/hyper_dmabuf_query.h | 16 + drivers/xen/hyper_dmabuf/hyper_dmabuf_struct.h | 70 ++ .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c | 328 .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.h | 62 ++ .../hyper_dmabuf/xen/hyper_dmabuf_xen_comm_list.c | 106 +++ .../hyper_dmabuf/xen/hyper_dmabuf_xen_comm_list.h | 35 + 20 files changed, 2586 insertions(+) create mode 100644 drivers/xen/hyper_dmabuf/Kconfig create mode 100644 drivers/xen/hyper_dmabuf/Makefile create mode 100644 drivers/xen/hyper_dmabuf/hyper_dmabuf_conf.h create mode 100644 drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c create mode 100644 drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h create mode 100644 drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c create mode 100644 drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.h create mode 100644 drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c create mode 100644 drivers/xen/hyper_dmabuf/hyper_dmabuf_list.c create mode 100644 drivers/xen/hyper_dmabuf/hyper_dmabuf_list.h create mode 100644 drivers/xen/hyper_dmabuf/hyper_dmabuf_msg.c create mode 100644 drivers/xen/hyper_dmabuf/hyper_dmabuf_msg.h create mode 100644 drivers/xen/hyper_dmabuf/hyper_dmabuf_query.h create mode 100644 drivers/xen/hyper_dmabuf/hyper_dmabuf_struct.h create mode 100644 drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c create mode 100644 drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.h create mode 100644 drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm_list.c create mode 100644 drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm_list.h diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig index d8dd546..b59b0e3 100644 --- a/drivers/xen/Kconfig +++ b/drivers/xen/Kconfig @@ -321,4 +321,6 @@ config XEN_SYMS config XEN_HAVE_VPMU bool +source "drivers/xen/hyper_dmabuf/Kconfig" + endmenu diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile index 451e833..a6e253a 100644 --- a/drivers/xen/Makefile +++ b/drivers/xen/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_X86) += fallback.o obj-y += grant-table.o features.o balloon.o manage.o preempt.o time.o obj-y += events/ obj-y += xenbus/
[Xen-devel] [RFC PATCH 36/60] hyper_dmabuf: error handling when share_pages fails
From: Mateusz PolrolaWhen error occurs while sharing pages, all pages already shared needs to be un-shared and proper error code has to be returned. Signed-off-by: Dongwon Kim --- drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c | 6 ++- .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_shm.c| 50 ++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c index f1581d5..375b664 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include #include @@ -242,6 +242,10 @@ static int hyper_dmabuf_export_remote(struct file *filp, void *data) operands[6] = page_info->last_len; operands[7] = ops->share_pages (page_info->pages, export_remote_attr->remote_domain, page_info->nents, _info->refs_info); + if (operands[7] < 0) { + dev_err(hyper_dmabuf_private.device, "pages sharing failed\n"); + goto fail_map_req; + } /* driver/application specific private info, max 4x4 bytes */ operands[8] = export_remote_attr->private[0]; diff --git a/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_shm.c b/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_shm.c index 1416a69..908eda8 100644 --- a/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_shm.c +++ b/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_shm.c @@ -109,6 +109,16 @@ int hyper_dmabuf_xen_share_pages(struct page **pages, int domid, int nents, lvl2_table[i] = gnttab_grant_foreign_access(domid, pfn_to_mfn(page_to_pfn(pages[i])), true /* read-only from remote domain */); + if (lvl2_table[i] == -ENOSPC) { + dev_err(hyper_dmabuf_private.device, "No more space left in grant table\n"); + + /* Unshare all already shared pages for lvl2 */ + while(i--) { + gnttab_end_foreign_access_ref(lvl2_table[i], 0); + gnttab_free_grant_reference(lvl2_table[i]); + } + goto err_cleanup; + } } /* Share 2nd level addressing pages in readonly mode*/ @@ -116,6 +126,23 @@ int hyper_dmabuf_xen_share_pages(struct page **pages, int domid, int nents, lvl3_table[i] = gnttab_grant_foreign_access(domid, virt_to_mfn((unsigned long)lvl2_table+i*PAGE_SIZE ), true); + if (lvl3_table[i] == -ENOSPC) { + dev_err(hyper_dmabuf_private.device, "No more space left in grant table\n"); + + /* Unshare all already shared pages for lvl3 */ + while(i--) { + gnttab_end_foreign_access_ref(lvl3_table[i], 1); + gnttab_free_grant_reference(lvl3_table[i]); + } + + /* Unshare all pages for lvl2 */ + while(nents--) { + gnttab_end_foreign_access_ref(lvl2_table[nents], 0); + gnttab_free_grant_reference(lvl2_table[nents]); + } + + goto err_cleanup; + } } /* Share lvl3_table in readonly mode*/ @@ -123,6 +150,23 @@ int hyper_dmabuf_xen_share_pages(struct page **pages, int domid, int nents, virt_to_mfn((unsigned long)lvl3_table), true); + if (lvl3_gref == -ENOSPC) { + dev_err(hyper_dmabuf_private.device, "No more space left in grant table\n"); + + /* Unshare all pages for lvl3 */ + while(i--) { + gnttab_end_foreign_access_ref(lvl3_table[i], 1); + gnttab_free_grant_reference(lvl3_table[i]); + } + + /* Unshare all pages for lvl2 */ + while(nents--) { + gnttab_end_foreign_access_ref(lvl2_table[nents], 0); + gnttab_free_grant_reference(lvl2_table[nents]); + } + + goto err_cleanup; + } /* Store lvl3_table page to be freed later */ sh_pages_info->lvl3_table = lvl3_table; @@ -136,6 +180,12 @@ int hyper_dmabuf_xen_share_pages(struct page **pages, int domid, int nents, dev_dbg(hyper_dmabuf_private.device, "%s exit\n", __func__); return lvl3_gref; +
[Xen-devel] [RFC PATCH 34/60] hyper_dmabuf: extend DMA bitmask to 64-bits.
From: Mateusz PolrolaExtending DMA bitmask of hyper_dmabuf device to cover whole address space driver may access. Signed-off-by: Dongwon Kim --- drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c index 476c0d7..f7d98c1 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c @@ -723,7 +723,7 @@ int register_device(void) hyper_dmabuf_private.device = hyper_dmabuf_miscdev.this_device; /* TODO: Check if there is a different way to initialize dma mask nicely */ - dma_coerce_mask_and_coherent(hyper_dmabuf_private.device, 0x); + dma_coerce_mask_and_coherent(hyper_dmabuf_private.device, DMA_BIT_MASK(64)); return ret; } -- 2.7.4 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [RFC PATCH 41/60] hyper_dmabuf: re-organize driver source
Re-orginized source code for more intuitive structure For this, 1. driver's file operations other than ioctls have been moved to hyper_dmabuf_drv.c. 2. Separated out dma-buf operations from hyper_dmabuf_ops.c and put those in a new file, 'hyper_dmabuf_ops.c'. Remaining part (SGT core management) is also put in the a new file, 'hyper_dmabuf_sgt_proc.c'. hyper_dmabuf_imp.c and hyper_dmabuf_imp.h are removed as a result. 3. Header files and Makefile are also updated accordingly. Signed-off-by: Dongwon Kim--- drivers/xen/hyper_dmabuf/Makefile | 3 +- drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c| 95 ++- drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c| 682 - drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.h| 48 -- drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c | 136 +--- drivers/xen/hyper_dmabuf/hyper_dmabuf_msg.c| 1 - drivers/xen/hyper_dmabuf/hyper_dmabuf_ops.c| 471 ++ drivers/xen/hyper_dmabuf/hyper_dmabuf_ops.h| 32 + .../xen/hyper_dmabuf/hyper_dmabuf_remote_sync.c| 2 +- drivers/xen/hyper_dmabuf/hyper_dmabuf_sgl_proc.c | 258 drivers/xen/hyper_dmabuf/hyper_dmabuf_sgl_proc.h | 41 ++ 11 files changed, 920 insertions(+), 849 deletions(-) delete mode 100644 drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c delete mode 100644 drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.h create mode 100644 drivers/xen/hyper_dmabuf/hyper_dmabuf_ops.c create mode 100644 drivers/xen/hyper_dmabuf/hyper_dmabuf_ops.h create mode 100644 drivers/xen/hyper_dmabuf/hyper_dmabuf_sgl_proc.c create mode 100644 drivers/xen/hyper_dmabuf/hyper_dmabuf_sgl_proc.h diff --git a/drivers/xen/hyper_dmabuf/Makefile b/drivers/xen/hyper_dmabuf/Makefile index 8865f50..5040b9f 100644 --- a/drivers/xen/hyper_dmabuf/Makefile +++ b/drivers/xen/hyper_dmabuf/Makefile @@ -7,7 +7,8 @@ ifneq ($(KERNELRELEASE),) $(TARGET_MODULE)-objs := hyper_dmabuf_drv.o \ hyper_dmabuf_ioctl.o \ hyper_dmabuf_list.o \ -hyper_dmabuf_imp.o \ +hyper_dmabuf_sgl_proc.o \ +hyper_dmabuf_ops.o \ hyper_dmabuf_msg.o \ hyper_dmabuf_id.o \ hyper_dmabuf_remote_sync.o \ diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c index c802c3e..8c488d7 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c @@ -28,10 +28,13 @@ #include #include +#include #include #include +#include #include "hyper_dmabuf_drv.h" #include "hyper_dmabuf_conf.h" +#include "hyper_dmabuf_ioctl.h" #include "hyper_dmabuf_msg.h" #include "hyper_dmabuf_list.h" #include "hyper_dmabuf_id.h" @@ -44,12 +47,94 @@ extern struct hyper_dmabuf_backend_ops xen_backend_ops; MODULE_LICENSE("GPL and additional rights"); MODULE_AUTHOR("Intel Corporation"); -int register_device(void); -int unregister_device(void); - struct hyper_dmabuf_private hyper_dmabuf_private; -/*===*/ +long hyper_dmabuf_ioctl(struct file *filp, + unsigned int cmd, unsigned long param); + +void hyper_dmabuf_emergency_release(struct hyper_dmabuf_sgt_info* sgt_info, + void *attr); + +int hyper_dmabuf_open(struct inode *inode, struct file *filp) +{ + int ret = 0; + + /* Do not allow exclusive open */ + if (filp->f_flags & O_EXCL) + return -EBUSY; + + /* +* Initialize backend if neededm, +* use mutex to prevent race conditions when +* two userspace apps will open device at the same time +*/ + mutex_lock(_dmabuf_private.lock); + + if (!hyper_dmabuf_private.backend_initialized) { + hyper_dmabuf_private.domid = hyper_dmabuf_private.backend_ops->get_vm_id(); + + ret = hyper_dmabuf_private.backend_ops->init_comm_env(); + if (ret < 0) { + dev_err(hyper_dmabuf_private.device, + "failed to initiailize hypervisor-specific comm env\n"); + } else { + hyper_dmabuf_private.backend_initialized = true; + } + } + + mutex_unlock(_dmabuf_private.lock); + + return ret; +} + +int hyper_dmabuf_release(struct inode *inode, struct file *filp) +{ + hyper_dmabuf_foreach_exported(hyper_dmabuf_emergency_release, filp); + + return 0; +} + +static struct file_operations hyper_dmabuf_driver_fops = +{ + .owner = THIS_MODULE, + .open = hyper_dmabuf_open, + .release = hyper_dmabuf_release, + .unlocked_ioctl = hyper_dmabuf_ioctl, +}; + +static
[Xen-devel] [RFC PATCH 18/60] hyper_dmabuf: reset comm channel when one end has disconnected.
From: Mateusz PolrolaWhen exporter or importer is disconnected, ring buffer should be reinitialzed, otherwise on next reconnection exporter/importer will receive old requests/responses remaining in the ring buffer, which are not valid anymore. This patch also blocks back ring irq until communication channel is initialized and fully active to prevent a race condition. Signed-off-by: Dongwon Kim --- .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c | 24 +++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c b/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c index 5e7a250..b629032 100644 --- a/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c +++ b/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c @@ -282,6 +282,7 @@ int hyper_dmabuf_xen_init_tx_rbuf(int domid) void hyper_dmabuf_xen_cleanup_tx_rbuf(int domid) { struct xen_comm_tx_ring_info *ring_info; + struct xen_comm_rx_ring_info *rx_ring_info; /* check if we at all have exporter ring for given rdomain */ ring_info = xen_comm_find_tx_ring(domid); @@ -307,6 +308,12 @@ void hyper_dmabuf_xen_cleanup_tx_rbuf(int domid) (unsigned long) ring_info->ring_front.sring); kfree(ring_info); + + rx_ring_info = xen_comm_find_rx_ring(domid); + if (!rx_ring_info) + return; + + BACK_RING_INIT(&(rx_ring_info->ring_back), rx_ring_info->ring_back.sring, PAGE_SIZE); } /* importer needs to know about shared page and port numbers for @@ -378,9 +385,8 @@ int hyper_dmabuf_xen_init_rx_rbuf(int domid) BACK_RING_INIT(_info->ring_back, sring, PAGE_SIZE); - ret = bind_interdomain_evtchn_to_irqhandler(domid, rx_port, - back_ring_isr, 0, - NULL, (void*)ring_info); + ret = bind_interdomain_evtchn_to_irq(domid, rx_port); + if (ret < 0) { return -EINVAL; } @@ -399,6 +405,10 @@ int hyper_dmabuf_xen_init_rx_rbuf(int domid) ret = hyper_dmabuf_xen_init_tx_rbuf(domid); } + ret = request_irq(ring_info->irq, + back_ring_isr, 0, + NULL, (void*)ring_info); + return ret; } @@ -406,6 +416,7 @@ int hyper_dmabuf_xen_init_rx_rbuf(int domid) void hyper_dmabuf_xen_cleanup_rx_rbuf(int domid) { struct xen_comm_rx_ring_info *ring_info; + struct xen_comm_tx_ring_info *tx_ring_info; struct page *shared_ring; /* check if we have importer ring created for given sdomain */ @@ -425,6 +436,13 @@ void hyper_dmabuf_xen_cleanup_rx_rbuf(int domid) gnttab_free_pages(1, _ring); kfree(ring_info); + + tx_ring_info = xen_comm_find_tx_ring(domid); + if (!tx_ring_info) + return; + + SHARED_RING_INIT(tx_ring_info->ring_front.sring); + FRONT_RING_INIT(&(tx_ring_info->ring_front), tx_ring_info->ring_front.sring, PAGE_SIZE); } int hyper_dmabuf_xen_init_comm_env(void) -- 2.7.4 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [RFC PATCH 14/60] hyper_dmabuf: clean-up process based on file->f_count
Now relaese funcs checks f_count for the file instead of our own refcount because it can't track dma_buf_get. Also, importer now sends out HYPER_DMABUF_FIRST_EXPORT to let the exporter know corresponding dma-buf has ever exported on importer's side. This is to cover the case where exporter exports a buffer and unexport it right away before importer does first export_fd (there won't be any dma_buf_release nofication to exporter since SGT was never created by importer.) After importer creates its own SGT, only condition it is completely released is that dma_buf is unexported (so valid == 0) and user app closes all locally assigned FDs (when dma_buf_release is called.) Otherwise, it needs to stay there since previously exported FD can be reused. Also includes minor changes; 1. flag had been changed to "bool valid" for conciseness. 2. added bool importer_exported in sgt_info as an indicator for usage of buffer on the importer. 3. num of pages is added (nents) to hyper_dmabuf_sgt_info to keep the size info in EXPORT list. 3. more minor changes and clean-ups. Signed-off-by: Dongwon KimSigned-off-by: Mateusz Polrola --- drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c| 1 + drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h| 1 + drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c| 76 - drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.h| 5 +- drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c | 78 -- drivers/xen/hyper_dmabuf/hyper_dmabuf_list.c | 2 +- drivers/xen/hyper_dmabuf/hyper_dmabuf_list.h | 2 +- drivers/xen/hyper_dmabuf/hyper_dmabuf_msg.c| 34 -- drivers/xen/hyper_dmabuf/hyper_dmabuf_msg.h| 2 + .../xen/hyper_dmabuf/hyper_dmabuf_remote_sync.c| 10 ++- drivers/xen/hyper_dmabuf/hyper_dmabuf_struct.h | 19 +++--- .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c | 6 +- 12 files changed, 143 insertions(+), 93 deletions(-) diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c index 5b5dae44..5a7cfa5 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c @@ -33,6 +33,7 @@ static int hyper_dmabuf_drv_init(void) /* device structure initialization */ /* currently only does work-queue initialization */ hyper_dmabuf_private.work_queue = create_workqueue("hyper_dmabuf_wqueue"); + hyper_dmabuf_private.domid = hyper_dmabuf_get_domid(); ret = hyper_dmabuf_table_init(); if (ret < 0) { diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h index 8778a19..ff883e1 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h @@ -3,6 +3,7 @@ struct hyper_dmabuf_private { struct device *device; + int domid; struct workqueue_struct *work_queue; }; diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c index f258981..fa445e5 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c @@ -13,6 +13,14 @@ #define REFS_PER_PAGE (PAGE_SIZE/sizeof(grant_ref_t)) +int dmabuf_refcount(struct dma_buf *dma_buf) +{ + if ((dma_buf != NULL) && (dma_buf->file != NULL)) + return file_count(dma_buf->file); + + return -1; +} + /* return total number of pages referecned by a sgt * for pre-calculation of # of pages behind a given sgt */ @@ -368,8 +376,8 @@ int hyper_dmabuf_cleanup_gref_table(struct hyper_dmabuf_sgt_info *sgt_info) { struct hyper_dmabuf_shared_pages_info *shared_pages_info = _info->shared_pages_info; grant_ref_t *ref = shared_pages_info->top_level_page; - int n_2nd_level_pages = (sgt_info->active_sgts->sgt->nents/REFS_PER_PAGE + - ((sgt_info->active_sgts->sgt->nents % REFS_PER_PAGE) ? 1: 0)); + int n_2nd_level_pages = (sgt_info->nents/REFS_PER_PAGE + + ((sgt_info->nents % REFS_PER_PAGE) ? 1: 0)); if (shared_pages_info->data_refs == NULL || @@ -388,26 +396,28 @@ int hyper_dmabuf_cleanup_gref_table(struct hyper_dmabuf_sgt_info *sgt_info) { if (!gnttab_end_foreign_access_ref(ref[i], 1)) { printk("refid still in use!!!\n"); } + gnttab_free_grant_reference(ref[i]); i++; } free_pages((unsigned long)shared_pages_info->addr_pages, i); + /* End foreign access for top level addressing page */ if (gnttab_query_foreign_access(shared_pages_info->top_level_ref)) { printk("refid not shared !!\n"); } - if (!gnttab_end_foreign_access_ref(shared_pages_info->top_level_ref, 1)) { - printk("refid still in use!!!\n"); -
[Xen-devel] [RFC PATCH 40/60] hyper_dmabuf: do not use 'private' as field name
From: Mateusz PolrolaUsing a word, 'private' is not recommended because of conflict with language keyword when compiling with C++. So changing those to 'priv'. Signed-off-by: Dongwon Kim --- drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c | 8 include/uapi/xen/hyper_dmabuf.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c index 2ff2c145..9d05d66 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c @@ -257,10 +257,10 @@ static int hyper_dmabuf_export_remote_ioctl(struct file *filp, void *data) } /* driver/application specific private info, max 4x4 bytes */ - operands[8] = export_remote_attr->private[0]; - operands[9] = export_remote_attr->private[1]; - operands[10] = export_remote_attr->private[2]; - operands[11] = export_remote_attr->private[3]; + operands[8] = export_remote_attr->priv[0]; + operands[9] = export_remote_attr->priv[1]; + operands[10] = export_remote_attr->priv[2]; + operands[11] = export_remote_attr->priv[3]; req = kcalloc(1, sizeof(*req), GFP_KERNEL); diff --git a/include/uapi/xen/hyper_dmabuf.h b/include/uapi/xen/hyper_dmabuf.h index bee0f86..a2d22d0 100644 --- a/include/uapi/xen/hyper_dmabuf.h +++ b/include/uapi/xen/hyper_dmabuf.h @@ -56,7 +56,7 @@ struct ioctl_hyper_dmabuf_export_remote { int remote_domain; /* exported dma buf id */ hyper_dmabuf_id_t hid; - int private[4]; + int priv[4]; }; #define IOCTL_HYPER_DMABUF_EXPORT_FD \ -- 2.7.4 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [RFC PATCH 28/60] hyper_dmabuf: address several synchronization issues
From: Mateusz PolrolaThis patch addresses several synchronization issues while sharing DMA_BUF with another VM. 1. Set WAIT_AFTER_SYNC_REQ to false by default to prevent possible performance degradation when waing for the response for every syncrhonization request to exporter VM. 2. Removed HYPER_DMABUF_OPS_RELEASE_FINAL message - now exporter can automatically detect when there are no more consumers of DMA_BUF so importer VM doesn't have to send out this message. 3. Renamed HYPER_DMABUF_FIRST_EXPORT into HYPER_DMABUF_EXPORT_FD 4. Introduced HYPER_DMABUF_EXPORT_FD_FAILED message to undo HYPER_DMABUF_FIRST_EXPORT in case of any failure while executing hyper_dmabuf_export_fd_ioctl 5. Waiting until other VM processes all pending requests when ring buffers are all full. 6. Create hyper_dmabuf.h with definitions of driver interface under include/uapi/xen/ Signed-off-by: Dongwon Kim --- drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c| 21 ++--- drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c | 17 +++- drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.h | 74 + drivers/xen/hyper_dmabuf/hyper_dmabuf_msg.c| 30 +-- drivers/xen/hyper_dmabuf/hyper_dmabuf_msg.h| 4 +- .../xen/hyper_dmabuf/hyper_dmabuf_remote_sync.c| 24 -- .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c | 5 +- include/uapi/xen/hyper_dmabuf.h| 96 ++ 8 files changed, 163 insertions(+), 108 deletions(-) create mode 100644 include/uapi/xen/hyper_dmabuf.h diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c index a0b3946..5a034ffb 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c @@ -187,10 +187,7 @@ int hyper_dmabuf_cleanup_sgt_info(struct hyper_dmabuf_sgt_info *sgt_info, int fo * side. */ if (!force && - (!list_empty(_info->va_kmapped->list) || - !list_empty(_info->va_vmapped->list) || - !list_empty(_info->active_sgts->list) || - !list_empty(_info->active_attached->list))) { + sgt_info->importer_exported) { dev_warn(hyper_dmabuf_private.device, "dma-buf is used by importer\n"); return -EPERM; } @@ -259,7 +256,7 @@ int hyper_dmabuf_cleanup_sgt_info(struct hyper_dmabuf_sgt_info *sgt_info, int fo return 0; } -#define WAIT_AFTER_SYNC_REQ 1 +#define WAIT_AFTER_SYNC_REQ 0 inline int hyper_dmabuf_sync_request(int id, int dmabuf_ops) { @@ -431,17 +428,11 @@ static void hyper_dmabuf_ops_release(struct dma_buf *dma_buf) final_release = sgt_info && !sgt_info->valid && !sgt_info->num_importers; - if (final_release) { - ret = hyper_dmabuf_sync_request(sgt_info->hyper_dmabuf_id, - HYPER_DMABUF_OPS_RELEASE_FINAL); - } else { - ret = hyper_dmabuf_sync_request(sgt_info->hyper_dmabuf_id, - HYPER_DMABUF_OPS_RELEASE); - } - + ret = hyper_dmabuf_sync_request(sgt_info->hyper_dmabuf_id, + HYPER_DMABUF_OPS_RELEASE); if (ret < 0) { - dev_err(hyper_dmabuf_private.device, - "hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); + dev_warn(hyper_dmabuf_private.device, +"hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); } /* diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c index 19ca725..58b115a 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c @@ -35,6 +35,7 @@ #include #include #include +#include #include "hyper_dmabuf_struct.h" #include "hyper_dmabuf_ioctl.h" #include "hyper_dmabuf_list.h" @@ -282,12 +283,17 @@ static int hyper_dmabuf_export_fd_ioctl(void *data) /* send notification for export_fd to exporter */ operand = sgt_info->hyper_dmabuf_id; + dev_dbg(hyper_dmabuf_private.device, "Exporting fd of buffer %d\n", operand); + req = kcalloc(1, sizeof(*req), GFP_KERNEL); - hyper_dmabuf_create_request(req, HYPER_DMABUF_FIRST_EXPORT, ); + hyper_dmabuf_create_request(req, HYPER_DMABUF_EXPORT_FD, ); ret = ops->send_req(HYPER_DMABUF_DOM_ID(operand), req, true); if (ret < 0) { + /* in case of timeout other end eventually will receive request, so we need to undo it */ + hyper_dmabuf_create_request(req, HYPER_DMABUF_EXPORT_FD_FAILED, ); + ops->send_req(HYPER_DMABUF_DOM_ID(operand), req, false); kfree(req); dev_err(hyper_dmabuf_private.device, "Failed
[Xen-devel] [RFC PATCH 20/60] hyper_dmabuf: optimized loop with less condition check
Redefined nents_last, which means # of gref in the last page of lvl2 table in any situation even if it is same as REFS_PER_PAGE. With this, loop can be simplified with less condition check. Signed-off-by: Dongwon Kim--- drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_shm.c | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_shm.c b/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_shm.c index cc9860b..cb5b86f 100644 --- a/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_shm.c +++ b/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_shm.c @@ -184,8 +184,10 @@ struct page ** hyper_dmabuf_xen_map_shared_pages(int lvl3_gref, int domid, int n struct gnttab_map_grant_ref *data_map_ops; struct gnttab_unmap_grant_ref *data_unmap_ops; - int nents_last = nents % REFS_PER_PAGE; - int n_lvl2_grefs = (nents / REFS_PER_PAGE) + ((nents_last > 0) ? 1 : 0); + /* # of grefs in the last page of lvl2 table */ + int nents_last = (nents - 1) % REFS_PER_PAGE + 1; + int n_lvl2_grefs = (nents / REFS_PER_PAGE) + ((nents_last > 0) ? 1 : 0) - + (nents_last == REFS_PER_PAGE); int i, j, k; dev_dbg(hyper_dmabuf_private.device, "%s entry\n", __func__); @@ -270,7 +272,7 @@ struct page ** hyper_dmabuf_xen_map_shared_pages(int lvl3_gref, int domid, int n k = 0; - for (i = 0; i < (nents_last ? n_lvl2_grefs - 1 : n_lvl2_grefs); i++) { + for (i = 0; i < n_lvl2_grefs - 1; i++) { lvl2_table = pfn_to_kaddr(page_to_pfn(lvl2_table_pages[i])); for (j = 0; j < REFS_PER_PAGE; j++) { gnttab_set_map_op(_map_ops[k], -- 2.7.4 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [RFC PATCH 25/60] hyper_dmabuf: introduced delayed unexport
From: Mateusz PolrolaTo prevent overhead when a DMA BUF needs to be exported right after it is unexported, a marginal delay is introduced in unexporting process. This adds a probation period to the unexporting process. If the same DMA_BUF is requested to be exported agagin, unexporting process is canceled right away and the buffer can be reused without any extensive re-exporting process. Additionally, "FIRST EXPORT" message is synchronously transmitted to the exporter VM (importer VM waits for the response.) to make sure the buffer is still valid (not unexported) on expoter VM's side before importer VM starts to use it. "delayed_ms" attribute is added to unexport ioctl, used for hardcoding delay from userspace. Signed-off-by: Dongwon Kim --- drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c| 4 + drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c | 157 ++--- drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.h | 2 + drivers/xen/hyper_dmabuf/hyper_dmabuf_msg.c| 41 +++--- drivers/xen/hyper_dmabuf/hyper_dmabuf_struct.h | 2 + .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c | 2 + 6 files changed, 139 insertions(+), 69 deletions(-) diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c index d7a35fc..a9bc354 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c @@ -341,6 +341,10 @@ static struct sg_table* hyper_dmabuf_ops_map(struct dma_buf_attachment *attachme /* extract pages from sgt */ page_info = hyper_dmabuf_ext_pgs(sgt_info->sgt); + if (!page_info) { + return NULL; + } + /* create a new sg_table with extracted pages */ st = hyper_dmabuf_create_sgt(page_info->pages, page_info->frst_ofst, page_info->last_len, page_info->nents); diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c index b0f5b5b..018de8c 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c @@ -115,11 +115,24 @@ static int hyper_dmabuf_export_remote(void *data) ret = hyper_dmabuf_find_id_exported(dma_buf, export_remote_attr->remote_domain); sgt_info = hyper_dmabuf_find_exported(ret); if (ret != -1 && sgt_info->valid) { + /* +* Check if unexport is already scheduled for that buffer, +* if so try to cancel it. If that will fail, buffer needs +* to be reexport once again. +*/ + if (sgt_info->unexport_scheduled) { + if (!cancel_delayed_work_sync(_info->unexport_work)) { + dma_buf_put(dma_buf); + goto reexport; + } + sgt_info->unexport_scheduled = 0; + } dma_buf_put(dma_buf); export_remote_attr->hyper_dmabuf_id = ret; return 0; } +reexport: attachment = dma_buf_attach(dma_buf, hyper_dmabuf_private.device); if (!attachment) { dev_err(hyper_dmabuf_private.device, "Cannot get attachment\n"); @@ -133,7 +146,7 @@ static int hyper_dmabuf_export_remote(void *data) sgt = dma_buf_map_attachment(attachment, DMA_BIDIRECTIONAL); - sgt_info = kmalloc(sizeof(*sgt_info), GFP_KERNEL); + sgt_info = kcalloc(1, sizeof(*sgt_info), GFP_KERNEL); sgt_info->hyper_dmabuf_id = hyper_dmabuf_get_id(); @@ -141,7 +154,6 @@ static int hyper_dmabuf_export_remote(void *data) sgt_info->hyper_dmabuf_rdomain = export_remote_attr->remote_domain; sgt_info->dma_buf = dma_buf; sgt_info->valid = 1; - sgt_info->importer_exported = 0; sgt_info->active_sgts = kmalloc(sizeof(struct sgt_list), GFP_KERNEL); sgt_info->active_attached = kmalloc(sizeof(struct attachment_list), GFP_KERNEL); @@ -245,8 +257,35 @@ static int hyper_dmabuf_export_fd_ioctl(void *data) /* look for dmabuf for the id */ sgt_info = hyper_dmabuf_find_imported(export_fd_attr->hyper_dmabuf_id); - if (sgt_info == NULL) /* can't find sgt from the table */ + if (sgt_info == NULL || !sgt_info->valid) /* can't find sgt from the table */ + return -1; + + sgt_info->num_importers++; + + /* send notification for export_fd to exporter */ + operand = sgt_info->hyper_dmabuf_id; + + req = kcalloc(1, sizeof(*req), GFP_KERNEL); + hyper_dmabuf_create_request(req, HYPER_DMABUF_FIRST_EXPORT, ); + + ret = ops->send_req(HYPER_DMABUF_DOM_ID(operand), req, true); + + if (ret < 0) { + kfree(req); + dev_err(hyper_dmabuf_private.device, "Failed to create sgt or notify exporter\n"); +
[Xen-devel] [RFC PATCH 27/60] hyper_dmabuf: use proper error codes
Cleaned up and corrected error codes and condition in various error check routines. Also added proper err messages when func returns error. Signed-off-by: Dongwon Kim--- drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c| 14 +++-- drivers/xen/hyper_dmabuf/hyper_dmabuf_id.c | 2 +- drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c| 8 +-- drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c | 66 ++ drivers/xen/hyper_dmabuf/hyper_dmabuf_list.c | 6 +- drivers/xen/hyper_dmabuf/hyper_dmabuf_msg.c| 5 +- .../xen/hyper_dmabuf/hyper_dmabuf_remote_sync.c| 38 ++--- .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c | 20 +++ .../hyper_dmabuf/xen/hyper_dmabuf_xen_comm_list.c | 4 +- .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_shm.c| 2 +- 10 files changed, 94 insertions(+), 71 deletions(-) diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c index 584d55d..44a9139 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c @@ -60,7 +60,7 @@ static int __init hyper_dmabuf_drv_init(void) ret = register_device(); if (ret < 0) { - return -EINVAL; + return ret; } #ifdef CONFIG_HYPER_DMABUF_XEN @@ -77,18 +77,24 @@ static int __init hyper_dmabuf_drv_init(void) ret = hyper_dmabuf_table_init(); if (ret < 0) { - return -EINVAL; + dev_err(hyper_dmabuf_private.device, + "failed to initialize table for exported/imported entries\n"); + return ret; } ret = hyper_dmabuf_private.backend_ops->init_comm_env(); if (ret < 0) { - return -EINVAL; + dev_err(hyper_dmabuf_private.device, + "failed to initiailize hypervisor-specific comm env\n"); + return ret; } #ifdef CONFIG_HYPER_DMABUF_SYSFS ret = hyper_dmabuf_register_sysfs(hyper_dmabuf_private.device); if (ret < 0) { - return -EINVAL; + dev_err(hyper_dmabuf_private.device, + "failed to initialize sysfs\n"); + return ret; } #endif diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_id.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_id.c index 9b4ff45..35bfdfb 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_id.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_id.c @@ -62,7 +62,7 @@ static int retrieve_reusable_id(void) return id; } - return -1; + return -ENOENT; } void destroy_reusable_list(void) diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c index a9bc354..a0b3946 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c @@ -84,11 +84,11 @@ struct hyper_dmabuf_pages_info *hyper_dmabuf_ext_pgs(struct sg_table *sgt) struct scatterlist *sgl; pinfo = kmalloc(sizeof(*pinfo), GFP_KERNEL); - if (pinfo == NULL) + if (!pinfo) return NULL; pinfo->pages = kmalloc(sizeof(struct page *)*hyper_dmabuf_get_num_pgs(sgt), GFP_KERNEL); - if (pinfo->pages == NULL) + if (!pinfo->pages) return NULL; sgl = sgt->sgl; @@ -138,7 +138,7 @@ struct sg_table* hyper_dmabuf_create_sgt(struct page **pages, int i, ret; sgt = kmalloc(sizeof(struct sg_table), GFP_KERNEL); - if (sgt == NULL) { + if (!sgt) { return NULL; } @@ -348,7 +348,7 @@ static struct sg_table* hyper_dmabuf_ops_map(struct dma_buf_attachment *attachme /* create a new sg_table with extracted pages */ st = hyper_dmabuf_create_sgt(page_info->pages, page_info->frst_ofst, page_info->last_len, page_info->nents); - if (st == NULL) + if (!st) goto err_free_sg; if (!dma_map_sg(attachment->dev, st->sgl, st->nents, dir)) { diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c index 8851a9c..19ca725 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c @@ -54,7 +54,7 @@ static int hyper_dmabuf_tx_ch_setup(void *data) if (!data) { dev_err(hyper_dmabuf_private.device, "user data is NULL\n"); - return -1; + return -EINVAL; } tx_ch_attr = (struct ioctl_hyper_dmabuf_tx_ch_setup *)data; @@ -71,7 +71,7 @@ static int hyper_dmabuf_rx_ch_setup(void *data) if (!data) { dev_err(hyper_dmabuf_private.device, "user data is NULL\n"); - return -1; + return -EINVAL; } rx_ch_attr = (struct ioctl_hyper_dmabuf_rx_ch_setup *)data; @@ -96,16
[Xen-devel] [RFC PATCH 09/60] hyper_dmabuf: indirect DMA_BUF synchronization via shadowing
Importer now sends a synchronization request to the exporter when any of DMA_BUF operations on imported Hyper_DMABUF is executed (e.g dma_buf_map and dma_buf_unmap). This results in a creation of shadow DMA_BUF and exactly same DMA_BUF operation to be executed on it. The main purpose of this is to get DMA_BUF synchronized eventually between the original creator of DMA_BUF and the end consumer of it running on the importer VM. Signed-off-by: Dongwon Kim--- drivers/xen/hyper_dmabuf/Makefile | 1 + drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c| 90 ++ drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c | 52 -- drivers/xen/hyper_dmabuf/hyper_dmabuf_list.c | 8 +- drivers/xen/hyper_dmabuf/hyper_dmabuf_msg.c| 43 +++-- .../xen/hyper_dmabuf/hyper_dmabuf_remote_sync.c| 189 + .../xen/hyper_dmabuf/hyper_dmabuf_remote_sync.h| 6 + drivers/xen/hyper_dmabuf/hyper_dmabuf_struct.h | 32 +++- .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c | 52 +- .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.h | 2 +- 10 files changed, 397 insertions(+), 78 deletions(-) create mode 100644 drivers/xen/hyper_dmabuf/hyper_dmabuf_remote_sync.c create mode 100644 drivers/xen/hyper_dmabuf/hyper_dmabuf_remote_sync.h diff --git a/drivers/xen/hyper_dmabuf/Makefile b/drivers/xen/hyper_dmabuf/Makefile index 0be7445..3459382 100644 --- a/drivers/xen/hyper_dmabuf/Makefile +++ b/drivers/xen/hyper_dmabuf/Makefile @@ -7,6 +7,7 @@ ifneq ($(KERNELRELEASE),) hyper_dmabuf_list.o \ hyper_dmabuf_imp.o \ hyper_dmabuf_msg.o \ +hyper_dmabuf_remote_sync.o \ xen/hyper_dmabuf_xen_comm.o \ xen/hyper_dmabuf_xen_comm_list.o diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c index 6b16e37..2c78bc1 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c @@ -169,7 +169,8 @@ grant_ref_t hyper_dmabuf_create_addressing_tables(grant_ref_t *data_refs, int ne /* * Calculate number of pages needed for 2nd level addresing: */ - int n_2nd_level_pages = (nents/REFS_PER_PAGE + ((nents % REFS_PER_PAGE) ? 1: 0));/* rounding */ + int n_2nd_level_pages = (nents/REFS_PER_PAGE + + ((nents % REFS_PER_PAGE) ? 1: 0)); int i; unsigned long gref_page_start; grant_ref_t *tmp_page; @@ -187,7 +188,9 @@ grant_ref_t hyper_dmabuf_create_addressing_tables(grant_ref_t *data_refs, int ne /* Share 2nd level addressing pages in readonly mode*/ for (i=0; i< n_2nd_level_pages; i++) { - addr_refs[i] = gnttab_grant_foreign_access(rdomain, virt_to_mfn((unsigned long)tmp_page+i*PAGE_SIZE ), 1); + addr_refs[i] = gnttab_grant_foreign_access(rdomain, + virt_to_mfn((unsigned long)tmp_page+i*PAGE_SIZE ), + 1); } /* @@ -213,7 +216,9 @@ grant_ref_t hyper_dmabuf_create_addressing_tables(grant_ref_t *data_refs, int ne } /* Share top level addressing page in readonly mode*/ - top_level_ref = gnttab_grant_foreign_access(rdomain, virt_to_mfn((unsigned long)tmp_page), 1); + top_level_ref = gnttab_grant_foreign_access(rdomain, + virt_to_mfn((unsigned long)tmp_page), + 1); kfree(addr_refs); @@ -255,7 +260,9 @@ struct page** hyper_dmabuf_get_data_refs(grant_ref_t top_level_ref, int domid, i } addr = (unsigned long)pfn_to_kaddr(page_to_pfn(top_level_page)); - gnttab_set_map_op(_level_map_ops, addr, GNTMAP_host_map | GNTMAP_readonly, top_level_ref, domid); + gnttab_set_map_op(_level_map_ops, addr, GNTMAP_host_map | GNTMAP_readonly, + top_level_ref, domid); + gnttab_set_unmap_op(_level_unmap_ops, addr, GNTMAP_host_map | GNTMAP_readonly, -1); if (gnttab_map_refs(_level_map_ops, NULL, _level_page, 1)) { @@ -282,7 +289,8 @@ struct page** hyper_dmabuf_get_data_refs(grant_ref_t top_level_ref, int domid, i for (i = 0; i < n_level2_refs; i++) { addr = (unsigned long)pfn_to_kaddr(page_to_pfn(level2_pages[i])); - gnttab_set_map_op(_ops[i], addr, GNTMAP_host_map | GNTMAP_readonly, top_level_refs[i], domid); + gnttab_set_map_op(_ops[i], addr, GNTMAP_host_map | GNTMAP_readonly, + top_level_refs[i], domid); gnttab_set_unmap_op(_ops[i], addr, GNTMAP_host_map | GNTMAP_readonly, -1); } @@ -295,7 +303,7 @@
[Xen-devel] [RFC PATCH 33/60] hyper_dmabuf: error checking on the result of dma_buf_map_attachment
From: Mateusz PolrolaAdded error checking on the result of function call, dma_buf_map_attachment Signed-off-by: Dongwon Kim --- drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c index c0048d9..476c0d7 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c @@ -149,6 +149,11 @@ static int hyper_dmabuf_export_remote(struct file *filp, void *data) sgt = dma_buf_map_attachment(attachment, DMA_BIDIRECTIONAL); + if (IS_ERR(sgt)) { + dev_err(hyper_dmabuf_private.device, "Cannot map attachment\n"); + return PTR_ERR(sgt); + } + sgt_info = kcalloc(1, sizeof(*sgt_info), GFP_KERNEL); if(!sgt_info) { -- 2.7.4 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [RFC PATCH 22/60] hyper_dmabuf: configure license
Set the license of the driver to "GPL and MIT-X dual" and owner to "Intel". Also attached license term to all source and header files Signed-off-by: Dongwon Kim--- drivers/xen/hyper_dmabuf/hyper_dmabuf_conf.h | 26 ++ drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c| 32 -- drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h| 24 drivers/xen/hyper_dmabuf/hyper_dmabuf_id.c | 28 +++ drivers/xen/hyper_dmabuf/hyper_dmabuf_id.h | 24 drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c| 28 +++ drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.h| 24 drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c | 28 +++ drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.h | 24 drivers/xen/hyper_dmabuf/hyper_dmabuf_list.c | 28 +++ drivers/xen/hyper_dmabuf/hyper_dmabuf_list.h | 24 drivers/xen/hyper_dmabuf/hyper_dmabuf_msg.c| 28 +++ drivers/xen/hyper_dmabuf/hyper_dmabuf_msg.h| 24 drivers/xen/hyper_dmabuf/hyper_dmabuf_query.h | 24 .../xen/hyper_dmabuf/hyper_dmabuf_remote_sync.c| 28 +++ .../xen/hyper_dmabuf/hyper_dmabuf_remote_sync.h| 24 drivers/xen/hyper_dmabuf/hyper_dmabuf_struct.h | 24 .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c | 28 +++ .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.h | 24 .../hyper_dmabuf/xen/hyper_dmabuf_xen_comm_list.c | 28 +++ .../hyper_dmabuf/xen/hyper_dmabuf_xen_comm_list.h | 24 .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_drv.c| 28 +++ .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_drv.h| 24 .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_shm.c| 28 +++ .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_shm.h| 24 25 files changed, 648 insertions(+), 2 deletions(-) diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_conf.h b/drivers/xen/hyper_dmabuf/hyper_dmabuf_conf.h index d012b05..ee1886c 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_conf.h +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_conf.h @@ -1 +1,27 @@ +/* + * Copyright © 2017 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + */ + +/* configuration */ + #define CURRENT_TARGET XEN diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c index 3fc30e6..4e0ccdd 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c @@ -1,3 +1,31 @@ +/* + * Copyright © 2017 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
[Xen-devel] [RFC PATCH 31/60] hyper_dmabuf: built-in compilation option
From: Mateusz PolrolaEnabled built-in compilation option of hyper_dmabuf driver. Also, moved backend initialization into open() to remove its dependencies on Kernel booting sequence. hyper_dmabuf.h is now installed as one of standard header files of Kernel. This patch also addresses possible memory leaks in various places. Signed-off-by: Dongwon Kim --- drivers/xen/hyper_dmabuf/Kconfig | 1 + drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c| 17 ++-- drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h| 1 + drivers/xen/hyper_dmabuf/hyper_dmabuf_id.c | 14 +++ drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c| 13 ++- drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c | 113 + drivers/xen/hyper_dmabuf/hyper_dmabuf_list.c | 15 +++ drivers/xen/hyper_dmabuf/hyper_dmabuf_msg.c| 20 .../xen/hyper_dmabuf/hyper_dmabuf_remote_sync.c| 32 +- .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c | 6 ++ .../hyper_dmabuf/xen/hyper_dmabuf_xen_comm_list.c | 15 +++ .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_shm.c| 6 ++ include/uapi/xen/Kbuild| 6 ++ 13 files changed, 227 insertions(+), 32 deletions(-) create mode 100644 include/uapi/xen/Kbuild diff --git a/drivers/xen/hyper_dmabuf/Kconfig b/drivers/xen/hyper_dmabuf/Kconfig index 56633a2..185fdf8 100644 --- a/drivers/xen/hyper_dmabuf/Kconfig +++ b/drivers/xen/hyper_dmabuf/Kconfig @@ -14,6 +14,7 @@ config HYPER_DMABUF_XEN config HYPER_DMABUF_SYSFS bool "Enable sysfs information about hyper DMA buffers" default y + depends on HYPER_DMABUF help Expose information about imported and exported buffers using hyper_dmabuf driver diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c index a12d4dc..92d710e 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c @@ -66,6 +66,15 @@ static int __init hyper_dmabuf_drv_init(void) #ifdef CONFIG_HYPER_DMABUF_XEN hyper_dmabuf_private.backend_ops = _backend_ops; #endif + /* +* Defer backend setup to first open call. +* Due to fact that some hypervisors eg. Xen, may have dependencies +* to userspace daemons like xenstored, in that case all xenstore +* calls done from kernel will block until that deamon will be +* started, in case where module is built in that will block entire +* kernel initialization. +*/ + hyper_dmabuf_private.backend_initialized = false; dev_info(hyper_dmabuf_private.device, "initializing database for imported/exported dmabufs\n"); @@ -73,7 +82,6 @@ static int __init hyper_dmabuf_drv_init(void) /* device structure initialization */ /* currently only does work-queue initialization */ hyper_dmabuf_private.work_queue = create_workqueue("hyper_dmabuf_wqueue"); - hyper_dmabuf_private.domid = hyper_dmabuf_private.backend_ops->get_vm_id(); ret = hyper_dmabuf_table_init(); if (ret < 0) { @@ -82,13 +90,6 @@ static int __init hyper_dmabuf_drv_init(void) return ret; } - ret = hyper_dmabuf_private.backend_ops->init_comm_env(); - if (ret < 0) { - dev_err(hyper_dmabuf_private.device, - "failed to initiailize hypervisor-specific comm env\n"); - return ret; - } - #ifdef CONFIG_HYPER_DMABUF_SYSFS ret = hyper_dmabuf_register_sysfs(hyper_dmabuf_private.device); if (ret < 0) { diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h index 8445416..91fda04 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h @@ -77,6 +77,7 @@ struct hyper_dmabuf_private { /* backend ops - hypervisor specific */ struct hyper_dmabuf_backend_ops *backend_ops; struct mutex lock; + bool backend_initialized; }; #endif /* __LINUX_PUBLIC_HYPER_DMABUF_DRV_H__ */ diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_id.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_id.c index 35bfdfb..fe95091 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_id.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_id.c @@ -40,6 +40,13 @@ void store_reusable_id(int id) struct list_reusable_id *new_reusable; new_reusable = kmalloc(sizeof(*new_reusable), GFP_KERNEL); + + if (!new_reusable) { + dev_err(hyper_dmabuf_private.device, + "No memory left to be allocated\n"); + return; + } + new_reusable->id = id; list_add(_reusable->list, _head->list); @@ -94,6 +101,13 @@ int hyper_dmabuf_get_id(void) /* first cla to hyper_dmabuf_get_id */ if (id == 0) {
[Xen-devel] [RFC PATCH 29/60] hyper_dmabuf: make sure to release allocated buffers when exiting
From: Mateusz PolrolaIt is required to release all allocated buffers when the application crashes. With the change, hyper_dmabuf_sgt_info includes file pointers for the driver. If it's released unexpectedly, the driver is now unexporting all already-exported buffers to prevent memory leak. In case there are multiple applications exporting same buffer to another VM, unexporting is not started when one of those crashes. Actual unexporting is invoked only if the last application that exported the buffer is crashed or finished via "emergency-unexport" routine, that is executed automatically when all of file pointers opened for accessing hyper_dmabuf driver are closed. Signed-off-by: Dongwon Kim --- drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c| 6 ++- drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c | 73 ++ drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.h | 2 +- drivers/xen/hyper_dmabuf/hyper_dmabuf_list.c | 14 + drivers/xen/hyper_dmabuf/hyper_dmabuf_list.h | 4 ++ drivers/xen/hyper_dmabuf/hyper_dmabuf_struct.h | 7 +++ 6 files changed, 81 insertions(+), 25 deletions(-) diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c index 44a9139..a12d4dc 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c @@ -54,7 +54,7 @@ static int __init hyper_dmabuf_drv_init(void) { int ret = 0; - printk( KERN_NOTICE "hyper_dmabuf_starting: Initialization started" ); + printk( KERN_NOTICE "hyper_dmabuf_starting: Initialization started\n"); mutex_init(_dmabuf_private.lock); @@ -122,7 +122,9 @@ static void hyper_dmabuf_drv_exit(void) if (hyper_dmabuf_private.id_queue) destroy_reusable_list(); - printk( KERN_NOTICE "dma_buf-src_sink model: Exiting" ); + dev_info(hyper_dmabuf_private.device, +"hyper_dmabuf driver: Exiting\n"); + unregister_device(); } /*===*/ diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c index 58b115a..fa700f2 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c @@ -47,7 +47,7 @@ extern struct hyper_dmabuf_private hyper_dmabuf_private; -static int hyper_dmabuf_tx_ch_setup(void *data) +static int hyper_dmabuf_tx_ch_setup(struct file *filp, void *data) { struct ioctl_hyper_dmabuf_tx_ch_setup *tx_ch_attr; struct hyper_dmabuf_backend_ops *ops = hyper_dmabuf_private.backend_ops; @@ -64,7 +64,7 @@ static int hyper_dmabuf_tx_ch_setup(void *data) return ret; } -static int hyper_dmabuf_rx_ch_setup(void *data) +static int hyper_dmabuf_rx_ch_setup(struct file *filp, void *data) { struct ioctl_hyper_dmabuf_rx_ch_setup *rx_ch_attr; struct hyper_dmabuf_backend_ops *ops = hyper_dmabuf_private.backend_ops; @@ -82,7 +82,7 @@ static int hyper_dmabuf_rx_ch_setup(void *data) return ret; } -static int hyper_dmabuf_export_remote(void *data) +static int hyper_dmabuf_export_remote(struct file *filp, void *data) { struct ioctl_hyper_dmabuf_export_remote *export_remote_attr; struct hyper_dmabuf_backend_ops *ops = hyper_dmabuf_private.backend_ops; @@ -227,6 +227,8 @@ static int hyper_dmabuf_export_remote(void *data) kfree(page_info->pages); kfree(page_info); + sgt_info->filp = filp; + return ret; fail_send_request: @@ -248,7 +250,7 @@ static int hyper_dmabuf_export_remote(void *data) return ret; } -static int hyper_dmabuf_export_fd_ioctl(void *data) +static int hyper_dmabuf_export_fd_ioctl(struct file *filp, void *data) { struct ioctl_hyper_dmabuf_export_fd *export_fd_attr; struct hyper_dmabuf_backend_ops *ops = hyper_dmabuf_private.backend_ops; @@ -411,7 +413,7 @@ static void hyper_dmabuf_delayed_unexport(struct work_struct *work) /* Schedules unexport of dmabuf. */ -static int hyper_dmabuf_unexport(void *data) +static int hyper_dmabuf_unexport(struct file *filp, void *data) { struct ioctl_hyper_dmabuf_unexport *unexport_attr; struct hyper_dmabuf_sgt_info *sgt_info; @@ -448,7 +450,7 @@ static int hyper_dmabuf_unexport(void *data) return 0; } -static int hyper_dmabuf_query(void *data) +static int hyper_dmabuf_query(struct file *filp, void *data) { struct ioctl_hyper_dmabuf_query *query_attr; struct hyper_dmabuf_sgt_info *sgt_info; @@ -558,7 +560,7 @@ static long hyper_dmabuf_ioctl(struct file *filp, return -EFAULT; } - ret = func(kdata); + ret = func(filp, kdata); if (copy_to_user((void __user *)param, kdata, _IOC_SIZE(cmd)) != 0) { dev_err(hyper_dmabuf_private.device, "failed to copy to
[Xen-devel] [RFC PATCH 30/60] hyper_dmabuf: free already mapped pages when error happens
From: Mateusz PolrolaIt is needed to freeing already-mapped pages if it gets error before finishing mapping all pages. Signed-off-by: Dongwon Kim --- .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_shm.c| 43 +++--- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_shm.c b/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_shm.c index c03e5a0..524f75c 100644 --- a/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_shm.c +++ b/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_shm.c @@ -255,7 +255,7 @@ struct page ** hyper_dmabuf_xen_map_shared_pages(int lvl3_gref, int domid, int n if (lvl3_map_ops.status) { dev_err(hyper_dmabuf_private.device, "HYPERVISOR map grant ref failed status = %d", lvl3_map_ops.status); - return NULL; + goto error_cleanup_lvl3; } else { lvl3_unmap_ops.handle = lvl3_map_ops.handle; } @@ -263,7 +263,7 @@ struct page ** hyper_dmabuf_xen_map_shared_pages(int lvl3_gref, int domid, int n /* Map all second level pages */ if (gnttab_alloc_pages(n_lvl2_grefs, lvl2_table_pages)) { dev_err(hyper_dmabuf_private.device, "Cannot allocate pages\n"); - return NULL; + goto error_cleanup_lvl3; } for (i = 0; i < n_lvl2_grefs; i++) { @@ -277,6 +277,9 @@ struct page ** hyper_dmabuf_xen_map_shared_pages(int lvl3_gref, int domid, int n if (gnttab_unmap_refs(_unmap_ops, NULL, _table_page, 1)) { dev_err(hyper_dmabuf_private.device, "xen: cannot unmap top level page\n"); return NULL; + } else { + /* Mark that page was unmapped */ + lvl3_unmap_ops.handle = -1; } if (gnttab_map_refs(lvl2_map_ops, NULL, lvl2_table_pages, n_lvl2_grefs)) { @@ -290,7 +293,7 @@ struct page ** hyper_dmabuf_xen_map_shared_pages(int lvl3_gref, int domid, int n dev_err(hyper_dmabuf_private.device, "HYPERVISOR map grant ref failed status = %d", lvl2_map_ops[i].status); - return NULL; + goto error_cleanup_lvl2; } else { lvl2_unmap_ops[i].handle = lvl2_map_ops[i].handle; } @@ -298,7 +301,7 @@ struct page ** hyper_dmabuf_xen_map_shared_pages(int lvl3_gref, int domid, int n if (gnttab_alloc_pages(nents, data_pages)) { dev_err(hyper_dmabuf_private.device, "Cannot allocate pages\n"); - return NULL; + goto error_cleanup_lvl2; } k = 0; @@ -343,6 +346,11 @@ struct page ** hyper_dmabuf_xen_map_shared_pages(int lvl3_gref, int domid, int n n_lvl2_grefs)) { dev_err(hyper_dmabuf_private.device, "Cannot unmap 2nd level refs\n"); return NULL; + } else { + /* Mark that pages were unmapped */ + for (i = 0; i < n_lvl2_grefs; i++) { + lvl2_unmap_ops[i].handle = -1; + } } for (i = 0; i < nents; i++) { @@ -350,7 +358,7 @@ struct page ** hyper_dmabuf_xen_map_shared_pages(int lvl3_gref, int domid, int n dev_err(hyper_dmabuf_private.device, "HYPERVISOR map grant ref failed status = %d\n", data_map_ops[i].status); - return NULL; + goto error_cleanup_data; } else { data_unmap_ops[i].handle = data_map_ops[i].handle; } @@ -369,6 +377,31 @@ struct page ** hyper_dmabuf_xen_map_shared_pages(int lvl3_gref, int domid, int n dev_dbg(hyper_dmabuf_private.device, "%s exit\n", __func__); return data_pages; + +error_cleanup_data: + gnttab_unmap_refs(data_unmap_ops, NULL, data_pages, + nents); + + gnttab_free_pages(nents, data_pages); + +error_cleanup_lvl2: + if (lvl2_unmap_ops[0].handle != -1) + gnttab_unmap_refs(lvl2_unmap_ops, NULL, lvl2_table_pages, + n_lvl2_grefs); + gnttab_free_pages(n_lvl2_grefs, lvl2_table_pages); + +error_cleanup_lvl3: + if (lvl3_unmap_ops.handle != -1) + gnttab_unmap_refs(_unmap_ops, NULL, _table_page, 1); + gnttab_free_pages(1, _table_page); + + kfree(lvl2_table_pages); + kfree(lvl2_map_ops); + kfree(lvl2_unmap_ops); + kfree(data_map_ops); + + + return NULL; } int hyper_dmabuf_xen_unmap_shared_pages(void **refs_info, int nents) { -- 2.7.4 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org
[Xen-devel] [RFC PATCH 03/60] hyper_dmabuf: re-use dma_buf previously exported if exist
Now we re-use dma_buf instead of exporting it via normal process (including new mappings). For this, hyper_dmabuf list entries can be searched with "struct dma_buf*". Also, ioctl (export_remote) is modified to just return hyper_dmabuf_id if the specific dmabuf has already been exported to the target domain. This patch also Includes changes in printk calles for debugging. Signed-off-by: Dongwon Kim--- drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c | 28 +-- drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c | 17 drivers/xen/hyper_dmabuf/hyper_dmabuf_list.c | 4 ++-- drivers/xen/hyper_dmabuf/hyper_dmabuf_list.h | 2 +- 4 files changed, 26 insertions(+), 25 deletions(-) diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c index faa5c1b..7cb5c35 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c @@ -532,7 +532,7 @@ static int hyper_dmabuf_ops_attach(struct dma_buf* dmabuf, struct device* dev, HYPER_DMABUF_OPS_ATTACH); if (ret < 0) { - printk("send dmabuf sync request failed\n"); + printk("hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); } return ret; @@ -552,7 +552,7 @@ static void hyper_dmabuf_ops_detach(struct dma_buf* dmabuf, struct dma_buf_attac HYPER_DMABUF_OPS_DETACH); if (ret < 0) { - printk("send dmabuf sync request failed\n"); + printk("hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); } } @@ -586,7 +586,7 @@ static struct sg_table* hyper_dmabuf_ops_map(struct dma_buf_attachment *attachme HYPER_DMABUF_OPS_MAP); if (ret < 0) { - printk("send dmabuf sync request failed\n"); + printk("hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); } return st; @@ -618,7 +618,7 @@ static void hyper_dmabuf_ops_unmap(struct dma_buf_attachment *attachment, HYPER_DMABUF_OPS_UNMAP); if (ret < 0) { - printk("send dmabuf sync request failed\n"); + printk("hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); } } @@ -636,7 +636,7 @@ static void hyper_dmabuf_ops_release(struct dma_buf *dmabuf) HYPER_DMABUF_OPS_RELEASE); if (ret < 0) { - printk("send dmabuf sync request failed\n"); + printk("hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); } } @@ -653,7 +653,7 @@ static int hyper_dmabuf_ops_begin_cpu_access(struct dma_buf *dmabuf, enum dma_da ret = hyper_dmabuf_sync_request_and_wait(HYPER_DMABUF_ID_IMPORTER_GET_SDOMAIN_ID(sgt_info->hyper_dmabuf_id), HYPER_DMABUF_OPS_BEGIN_CPU_ACCESS); if (ret < 0) { - printk("send dmabuf sync request failed\n"); + printk("hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); } return ret; @@ -672,7 +672,7 @@ static int hyper_dmabuf_ops_end_cpu_access(struct dma_buf *dmabuf, enum dma_data ret = hyper_dmabuf_sync_request_and_wait(HYPER_DMABUF_ID_IMPORTER_GET_SDOMAIN_ID(sgt_info->hyper_dmabuf_id), HYPER_DMABUF_OPS_END_CPU_ACCESS); if (ret < 0) { - printk("send dmabuf sync request failed\n"); + printk("hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); } return 0; @@ -691,7 +691,7 @@ static void *hyper_dmabuf_ops_kmap_atomic(struct dma_buf *dmabuf, unsigned long ret = hyper_dmabuf_sync_request_and_wait(HYPER_DMABUF_ID_IMPORTER_GET_SDOMAIN_ID(sgt_info->hyper_dmabuf_id), HYPER_DMABUF_OPS_KMAP_ATOMIC); if (ret < 0) { - printk("send dmabuf sync request failed\n"); + printk("hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); } return NULL; /* for now NULL.. need to return the address of mapped region */ @@ -710,7 +710,7 @@ static void hyper_dmabuf_ops_kunmap_atomic(struct dma_buf *dmabuf, unsigned long ret = hyper_dmabuf_sync_request_and_wait(HYPER_DMABUF_ID_IMPORTER_GET_SDOMAIN_ID(sgt_info->hyper_dmabuf_id), HYPER_DMABUF_OPS_KUNMAP_ATOMIC); if (ret < 0) { - printk("send dmabuf sync request failed\n"); + printk("hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); } } @@ -727,7 +727,7 @@ static void
[Xen-devel] [RFC PATCH 21/60] hyper_dmabuf: exposing drv information using sysfs
From: Michał JaniszewskiThis adds two entries in SYSFS with information about imported and exported entries. The information exposed contains details about number of pages, whether a buffer is valid or not, and importer/exporter count. Sysfs for hyper_dmabuf can be enabled by setting a new config option, "CONFIG_HYPER_DMABUF_SYSFS" to 'yes'. Signed-off-by: Dongwon Kim --- drivers/xen/hyper_dmabuf/Kconfig | 7 +++ drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c | 12 - drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c | 2 +- drivers/xen/hyper_dmabuf/hyper_dmabuf_list.c | 74 drivers/xen/hyper_dmabuf/hyper_dmabuf_list.h | 3 ++ 5 files changed, 96 insertions(+), 2 deletions(-) diff --git a/drivers/xen/hyper_dmabuf/Kconfig b/drivers/xen/hyper_dmabuf/Kconfig index 75e1f96..56633a2 100644 --- a/drivers/xen/hyper_dmabuf/Kconfig +++ b/drivers/xen/hyper_dmabuf/Kconfig @@ -11,4 +11,11 @@ config HYPER_DMABUF_XEN help Configuring hyper_dmabuf driver for XEN hypervisor +config HYPER_DMABUF_SYSFS + bool "Enable sysfs information about hyper DMA buffers" + default y + help + Expose information about imported and exported buffers using + hyper_dmabuf driver + endmenu diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c index 9d99769..3fc30e6 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c @@ -22,7 +22,7 @@ int unregister_device(void); struct hyper_dmabuf_private hyper_dmabuf_private; /*===*/ -static int hyper_dmabuf_drv_init(void) +static int __init hyper_dmabuf_drv_init(void) { int ret = 0; @@ -51,10 +51,16 @@ static int hyper_dmabuf_drv_init(void) } ret = hyper_dmabuf_private.backend_ops->init_comm_env(); + if (ret < 0) { + return -EINVAL; + } +#ifdef CONFIG_HYPER_DMABUF_SYSFS + ret = hyper_dmabuf_register_sysfs(hyper_dmabuf_private.device); if (ret < 0) { return -EINVAL; } +#endif /* interrupt for comm should be registered here: */ return ret; @@ -63,6 +69,10 @@ static int hyper_dmabuf_drv_init(void) /*---*/ static void hyper_dmabuf_drv_exit(void) { +#ifdef CONFIG_HYPER_DMABUF_SYSFS + hyper_dmabuf_unregister_sysfs(hyper_dmabuf_private.device); +#endif + /* hash tables for export/import entries and ring_infos */ hyper_dmabuf_table_destroy(); diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c index 9b05063..924710f 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c @@ -24,7 +24,7 @@ int dmabuf_refcount(struct dma_buf *dma_buf) return -1; } -/* return total number of pages referecned by a sgt +/* return total number of pages referenced by a sgt * for pre-calculation of # of pages behind a given sgt */ static int hyper_dmabuf_get_num_pgs(struct sg_table *sgt) diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_list.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_list.c index 18731de..1d224c4 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_list.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_list.c @@ -11,6 +11,80 @@ DECLARE_HASHTABLE(hyper_dmabuf_hash_imported, MAX_ENTRY_IMPORTED); DECLARE_HASHTABLE(hyper_dmabuf_hash_exported, MAX_ENTRY_EXPORTED); +#ifdef CONFIG_HYPER_DMABUF_SYSFS +static ssize_t hyper_dmabuf_imported_show(struct device *drv, struct device_attribute *attr, char *buf) +{ + struct hyper_dmabuf_info_entry_imported *info_entry; + int bkt; + ssize_t count = 0; + size_t total = 0; + + hash_for_each(hyper_dmabuf_hash_imported, bkt, info_entry, node) { + int id = info_entry->info->hyper_dmabuf_id; + int nents = info_entry->info->nents; + bool valid = info_entry->info->valid; + int num_importers = info_entry->info->num_importers; + total += nents; + count += scnprintf(buf + count, PAGE_SIZE - count, "id:%d, nents:%d, v:%c, numi:%d\n", + id, nents, (valid ? 't' : 'f'), num_importers); + } + count += scnprintf(buf + count, PAGE_SIZE - count, "total nents: %lu\n", + total); + + return count; +} + +static ssize_t hyper_dmabuf_exported_show(struct device *drv, struct device_attribute *attr, char *buf) +{ + struct hyper_dmabuf_info_entry_exported *info_entry; + int bkt; + ssize_t count = 0; + size_t total = 0; + + hash_for_each(hyper_dmabuf_hash_exported, bkt, info_entry, node) { +
[Xen-devel] [RFC PATCH 05/60] hyper_dmabuf: skip creating a comm ch if exist for the VM
hyper_dmabuf_importer_ring_setup creates new channel only if there is no existing downstream communication channel previously created for the exporter VM. Signed-off-by: Dongwon Kim--- drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c | 13 +++-- drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c | 20 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c index 3b40ec0..6b16e37 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c @@ -827,12 +827,11 @@ static const struct dma_buf_ops hyper_dmabuf_ops = { int hyper_dmabuf_export_fd(struct hyper_dmabuf_imported_sgt_info *dinfo, int flags) { int fd; - struct dma_buf* dmabuf; -/* call hyper_dmabuf_export_dmabuf and create and bind a handle for it - * then release */ - + /* call hyper_dmabuf_export_dmabuf and create +* and bind a handle for it then release +*/ dmabuf = hyper_dmabuf_export_dma_buf(dinfo); fd = dma_buf_fd(dmabuf, flags); @@ -845,9 +844,11 @@ struct dma_buf* hyper_dmabuf_export_dma_buf(struct hyper_dmabuf_imported_sgt_inf DEFINE_DMA_BUF_EXPORT_INFO(exp_info); exp_info.ops = _dmabuf_ops; - exp_info.size = dinfo->sgt->nents * PAGE_SIZE; /* multiple of PAGE_SIZE, not considering offset */ + + /* multiple of PAGE_SIZE, not considering offset */ + exp_info.size = dinfo->sgt->nents * PAGE_SIZE; exp_info.flags = /* not sure about flag */0; exp_info.priv = dinfo; return dma_buf_export(_info); -}; +} diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c index 665cada..90e0c65 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c @@ -12,6 +12,7 @@ #include "hyper_dmabuf_drv.h" #include "hyper_dmabuf_query.h" #include "xen/hyper_dmabuf_xen_comm.h" +#include "xen/hyper_dmabuf_xen_comm_list.h" #include "hyper_dmabuf_msg.h" struct hyper_dmabuf_private { @@ -31,6 +32,7 @@ static uint32_t hyper_dmabuf_id_gen(void) { static int hyper_dmabuf_exporter_ring_setup(void *data) { struct ioctl_hyper_dmabuf_exporter_ring_setup *ring_attr; + struct hyper_dmabuf_ring_info_export *ring_info; int ret = 0; if (!data) { @@ -39,6 +41,15 @@ static int hyper_dmabuf_exporter_ring_setup(void *data) } ring_attr = (struct ioctl_hyper_dmabuf_exporter_ring_setup *)data; + /* check if the ring ch already exists */ + ring_info = hyper_dmabuf_find_exporter_ring(ring_attr->remote_domain); + + if (ring_info) { + printk("(exporter's) ring ch to domid = %d already exist\ngref = %d, port = %d\n", + ring_info->rdomain, ring_info->gref_ring, ring_info->port); + return 0; + } + ret = hyper_dmabuf_exporter_ringbuf_init(ring_attr->remote_domain, _attr->ring_refid, _attr->port); @@ -49,6 +60,7 @@ static int hyper_dmabuf_exporter_ring_setup(void *data) static int hyper_dmabuf_importer_ring_setup(void *data) { struct ioctl_hyper_dmabuf_importer_ring_setup *setup_imp_ring_attr; + struct hyper_dmabuf_ring_info_import *ring_info; int ret = 0; if (!data) { @@ -58,6 +70,14 @@ static int hyper_dmabuf_importer_ring_setup(void *data) setup_imp_ring_attr = (struct ioctl_hyper_dmabuf_importer_ring_setup *)data; + /* check if the ring ch already exist */ + ring_info = hyper_dmabuf_find_importer_ring(setup_imp_ring_attr->source_domain); + + if (ring_info) { + printk("(importer's) ring ch to domid = %d already exist\n", ring_info->sdomain); + return 0; + } + /* user need to provide a port number and ref # for the page used as ring buffer */ ret = hyper_dmabuf_importer_ringbuf_init(setup_imp_ring_attr->source_domain, setup_imp_ring_attr->ring_refid, -- 2.7.4 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [RFC PATCH 26/60] hyper_dmabuf: add mutexes to prevent several race conditions
From: Mateusz PolrolaAdded mutex to export_fd ioctl to prevent double pages mapping of the same buffer to prevent race condition when two consumers are trying to map the same buffer on importer VM. Also locked mutex before sending request via xen communication channel to prevent req_pending override by another caller. Signed-off-by: Dongwon Kim --- drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c | 2 ++ drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h | 1 + drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c| 6 ++ drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c | 10 ++ drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.h | 1 + 5 files changed, 20 insertions(+) diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c index 569b95e..584d55d 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c @@ -56,6 +56,8 @@ static int __init hyper_dmabuf_drv_init(void) printk( KERN_NOTICE "hyper_dmabuf_starting: Initialization started" ); + mutex_init(_dmabuf_private.lock); + ret = register_device(); if (ret < 0) { return -EINVAL; diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h index 0b1441e..8445416 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h @@ -76,6 +76,7 @@ struct hyper_dmabuf_private { /* backend ops - hypervisor specific */ struct hyper_dmabuf_backend_ops *backend_ops; + struct mutex lock; }; #endif /* __LINUX_PUBLIC_HYPER_DMABUF_DRV_H__ */ diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c index 018de8c..8851a9c 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c @@ -260,6 +260,8 @@ static int hyper_dmabuf_export_fd_ioctl(void *data) if (sgt_info == NULL || !sgt_info->valid) /* can't find sgt from the table */ return -1; + mutex_lock(_dmabuf_private.lock); + sgt_info->num_importers++; /* send notification for export_fd to exporter */ @@ -274,6 +276,7 @@ static int hyper_dmabuf_export_fd_ioctl(void *data) kfree(req); dev_err(hyper_dmabuf_private.device, "Failed to create sgt or notify exporter\n"); sgt_info->num_importers--; + mutex_unlock(_dmabuf_private.lock); return -EINVAL; } kfree(req); @@ -282,6 +285,7 @@ static int hyper_dmabuf_export_fd_ioctl(void *data) dev_err(hyper_dmabuf_private.device, "Buffer invalid\n"); sgt_info->num_importers--; + mutex_unlock(_dmabuf_private.lock); return -1; } else { dev_dbg(hyper_dmabuf_private.device, "Can import buffer\n"); @@ -303,6 +307,7 @@ static int hyper_dmabuf_export_fd_ioctl(void *data) if (!data_pages) { sgt_info->num_importers--; + mutex_unlock(_dmabuf_private.lock); return -EINVAL; } @@ -318,6 +323,7 @@ static int hyper_dmabuf_export_fd_ioctl(void *data) ret = export_fd_attr->fd; } + mutex_unlock(_dmabuf_private.lock); dev_dbg(hyper_dmabuf_private.device, "%s exit\n", __func__); return 0; } diff --git a/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c b/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c index a8cce26..9d67b47 100644 --- a/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c +++ b/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c @@ -278,6 +278,8 @@ int hyper_dmabuf_xen_init_tx_rbuf(int domid) ring_info->irq = ret; ring_info->port = alloc_unbound.port; + mutex_init(_info->lock); + dev_dbg(hyper_dmabuf_private.device, "%s: allocated eventchannel gref %d port: %d irq: %d\n", __func__, @@ -512,6 +514,9 @@ int hyper_dmabuf_xen_send_req(int domid, struct hyper_dmabuf_req *req, int wait) return -EINVAL; } + + mutex_lock(_info->lock); + ring = _info->ring_front; if (RING_FULL(ring)) @@ -519,6 +524,7 @@ int hyper_dmabuf_xen_send_req(int domid, struct hyper_dmabuf_req *req, int wait) new_req = RING_GET_REQUEST(ring, ring->req_prod_pvt); if (!new_req) { + mutex_unlock(_info->lock); dev_err(hyper_dmabuf_private.device, "NULL REQUEST\n"); return -EIO; @@ -548,13 +554,17 @@ int hyper_dmabuf_xen_send_req(int domid, struct hyper_dmabuf_req *req, int wait) } if (timeout < 0) { +
[Xen-devel] [RFC PATCH 11/60] hyper_dmabuf: check stack before unmapping/detaching shadow DMA_BUF
Make sure list of mapping/attaching activities on impoter VM is not empty before doing unmapping/detaching shadow DMA BUF for indirect synchronization. Signed-off-by: Dongwon Kim--- .../xen/hyper_dmabuf/hyper_dmabuf_remote_sync.c| 68 +- 1 file changed, 53 insertions(+), 15 deletions(-) diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_remote_sync.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_remote_sync.c index 6ba932f..fa2fa11 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_remote_sync.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_remote_sync.c @@ -11,6 +11,21 @@ extern struct hyper_dmabuf_private hyper_dmabuf_private; +/* Whenever importer does dma operations from remote domain, + * a notification is sent to the exporter so that exporter + * issues equivalent dma operation on the original dma buf + * for indirect synchronization via shadow operations. + * + * All ptrs and references (e.g struct sg_table*, + * struct dma_buf_attachment) created via these operations on + * exporter's side are kept in stack (implemented as circular + * linked-lists) separately so that those can be re-referenced + * later when unmapping operations are invoked to free those. + * + * The very first element on the bottom of each stack holds + * are what is created when initial exporting is issued so it + * should not be modified or released by this fuction. + */ int hyper_dmabuf_remote_sync(int id, int ops) { struct hyper_dmabuf_sgt_info *sgt_info; @@ -33,7 +48,7 @@ int hyper_dmabuf_remote_sync(int id, int ops) attachl = kcalloc(1, sizeof(*attachl), GFP_KERNEL); attachl->attach = dma_buf_attach(sgt_info->dma_buf, - hyper_dmabuf_private.device); +hyper_dmabuf_private.device); if (!attachl->attach) { kfree(attachl); @@ -45,22 +60,31 @@ int hyper_dmabuf_remote_sync(int id, int ops) break; case HYPER_DMABUF_OPS_DETACH: - attachl = list_first_entry(_info->active_attached->list, - struct attachment_list, list); - - if (!attachl) { + if (list_empty(_info->active_attached->list)) { printk("dmabuf remote sync::error while processing HYPER_DMABUF_OPS_DETACH\n"); + printk("no more dmabuf attachment left to be detached\n"); return -EINVAL; } + + attachl = list_first_entry(_info->active_attached->list, + struct attachment_list, list); + dma_buf_detach(sgt_info->dma_buf, attachl->attach); list_del(>list); kfree(attachl); break; case HYPER_DMABUF_OPS_MAP: - sgtl = kcalloc(1, sizeof(*sgtl), GFP_KERNEL); + if (list_empty(_info->active_attached->list)) { + printk("dmabuf remote sync::error while processing HYPER_DMABUF_OPS_MAP\n"); + printk("no more dmabuf attachment left to be detached\n"); + return -EINVAL; + } + attachl = list_first_entry(_info->active_attached->list, - struct attachment_list, list); + struct attachment_list, list); + + sgtl = kcalloc(1, sizeof(*sgtl), GFP_KERNEL); sgtl->sgt = dma_buf_map_attachment(attachl->attach, DMA_BIDIRECTIONAL); if (!sgtl->sgt) { kfree(sgtl); @@ -71,17 +95,20 @@ int hyper_dmabuf_remote_sync(int id, int ops) break; case HYPER_DMABUF_OPS_UNMAP: - attachl = list_first_entry(_info->active_attached->list, - struct attachment_list, list); - sgtl = list_first_entry(_info->active_sgts->list, - struct sgt_list, list); - if (!attachl || !sgtl) { + if (list_empty(_info->active_sgts->list) || + list_empty(_info->active_attached->list)) { printk("dmabuf remote sync::error while processing HYPER_DMABUF_OPS_UNMAP\n"); + printk("no more SGT or attachment left to be freed\n"); return -EINVAL; } + attachl = list_first_entry(_info->active_attached->list, + struct attachment_list, list); + sgtl = list_first_entry(_info->active_sgts->list, + struct sgt_list, list); + dma_buf_unmap_attachment(attachl->attach, sgtl->sgt, - DMA_BIDIRECTIONAL); +
[Xen-devel] [RFC PATCH 12/60] hyper_dmabuf: two different unexporting mechanisms
unexporting on exporter's side now have two options, one is , that just remove and free everything to literally "disconnect" from importer, the other is just to return fail if any apps running on importer is still attached or DMAing. Currently whether forcing or unforcing it is determined by how "FORCED_UNEXPORING" is defined. Also, the word "destroy" in IOCTL commands and several functions have been modified to "unexport", which sounds more reasonable. Signed-off-by: Dongwon Kim--- drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h | 8 +-- drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c | 94 ++- drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.h | 4 ++ drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c | 20 +++--- drivers/xen/hyper_dmabuf/hyper_dmabuf_msg.c | 62 +- drivers/xen/hyper_dmabuf/hyper_dmabuf_msg.h | 4 +- 6 files changed, 142 insertions(+), 50 deletions(-) diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h index 7511afb..8778a19 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h @@ -65,11 +65,11 @@ struct ioctl_hyper_dmabuf_export_fd { uint32_t fd; }; -#define IOCTL_HYPER_DMABUF_DESTROY \ -_IOC(_IOC_NONE, 'G', 4, sizeof(struct ioctl_hyper_dmabuf_destroy)) -struct ioctl_hyper_dmabuf_destroy { +#define IOCTL_HYPER_DMABUF_UNEXPORT \ +_IOC(_IOC_NONE, 'G', 4, sizeof(struct ioctl_hyper_dmabuf_unexport)) +struct ioctl_hyper_dmabuf_unexport { /* IN parameters */ - /* hyper dmabuf id to be destroyed */ + /* hyper dmabuf id to be unexported */ uint32_t hyper_dmabuf_id; /* OUT parameters */ /* Status of request */ diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c index 2c78bc1..06bd8e5 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c @@ -104,7 +104,7 @@ struct sg_table* hyper_dmabuf_create_sgt(struct page **pages, ret = sg_alloc_table(sgt, nents, GFP_KERNEL); if (ret) { - kfree(sgt); + sg_free_table(sgt); return NULL; } @@ -125,6 +125,12 @@ struct sg_table* hyper_dmabuf_create_sgt(struct page **pages, return sgt; } +/* free sg_table */ +void hyper_dmabuf_free_sgt(struct sg_table* sgt) +{ + sg_free_table(sgt); +} + /* * Creates 2 level page directory structure for referencing shared pages. * Top level page is a single page that contains up to 1024 refids that @@ -512,6 +518,92 @@ struct sg_table* hyper_dmabuf_map_pages(grant_ref_t top_level_gref, int frst_ofs return st; } +int hyper_dmabuf_cleanup_sgt_info(struct hyper_dmabuf_sgt_info *sgt_info, int force) +{ + struct sgt_list *sgtl; + struct attachment_list *attachl; + struct kmap_vaddr_list *va_kmapl; + struct vmap_vaddr_list *va_vmapl; + + if (!sgt_info) { + printk("invalid hyper_dmabuf_id\n"); + return -EINVAL; + } + + /* if force != 1, sgt_info can be released only if +* there's no activity on exported dma-buf on importer +* side. +*/ + if (!force && + (!list_empty(_info->va_kmapped->list) || + !list_empty(_info->va_vmapped->list) || + !list_empty(_info->active_sgts->list) || + !list_empty(_info->active_attached->list))) { + printk("dma-buf is used by importer\n"); + return -EPERM; + } + + while (!list_empty(_info->va_kmapped->list)) { + va_kmapl = list_first_entry(_info->va_kmapped->list, + struct kmap_vaddr_list, list); + + dma_buf_kunmap(sgt_info->dma_buf, 1, va_kmapl->vaddr); + list_del(_kmapl->list); + kfree(va_kmapl); + } + + while (!list_empty(_info->va_vmapped->list)) { + va_vmapl = list_first_entry(_info->va_vmapped->list, + struct vmap_vaddr_list, list); + + dma_buf_vunmap(sgt_info->dma_buf, va_vmapl->vaddr); + list_del(_vmapl->list); + kfree(va_vmapl); + } + + while (!list_empty(_info->active_sgts->list)) { + attachl = list_first_entry(_info->active_attached->list, + struct attachment_list, list); + + sgtl = list_first_entry(_info->active_sgts->list, + struct sgt_list, list); + + dma_buf_unmap_attachment(attachl->attach, sgtl->sgt, +DMA_BIDIRECTIONAL); + list_del(>list); + kfree(sgtl); + } + + while (!list_empty(_info->active_sgts->list)) { + attachl =
[Xen-devel] [RFC PATCH 19/60] hyper_dmabuf: fix the case with sharing a buffer with 2 pages
From: Mateusz PolrolaChecking whether buffer has more than two pages should be done by evaluating nents > 1 instead of i > 1 to properly cover the case when nents == 2. Signed-off-by: Dongwon Kim --- drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c index b61d29a..9b05063 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c @@ -129,7 +129,7 @@ struct sg_table* hyper_dmabuf_create_sgt(struct page **pages, sg_set_page(sgl, pages[i], PAGE_SIZE, 0); } - if (i > 1) /* more than one page */ { + if (nents > 1) /* more than one page */ { sgl = sg_next(sgl); sg_set_page(sgl, pages[i], last_len, 0); } -- 2.7.4 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [RFC PATCH 04/60] hyper_dmabuf: new index, k for pointing a right n-th page
Need a new index, k in hyper_dmabuf_extract_pgs function for picking up a correct n-th page in contigous memory space. Signed-off-by: Dongwon Kim--- drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c | 11 ++- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c index 7cb5c35..3b40ec0 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_imp.c @@ -39,7 +39,7 @@ static int hyper_dmabuf_get_num_pgs(struct sg_table *sgt) struct hyper_dmabuf_pages_info *hyper_dmabuf_ext_pgs(struct sg_table *sgt) { struct hyper_dmabuf_pages_info *pinfo; - int i, j; + int i, j, k; int length; struct scatterlist *sgl; @@ -57,7 +57,7 @@ struct hyper_dmabuf_pages_info *hyper_dmabuf_ext_pgs(struct sg_table *sgt) pinfo->frst_ofst = sgl->offset; pinfo->pages[0] = sg_page(sgl); length = sgl->length - PAGE_SIZE + sgl->offset; - i=1; + i = 1; while (length > 0) { pinfo->pages[i] = nth_page(sg_page(sgl), i); @@ -71,12 +71,12 @@ struct hyper_dmabuf_pages_info *hyper_dmabuf_ext_pgs(struct sg_table *sgt) pinfo->pages[i++] = sg_page(sgl); length = sgl->length - PAGE_SIZE; pinfo->nents++; + k = 1; while (length > 0) { - pinfo->pages[i] = nth_page(sg_page(sgl), i); + pinfo->pages[i++] = nth_page(sg_page(sgl), k++); length -= PAGE_SIZE; pinfo->nents++; - i++; } } @@ -535,7 +535,8 @@ static int hyper_dmabuf_ops_attach(struct dma_buf* dmabuf, struct device* dev, printk("hyper_dmabuf::%s Error:send dmabuf sync request failed\n", __func__); } - return ret; + /* Ignoring ret for now */ + return 0; } static void hyper_dmabuf_ops_detach(struct dma_buf* dmabuf, struct dma_buf_attachment *attach) -- 2.7.4 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [RFC PATCH 10/60] hyper_dmabuf: make sure to free memory to prevent leak
From: Mateusz PolrolaIn hyper_dmabuf_export_remote, page_info->pages needs to be freed before freeing page_info. Also, info_entry in hyper_dmabuf_remove_exported/imported and hyper_dmabuf_remove_exporter/importer_ring needs to be freed after removal of an entry. Signed-off-by: Dongwon Kim --- drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c | 1 + drivers/xen/hyper_dmabuf/hyper_dmabuf_list.c | 2 ++ drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c | 2 ++ drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm_list.c | 2 ++ 4 files changed, 7 insertions(+) diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c index bace8b2..6f100ef 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c @@ -191,6 +191,7 @@ static int hyper_dmabuf_export_remote(void *data) /* free msg */ kfree(req); /* free page_info */ + kfree(page_info->pages); kfree(page_info); return ret; diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_list.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_list.c index 2b3ef6b..1420df9 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_list.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_list.c @@ -98,6 +98,7 @@ int hyper_dmabuf_remove_exported(int id) hash_for_each(hyper_dmabuf_hash_exported, bkt, info_entry, node) if(info_entry->info->hyper_dmabuf_id == id) { hash_del(_entry->node); + kfree(info_entry); return 0; } @@ -112,6 +113,7 @@ int hyper_dmabuf_remove_imported(int id) hash_for_each(hyper_dmabuf_hash_imported, bkt, info_entry, node) if(info_entry->info->hyper_dmabuf_id == id) { hash_del(_entry->node); + kfree(info_entry); return 0; } diff --git a/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c b/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c index 576085f..116850e 100644 --- a/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c +++ b/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c @@ -320,6 +320,8 @@ int hyper_dmabuf_importer_ringbuf_init(int sdomain) ring_info->unmap_op.handle = ops[0].handle; } + kfree(ops); + sring = (struct hyper_dmabuf_sring*) pfn_to_kaddr(page_to_pfn(shared_ring)); BACK_RING_INIT(_info->ring_back, sring, PAGE_SIZE); diff --git a/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm_list.c b/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm_list.c index 5778468..a068276 100644 --- a/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm_list.c +++ b/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm_list.c @@ -85,6 +85,7 @@ int hyper_dmabuf_remove_exporter_ring(int domid) hash_for_each(hyper_dmabuf_hash_exporter_ring, bkt, info_entry, node) if(info_entry->info->rdomain == domid) { hash_del(_entry->node); + kfree(info_entry); return 0; } @@ -99,6 +100,7 @@ int hyper_dmabuf_remove_importer_ring(int domid) hash_for_each(hyper_dmabuf_hash_importer_ring, bkt, info_entry, node) if(info_entry->info->sdomain == domid) { hash_del(_entry->node); + kfree(info_entry); return 0; } -- 2.7.4 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [Xen-users] Data corruption with xl migrate
Am 19.12.17 um 11:33 schrieb George Dunlap: > On Sun, Dec 17, 2017 at 3:53 PM, Andreas Pflug >wrote: >> Still experiencing data corruption when migrating 3.16 VMs from one host >> to another... >> Seems independent of Xen version or storage backend. >> >> Regards >> Andreas >> >> Am 13.12.17 um 09:12 schrieb Andreas Pflug: >>> Recently, I encountered file system data corruption on several systems >>> after a migration (ext4, xfs, zfs). So far, I haven't been able to nail >>> down the cause for it. >>> >>> All VMs affected run Debian Jessie with 3.16 kernel. Possibly newer 3.16 >>> kernels are more likely to suffer corruption. >>> >>> This happened on a Xen 4.1 cluster (yes, really old) using a SAN storage >>> system, but also on a Xen 4.8 cluster with DRBD mirroring. All systems >>> are working for >>1 year now, only recently those filesystem corruption >>> started to happen. Data blocks seem to get randomly garbled. >>> >>> Migration of Debian Stretch or Windows VMs didn't show any anomalies >>> Can anyone shed some light on this? > Thanks for the report -- cc'ing a few random people who know more > about the block layer / Debian kernels. > > It seems Debian Jessie 3.16 kernel was experiencing corruption on > migration, but not the Debian Stretch kernel or Windows VMs. That > sounds like a bug in the Debian kernel; any ideas about what patch may > be worth backporting / any steps to help further investigate the > source of the problems? The latest kernel that didn't show these problems so far seems to be 3.16.36. Actually, yesterday I encountered a fs inconsistency (remount-ro) by shutting down a 3.16.39 VM and starting back on the other machine (drbd synced, no anomalies seen on the drbd layer). So apparently it's not only migration related. All kinds of FS are affected: ext4, xfs, zfs. I filed the bug at https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=884622 Regards Andreas ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH V5] pci: removed the is_express field since a uniform interface was inserted
On 18/12/2017 17:21, Yoni Bettan wrote: according to Eduardo Habkost's commit fd3b02c889 all PCIEs now implement INTERFACE_PCIE_DEVICE so we don't need is_express field anymore. Devices that implements only INTERFACE_PCIE_DEVICE (is_express == 1) or devices that implements only INTERFACE_CONVENTIONAL_PCI_DEVICE (is_express == 0) where not affected by the change. The only devices that were affected are those that are hybrid and also had (is_express == 1) - therefor only: - hw/vfio/pci.c - hw/usb/hcd-xhci.c - hw/xen/xen_pt.c For those 3 I made sure that QEMU_PCI_CAP_EXPRESS is on in instance_init() Signed-off-by: Yoni Bettan--- docs/pcie_pci_bridge.txt | 2 +- hw/block/nvme.c| 1 - hw/net/e1000e.c| 1 - hw/pci-bridge/pcie_pci_bridge.c| 1 - hw/pci-bridge/pcie_root_port.c | 1 - hw/pci-bridge/xio3130_downstream.c | 1 - hw/pci-bridge/xio3130_upstream.c | 1 - hw/pci-host/xilinx-pcie.c | 1 - hw/pci/pci.c | 8 ++-- hw/scsi/megasas.c | 4 hw/usb/hcd-xhci.c | 9 - hw/vfio/pci.c | 5 - hw/xen/xen_pt.c| 9 - include/hw/pci/pci.h | 3 --- 14 files changed, 27 insertions(+), 20 deletions(-) diff --git a/docs/pcie_pci_bridge.txt b/docs/pcie_pci_bridge.txt index 5a4203f97c..ab35ebf3ca 100644 --- a/docs/pcie_pci_bridge.txt +++ b/docs/pcie_pci_bridge.txt @@ -110,5 +110,5 @@ To enable device hot-plug into the bridge on Linux there're 3 ways: Implementation == The PCIE-PCI bridge is based on PCI-PCI bridge, but also accumulates PCI Express -features as a PCI Express device (is_express=1). +features as a PCI Express device. diff --git a/hw/block/nvme.c b/hw/block/nvme.c index 441e21ed1f..9325bc0911 100644 --- a/hw/block/nvme.c +++ b/hw/block/nvme.c @@ -1087,7 +1087,6 @@ static void nvme_class_init(ObjectClass *oc, void *data) pc->vendor_id = PCI_VENDOR_ID_INTEL; pc->device_id = 0x5845; pc->revision = 2; -pc->is_express = 1; set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); dc->desc = "Non-Volatile Memory Express"; diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c index f1af279e8d..c360f0d8c9 100644 --- a/hw/net/e1000e.c +++ b/hw/net/e1000e.c @@ -675,7 +675,6 @@ static void e1000e_class_init(ObjectClass *class, void *data) c->revision = 0; c->romfile = "efi-e1000e.rom"; c->class_id = PCI_CLASS_NETWORK_ETHERNET; -c->is_express = 1; dc->desc = "Intel 82574L GbE Controller"; dc->reset = e1000e_qdev_reset; diff --git a/hw/pci-bridge/pcie_pci_bridge.c b/hw/pci-bridge/pcie_pci_bridge.c index a4d827c99d..b7d9ebbec2 100644 --- a/hw/pci-bridge/pcie_pci_bridge.c +++ b/hw/pci-bridge/pcie_pci_bridge.c @@ -169,7 +169,6 @@ static void pcie_pci_bridge_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass); -k->is_express = 1; k->is_bridge = 1; k->vendor_id = PCI_VENDOR_ID_REDHAT; k->device_id = PCI_DEVICE_ID_REDHAT_PCIE_BRIDGE; diff --git a/hw/pci-bridge/pcie_root_port.c b/hw/pci-bridge/pcie_root_port.c index 9b6e4ce512..45f9e8cd4a 100644 --- a/hw/pci-bridge/pcie_root_port.c +++ b/hw/pci-bridge/pcie_root_port.c @@ -145,7 +145,6 @@ static void rp_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); -k->is_express = 1; k->is_bridge = 1; k->config_write = rp_write_config; k->realize = rp_realize; diff --git a/hw/pci-bridge/xio3130_downstream.c b/hw/pci-bridge/xio3130_downstream.c index 1e09d2afb7..613a0d6bb7 100644 --- a/hw/pci-bridge/xio3130_downstream.c +++ b/hw/pci-bridge/xio3130_downstream.c @@ -177,7 +177,6 @@ static void xio3130_downstream_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); -k->is_express = 1; k->is_bridge = 1; k->config_write = xio3130_downstream_write_config; k->realize = xio3130_downstream_realize; diff --git a/hw/pci-bridge/xio3130_upstream.c b/hw/pci-bridge/xio3130_upstream.c index 227997ce46..d4645bddee 100644 --- a/hw/pci-bridge/xio3130_upstream.c +++ b/hw/pci-bridge/xio3130_upstream.c @@ -148,7 +148,6 @@ static void xio3130_upstream_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); -k->is_express = 1; k->is_bridge = 1; k->config_write = xio3130_upstream_write_config; k->realize = xio3130_upstream_realize; diff --git a/hw/pci-host/xilinx-pcie.c b/hw/pci-host/xilinx-pcie.c index 7659253090..a4ca3ba30f 100644 --- a/hw/pci-host/xilinx-pcie.c +++ b/hw/pci-host/xilinx-pcie.c @@ -298,7 +298,6 @@ static void
Re: [Xen-devel] [Qemu-devel] [PATCH V5] pci: removed the is_express field since a uniform interface was inserted
On Mon, Dec 18, 2017 at 05:21:40PM +0200, Yoni Bettan wrote: > according to Eduardo Habkost's commit fd3b02c889 all PCIEs now implement > INTERFACE_PCIE_DEVICE so we don't need is_express field anymore. > > Devices that implements only INTERFACE_PCIE_DEVICE (is_express == 1) > or > devices that implements only INTERFACE_CONVENTIONAL_PCI_DEVICE (is_express == > 0) > where not affected by the change. > > The only devices that were affected are those that are hybrid and also > had (is_express == 1) - therefor only: > - hw/vfio/pci.c > - hw/usb/hcd-xhci.c > - hw/xen/xen_pt.c > > For those 3 I made sure that QEMU_PCI_CAP_EXPRESS is on in instance_init() > > Signed-off-by: Yoni BettanReviewed-by: Eduardo Habkost -- Eduardo ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH v2] libxl: put RSDP for PVH guest near 4GB
On 19/12/17 17:11, Roger Pau Monné wrote: > On Tue, Dec 19, 2017 at 04:46:37PM +0100, Juergen Gross wrote: >> On 19/12/17 16:38, Roger Pau Monné wrote: >>> On Fri, Dec 01, 2017 at 03:14:07PM +0100, Juergen Gross wrote: Instead of locating the RSDP table below 1MB put it just below 4GB like the rest of the ACPI tables in case of PVH guests. This will avoid punching more holes than necessary into the memory map. Signed-off-by: Juergen GrossAcked-by: Wei Liu --- tools/libxc/xc_dom_hvmloader.c | 2 +- tools/libxl/libxl_x86_acpi.c | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/tools/libxc/xc_dom_hvmloader.c b/tools/libxc/xc_dom_hvmloader.c index 59f94e51e5..3f0bd65547 100644 --- a/tools/libxc/xc_dom_hvmloader.c +++ b/tools/libxc/xc_dom_hvmloader.c @@ -136,7 +136,7 @@ static int module_init_one(struct xc_dom_image *dom, struct xc_dom_seg seg; void *dest; -if ( module->length ) +if ( module->length && !module->guest_addr_out ) >>> >>> Isn't that kind of a separate fix? AFAICT this just prevents >>> allocating memory if guest_addr_out is already set to a fixed >>> position. >> >> No, this is mandatory, as I have to skip the allocation for PVH, while >> HVM guests really want the allocation to take place. > > Was this also a problem before? Other ACPI modules also set > guest_addr_out, and previously they would also get memory allocated. module_init_one() would only be called for the first ACPI module, which happens to be the RSDP. Juergen ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH v2] libxl: put RSDP for PVH guest near 4GB
On Tue, Dec 19, 2017 at 04:46:37PM +0100, Juergen Gross wrote: > On 19/12/17 16:38, Roger Pau Monné wrote: > > On Fri, Dec 01, 2017 at 03:14:07PM +0100, Juergen Gross wrote: > >> Instead of locating the RSDP table below 1MB put it just below 4GB > >> like the rest of the ACPI tables in case of PVH guests. This will > >> avoid punching more holes than necessary into the memory map. > >> > >> Signed-off-by: Juergen Gross> >> Acked-by: Wei Liu > >> --- > >> tools/libxc/xc_dom_hvmloader.c | 2 +- > >> tools/libxl/libxl_x86_acpi.c | 5 ++--- > >> 2 files changed, 3 insertions(+), 4 deletions(-) > >> > >> diff --git a/tools/libxc/xc_dom_hvmloader.c > >> b/tools/libxc/xc_dom_hvmloader.c > >> index 59f94e51e5..3f0bd65547 100644 > >> --- a/tools/libxc/xc_dom_hvmloader.c > >> +++ b/tools/libxc/xc_dom_hvmloader.c > >> @@ -136,7 +136,7 @@ static int module_init_one(struct xc_dom_image *dom, > >> struct xc_dom_seg seg; > >> void *dest; > >> > >> -if ( module->length ) > >> +if ( module->length && !module->guest_addr_out ) > > > > Isn't that kind of a separate fix? AFAICT this just prevents > > allocating memory if guest_addr_out is already set to a fixed > > position. > > No, this is mandatory, as I have to skip the allocation for PVH, while > HVM guests really want the allocation to take place. Was this also a problem before? Other ACPI modules also set guest_addr_out, and previously they would also get memory allocated. Roger. ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH v2] libxl: put RSDP for PVH guest near 4GB
Juergen Gross writes ("[PATCH v2] libxl: put RSDP for PVH guest near 4GB"): > Instead of locating the RSDP table below 1MB put it just below 4GB > like the rest of the ACPI tables in case of PVH guests. This will > avoid punching more holes than necessary into the memory map. > > Signed-off-by: Juergen Gross> Acked-by: Wei Liu I had held off committing this despite it having Wei's ack because I didn't feel confident about it (mostly, because it seems to be about x86/ACPI things I don't feel I understand). Ian. ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH v2] libxl: put RSDP for PVH guest near 4GB
On 19/12/17 16:38, Roger Pau Monné wrote: > On Fri, Dec 01, 2017 at 03:14:07PM +0100, Juergen Gross wrote: >> Instead of locating the RSDP table below 1MB put it just below 4GB >> like the rest of the ACPI tables in case of PVH guests. This will >> avoid punching more holes than necessary into the memory map. >> >> Signed-off-by: Juergen Gross>> Acked-by: Wei Liu >> --- >> tools/libxc/xc_dom_hvmloader.c | 2 +- >> tools/libxl/libxl_x86_acpi.c | 5 ++--- >> 2 files changed, 3 insertions(+), 4 deletions(-) >> >> diff --git a/tools/libxc/xc_dom_hvmloader.c b/tools/libxc/xc_dom_hvmloader.c >> index 59f94e51e5..3f0bd65547 100644 >> --- a/tools/libxc/xc_dom_hvmloader.c >> +++ b/tools/libxc/xc_dom_hvmloader.c >> @@ -136,7 +136,7 @@ static int module_init_one(struct xc_dom_image *dom, >> struct xc_dom_seg seg; >> void *dest; >> >> -if ( module->length ) >> +if ( module->length && !module->guest_addr_out ) > > Isn't that kind of a separate fix? AFAICT this just prevents > allocating memory if guest_addr_out is already set to a fixed > position. No, this is mandatory, as I have to skip the allocation for PVH, while HVM guests really want the allocation to take place. Juergen ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH v2] libxl: put RSDP for PVH guest near 4GB
On Fri, Dec 01, 2017 at 03:14:07PM +0100, Juergen Gross wrote: > Instead of locating the RSDP table below 1MB put it just below 4GB > like the rest of the ACPI tables in case of PVH guests. This will > avoid punching more holes than necessary into the memory map. > > Signed-off-by: Juergen Gross> Acked-by: Wei Liu > --- > tools/libxc/xc_dom_hvmloader.c | 2 +- > tools/libxl/libxl_x86_acpi.c | 5 ++--- > 2 files changed, 3 insertions(+), 4 deletions(-) > > diff --git a/tools/libxc/xc_dom_hvmloader.c b/tools/libxc/xc_dom_hvmloader.c > index 59f94e51e5..3f0bd65547 100644 > --- a/tools/libxc/xc_dom_hvmloader.c > +++ b/tools/libxc/xc_dom_hvmloader.c > @@ -136,7 +136,7 @@ static int module_init_one(struct xc_dom_image *dom, > struct xc_dom_seg seg; > void *dest; > > -if ( module->length ) > +if ( module->length && !module->guest_addr_out ) Isn't that kind of a separate fix? AFAICT this just prevents allocating memory if guest_addr_out is already set to a fixed position. The rest LGTM. Thanks, Roger. ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH v2] libxl: put RSDP for PVH guest near 4GB
Ping? On 01/12/17 15:14, Juergen Gross wrote: > Instead of locating the RSDP table below 1MB put it just below 4GB > like the rest of the ACPI tables in case of PVH guests. This will > avoid punching more holes than necessary into the memory map. > > Signed-off-by: Juergen Gross> Acked-by: Wei Liu > --- > tools/libxc/xc_dom_hvmloader.c | 2 +- > tools/libxl/libxl_x86_acpi.c | 5 ++--- > 2 files changed, 3 insertions(+), 4 deletions(-) > > diff --git a/tools/libxc/xc_dom_hvmloader.c b/tools/libxc/xc_dom_hvmloader.c > index 59f94e51e5..3f0bd65547 100644 > --- a/tools/libxc/xc_dom_hvmloader.c > +++ b/tools/libxc/xc_dom_hvmloader.c > @@ -136,7 +136,7 @@ static int module_init_one(struct xc_dom_image *dom, > struct xc_dom_seg seg; > void *dest; > > -if ( module->length ) > +if ( module->length && !module->guest_addr_out ) > { > if ( xc_dom_alloc_segment(dom, , name, 0, module->length) ) > goto err; > diff --git a/tools/libxl/libxl_x86_acpi.c b/tools/libxl/libxl_x86_acpi.c > index 9a7c90467d..fe87418bc1 100644 > --- a/tools/libxl/libxl_x86_acpi.c > +++ b/tools/libxl/libxl_x86_acpi.c > @@ -22,8 +22,6 @@ > > /* Number of pages holding ACPI tables */ > #define NUM_ACPI_PAGES 16 > -/* Store RSDP in the last 64 bytes of BIOS RO memory */ > -#define RSDP_ADDRESS (0x10 - 64) > #define ACPI_INFO_PHYSICAL_ADDRESS 0xfc00 > > struct libxl_acpi_ctxt { > @@ -220,7 +218,8 @@ int libxl__dom_load_acpi(libxl__gc *gc, > > dom->acpi_modules[0].data = (void *)config.rsdp; > dom->acpi_modules[0].length = 64; > -dom->acpi_modules[0].guest_addr_out = RSDP_ADDRESS; > +dom->acpi_modules[0].guest_addr_out = ACPI_INFO_PHYSICAL_ADDRESS + > +(1 + acpi_pages_num) * libxl_ctxt.page_size; > > dom->acpi_modules[1].data = (void *)config.infop; > dom->acpi_modules[1].length = 4096; > ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH v2] xen/balloon: Mark unallocated host memory as UNUSABLE
On 12/19/2017 09:40 AM, Jan Beulich wrote: On 19.12.17 at 15:25,wrote: >> On 12/19/2017 03:23 AM, Jan Beulich wrote: >> On 18.12.17 at 23:22, wrote: + if (!xen_e820_table) + return; >>> Not saying "out of memory" here is certainly fine, but shouldn't >>> there nevertheless be a warning, as failure to go through the >>> rest of the function will impact overall functionality? >> Commit ebfdc40969f claims that these types of messages are unnecessary >> because allocation failures are signalled by the memory subsystem. > But the memory subsystem can't possibly provide an indication of > what will not work because of the failed allocation. There should be a stack dump which will make it clear which routine failed. > + memmap.nr_entries = ARRAY_SIZE(xen_e820_table->entries); >>> Is it really reasonable to have a static upper bound here? As we >>> know especially EFI systems can come with a pretty scattered >>> (pseudo) E820 table. Even if (iirc) this has a static upper bound >>> right now in the hypervisor too, it would be nice if the kernel >>> didn't need further changes once the hypervisor is being made >>> more flexible. >> This is how we obtain the map in xen_memory_setup(). Are you suggesting >> that we should query for the size first? > That would be better, I think. I think we will first need to fix xen_memory_setup() to do that too and that would be a separate patch. I am also not clear how this will work on earlier version of the hypervisor that didn't support querying for size. From what I am seeing in 4.4 we will get -EFAULT if the buffer is NULL. > + /* Mark non-RAM regions as not available. */ + for (; i < memmap.nr_entries; i++) { + entry = _e820_table->entries[i]; + + if (entry->type == E820_TYPE_RAM) + continue; >>> I can't seem to match up this with ... >>> + if (entry->addr >= hostmem_resource->end) + break; + + res = kzalloc(sizeof(*res), GFP_KERNEL); + if (!res) + goto out; + + res->name = "Host memory"; >>> ... this. Do you mean != instead (with the comment ahead of the >>> loop also clarified, saying something like "host RAM regions which >>> aren't RAM for us")? And perhaps better "Host RAM"? >> Right, this is not memory but rather something else (and so "!=" is >> correct). "Unavailable host RAM"? > If you like to be even more specific than what I had suggested - > sure. But did you want to have some changes in the preceding comment? Not sure I read your comment correctly. -boris ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH] libxl/pvh: force PVH guests to use the xenstore shutdown
On Tue, Dec 19, 2017 at 02:48:47PM +, Ian Jackson wrote: > Roger Pau Monné writes ("Re: [PATCH] libxl/pvh: force PVH guests to use the > xenstore shutdown"): > > Yes, that's exactly what I meant but failed to express. Feel free to > > replace the commit message with yours. > > OK, thanks :-). I have > > Acked-by: Ian Jackson> > and pushed it. > > I think this is a candidate for backporting as far as 4.9 ? Yes, 4.10 only though (that's when the PVH guest type was introduced) in it's current form. 4.9 will require some rework (like checking qemu pid). Roger. ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH] libxl/pvh: force PVH guests to use the xenstore shutdown
Roger Pau Monné writes ("Re: [PATCH] libxl/pvh: force PVH guests to use the xenstore shutdown"): > Yes, that's exactly what I meant but failed to express. Feel free to > replace the commit message with yours. OK, thanks :-). I have Acked-by: Ian Jacksonand pushed it. I think this is a candidate for backporting as far as 4.9 ? Ian. ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH] sched/null: skip vCPUs on the waitqueue that are blocked
On Tue, Dec 19, 2017 at 07:25:51AM -0700, Jan Beulich wrote: > >>> On 19.12.17 at 15:16,wrote: > > --- a/xen/common/sched_null.c > > +++ b/xen/common/sched_null.c > > @@ -781,6 +781,10 @@ static struct task_slice null_schedule(const struct > > scheduler *ops, > > { > > list_for_each_entry( wvc, >waitq, waitq_elem ) > > { > > +if ( test_bit(_VPF_down, >vcpu->pause_flags) ) > > +/* Skip vCPUs that are down. */ > > +continue; > > If such a custom check is indeed necessary here (looks to rather be > something generic scheduling code should be dealing with), why > would you take into consideration only this one VPF bit? I know that at least when a vCPU is brought up a call to vcpu_wake happens and the vCPU is scheduled. The same happens for unpause and some of the other events, but I'm not sure whether it applies to all of them. IMHO 'down' was the clearer one since there's no chance the vCPU is going to run in the near future if it's not brought up. Other pause_flags like 'blocked_in_xen' or 'migrating' seem more temporary. Thanks, Roger. ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH] libxl/pvh: force PVH guests to use the xenstore shutdown
Roger Pau Monne writes ("[PATCH] libxl/pvh: force PVH guests to use the xenstore shutdown"): > There's no other way to shutdown a PVH guest at the moment. This commit message is rather confusing. Do you mean, instead: PVH guests are all required to support the xenstore-based shutdown signalling, since there is no other way for a PVH guest to be requested to shut down. For HVM guests we check whether the guest has installed a PV-on-HVM interrupt callback; that does not make sense for PVH guests. So for PVH guests, take the PV path: assume that all PVH guests have suitable xenstore drivers. ? Ian. ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH 2/2] x86/dom0: remove is_pv_domain leftovers from the PV domain builder
On 19/12/17 14:20, Roger Pau Monne wrote: > Those where added when PVHv1 was sharing the domain builder with PV. > > Signed-off-by: Roger Pau MonnéReviewed-by: Andrew Cooper ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH 2/2] x86/dom0: remove is_pv_domain leftovers from the PV domain builder
>>> On 19.12.17 at 15:20,wrote: > Those where added when PVHv1 was sharing the domain builder with PV. > > Signed-off-by: Roger Pau Monné Reviewed-by: Jan Beulich ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel