[Swan] Kernel crash with klips

David McCullough ucdevel at gmail.com
Tue Oct 22 08:07:15 EEST 2013



Slava Bendersky wrote the following:
> Hello David, 
> Please see attached file. 

Try the attached patch to libreswan,  this should fix it.
Its really only a problem when CONFIG_DEBUG_SG is enabled.

Cheers,
Davidm

> 
> From: "David McCullough" <ucdevel at gmail.com> 
> To: "Slava Bendersky" <volga629 at networklab.ca> 
> Sent: Monday, October 21, 2013 9:21:23 PM 
> Subject: Re: [Swan] Kernel crash with klips 
> 
> 
> Slava Bendersky wrote the following: 
> > Hello David, 
> > If this this correct file ? 
> 
> Yes, send me the whole file as an attachment, no changes. 
> I need to know which line is exactly line 65. 
> 
> Thanks, 
> Davidm 
> 
> > Block on line 65 
> > 
> > vim /usr/src/kernels/3.2.2-10.nl.el6.x86_64/include/linux/scatterlist.h 
> > 
> > static inline void sg_assign_page(struct scatterlist *sg, struct page *page) 
> > { 
> > unsigned long page_link = sg->page_link & 0x3; 
> > 
> > /* 
> > * In order for the low bit stealing approach to work, pages 
> > * must be aligned at a 32-bit boundary as a minimum. 
> > */ 
> > BUG_ON((unsigned long) page & 0x03); 
> > #ifdef CONFIG_DEBUG_SG 
> > BUG_ON(sg->sg_magic != SG_MAGIC); 
> > BUG_ON(sg_is_chain(sg)); 
> > #endif 
> > sg->page_link = page_link | (unsigned long) page; 
> > } 
> > 
> > 
> > 
> > 
> > Slava. 
> > ----- Original Message ----- 
> > 
> > From: "David McCullough" <ucdevel at gmail.com> 
> > To: "Slava Bendersky" <volga629 at networklab.ca> 
> > Cc: swan at lists.libreswan.org 
> > Sent: Sunday, October 20, 2013 11:48:28 PM 
> > Subject: Re: [Swan] Kernel crash with klips 
> > 
> > 
> > Slava Bendersky wrote the following: 
> > > Hello David, 
> > > I was be able get crash report, see attached text file. 
> > 
> > Cool, that helps a lot. 
> > 
> > Do you have a copy of /usr/include/include/linux/scatterlist.h ? 
> > Specifically I need line 65. Perhaps if you have the kernel source 
> > or headers in /usr/src/.... 
> > 
> > I recall seeing something similar with OCF so if we can figure out exactly 
> > which "BUG" caused the oops we may be able to resolve it for you :-) 
> > 
> > Cheers, 
> > Davidm 
> > 
> > > ----- Original Message ----- 
> > > 
> > > From: "Slava Bendersky" <volga629 at skillsearch.ca> 
> > > To: "David McCullough" <ucdevel at gmail.com> 
> > > Cc: swan at lists.libreswan.org 
> > > Sent: Wednesday, October 9, 2013 5:45:48 PM 
> > > Subject: Re: [Swan] Kernel crash with klips 
> > > 
> > > Hello Everyone, 
> > > Finally I was be able catch first part of the crash. I hope it will give info. 
> > > http://ctrlv.in/246071 
> > > 
> > > Slava. 
> > > ----- Original Message ----- 
> > > 
> > > From: "David McCullough" <ucdevel at gmail.com> 
> > > To: "Slava Bendersky" <volga629 at skillsearch.ca> 
> > > Cc: swan at lists.libreswan.org 
> > > Sent: Wednesday, October 2, 2013 11:46:20 PM 
> > > Subject: Re: [Swan] Kernel crash with klips 
> > > 
> > > 
> > > Slava Bendersky wrote the following: 
> > > > Hello Everyone, 
> > > > Trying get more information about constant kernel crash. Please see this screen shot http://ctrlv.in/243365 . 
> > > > Libreswan 3.5 klips kernel 3.2.2-9.nl.el6.x86_64. This box is working for internal branch routing and it running quagga ospfd with vpn tunnel transport mode. 
> > > 
> > > Is there any chance you can retrieve the first part of the oops ? 
> > > Can you reproduce it ? 
> > > 
> > > Thanks, 
> > > Davidm 
> > > 
> > > 
> > > > [root@ ~]# ipsec verify 
> > > > Verifying installed system and configuration files 
> > > > 
> > > > Version check and ipsec on-path [OK] 
> > > > Libreswan 3.5 (klips) on 3.2.2-9.nl.el6.x86_64 
> > > > Checking for IPsec support in kernel [OK] 
> > > > KLIPS: checking for NAT Traversal support [OK] 
> > > > KLIPS: checking for OCF crypto offload support [OK] 
> > > > KLIPS: IPsec SAref kernel support [OK] 
> > > > KLIPS: IPsec SAref Bind kernel support [OK] 
> > > > Pluto ipsec.conf syntax [OK] 
> > > > 
> > > > 
> > > > 
> > > > Slava. 
> > > > 
> > > 
> > > > _______________________________________________ 
> > > > Swan mailing list 
> > > > Swan at lists.libreswan.org 
> > > > https://lists.libreswan.org/mailman/listinfo/swan 
> > > 
> > > 
> > > -- 
> > > David McCullough, davidm at spottygum.com, Ph: 0410 560 763 
> > > 
> > > 
> > > _______________________________________________ 
> > > Swan mailing list 
> > > Swan at lists.libreswan.org 
> > > https://lists.libreswan.org/mailman/listinfo/swan 
> > > 
> > 
> > > [ 122.209632] klips_info:ipsec_init: KLIPS startup, Libreswan KLIPS IPsec stack version: 3.5 
> > > [ 122.211792] NET: Registered protocol family 15 
> > > [ 122.224600] registered KLIPS /proc/sys/net 
> > > [ 122.224603] klips_info:ipsec_alg_init: KLIPS alg v=0.8.1-0 (EALG_MAX=255, AALG_MAX=255) 
> > > [ 122.224606] klips_info:ipsec_alg_init: calling ipsec_alg_static_init() 
> > > [ 122.224613] ipsec_aes_init(alg_type=15 alg_id=12 name=aes): ret=0 
> > > [ 122.224620] ipsec_aes_init(alg_type=14 alg_id=9 name=aes_mac): ret=0 
> > > [ 122.224634] ipsec_3des_init(alg_type=15 alg_id=3 name=3des): ret=0 
> > > [ 122.243327] KLIPS cryptoapi interface: alg_type=15 alg_id=12 name=cbc(aes) keyminbits=128 keymaxbits=256, found(0) 
> > > [ 122.243337] KLIPS cryptoapi interface: alg_type=15 alg_id=253 name=cbc(twofish) keyminbits=128 keymaxbits=256, found(0) 
> > > [ 122.262324] KLIPS cryptoapi interface: alg_type=15 alg_id=252 name=cbc(serpent) keyminbits=128 keymaxbits=256, found(0) 
> > > [ 122.281322] KLIPS cryptoapi interface: alg_type=15 alg_id=6 name=cbc(cast5) keyminbits=128 keymaxbits=128, found(0) 
> > > [ 122.281332] KLIPS cryptoapi interface: alg_type=15 alg_id=7 name=cbc(blowfish) keyminbits=96 keymaxbits=448, found(0) 
> > > [ 122.298314] KLIPS cryptoapi interface: alg_type=15 alg_id=3 name=cbc(des3_ede) keyminbits=192 keymaxbits=192, found(0) 
> > > [ 122.423733] 
> > > [ 125.217139] ------------[ cut here ]------------ 
> > > [ 125.217246] kernel BUG at include/linux/scatterlist.h:65! 
> > > [ 125.217322] invalid opcode: 0000 [#1] SMP 
> > > [ 125.217434] CPU 0 
> > > [ 125.217476] Modules linked in: ipsec(O) camellia lzo cast6 cast5 deflate zlib_deflate cts gcm ccm serpent blowfish_generic blowfish_x86_64 blowfish_common twofish_generic twofish_x86_64_3way twofish_x86_64 twofish_common xcbc sha256_generic sha512_generic des_generic timeriomem_rng virtio_rng ipt_LOG xt_limit ipt_MASQUERADE xt_recent iptable_rawpost(O) xt_geoip(O) xt_comment iptable_nat xt_addrtype xt_NFLOG nfnetlink_log xt_mark iptable_mangle xt_helper iptable_raw xt_multiport xt_conntrack nf_nat_tftp nf_nat_snmp_basic nf_conntrack_snmp nf_nat_pptp nf_nat_proto_gre nf_nat_irc nf_nat_h323 nf_nat_ftp nf_nat_amanda nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 ts_kmp nf_conntrack_amanda nf_conntrack_sane nf_conntrack_tftp nf_conntrack_proto_udplite nf_conntrack_proto_sctp nf_conntrack_pptp nf_conntrack_proto_gre nf_conntrack_netlink nfnetlink nf_conntrack_netbios_ns nf_conntrack_broadcast nf_conntrack_irc nf_conntrack_h323 nf_conntrack_ftp nf_conntrack xpp_usb(O) xpp(O) wctc4xxp(O) dahdi_transcode(O) wcb4xxp(O) wctdm(O) wcfxo(O) wctdm24xxp(O) wcte11xp(O) wct1xxp(O) wcte12xp(O) dahdi_voicebus(O) wct4xxp(O) dahdi(O) crc_ccitt ip_gre gre vmci(O) binfmt_misc l2tp_ppp pppox ppp_generic slhc l2tp_netlink l2tp_core ppdev joydev e1000 vmw_balloon parport_pc parport i2c_piix4 i2c_core shpchp mptspi mptscsih mptbase scsi_transport_spi [last unloaded: scsi_wait_scan] 
> > > [ 125.221900] 
> > > [ 125.221968] Pid: 0, comm: swapper/0 Tainted: G O 3.2.2-10.nl.el6.x86_64 #1 VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform 
> > > [ 125.222271] RIP: 0010:[<ffffffffa04141d2>] [<ffffffffa04141d2>] _capi_cbc_encrypt+0x1a2/0x1f0 [ipsec] 
> > > [ 125.222480] RSP: 0018:ffff880079603860 EFLAGS: 00010293 
> > > [ 125.222587] RAX: ffffea0001d0f1c0 RBX: ffff880075741ab8 RCX: 0000000087654321 
> > > [ 125.222713] RDX: 0000000000000000 RSI: ffff8800743c749a RDI: ffff8800743c74a2 
> > > [ 125.222838] RBP: ffff880079603920 R08: 1b784d5c6042031a R09: 1b784d5c6042031a 
> > > [ 125.222964] R10: ffff8800743c74a2 R11: 0000000000000005 R12: ffff880079603870 
> > > [ 125.223089] R13: 0000000000000048 R14: ffff8800743c74a2 R15: ffff8800796038a0 
> > > [ 125.223215] FS: 0000000000000000(0000) GS:ffff880079600000(0000) knlGS:0000000000000000 
> > > [ 125.223379] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b 
> > > [ 125.223490] CR2: 00007fffa721d140 CR3: 0000000037cc7000 CR4: 00000000000006f0 
> > > [ 125.223645] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 
> > > [ 125.223790] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 
> > > [ 125.223917] Process swapper/0 (pid: 0, threadinfo ffffffff81c00000, task ffffffff81c0d020) 
> > > [ 125.224079] Stack: 
> > > [ 125.224159] 0000000000000000 0000000000000000 1b784d5c6042031a 0000000000000000 
> > > [ 125.224423] 0000000000000000 0000000000000000 0000000000000000 0000000000000000 
> > > [ 125.224686] 0000000000000000 0000000000000000 0000000000000000 0000000000000000 
> > > [ 125.224949] Call Trace: 
> > > [ 125.225025] <IRQ> 
> > > [ 125.225133] [<ffffffffa040c9b3>] ipsec_alg_esp_encrypt+0x73/0x160 [ipsec] 
> > > [ 125.225262] [<ffffffffa0408048>] ipsec_rcv_esp_decrypt+0x88/0x130 [ipsec] 
> > > [ 125.225390] [<ffffffffa03f3172>] ipsec_rcv_decrypt+0x32/0x60 [ipsec] 
> > > [ 125.225513] [<ffffffffa03f5349>] ipsec_rsm+0x69/0x350 [ipsec] 
> > > [ 125.225629] [<ffffffff8157e9f0>] ? ip_rcv_finish+0x5e0/0x5e0 
> > > [ 125.225745] [<ffffffffa03f57b5>] ipsec_rcv+0x35/0xb0 [ipsec] 
> > > [ 125.225858] [<ffffffff8157eb0d>] ip_local_deliver_finish+0x11d/0x400 
> > > [ 125.225977] [<ffffffff8157ea3c>] ? ip_local_deliver_finish+0x4c/0x400 
> > > [ 125.226098] [<ffffffff8157e1f0>] ip_local_deliver+0x80/0x90 
> > > [ 125.226213] [<ffffffff8157e582>] ip_rcv_finish+0x172/0x5e0 
> > > [ 125.226324] [<ffffffff8157e098>] ip_rcv+0x238/0x310 
> > > [ 125.226429] [<ffffffff81541320>] __netif_receive_skb+0x2a0/0x840 
> > > [ 125.226545] [<ffffffff81541185>] ? __netif_receive_skb+0x105/0x840 
> > > [ 125.226662] [<ffffffff81541fda>] ? netif_receive_skb+0x2a/0x120 
> > > [ 125.226777] [<ffffffff815420be>] netif_receive_skb+0x10e/0x120 
> > > [ 125.226891] [<ffffffff81541fda>] ? netif_receive_skb+0x2a/0x120 
> > > [ 125.227006] [<ffffffff8154257d>] ? dev_gro_receive+0x23d/0x390 
> > > [ 125.227119] [<ffffffff8154248e>] ? dev_gro_receive+0x14e/0x390 
> > > [ 125.227233] [<ffffffff81542120>] napi_skb_finish+0x50/0x70 
> > > [ 125.227344] [<ffffffff81542795>] napi_gro_receive+0xc5/0xd0 
> > > [ 125.227465] [<ffffffffa00706ae>] e1000_receive_skb+0x6e/0x90 [e1000] 
> > > [ 125.227589] [<ffffffffa0073c9a>] e1000_clean_rx_irq+0x2fa/0x590 [e1000] 
> > > [ 125.227717] [<ffffffffa0072a8e>] e1000_clean+0x1de/0x550 [e1000] 
> > > [ 125.227834] [<ffffffff8131892c>] ? debug_object_activate+0x5c/0x160 
> > > [ 125.227953] [<ffffffff8131892c>] ? debug_object_activate+0x5c/0x160 
> > > [ 125.228074] [<ffffffff8101b8ef>] ? update_vsyscall+0x4f/0x130 
> > > [ 125.228188] [<ffffffff81542995>] net_rx_action+0x145/0x3c0 
> > > [ 125.228300] [<ffffffff810815b0>] __do_softirq+0xf0/0x390 
> > > [ 125.228410] [<ffffffff816731fc>] call_softirq+0x1c/0x30 
> > > [ 125.228518] [<ffffffff8101842d>] do_softirq+0xad/0xe0 
> > > [ 125.228624] [<ffffffff810810e5>] irq_exit+0xf5/0x110 
> > > [ 125.228730] [<ffffffff81673ad6>] do_IRQ+0x66/0xe0 
> > > [ 125.228833] [<ffffffff81668733>] common_interrupt+0x73/0x73 
> > > [ 125.228943] <EOI> 
> > > [ 125.229045] [<ffffffff8101fadf>] ? default_idle+0x4f/0x340 
> > > [ 125.229156] [<ffffffff810414ab>] ? native_safe_halt+0xb/0x10 
> > > [ 125.229269] [<ffffffff810bae7d>] ? trace_hardirqs_on+0xd/0x10 
> > > [ 125.229382] [<ffffffff8101fae4>] default_idle+0x54/0x340 
> > > [ 125.229491] [<ffffffff81016136>] cpu_idle+0xe6/0x130 
> > > [ 125.229597] [<ffffffff8164c95b>] rest_init+0xdb/0xf0 
> > > [ 125.229703] [<ffffffff8164c880>] ? csum_partial_copy_generic+0x170/0x170 
> > > [ 125.229827] [<ffffffff81ecbdaa>] start_kernel+0x3f3/0x3fe 
> > > [ 125.229936] [<ffffffff81ecb346>] x86_64_start_reservations+0x131/0x135 
> > > [ 125.230057] [<ffffffff81ecb44d>] x86_64_start_kernel+0x103/0x112 
> > > [ 125.230172] Code: 5f c9 c3 66 0f 1f 44 00 00 44 89 e9 4c 89 fa 4c 89 fe ff 53 18 89 c3 eb b7 e8 3b 55 c6 e0 0f 0b eb fe 0f 0b 0f 1f 44 00 00 eb f9 <0f> 0b eb fe 8b 95 7c ff ff ff 4d 89 f9 45 89 e8 4c 89 f1 48 89 
> > > [ 125.232246] RIP [<ffffffffa04141d2>] _capi_cbc_encrypt+0x1a2/0x1f0 [ipsec] 
> > > [ 125.232403] RSP <ffff880079603860> 
> > > 
> > > crash> bt 
> > > PID: 0 TASK: ffffffff81c0d020 CPU: 0 COMMAND: "swapper/0" 
> > > #0 [ffff880079603510] machine_kexec at ffffffff8103c27e 
> > > #1 [ffff880079603580] crash_kexec at ffffffff810d63a2 
> > > #2 [ffff880079603650] oops_end at ffffffff81669638 
> > > #3 [ffff880079603680] die at ffffffff8101982b 
> > > #4 [ffff8800796036b0] do_trap at ffffffff81668ff4 
> > > #5 [ffff880079603710] do_invalid_op at ffffffff81017775 
> > > #6 [ffff8800796037b0] invalid_op at ffffffff81672f7b 
> > > [exception RIP: _capi_cbc_encrypt+418] 
> > > RIP: ffffffffa04141d2 RSP: ffff880079603860 RFLAGS: 00010293 
> > > RAX: ffffea0001d0f1c0 RBX: ffff880075741ab8 RCX: 0000000087654321 
> > > RDX: 0000000000000000 RSI: ffff8800743c749a RDI: ffff8800743c74a2 
> > > RBP: ffff880079603920 R8: 1b784d5c6042031a R9: 1b784d5c6042031a 
> > > R10: ffff8800743c74a2 R11: 0000000000000005 R12: ffff880079603870 
> > > R13: 0000000000000048 R14: ffff8800743c74a2 R15: ffff8800796038a0 
> > > ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018 
> > > #7 [ffff880079603928] ipsec_alg_esp_encrypt at ffffffffa040c9b3 [ipsec] 
> > > #8 [ffff880079603988] ipsec_rcv_esp_decrypt at ffffffffa0408048 [ipsec] 
> > > #9 [ffff8800796039c8] ipsec_rcv_decrypt at ffffffffa03f3172 [ipsec] 
> > > #10 [ffff8800796039e8] ipsec_rsm at ffffffffa03f5349 [ipsec] 
> > > #11 [ffff880079603a08] ipsec_rcv at ffffffffa03f57b5 [ipsec] 
> > > #12 [ffff880079603a28] ip_local_deliver_finish at ffffffff8157eb0d 
> > > #13 [ffff880079603a78] ip_local_deliver at ffffffff8157e1f0 
> > > #14 [ffff880079603aa8] ip_rcv_finish at ffffffff8157e582 
> > > #15 [ffff880079603ad8] ip_rcv at ffffffff8157e098 
> > > #16 [ffff880079603b18] __netif_receive_skb at ffffffff81541320 
> > > #17 [ffff880079603b98] netif_receive_skb at ffffffff815420be 
> > > #18 [ffff880079603bf8] napi_skb_finish at ffffffff81542120 
> > > #19 [ffff880079603c18] napi_gro_receive at ffffffff81542795 
> > > #20 [ffff880079603c38] e1000_receive_skb at ffffffffa00706ae [e1000] 
> > > #21 [ffff880079603c68] e1000_clean_rx_irq at ffffffffa0073c9a [e1000] 
> > > #22 [ffff880079603d38] e1000_clean at ffffffffa0072a8e [e1000] 
> > > #23 [ffff880079603e18] net_rx_action at ffffffff81542995 
> > > #24 [ffff880079603e98] __do_softirq at ffffffff810815b0 
> > > #25 [ffff880079603f28] call_softirq at ffffffff816731fc 
> > > #26 [ffff880079603f40] do_softirq at ffffffff8101842d 
> > > #27 [ffff880079603f60] irq_exit at ffffffff810810e5 
> > > #28 [ffff880079603f80] do_IRQ at ffffffff81673ad6 
> > > --- <IRQ stack> --- 
> > > #29 [ffffffff81c01de8] ret_from_intr at ffffffff81668733 
> > > [exception RIP: native_safe_halt+11] 
> > > RIP: ffffffff810414ab RSP: ffffffff81c01e98 RFLAGS: 00000246 
> > > RAX: 0000000000000000 RBX: ffffffff81c00000 RCX: 0000000000000001 
> > > RDX: ffffffff81c0d020 RSI: 0000000000000001 RDI: ffffffff8101fadf 
> > > RBP: ffffffff81c01e98 R8: 0000000000000000 R9: 0000000000000000 
> > > R10: 0000000000000000 R11: 0000000000000001 R12: 0000000000000046 
> > > R13: 0000000000000001 R14: ffffffff8166c60b R15: ffffffff81c01e38 
> > > ORIG_RAX: ffffffffffffff4d CS: 0010 SS: 0018 
> > > #30 [ffffffff81c01e90] trace_hardirqs_on at ffffffff810bae7d 
> > > #31 [ffffffff81c01ea0] default_idle at ffffffff8101fae4 
> > > #32 [ffffffff81c01ec0] cpu_idle at ffffffff81016136 
> > 
> > 
> > -- 
> > David McCullough, davidm at spottygum.com, Ph: 0410 560 763 
> > 
> 
> -- 
> David McCullough, davidm at spottygum.com, Ph: 0410 560 763 
> 

> [root at eusipgw01 ~]# cat /usr/src/kernels/3.2.2-10.nl.el6.x86_64/include/linux/scatterlist.h
> #ifndef _LINUX_SCATTERLIST_H
> #define _LINUX_SCATTERLIST_H
> 
> #include <asm/types.h>
> #include <asm/scatterlist.h>
> #include <linux/mm.h>
> #include <linux/string.h>
> #include <asm/io.h>
> 
> struct sg_table {
> 	struct scatterlist *sgl;	/* the list */
> 	unsigned int nents;		/* number of mapped entries */
> 	unsigned int orig_nents;	/* original size of list */
> };
> 
> /*
>  * Notes on SG table design.
>  *
>  * Architectures must provide an unsigned long page_link field in the
>  * scatterlist struct. We use that to place the page pointer AND encode
>  * information about the sg table as well. The two lower bits are reserved
>  * for this information.
>  *
>  * If bit 0 is set, then the page_link contains a pointer to the next sg
>  * table list. Otherwise the next entry is at sg + 1.
>  *
>  * If bit 1 is set, then this sg entry is the last element in a list.
>  *
>  * See sg_next().
>  *
>  */
> 
> #define SG_MAGIC	0x87654321
> 
> /*
>  * We overload the LSB of the page pointer to indicate whether it's
>  * a valid sg entry, or whether it points to the start of a new scatterlist.
>  * Those low bits are there for everyone! (thanks mason :-)
>  */
> #define sg_is_chain(sg)		((sg)->page_link & 0x01)
> #define sg_is_last(sg)		((sg)->page_link & 0x02)
> #define sg_chain_ptr(sg)	\
> 	((struct scatterlist *) ((sg)->page_link & ~0x03))
> 
> /**
>  * sg_assign_page - Assign a given page to an SG entry
>  * @sg:		    SG entry
>  * @page:	    The page
>  *
>  * Description:
>  *   Assign page to sg entry. Also see sg_set_page(), the most commonly used
>  *   variant.
>  *
>  **/
> static inline void sg_assign_page(struct scatterlist *sg, struct page *page)
> {
> 	unsigned long page_link = sg->page_link & 0x3;
> 
> 	/*
> 	 * In order for the low bit stealing approach to work, pages
> 	 * must be aligned at a 32-bit boundary as a minimum.
> 	 */
> 	BUG_ON((unsigned long) page & 0x03);
> #ifdef CONFIG_DEBUG_SG
> 	BUG_ON(sg->sg_magic != SG_MAGIC);
> 	BUG_ON(sg_is_chain(sg));
> #endif
> 	sg->page_link = page_link | (unsigned long) page;
> }
> 
> /**
>  * sg_set_page - Set sg entry to point at given page
>  * @sg:		 SG entry
>  * @page:	 The page
>  * @len:	 Length of data
>  * @offset:	 Offset into page
>  *
>  * Description:
>  *   Use this function to set an sg entry pointing at a page, never assign
>  *   the page directly. We encode sg table information in the lower bits
>  *   of the page pointer. See sg_page() for looking up the page belonging
>  *   to an sg entry.
>  *
>  **/
> static inline void sg_set_page(struct scatterlist *sg, struct page *page,
> 			       unsigned int len, unsigned int offset)
> {
> 	sg_assign_page(sg, page);
> 	sg->offset = offset;
> 	sg->length = len;
> }
> 
> static inline struct page *sg_page(struct scatterlist *sg)
> {
> #ifdef CONFIG_DEBUG_SG
> 	BUG_ON(sg->sg_magic != SG_MAGIC);
> 	BUG_ON(sg_is_chain(sg));
> #endif
> 	return (struct page *)((sg)->page_link & ~0x3);
> }
> 
> /**
>  * sg_set_buf - Set sg entry to point at given data
>  * @sg:		 SG entry
>  * @buf:	 Data
>  * @buflen:	 Data length
>  *
>  **/
> static inline void sg_set_buf(struct scatterlist *sg, const void *buf,
> 			      unsigned int buflen)
> {
> 	sg_set_page(sg, virt_to_page(buf), buflen, offset_in_page(buf));
> }
> 
> /*
>  * Loop over each sg element, following the pointer to a new list if necessary
>  */
> #define for_each_sg(sglist, sg, nr, __i)	\
> 	for (__i = 0, sg = (sglist); __i < (nr); __i++, sg = sg_next(sg))
> 
> /**
>  * sg_chain - Chain two sglists together
>  * @prv:	First scatterlist
>  * @prv_nents:	Number of entries in prv
>  * @sgl:	Second scatterlist
>  *
>  * Description:
>  *   Links @prv@ and @sgl@ together, to form a longer scatterlist.
>  *
>  **/
> static inline void sg_chain(struct scatterlist *prv, unsigned int prv_nents,
> 			    struct scatterlist *sgl)
> {
> #ifndef ARCH_HAS_SG_CHAIN
> 	BUG();
> #endif
> 
> 	/*
> 	 * offset and length are unused for chain entry.  Clear them.
> 	 */
> 	prv[prv_nents - 1].offset = 0;
> 	prv[prv_nents - 1].length = 0;
> 
> 	/*
> 	 * Set lowest bit to indicate a link pointer, and make sure to clear
> 	 * the termination bit if it happens to be set.
> 	 */
> 	prv[prv_nents - 1].page_link = ((unsigned long) sgl | 0x01) & ~0x02;
> }
> 
> /**
>  * sg_mark_end - Mark the end of the scatterlist
>  * @sg:		 SG entryScatterlist
>  *
>  * Description:
>  *   Marks the passed in sg entry as the termination point for the sg
>  *   table. A call to sg_next() on this entry will return NULL.
>  *
>  **/
> static inline void sg_mark_end(struct scatterlist *sg)
> {
> #ifdef CONFIG_DEBUG_SG
> 	BUG_ON(sg->sg_magic != SG_MAGIC);
> #endif
> 	/*
> 	 * Set termination bit, clear potential chain bit
> 	 */
> 	sg->page_link |= 0x02;
> 	sg->page_link &= ~0x01;
> }
> 
> /**
>  * sg_phys - Return physical address of an sg entry
>  * @sg:	     SG entry
>  *
>  * Description:
>  *   This calls page_to_phys() on the page in this sg entry, and adds the
>  *   sg offset. The caller must know that it is legal to call page_to_phys()
>  *   on the sg page.
>  *
>  **/
> static inline dma_addr_t sg_phys(struct scatterlist *sg)
> {
> 	return page_to_phys(sg_page(sg)) + sg->offset;
> }
> 
> /**
>  * sg_virt - Return virtual address of an sg entry
>  * @sg:      SG entry
>  *
>  * Description:
>  *   This calls page_address() on the page in this sg entry, and adds the
>  *   sg offset. The caller must know that the sg page has a valid virtual
>  *   mapping.
>  *
>  **/
> static inline void *sg_virt(struct scatterlist *sg)
> {
> 	return page_address(sg_page(sg)) + sg->offset;
> }
> 
> struct scatterlist *sg_next(struct scatterlist *);
> struct scatterlist *sg_last(struct scatterlist *s, unsigned int);
> void sg_init_table(struct scatterlist *, unsigned int);
> void sg_init_one(struct scatterlist *, const void *, unsigned int);
> 
> typedef struct scatterlist *(sg_alloc_fn)(unsigned int, gfp_t);
> typedef void (sg_free_fn)(struct scatterlist *, unsigned int);
> 
> void __sg_free_table(struct sg_table *, unsigned int, sg_free_fn *);
> void sg_free_table(struct sg_table *);
> int __sg_alloc_table(struct sg_table *, unsigned int, unsigned int, gfp_t,
> 		     sg_alloc_fn *);
> int sg_alloc_table(struct sg_table *, unsigned int, gfp_t);
> 
> size_t sg_copy_from_buffer(struct scatterlist *sgl, unsigned int nents,
> 			   void *buf, size_t buflen);
> size_t sg_copy_to_buffer(struct scatterlist *sgl, unsigned int nents,
> 			 void *buf, size_t buflen);
> 
> /*
>  * Maximum number of entries that will be allocated in one piece, if
>  * a list larger than this is required then chaining will be utilized.
>  */
> #define SG_MAX_SINGLE_ALLOC		(PAGE_SIZE / sizeof(struct scatterlist))
> 
> 
> /*
>  * Mapping sg iterator
>  *
>  * Iterates over sg entries mapping page-by-page.  On each successful
>  * iteration, @miter->page points to the mapped page and
>  * @miter->length bytes of data can be accessed at @miter->addr.  As
>  * long as an interation is enclosed between start and stop, the user
>  * is free to choose control structure and when to stop.
>  *
>  * @miter->consumed is set to @miter->length on each iteration.  It
>  * can be adjusted if the user can't consume all the bytes in one go.
>  * Also, a stopped iteration can be resumed by calling next on it.
>  * This is useful when iteration needs to release all resources and
>  * continue later (e.g. at the next interrupt).
>  */
> 
> #define SG_MITER_ATOMIC		(1 << 0)	 /* use kmap_atomic */
> #define SG_MITER_TO_SG		(1 << 1)	/* flush back to phys on unmap */
> #define SG_MITER_FROM_SG	(1 << 2)	/* nop */
> 
> struct sg_mapping_iter {
> 	/* the following three fields can be accessed directly */
> 	struct page		*page;		/* currently mapped page */
> 	void			*addr;		/* pointer to the mapped area */
> 	size_t			length;		/* length of the mapped area */
> 	size_t			consumed;	/* number of consumed bytes */
> 
> 	/* these are internal states, keep away */
> 	struct scatterlist	*__sg;		/* current entry */
> 	unsigned int		__nents;	/* nr of remaining entries */
> 	unsigned int		__offset;	/* offset within sg */
> 	unsigned int		__flags;
> };
> 
> void sg_miter_start(struct sg_mapping_iter *miter, struct scatterlist *sgl,
> 		    unsigned int nents, unsigned int flags);
> bool sg_miter_next(struct sg_mapping_iter *miter);
> void sg_miter_stop(struct sg_mapping_iter *miter);
> 
> #endif /* _LINUX_SCATTERLIST_H */


-- 
David McCullough,  davidm at spottygum.com,   Ph: 0410 560 763
-------------- next part --------------
A non-text attachment was scrubbed...
Name: libreswan-cryptoapi.patch
Type: text/x-diff
Size: 494 bytes
Desc: not available
URL: <https://lists.libreswan.org/pipermail/swan/attachments/20131022/694d18f5/attachment.bin>


More information about the Swan mailing list