1. 24 Aug, 2016 7 commits
  2. 16 Aug, 2016 10 commits
  3. 09 Aug, 2016 23 commits
    • Romain Perier's avatar
      crypto: marvell - Don't hardcode block size in mv_cesa_ahash_cache_req · 47856204
      Romain Perier authored
      Don't use 64 'as is', as max block size in mv_cesa_ahash_cache_req. Use
      CESA_MAX_HASH_BLOCK_SIZE instead, this is better for readability.
      Signed-off-by: default avatarRomain Perier <romain.perier@free-electrons.com>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      47856204
    • Romain Perier's avatar
      crypto: marvell - Don't overwrite default creq->state during initialization · 57cfda1a
      Romain Perier authored
      Currently, in mv_cesa_{md5,sha1,sha256}_init creq->state is initialized
      before the call to mv_cesa_ahash_init. This is wrong because this
      function fills creq with zero by using memset, so its 'state' that
      contains the default DIGEST is overwritten. This commit fixes the issue
      by initializing creq->state just after the call to mv_cesa_ahash_init.
      
      Fixes: commit b0ef5106 ("crypto: marvell/cesa - initialize hash...")
      Signed-off-by: default avatarRomain Perier <romain.perier@free-electrons.com>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      57cfda1a
    • Romain Perier's avatar
      crypto: marvell - Update transformation context for each dequeued req · 09951d83
      Romain Perier authored
      So far, sub part of mv_cesa_int was responsible of dequeuing complete
      requests, then call the 'cleanup' operation on these reqs and call the
      crypto api callback 'complete'. The problem is that the transformation
      context 'ctx' is retrieved only once before the while loop. Which means
      that the wrong 'cleanup' operation might be called on the wrong type of
      cesa requests, it can lead to memory corruptions with this message:
      
      marvell-cesa f1090000.crypto: dma_pool_free cesa_padding, 5a5a5a5a/5a5a5a5a (bad dma)
      
      This commit fixes the issue, by updating the transformation context for
      each dequeued cesa request.
      
      Fixes: commit 85030c51 ("crypto: marvell - Add support for chai...")
      Signed-off-by: default avatarRomain Perier <romain.perier@free-electrons.com>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      09951d83
    • Thomas Petazzoni's avatar
      crypto: marvell - make mv_cesa_ahash_cache_req() return bool · 6dc156f4
      Thomas Petazzoni authored
      The mv_cesa_ahash_cache_req() function always returns 0, which makes
      its return value pretty much useless. However, in addition to
      returning a useless value, it also returns a boolean in a variable
      passed by reference to indicate if the request was already cached.
      
      So, this commit changes mv_cesa_ahash_cache_req() to return this
      boolean. It consequently simplifies the only call site of
      mv_cesa_ahash_cache_req(), where the "ret" variable is no longer
      needed.
      Signed-off-by: default avatarThomas Petazzoni <thomas.petazzoni@free-electrons.com>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      6dc156f4
    • Thomas Petazzoni's avatar
      crypto: marvell - turn mv_cesa_ahash_init() into a function returning void · 3e5c66c9
      Thomas Petazzoni authored
      The mv_cesa_ahash_init() function always returns 0, and the return
      value is anyway never checked. Turn it into a function returning void.
      Signed-off-by: default avatarThomas Petazzoni <thomas.petazzoni@free-electrons.com>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      3e5c66c9
    • Thomas Petazzoni's avatar
      crypto: marvell - remove unused parameter in mv_cesa_ahash_dma_add_cache() · 2a8a7857
      Thomas Petazzoni authored
      The dma_iter parameter of mv_cesa_ahash_dma_add_cache() is never used,
      so get rid of it.
      Signed-off-by: default avatarThomas Petazzoni <thomas.petazzoni@free-electrons.com>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      2a8a7857
    • Thomas Petazzoni's avatar
      crypto: marvell - be explicit about destination in mv_cesa_dma_add_op() · 36225b91
      Thomas Petazzoni authored
      The mv_cesa_dma_add_op() function builds a mv_cesa_tdma_desc structure
      to copy the operation description to the SRAM, but doesn't explicitly
      initialize the destination of the copy. It works fine because the
      operatin description must be copied at the beginning of the SRAM, and
      the mv_cesa_tdma_desc structure is initialized to zero when
      allocated. However, it is somewhat confusing to not have a destination
      defined.
      Signed-off-by: default avatarThomas Petazzoni <thomas.petazzoni@free-electrons.com>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      36225b91
    • Russell King's avatar
      crypto: caam - avoid kernel warnings on probe failure · bdc67da7
      Russell King authored
      While debugging setkey issues, the following warnings were found while
      trying to reinsert the caam module.  Fix this by avoiding the duplicated
      cleanup in the probe path after caam_remove(), which has already cleaned
      up the resources.
      
      ------------[ cut here ]------------
      WARNING: CPU: 0 PID: 2346 at /home/rmk/git/linux-rmk/mm/vmalloc.c:1490 __vunmap+0xcc/0xf4
      Trying to vfree() nonexistent vm area (f2400000)
      Modules linked in: caam(+) cbc rfcomm bnep bluetooth nfsd em28xx_rc si2157 si2168 em28xx_dvb uvcvideo snd_soc_imx_sgtl5000 em28xx snd_soc_imx_spdif tveeprom snd_soc_fsl_asoc_card snd_soc_imx_audmux snd_soc_sgtl5000 imx_sdma imx2_wdt coda v4l2_mem2mem videobuf2_dma_contig snd_soc_fsl_ssi rc_cec snd_soc_fsl_spdif imx_pcm_dma videobuf2_vmalloc videobuf2_memops imx_thermal dw_hdmi_ahb_audio dw_hdmi_cec etnaviv fuse rc_pinnacle_pctv_hd [last unloaded: caam]
      CPU: 0 PID: 2346 Comm: modprobe Tainted: G        W       4.8.0-rc1+ #2014
      Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
      Backtrace:
      [<c0013bb0>] (dump_backtrace) from [<c0013d4c>] (show_stack+0x18/0x1c)
      [<c0013d34>] (show_stack) from [<c0357c00>] (dump_stack+0xa4/0xdc)
      [<c0357b5c>] (dump_stack) from [<c002e650>] (__warn+0xdc/0x108)
      [<c002e574>] (__warn) from [<c002e734>] (warn_slowpath_fmt+0x40/0x48)
      [<c002e6f8>] (warn_slowpath_fmt) from [<c0151708>] (__vunmap+0xcc/0xf4)
      [<c015163c>] (__vunmap) from [<c015177c>] (vunmap+0x4c/0x54)
      [<c0151730>] (vunmap) from [<c001f48c>] (__iounmap+0x2c/0x30)
      [<c001f460>] (__iounmap) from [<c001f118>] (iounmap+0x1c/0x20)
      [<c001f0fc>] (iounmap) from [<bf247ae4>] (caam_probe+0x3dc/0x1498 [caam])
      [<bf247708>] (caam_probe [caam]) from [<c042da8c>] (platform_drv_probe+0x58/0xb8)
      [<c042da34>] (platform_drv_probe) from [<c042bb4c>] (driver_probe_device+0x1fc/0x2b8)
      [<c042b950>] (driver_probe_device) from [<c042bcc4>] (__driver_attach+0xbc/0xc0) r10:00000000 r8:bf24b000 r7:00000000 r6:ef215844 r5:bf2490c4 r4:ef215810
      [<c042bc08>] (__driver_attach) from [<c0429f14>] (bus_for_each_dev+0x5c/0x90)
      [<c0429eb8>] (bus_for_each_dev) from [<c042b358>] (driver_attach+0x24/0x28)
      [<c042b334>] (driver_attach) from [<c042b058>] (bus_add_driver+0xf4/0x200)
      [<c042af64>] (bus_add_driver) from [<c042cadc>] (driver_register+0x80/0xfc)
      [<c042ca5c>] (driver_register) from [<c042d960>] (__platform_driver_register+0x48/0x4c)
      [<c042d918>] (__platform_driver_register) from [<bf24b018>] (caam_driver_init+0x18/0x24 [caam])
      [<bf24b000>] (caam_driver_init [caam]) from [<c00098ac>] (do_one_initcall+0x44/0x178)
      [<c0009868>] (do_one_initcall) from [<c010e034>] (do_init_module+0x68/0x1d8)
      [<c010dfcc>] (do_init_module) from [<c00c8fbc>] (load_module+0x1974/0x20b0)
      [<c00c7648>] (load_module) from [<c00c98d0>] (SyS_finit_module+0x94/0xa0)
      [<c00c983c>] (SyS_finit_module) from [<c000fda0>] (ret_fast_syscall+0x0/0x1c)
      ---[ end trace 34e3370d88bb1786 ]---
      ------------[ cut here ]------------
      WARNING: CPU: 0 PID: 2346 at /home/rmk/git/linux-rmk/drivers/clk/clk.c:594 clk_core_disable+0xe4/0x26c
      Modules linked in: caam(+) cbc rfcomm bnep bluetooth nfsd em28xx_rc si2157 si2168 em28xx_dvb uvcvideo snd_soc_imx_sgtl5000 em28xx snd_soc_imx_spdif tveeprom snd_soc_fsl_asoc_card snd_soc_imx_audmux snd_soc_sgtl5000 imx_sdma imx2_wdt coda v4l2_mem2mem videobuf2_dma_contig snd_soc_fsl_ssi rc_cec snd_soc_fsl_spdif imx_pcm_dma videobuf2_vmalloc videobuf2_memops imx_thermal dw_hdmi_ahb_audio dw_hdmi_cec etnaviv fuse rc_pinnacle_pctv_hd [last unloaded: caam]
      CPU: 0 PID: 2346 Comm: modprobe Tainted: G        W       4.8.0-rc1+ #2014
      Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
      Backtrace:
      [<c0013bb0>] (dump_backtrace) from [<c0013d4c>] (show_stack+0x18/0x1c)
      [<c0013d34>] (show_stack) from [<c0357c00>] (dump_stack+0xa4/0xdc)
      [<c0357b5c>] (dump_stack) from [<c002e650>] (__warn+0xdc/0x108)
      [<c002e574>] (__warn) from [<c002e6a4>] (warn_slowpath_null+0x28/0x30)
      [<c002e67c>] (warn_slowpath_null) from [<c05b113c>] (clk_core_disable+0xe4/0x26c)
      [<c05b1058>] (clk_core_disable) from [<c05b2e3c>] (clk_core_disable_lock+0x20/0x2c)
      [<c05b2e1c>] (clk_core_disable_lock) from [<c05b2e6c>] (clk_disable+0x24/0x28)
      [<c05b2e48>] (clk_disable) from [<bf247b04>] (caam_probe+0x3fc/0x1498 [caam])
      [<bf247708>] (caam_probe [caam]) from [<c042da8c>] (platform_drv_probe+0x58/0xb8)
      [<c042da34>] (platform_drv_probe) from [<c042bb4c>] (driver_probe_device+0x1fc/0x2b8)
      [<c042b950>] (driver_probe_device) from [<c042bcc4>] (__driver_attach+0xbc/0xc0) r10:00000000 r8:bf24b000 r7:00000000 r6:ef215844 r5:bf2490c4 r4:ef215810
      [<c042bc08>] (__driver_attach) from [<c0429f14>] (bus_for_each_dev+0x5c/0x90)
      [<c0429eb8>] (bus_for_each_dev) from [<c042b358>] (driver_attach+0x24/0x28)
      [<c042b334>] (driver_attach) from [<c042b058>] (bus_add_driver+0xf4/0x200)
      [<c042af64>] (bus_add_driver) from [<c042cadc>] (driver_register+0x80/0xfc)
      [<c042ca5c>] (driver_register) from [<c042d960>] (__platform_driver_register+0x48/0x4c)
      [<c042d918>] (__platform_driver_register) from [<bf24b018>] (caam_driver_init+0x18/0x24 [caam])
      [<bf24b000>] (caam_driver_init [caam]) from [<c00098ac>] (do_one_initcall+0x44/0x178)
      [<c0009868>] (do_one_initcall) from [<c010e034>] (do_init_module+0x68/0x1d8)
      [<c010dfcc>] (do_init_module) from [<c00c8fbc>] (load_module+0x1974/0x20b0)
      [<c00c7648>] (load_module) from [<c00c98d0>] (SyS_finit_module+0x94/0xa0)
      [<c00c983c>] (SyS_finit_module) from [<c000fda0>] (ret_fast_syscall+0x0/0x1c)
      ---[ end trace 34e3370d88bb1787 ]---
      ------------[ cut here ]------------
      WARNING: CPU: 0 PID: 2346 at /home/rmk/git/linux-rmk/drivers/clk/clk.c:476 clk_core_unprepare+0x204/0x388
      Modules linked in: caam(+) cbc rfcomm bnep bluetooth nfsd em28xx_rc si2157 si2168 em28xx_dvb uvcvideo snd_soc_imx_sgtl5000 em28xx snd_soc_imx_spdif tveeprom snd_soc_fsl_asoc_card snd_soc_imx_audmux snd_soc_sgtl5000 imx_sdma imx2_wdt coda v4l2_mem2mem videobuf2_dma_contig snd_soc_fsl_ssi rc_cec snd_soc_fsl_spdif imx_pcm_dma videobuf2_vmalloc videobuf2_memops imx_thermal dw_hdmi_ahb_audio dw_hdmi_cec etnaviv fuse rc_pinnacle_pctv_hd [last unloaded: caam]
      CPU: 0 PID: 2346 Comm: modprobe Tainted: G        W       4.8.0-rc1+ #2014
      Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
      Backtrace:
      [<c0013bb0>] (dump_backtrace) from [<c0013d4c>] (show_stack+0x18/0x1c)
      [<c0013d34>] (show_stack) from [<c0357c00>] (dump_stack+0xa4/0xdc)
      [<c0357b5c>] (dump_stack) from [<c002e650>] (__warn+0xdc/0x108)
      [<c002e574>] (__warn) from [<c002e6a4>] (warn_slowpath_null+0x28/0x30)
      [<c002e67c>] (warn_slowpath_null) from [<c05b0834>] (clk_core_unprepare+0x204/0x388)
      [<c05b0630>] (clk_core_unprepare) from [<c05b4c0c>] (clk_unprepare+0x2c/0x34)
      [<c05b4be0>] (clk_unprepare) from [<bf247b0c>] (caam_probe+0x404/0x1498 [caam])
      [<bf247708>] (caam_probe [caam]) from [<c042da8c>] (platform_drv_probe+0x58/0xb8)
      [<c042da34>] (platform_drv_probe) from [<c042bb4c>] (driver_probe_device+0x1fc/0x2b8)
      [<c042b950>] (driver_probe_device) from [<c042bcc4>] (__driver_attach+0xbc/0xc0) r10:00000000 r8:bf24b000 r7:00000000 r6:ef215844 r5:bf2490c4 r4:ef215810
      [<c042bc08>] (__driver_attach) from [<c0429f14>] (bus_for_each_dev+0x5c/0x90)
      [<c0429eb8>] (bus_for_each_dev) from [<c042b358>] (driver_attach+0x24/0x28)
      [<c042b334>] (driver_attach) from [<c042b058>] (bus_add_driver+0xf4/0x200)
      [<c042af64>] (bus_add_driver) from [<c042cadc>] (driver_register+0x80/0xfc)
      [<c042ca5c>] (driver_register) from [<c042d960>] (__platform_driver_register+0x48/0x4c)
      [<c042d918>] (__platform_driver_register) from [<bf24b018>] (caam_driver_init+0x18/0x24 [caam])
      [<bf24b000>] (caam_driver_init [caam]) from [<c00098ac>] (do_one_initcall+0x44/0x178)
      [<c0009868>] (do_one_initcall) from [<c010e034>] (do_init_module+0x68/0x1d8)
      [<c010dfcc>] (do_init_module) from [<c00c8fbc>] (load_module+0x1974/0x20b0)
      [<c00c7648>] (load_module) from [<c00c98d0>] (SyS_finit_module+0x94/0xa0)
      [<c00c983c>] (SyS_finit_module) from [<c000fda0>] (ret_fast_syscall+0x0/0x1c)
      ---[ end trace 34e3370d88bb1788 ]---
      Signed-off-by: default avatarRussell King <rmk+kernel@armlinux.org.uk>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      bdc67da7
    • Russell King's avatar
      crypto: caam - get rid of tasklet · 66d2e202
      Russell King authored
      Threaded interrupts can perform the function of the tasklet, and much
      more safely too - without races when trying to take the tasklet and
      interrupt down on device removal.
      
      With the old code, there is a window where we call tasklet_kill().  If
      the interrupt handler happens to be running on a different CPU, and
      subsequently calls tasklet_schedule(), the tasklet will be re-scheduled
      for execution.
      
      Switching to a hardirq/threadirq combination implementation avoids this,
      and it also means generic code deals with the teardown sequencing of the
      threaded and non-threaded parts.
      Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      66d2e202
    • Russell King's avatar
      crypto: caam - add ahash_edesc_add_src() · 65cf164a
      Russell King authored
      Add a helper to map the source scatterlist into the descriptor.
      Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      65cf164a
    • Russell King's avatar
    • Russell King's avatar
      crypto: caam - add ahash_edesc_alloc() for descriptor allocation · 5588d039
      Russell King authored
      Add a helper function to perform the descriptor allocation.
      Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      5588d039
    • Russell King's avatar
      crypto: caam - check and use dma_map_sg() return code · bc13c69e
      Russell King authored
      Strictly, dma_map_sg() may coalesce SG entries, but in practise on iMX
      hardware, this will never happen.  However, dma_map_sg() can fail, and
      we completely fail to check its return value.  So, fix this properly.
      
      Arrange the code to map the scatterlist early, so we know how many
      scatter table entries to allocate, and then fill them in.  This allows
      us to keep relatively simple error cleanup paths.
      Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      bc13c69e
    • Russell King's avatar
      crypto: caam - ensure that we clean up after an error · 32686d34
      Russell King authored
      Ensure that we clean up allocations and DMA mappings after encountering
      an error rather than just giving up and leaking memory and resources.
      Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      32686d34
    • Russell King's avatar
      crypto: caam - replace sec4_sg pointer with array · 343e44b1
      Russell King authored
      Since the extended descriptor includes the hardware descriptor, and the
      sec4 scatterlist immediately follows this, we can declare it as a array
      at the very end of the extended descriptor.  This allows us to get rid
      of an initialiser for every site where we allocate an extended
      descriptor.
      Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      343e44b1
    • Russell King's avatar
      crypto: caam - mark the hardware descriptor as cache line aligned · d7b24ed4
      Russell King authored
      Mark the hardware descriptor as being cache line aligned; on DMA
      incoherent architectures, the hardware descriptor should sit in a
      separate cache line from the CPU accessed data to avoid polluting
      the caches.
      Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      d7b24ed4
    • Russell King's avatar
      crypto: caam - incorporate job descriptor into struct ahash_edesc · 64ce56cb
      Russell King authored
      Rather than giving the descriptor as hw_desc[0], give it's real size.
      All places where we allocate an ahash_edesc incorporate DESC_JOB_IO_LEN
      bytes of job descriptor.
      Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      64ce56cb
    • Russell King's avatar
    • Russell King's avatar
      crypto: caam - fix DMA API mapping leak · 3d5a2db6
      Russell King authored
      caamhash contains this weird code:
      
      	src_nents = sg_count(req->src, req->nbytes);
      	dma_map_sg(jrdev, req->src, src_nents ? : 1, DMA_TO_DEVICE);
      	...
      	edesc->src_nents = src_nents;
      
      sg_count() returns zero when sg_nents_for_len() returns zero or one.
      This means we don't need to use a hardware scatterlist.  However,
      setting src_nents to zero causes problems when we unmap:
      
      	if (edesc->src_nents)
      		dma_unmap_sg_chained(dev, req->src, edesc->src_nents,
      				     DMA_TO_DEVICE, edesc->chained);
      
      as zero here means that we have no entries to unmap.  This causes us
      to leak DMA mappings, where we map one scatterlist entry and then
      fail to unmap it.
      
      This can be fixed in two ways: either by writing the number of entries
      that were requested of dma_map_sg(), or by reworking the "no SG
      required" case.
      
      We adopt the re-work solution here - we replace sg_count() with
      sg_nents_for_len(), so src_nents now contains the real number of
      scatterlist entries, and we then change the test for using the
      hardware scatterlist to src_nents > 1 rather than just non-zero.
      
      This change passes my sshd, openssl tests hashing /bin and tcrypt
      tests.
      Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      3d5a2db6
    • Will Thomas's avatar
      crypto: img-hash - Fix set_reqsize call · 5e38d200
      Will Thomas authored
      Properly allocate enough memory to respect the fallback.
      Signed-off-by: default avatarWill Thomas <will.thomas@imgtec.com>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      5e38d200
    • James Hartley's avatar
      crypto: img-hash - log a successful probe · fb67740e
      James Hartley authored
      Currently the probe function only emits an output on success
      when debug is specifically enabled. It would be more useful
      if this happens by default.
      Signed-off-by: default avatarJames Hartley <james.hartley@imgtec.com>
      Reviewed-by: default avatarWill Thomas <will.thomas@imgtec.com>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      fb67740e
    • James Hartley's avatar
      crypto: img-hash - Add support for export and import · 436e3bb5
      James Hartley authored
      Currently the img-hash accelerator does not probe
      successfully due to a change in the checks made during
      registration with the crypto framework. This is due to
      import and export functions not being defined. Correct
      this.
      Signed-off-by: default avatarJames Hartley <james.hartley@imgtec.com>
      Signed-off-by: default avatarWill Thomas <will.thomas@imgtec.com>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      436e3bb5
    • Govindraj Raja's avatar
      crypto: img-hash - Add suspend resume hooks for img hash · d084e13a
      Govindraj Raja authored
      Current img hash claims sys and periph gate clocks
      and this can be gated in system suspend scenarios.
      
      Add support for Device pm ops for img hash to gate
      the clocks claimed by img hash.
      Signed-off-by: default avatarGovindraj Raja <Govindraj.Raja@imgtec.com>
      Reviewed-by: default avatarWill Thomas <will.thomas@imgtec.com>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      d084e13a