[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH for-4.11 v3.5 1/2] doc: correct livepatch.markdown syntax


  • To: Xen-devel <xen-devel@xxxxxxxxxxxxx>
  • From: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
  • Date: Fri, 18 May 2018 18:35:07 +0100
  • Autocrypt: addr=andrew.cooper3@xxxxxxxxxx; prefer-encrypt=mutual; keydata= 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 6+ahAA==
  • Cc: Juergen Gross <jgross@xxxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Wei Liu <wei.liu2@xxxxxxxxxx>, George Dunlap <george.dunlap@xxxxxxxxxxxxx>, Tim Deegan <tim@xxxxxxx>, Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>, Julien Grall <julien.grall@xxxxxxx>, Jan Beulich <JBeulich@xxxxxxxx>
  • Delivery-date: Fri, 18 May 2018 17:35:32 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Openpgp: preference=signencrypt

Sorry - it appears I mess the CC list up here.  CC'ing "The Rest" for
this combined fixup and cleanup patch for livepatch.markdown, for
inclusion into 4.11

~Andrew

On 08/05/18 10:55, Andrew Cooper wrote:
> From: Juergen Gross <jgross@xxxxxxxx>
>
> "make -C docs all" fails due to incorrect markdown syntax in
> livepatch.markdown. Correct it.
>
> Signed-off-by: Juergen Gross <jgross@xxxxxxxx>
> Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>
>
> Misc fixes:
>  * Insert real URLs
>  * Drop trailing whitespace
>  * Consistent alignment and indentation for code blocks and lists
>  * Consistent capitalisation
>  * Consistent use of `` blocks for command line arguments and function names
>  * Rearrange things not to leave &lt; and &gt; in the text
>
> No change in content.  The document now reads rather more consistently in HTML
> and PDF form.
>
> Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
> ---
>  docs/misc/livepatch.markdown | 693 
> ++++++++++++++++++++-----------------------
>  1 file changed, 320 insertions(+), 373 deletions(-)
>
> diff --git a/docs/misc/livepatch.markdown b/docs/misc/livepatch.markdown
> index 54a6b85..2bdf871 100644
> --- a/docs/misc/livepatch.markdown
> +++ b/docs/misc/livepatch.markdown
> @@ -85,53 +85,42 @@ mechanism. See `Trampoline (e9 opcode)` section for more 
> details.
>  ### Example of trampoline and in-place splicing
>  
>  As example we will assume the hypervisor does not have XSA-132 (see
> -*domctl/sysctl: don't leak hypervisor stack to toolstacks*
> -4ff3449f0e9d175ceb9551d3f2aecb59273f639d) and we would like to binary patch
> -the hypervisor with it. The original code looks as so:
> +[domctl/sysctl: don't leak hypervisor stack to 
> toolstacks](http://xenbits.xen.org/gitweb/?p=xen.git;a=commitdiff;h=4ff3449f0e9d175ceb9551d3f2aecb59273f639d))
> +and we would like to binary patch the hypervisor with it. The original code
> +looks as so:
>  
> -<pre>
> -   48 89 e0                  mov    %rsp,%rax  
> -   48 25 00 80 ff ff         and    $0xffffffffffff8000,%rax  
> -</pre>
> +    48 89 e0                  mov    %rsp,%rax
> +    48 25 00 80 ff ff         and    $0xffffffffffff8000,%rax
>  
>  while the new patched hypervisor would be:
>  
> -<pre>
> -   48 c7 45 b8 00 00 00 00   movq   $0x0,-0x48(%rbp)  
> -   48 c7 45 c0 00 00 00 00   movq   $0x0,-0x40(%rbp)  
> -   48 c7 45 c8 00 00 00 00   movq   $0x0,-0x38(%rbp)  
> -   48 89 e0                  mov    %rsp,%rax  
> -   48 25 00 80 ff ff         and    $0xffffffffffff8000,%rax  
> -</pre>
> +    48 c7 45 b8 00 00 00 00   movq   $0x0,-0x48(%rbp)
> +    48 c7 45 c0 00 00 00 00   movq   $0x0,-0x40(%rbp)
> +    48 c7 45 c8 00 00 00 00   movq   $0x0,-0x38(%rbp)
> +    48 89 e0                  mov    %rsp,%rax
> +    48 25 00 80 ff ff         and    $0xffffffffffff8000,%rax
>  
> -This is inside the arch_do_domctl. This new change adds 21 extra
> +This is inside the arch\_do\_domctl. This new change adds 21 extra
>  bytes of code which alters all the offsets inside the function. To alter
>  these offsets and add the extra 21 bytes of code we might not have enough
>  space in .text to squeeze this in.
>  
>  As such we could simplify this problem by only patching the site
> -which calls arch_do_domctl:
> +which calls arch\_do\_domctl:
>  
> -<pre>
> -do_domctl:  
> - e8 4b b1 05 00          callq  ffff82d08015fbb9 <arch_do_domctl>  
> -</pre>
> +    do_domctl:
> +    e8 4b b1 05 00          callq  ffff82d08015fbb9 <arch_do_domctl>
>  
>  with a new address for where the new `arch_do_domctl` would be (this
>  area would be allocated dynamically).
>  
>  Astute readers will wonder what we need to do if we were to patch `do_domctl`
>  - which is not called directly by hypervisor but on behalf of the guests via
> -the `compat_hypercall_table` and `hypercall_table`.
> -Patching the offset in `hypercall_table` for `do_domctl:
> -(ffff82d080103079 <do_domctl>:)
> +the `compat_hypercall_table` and `hypercall_table`.  Patching the offset in
> +`hypercall_table` for `do_domctl`:
>  
> -<pre>
> -
> - ffff82d08024d490:   79 30  
> - ffff82d08024d492:   10 80 d0 82 ff ff   
> -
> -</pre>
> +    ffff82d08024d490:   79 30
> +    ffff82d08024d492:   10 80 d0 82 ff ff
>  
>  with the new address where the new `do_domctl` is possible. The other
>  place where it is used is in `hvm_hypercall64_table` which would need
> @@ -139,10 +128,11 @@ to be patched in a similar way. This would require an 
> in-place splicing
>  of the new virtual address of `arch_do_domctl`.
>  
>  In summary this example patched the callee of the affected function by
> - * allocating memory for the new code to live in,
> - * changing the virtual address in all the functions which called the old
> +
> + * Allocating memory for the new code to live in,
> + * Changing the virtual address in all the functions which called the old
>     code (computing the new offset, patching the callq with a new callq).
> - * changing the function pointer tables with the new virtual address of
> + * Changing the function pointer tables with the new virtual address of
>     the function (splicing in the new virtual address). Since this table
>     resides in the .rodata section we would need to temporarily change the
>     page table permissions during this part.
> @@ -162,21 +152,18 @@ existing function to be patched to jump directly to the 
> new code. This
>  lessens the locations to be patched to one but it puts pressure on the
>  CPU branching logic (I-cache, but it is just one unconditional jump).
>  
> -For this example we will assume that the hypervisor has not been compiled
> -with fe2e079f642effb3d24a6e1a7096ef26e691d93e (XSA-125: *pre-fill structures
> -for certain HYPERVISOR_xen_version sub-ops*) which mem-sets an structure
> -in `xen_version` hypercall. This function is not called **anywhere** in
> -the hypervisor (it is called by the guest) but referenced in the
> -`compat_hypercall_table` and `hypercall_table` (and indirectly called
> -from that). Patching the offset in `hypercall_table` for the old
> -`do_xen_version` (ffff82d080112f9e <do_xen_version>)
> -
> -</pre>
> - ffff82d08024b270 <hypercall_table>:   
> - ...  
> - ffff82d08024b2f8:   9e 2f 11 80 d0 82 ff ff  
> +For this example we will assume that the hypervisor has not been compiled 
> with
> +XSA-125 (see
> +[pre-fill structures for certain HYPERVISOR\_xen\_version 
> sub-ops](http://xenbits.xen.org/gitweb/?p=xen.git;a=commitdiff;h=fe2e079f642effb3d24a6e1a7096ef26e691d93e))
> +which mem-sets an structure in `xen_version` hypercall. This function is not
> +called **anywhere** in the hypervisor (it is called by the guest) but
> +referenced in the `compat_hypercall_table` and `hypercall_table` (and
> +indirectly called from that). Patching the offset in `hypercall_table` for 
> the
> +old `do_xen_version`:
>  
> -</pre>
> +    ffff82d08024b270 <hypercall_table>:
> +    ...
> +    ffff82d08024b2f8:   9e 2f 11 80 d0 82 ff ff
>  
>  with the new address where the new `do_xen_version` is possible. The other
>  place where it is used is in `hvm_hypercall64_table` which would need
> @@ -184,31 +171,28 @@ to be patched in a similar way. This would require an 
> in-place splicing
>  of the new virtual address of `do_xen_version`.
>  
>  An alternative solution would be to patch insert a trampoline in the
> -old `do_xen_version' function to directly jump to the new `do_xen_version`.
> +old `do_xen_version` function to directly jump to the new `do_xen_version`:
>  
> -<pre>
> - ffff82d080112f9e do_xen_version:  
> - ffff82d080112f9e:       48 c7 c0 da ff ff ff    mov    
> $0xffffffffffffffda,%rax  
> - ffff82d080112fa5:       83 ff 09                cmp    $0x9,%edi  
> - ffff82d080112fa8:       0f 87 24 05 00 00       ja     ffff82d0801134d2 ; 
> do_xen_version+0x534  
> -</pre>
> +    ffff82d080112f9e do_xen_version:
> +    ffff82d080112f9e:       48 c7 c0 da ff ff ff    mov    
> $0xffffffffffffffda,%rax
> +    ffff82d080112fa5:       83 ff 09                cmp    $0x9,%edi
> +    ffff82d080112fa8:       0f 87 24 05 00 00       ja     ffff82d0801134d2 
> ; do_xen_version+0x534
>  
>  with:
>  
> -<pre>
> - ffff82d080112f9e do_xen_version:  
> - ffff82d080112f9e:       e9 XX YY ZZ QQ          jmpq   [new do_xen_version] 
>  
> -</pre>
> +    ffff82d080112f9e do_xen_version:
> +    ffff82d080112f9e:       e9 XX YY ZZ QQ          jmpq   [new 
> do_xen_version]
>  
>  which would lessen the amount of patching to just one location.
>  
>  In summary this example patched the affected function to jump to the
>  new replacement function which required:
> - * allocating memory for the new code to live in,
> - * inserting trampoline with new offset in the old function to point to the
> +
> + * Allocating memory for the new code to live in,
> + * Inserting trampoline with new offset in the old function to point to the
>     new function.
>   * Optionally we can insert in the old function a trampoline jump to an 
> function
> -   providing an BUG_ON to catch errant code.
> +   providing an BUG\_ON to catch errant code.
>  
>  The disadvantage of this are that the unconditional jump will consume a small
>  I-cache penalty. However the simplicity of the patching and higher chance
> @@ -260,7 +244,7 @@ Note that every structure has padding. This is added so 
> that the hypervisor
>  can re-use those fields as it sees fit.
>  
>  Earlier design attempted to ineptly explain the relations of the ELF sections
> -to each other without using proper ELF mechanism (sh_info, sh_link, data
> +to each other without using proper ELF mechanism (sh\_info, sh\_link, data
>  structures using Elf types, etc). This design will explain the structures
>  and how they are used together and not dig in the ELF format - except mention
>  that the section names should match the structure names.
> @@ -285,60 +269,53 @@ like what the Linux kernel module loader does.
>  
>  The payload contains at least three sections:
>  
> - * `.livepatch.funcs` - which is an array of livepatch_func structures.
> + * `.livepatch.funcs` - which is an array of livepatch\_func structures.
>   * `.livepatch.depends` - which is an ELF Note that describes what the 
> payload
>      depends on. **MUST** have one.
>   *  `.note.gnu.build-id` - the build-id of this payload. **MUST** have one.
>  
>  ### .livepatch.funcs
>  
> -The `.livepatch.funcs` contains an array of livepatch_func structures
> +The `.livepatch.funcs` contains an array of livepatch\_func structures
>  which describe the functions to be patched:
>  
> -<pre>
> -struct livepatch_func {  
> -    const char *name;  
> -    void *new_addr;  
> -    void *old_addr;  
> -    uint32_t new_size;  
> -    uint32_t old_size;  
> -    uint8_t version;  
> -    uint8_t opaque[31];  
> -};  
> -</pre>
> +    struct livepatch_func {
> +        const char *name;
> +        void *new_addr;
> +        void *old_addr;
> +        uint32_t new_size;
> +        uint32_t old_size;
> +        uint8_t version;
> +        uint8_t opaque[31];
> +    };
>  
>  The size of the structure is 64 bytes on 64-bit hypervisors. It will be
>  52 on 32-bit hypervisors.
>  
> -* `name` is the symbol name of the old function. Only used if `old_addr` is
> + * `name` is the symbol name of the old function. Only used if `old_addr` is
>     zero, otherwise will be used during dynamic linking (when hypervisor loads
>     the payload).
> -
> -* `old_addr` is the address of the function to be patched and is filled in at
> -  payload generation time if hypervisor function address is known. If 
> unknown,
> -  the value *MUST* be zero and the hypervisor will attempt to resolve the 
> address.
> -
> -* `new_addr` can either have a non-zero value or be zero.
> -  * If there is a non-zero value, then it is the address of the function 
> that is
> -    replacing the old function and the address is recomputed during 
> relocation.
> -    The value **MUST** be the address of the new function in the payload 
> file.
> -
> -  * If the value is zero, then we NOPing out at the `old_addr` location
> + * `old_addr` is the address of the function to be patched and is filled in 
> at
> +   payload generation time if hypervisor function address is known. If 
> unknown,
> +   the value *MUST* be zero and the hypervisor will attempt to resolve the
> +   address.
> + * `new_addr` can either have a non-zero value or be zero.
> +   * If there is a non-zero value, then it is the address of the function 
> that
> +    is replacing the old function and the address is recomputed during
> +    relocation.  The value **MUST** be the address of the new function in the
> +    payload file.
> +   * If the value is zero, then we NOPing out at the `old_addr` location
>      `new_size` bytes.
> -
> -* `old_size` contains the sizes of the respective `old_addr` function in 
> bytes.
> -   The value of `old_size` **MUST** not be zero.
> -
> -* `new_size` depends on what `new_addr` contains:
> -  * If `new_addr` contains an non-zero value, then `new_size` has the size of
> -    the new function (which will replace the one at `old_addr`)  in bytes.
> -  * If the value of `new_addr` is zero then `new_size` determines how many
> + * `old_size` contains the sizes of the respective `old_addr` function in
> +    bytes.  The value of `old_size` **MUST** not be zero.
> + * `new_size` depends on what `new_addr` contains:
> +   * If `new_addr` contains an non-zero value, then `new_size` has the size 
> of
> +    the new function (which will replace the one at `old_addr`) in bytes.
> +   * If the value of `new_addr` is zero then `new_size` determines how many
>      instruction bytes to NOP (up to opaque size modulo smallest platform
>      instruction - 1 byte x86 and 4 bytes on ARM).
> -
> -* `version` is to be one.
> -
> -* `opaque` **MUST** be zero.
> + * `version` is to be one.
> + * `opaque` **MUST** be zero.
>  
>  The size of the `livepatch_func` array is determined from the ELF section
>  size.
> @@ -362,38 +339,35 @@ being applied and after being reverted:
>  
>  A simple example of what a payload file can be:
>  
> -<pre>
> -/* MUST be in sync with hypervisor. */  
> -struct livepatch_func {  
> -    const char *name;  
> -    void *new_addr;  
> -    void *old_addr;  
> -    uint32_t new_size;  
> -    uint32_t old_size;  
> -    uint8_t version;
> -    uint8_t pad[31];  
> -};  
> -
> -/* Our replacement function for xen_extra_version. */  
> -const char *xen_hello_world(void)  
> -{  
> -    return "Hello World";  
> -}  
> -
> -static unsigned char patch_this_fnc[] = "xen_extra_version";  
> -
> -struct livepatch_func livepatch_hello_world = {  
> -    .version = LIVEPATCH_PAYLOAD_VERSION,
> -    .name = patch_this_fnc,  
> -    .new_addr = xen_hello_world,  
> -    .old_addr = (void *)0xffff82d08013963c, /* Extracted from xen-syms. */  
> -    .new_size = 13, /* To be be computed by scripts. */  
> -    .old_size = 13, /* -----------""---------------  */  
> -} __attribute__((__section__(".livepatch.funcs")));  
> -
> -</pre>
> -
> -Code must be compiled with -fPIC.
> +    /* MUST be in sync with hypervisor. */
> +    struct livepatch_func {
> +        const char *name;
> +        void *new_addr;
> +        void *old_addr;
> +        uint32_t new_size;
> +        uint32_t old_size;
> +        uint8_t version;
> +        uint8_t pad[31];
> +    };
> +
> +    /* Our replacement function for xen_extra_version. */
> +    const char *xen_hello_world(void)
> +    {
> +        return "Hello World";
> +    }
> +
> +    static unsigned char patch_this_fnc[] = "xen_extra_version";
> +
> +    struct livepatch_func livepatch_hello_world = {
> +        .version = LIVEPATCH_PAYLOAD_VERSION,
> +        .name = patch_this_fnc,
> +        .new_addr = xen_hello_world,
> +        .old_addr = (void *)0xffff82d08013963c, /* Extracted from xen-syms. 
> */
> +        .new_size = 13, /* To be be computed by scripts. */
> +        .old_size = 13, /* -----------""---------------  */
> +    } __attribute__((__section__(".livepatch.funcs")));
> +
> +Code must be compiled with `-fPIC`.
>  
>  ### .livepatch.hooks.load and .livepatch.hooks.unload
>  
> @@ -406,10 +380,8 @@ Each entry in this array is eight bytes.
>  
>  The type definition of the function are as follow:
>  
> -<pre>
> -typedef void (*livepatch_loadcall_t)(void);  
> -typedef void (*livepatch_unloadcall_t)(void);   
> -</pre>
> +    typedef void (*livepatch_loadcall_t)(void);
> +    typedef void (*livepatch_unloadcall_t)(void);
>  
>  ### .livepatch.depends and .note.gnu.build-id
>  
> @@ -423,10 +395,10 @@ which follows the format of an ELF Note. The contents 
> of this
>  build the hypevisor and payload.
>  
>  If GNU linker is used then the name is `GNU` and the description
> -is a NT_GNU_BUILD_ID type ID. The description can be an SHA1
> +is a NT\_GNU\_BUILD\_ID type ID. The description can be an SHA1
>  checksum, MD5 checksum or any unique value.
>  
> -The size of these structures varies with the --build-id linker option.
> +The size of these structures varies with the `--build-id` linker option.
>  
>  ## Hypercalls
>  
> @@ -454,22 +426,20 @@ Furthermore it is possible to have multiple different 
> payloads for the same
>  function. As such an unique name per payload has to be visible to allow 
> proper manipulation.
>  
>  The hypercall is part of the `xen_sysctl`. The top level structure contains
> -one uint32_t to determine the sub-operations and one padding field which
> +one uint32\_t to determine the sub-operations and one padding field which
>  *MUST* always be zero.
>  
> -<pre>
> -struct xen_sysctl_livepatch_op {  
> -    uint32_t cmd;                   /* IN: XEN_SYSCTL_LIVEPATCH_*. */  
> -    uint32_t pad;                   /* IN: Always zero. */  
> -     union {  
> -          ... see below ...  
> -        } u;  
> -};  
> +    struct xen_sysctl_livepatch_op {
> +        uint32_t cmd;                   /* IN: XEN_SYSCTL_LIVEPATCH_*. */
> +        uint32_t pad;                   /* IN: Always zero. */
> +         union {
> +              ... see below ...
> +            } u;
> +    };
>  
> -</pre>
>  while the rest of hypercall specific structures are part of the this 
> structure.
>  
> -### Basic type: struct xen_livepatch_name
> +### Basic type: struct xen\_livepatch\_name
>  
>  Most of the hypercalls employ an shared structure called `struct 
> xen_livepatch_name`
>  which contains:
> @@ -480,26 +450,24 @@ which contains:
>  
>  The structure is as follow:
>  
> -<pre>
> -/*  
> - *  Uniquely identifies the payload.  Should be human readable.  
> - * Includes the NUL terminator  
> - */  
> -#define XEN_LIVEPATCH_NAME_SIZE 128  
> -struct xen_livepatch_name {  
> -    XEN_GUEST_HANDLE_64(char) name;         /* IN, pointer to name. */  
> -    uint16_t size;                          /* IN, size of name. May be upto 
>   
> -                                               XEN_LIVEPATCH_NAME_SIZE. */  
> -    uint16_t pad[3];                        /* IN: MUST be zero. */ 
> -};  
> -</pre>
> -
> -### XEN_SYSCTL_LIVEPATCH_UPLOAD (0)
> +    /*
> +     *  Uniquely identifies the payload.  Should be human readable.
> +     * Includes the NUL terminator
> +     */
> +    #define XEN_LIVEPATCH_NAME_SIZE 128
> +    struct xen_livepatch_name {
> +        XEN_GUEST_HANDLE_64(char) name;         /* IN, pointer to name. */
> +        uint16_t size;                          /* IN, size of name. May be 
> upto
> +                                                   XEN_LIVEPATCH_NAME_SIZE. 
> */
> +        uint16_t pad[3];                        /* IN: MUST be zero. */
> +    };
> +
> +### XEN\_SYSCTL\_LIVEPATCH\_UPLOAD (0)
>  
>  Upload a payload to the hypervisor. The payload is verified
>  against basic checks and if there are any issues the proper return code
>  will be returned. The payload is not applied at this time - that is
> -controlled by *XEN_SYSCTL_LIVEPATCH_ACTION*.
> +controlled by *XEN\_SYSCTL\_LIVEPATCH\_ACTION*.
>  
>  The caller provides:
>  
> @@ -512,21 +480,19 @@ payload. It can be embedded into the ELF payload at 
> creation time
>  and extracted by tools.
>  
>  The return value is zero if the payload was succesfully uploaded.
> -Otherwise an -XEN_EXX return value is provided. Duplicate `name` are not 
> supported.
> +Otherwise an -XEN\_EXX return value is provided. Duplicate `name` are not 
> supported.
>  
>  The `payload` is the ELF payload as mentioned in the `Payload format` 
> section.
>  
>  The structure is as follow:
>  
> -<pre>
> -struct xen_sysctl_livepatch_upload {  
> -    xen_livepatch_name_t name;          /* IN, name of the patch. */  
> -    uint64_t size;                      /* IN, size of the ELF file. */  
> -    XEN_GUEST_HANDLE_64(uint8) payload; /* IN: ELF file. */  
> -};  
> -</pre>
> +    struct xen_sysctl_livepatch_upload {
> +        xen_livepatch_name_t name;          /* IN, name of the patch. */
> +        uint64_t size;                      /* IN, size of the ELF file. */
> +        XEN_GUEST_HANDLE_64(uint8) payload; /* IN: ELF file. */
> +    };
>  
> -### XEN_SYSCTL_LIVEPATCH_GET (1)
> +### XEN\_SYSCTL\_LIVEPATCH\_GET (1)
>  
>  Retrieve an status of an specific payload. This caller provides:
>  
> @@ -537,33 +503,29 @@ Retrieve an status of an specific payload. This caller 
> provides:
>  Upon completion the `struct xen_livepatch_status` is updated.
>  
>   * `status` - indicates the current status of the payload:
> -   * *LIVEPATCH_STATUS_CHECKED*  (1) loaded and the ELF payload safety 
> checks passed.
> -   * *LIVEPATCH_STATUS_APPLIED* (2) loaded, checked, and applied.
> +   * *LIVEPATCH\_STATUS\_CHECKED* (1) loaded and the ELF payload safety 
> checks passed.
> +   * *LIVEPATCH\_STATUS\_APPLIED* (2) loaded, checked, and applied.
>     *  No other value is possible.
> - * `rc` - -XEN_EXX type errors encountered while performing the last
> -   LIVEPATCH_ACTION_* operation. The normal values can be zero or 
> -XEN_EAGAIN which
> + * `rc` - -XEN\_EXX type errors encountered while performing the last
> +   LIVEPATCH\_ACTION\_\* operation. The normal values can be zero or 
> -XEN\_EAGAIN which
>     respectively mean: success or operation in progress. Other values
>     imply an error occurred. If there is an error in `rc`, `status` will 
> **NOT**
>     have changed.
>  
> -The return value of the hypercall is zero on success and -XEN_EXX on failure.
> -(Note that the `rc`` value can be different from the return value, as in
> -rc=-XEN_EAGAIN and return value can be 0).
> +The return value of the hypercall is zero on success and -XEN\_EXX on 
> failure.
> +(Note that the `rc` value can be different from the return value, as in
> +rc=-XEN\_EAGAIN and return value can be 0).
>  
>  For example, supposing there is an payload:
>  
> -<pre>
> - status: LIVEPATCH_STATUS_CHECKED
> - rc: 0
> -</pre>
> +    status: LIVEPATCH_STATUS_CHECKED
> +    rc: 0
>  
> -We apply an action - LIVEPATCH_ACTION_REVERT - to revert it (which won't work
> +We apply an action - LIVEPATCH\_ACTION\_REVERT - to revert it (which won't 
> work
>  as we have not even applied it. Afterwards we will have:
>  
> -<pre>
> - status: LIVEPATCH_STATUS_CHECKED
> - rc: -XEN_EINVAL
> -</pre>
> +    status: LIVEPATCH_STATUS_CHECKED
> +    rc: -XEN_EINVAL
>  
>  It has failed but it remains loaded.
>  
> @@ -571,21 +533,19 @@ This operation is synchronous and does not require 
> preemption.
>  
>  The structure is as follow:
>  
> -<pre>
> -struct xen_livepatch_status {  
> -#define LIVEPATCH_STATUS_CHECKED      1  
> -#define LIVEPATCH_STATUS_APPLIED      2  
> -    uint32_t state;                 /* OUT: LIVEPATCH_STATE_*. */  
> -    int32_t rc;                     /* OUT: 0 if no error, otherwise 
> -XEN_EXX. */  
> -};  
> +    struct xen_livepatch_status {
> +    #define LIVEPATCH_STATUS_CHECKED      1
> +    #define LIVEPATCH_STATUS_APPLIED      2
> +        uint32_t state;                 /* OUT: LIVEPATCH_STATE_*. */
> +        int32_t rc;                     /* OUT: 0 if no error, otherwise 
> -XEN_EXX. */
> +    };
>  
> -struct xen_sysctl_livepatch_get {  
> -    xen_livepatch_name_t name;      /* IN, the name of the payload. */  
> -    xen_livepatch_status_t status;  /* IN/OUT: status of the payload. */  
> -};  
> -</pre>
> +    struct xen_sysctl_livepatch_get {
> +        xen_livepatch_name_t name;      /* IN, the name of the payload. */
> +        xen_livepatch_status_t status;  /* IN/OUT: status of the payload. */
> +    };
>  
> -### XEN_SYSCTL_LIVEPATCH_LIST (2)
> +### XEN\_SYSCTL\_LIVEPATCH\_LIST (2)
>  
>  Retrieve an array of abbreviated status and names of payloads that are 
> loaded in the
>  hypervisor.
> @@ -594,32 +554,32 @@ The caller provides:
>  
>   * `version`. Version of the payload. Caller should re-use the field 
> provided by
>      the hypervisor. If the value differs the data is stale.
> - * `idx` index iterator. The index into the hypervisor's payload count. It is
> + * `idx` Index iterator. The index into the hypervisor's payload count. It is
>      recommended that on first invocation zero be used so that `nr` (which the
>      hypervisor will update with the remaining payload count) be provided.
>      Also the hypervisor will provide `version` with the most current value.
> - * `nr` the max number of entries to populate. Can be zero which will result
> + * `nr` The max number of entries to populate. Can be zero which will result
>      in the hypercall being a probing one and return the number of payloads
>      (and update the `version`).
>   * `pad` - *MUST* be zero.
> - * `status` virtual address of where to write `struct xen_livepatch_status`
> + * `status` Virtual address of where to write `struct xen_livepatch_status`
>     structures. Caller *MUST* allocate up to `nr` of them.
> - * `name` - virtual address of where to write the unique name of the payload.
> + * `name` - Virtual address of where to write the unique name of the payload.
>     Caller *MUST* allocate up to `nr` of them. Each *MUST* be of
> -   **XEN_LIVEPATCH_NAME_SIZE** size. Note that **XEN_LIVEPATCH_NAME_SIZE** 
> includes
> +   **XEN\_LIVEPATCH\_NAME\_SIZE** size. Note that 
> **XEN\_LIVEPATCH\_NAME\_SIZE** includes
>     the NUL terminator.
> - * `len` - virtual address of where to write the length of each unique name
> + * `len` - Virtual address of where to write the length of each unique name
>     of the payload. Caller *MUST* allocate up to `nr` of them. Each *MUST* be
> -   of sizeof(uint32_t) (4 bytes).
> +   of sizeof(uint32\_t) (4 bytes).
>  
>  If the hypercall returns an positive number, it is the number (upto `nr`
>  provided to the hypercall) of the payloads returned, along with `nr` updated
>  with the number of remaining payloads, `version` updated (it may be the same
>  across hypercalls - if it varies the data is stale and further calls could
> -fail). The `status`, `name`, and `len`' are updated at their designed index
> +fail). The `status`, `name`, and `len` are updated at their designed index
>  value (`idx`) with the returned value of data.
>  
> -If the hypercall returns -XEN_E2BIG the `nr` is too big and should be
> +If the hypercall returns -XEN\_E2BIG the `nr` is too big and should be
>  lowered.
>  
>  If the hypercall returns an zero value there are no more payloads.
> @@ -634,62 +594,60 @@ data and start from scratch. It is OK for the toolstack 
> to use the new
>  The `struct xen_livepatch_status` structure contains an status of payload 
> which includes:
>  
>   * `status` - indicates the current status of the payload:
> -   * *LIVEPATCH_STATUS_CHECKED*  (1) loaded and the ELF payload safety 
> checks passed.
> -   * *LIVEPATCH_STATUS_APPLIED* (2) loaded, checked, and applied.
> +   * *LIVEPATCH\_STATUS\_CHECKED* (1) loaded and the ELF payload safety 
> checks passed.
> +   * *LIVEPATCH\_STATUS\_APPLIED* (2) loaded, checked, and applied.
>     *  No other value is possible.
> - * `rc` - -XEN_EXX type errors encountered while performing the last
> -   LIVEPATCH_ACTION_* operation. The normal values can be zero or 
> -XEN_EAGAIN which
> + * `rc` - -XEN\_EXX type errors encountered while performing the last
> +   LIVEPATCH\_ACTION\_\* operation. The normal values can be zero or 
> -XEN\_EAGAIN which
>     respectively mean: success or operation in progress. Other values
>     imply an error occurred. If there is an error in `rc`, `status` will 
> **NOT**
>     have changed.
>  
>  The structure is as follow:
>  
> -<pre>
> -struct xen_sysctl_livepatch_list {  
> -    uint32_t version;                       /* OUT: Hypervisor stamps value.
> -                                               If varies between calls, we 
> are  
> -                                               getting stale data. */  
> -    uint32_t idx;                           /* IN: Index into hypervisor 
> list. */
> -    uint32_t nr;                            /* IN: How many status, names, 
> and len  
> -                                               should be filled out. Can be 
> zero to get  
> -                                               amount of payloads and 
> version.  
> -                                               OUT: How many payloads left. 
> */  
> -    uint32_t pad;                           /* IN: Must be zero. */  
> -    XEN_GUEST_HANDLE_64(xen_livepatch_status_t) status;  /* OUT. Must have 
> enough  
> -                                               space allocate for nr of 
> them. */  
> -    XEN_GUEST_HANDLE_64(char) id;           /* OUT: Array of names. Each 
> member  
> -                                               MUST XEN_LIVEPATCH_NAME_SIZE 
> in size.  
> -                                               Must have nr of them. */  
> -    XEN_GUEST_HANDLE_64(uint32) len;        /* OUT: Array of lengths of 
> name's.  
> -                                               Must have nr of them. */  
> -};  
> -</pre>
> -
> -### XEN_SYSCTL_LIVEPATCH_ACTION (3)
> +    struct xen_sysctl_livepatch_list {
> +        uint32_t version;                       /* OUT: Hypervisor stamps 
> value.
> +                                                   If varies between calls, 
> we are
> +                                                   getting stale data. */
> +        uint32_t idx;                           /* IN: Index into hypervisor 
> list. */
> +        uint32_t nr;                            /* IN: How many status, 
> names, and len
> +                                                   should be filled out. Can 
> be zero to get
> +                                                   amount of payloads and 
> version.
> +                                                   OUT: How many payloads 
> left. */
> +        uint32_t pad;                           /* IN: Must be zero. */
> +        XEN_GUEST_HANDLE_64(xen_livepatch_status_t) status;  /* OUT. Must 
> have enough
> +                                                   space allocate for nr of 
> them. */
> +        XEN_GUEST_HANDLE_64(char) id;           /* OUT: Array of names. Each 
> member
> +                                                   MUST 
> XEN_LIVEPATCH_NAME_SIZE in size.
> +                                                   Must have nr of them. */
> +        XEN_GUEST_HANDLE_64(uint32) len;        /* OUT: Array of lengths of 
> name's.
> +                                                   Must have nr of them. */
> +    };
> +
> +### XEN\_SYSCTL\_LIVEPATCH\_ACTION (3)
>  
>  Perform an operation on the payload structure referenced by the `name` field.
>  The operation request is asynchronous and the status should be retrieved
> -by using either **XEN_SYSCTL_LIVEPATCH_GET** or 
> **XEN_SYSCTL_LIVEPATCH_LIST** hypercall.
> +by using either **XEN\_SYSCTL\_LIVEPATCH\_GET** or 
> **XEN\_SYSCTL\_LIVEPATCH\_LIST** hypercall.
>  
>  The caller provides:
>  
> - * A 'struct xen_livepatch_name` `name` containing the unique name.
> - * `cmd` the command requested:
> -  * *LIVEPATCH_ACTION_UNLOAD* (1) unload the payload.
> + * A `struct xen_livepatch_name` `name` containing the unique name.
> + * `cmd` The command requested:
> +  * *LIVEPATCH\_ACTION\_UNLOAD* (1) Unload the payload.
>     Any further hypercalls against the `name` will result in failure unless
> -   **XEN_SYSCTL_LIVEPATCH_UPLOAD** hypercall is perfomed with same `name`.
> -  * *LIVEPATCH_ACTION_REVERT* (2) revert the payload. If the operation takes
> -  more time than the upper bound of time the `rc` in `xen_livepatch_status'
> -  retrieved via **XEN_SYSCTL_LIVEPATCH_GET** will be -XEN_EBUSY.
> -  * *LIVEPATCH_ACTION_APPLY* (3) apply the payload. If the operation takes
> -  more time than the upper bound of time the `rc` in `xen_livepatch_status'
> -  retrieved via **XEN_SYSCTL_LIVEPATCH_GET** will be -XEN_EBUSY.
> -  * *LIVEPATCH_ACTION_REPLACE* (4) revert all applied payloads and apply this
> +   **XEN\_SYSCTL\_LIVEPATCH\_UPLOAD** hypercall is perfomed with same `name`.
> +  * *LIVEPATCH\_ACTION\_REVERT* (2) Revert the payload. If the operation 
> takes
> +  more time than the upper bound of time the `rc` in `xen_livepatch_status`
> +  retrieved via **XEN\_SYSCTL\_LIVEPATCH\_GET** will be -XEN\_EBUSY.
> +  * *LIVEPATCH\_ACTION\_APPLY* (3) Apply the payload. If the operation takes
> +  more time than the upper bound of time the `rc` in `xen_livepatch_status`
> +  retrieved via **XEN\_SYSCTL\_LIVEPATCH\_GET** will be -XEN\_EBUSY.
> +  * *LIVEPATCH\_ACTION\_REPLACE* (4) Revert all applied payloads and apply 
> this
>    payload. If the operation takes more time than the upper bound of time
> -  the `rc` in `xen_livepatch_status' retrieved via 
> **XEN_SYSCTL_LIVEPATCH_GET**
> -  will be -XEN_EBUSY.
> - * `time` the upper bound of time (ns) the cmd should take. Zero means to use
> +  the `rc` in `xen_livepatch_status` retrieved via 
> **XEN\_SYSCTL\_LIVEPATCH\_GET**
> +  will be -XEN\_EBUSY.
> + * `time` The upper bound of time (ns) the cmd should take. Zero means to use
>     the hypervisor default. If within the time the operation does not succeed
>     the operation would go in error state.
>   * `pad` - *MUST* be zero.
> @@ -698,71 +656,64 @@ The return value will be zero unless the provided 
> fields are incorrect.
>  
>  The structure is as follow:
>  
> -<pre>
> -#define LIVEPATCH_ACTION_UNLOAD  1  
> -#define LIVEPATCH_ACTION_REVERT  2  
> -#define LIVEPATCH_ACTION_APPLY   3  
> -#define LIVEPATCH_ACTION_REPLACE 4  
> -struct xen_sysctl_livepatch_action {  
> -    xen_livepatch_name_t name;              /* IN, name of the patch. */  
> -    uint32_t cmd;                           /* IN: LIVEPATCH_ACTION_* */  
> -    uint32_t time;                          /* IN: If zero then uses */
> -                                            /* hypervisor default. */
> -                                            /* Or upper bound of time (ns) */
> -                                            /* for operation to take. */
> -};  
> +    #define LIVEPATCH_ACTION_UNLOAD  1
> +    #define LIVEPATCH_ACTION_REVERT  2
> +    #define LIVEPATCH_ACTION_APPLY   3
> +    #define LIVEPATCH_ACTION_REPLACE 4
> +    struct xen_sysctl_livepatch_action {
> +        xen_livepatch_name_t name;              /* IN, name of the patch. */
> +        uint32_t cmd;                           /* IN: LIVEPATCH_ACTION_* */
> +        uint32_t time;                          /* IN: If zero then uses */
> +                                                /* hypervisor default. */
> +                                                /* Or upper bound of time 
> (ns) */
> +                                                /* for operation to take. */
> +    };
>  
> -</pre>
>  
> -## State diagrams of LIVEPATCH_ACTION commands.
> +## State diagrams of LIVEPATCH\_ACTION commands.
>  
>  There is a strict ordering state of what the commands can be.
> -The LIVEPATCH_ACTION prefix has been dropped to easy reading and
> -does not include the LIVEPATCH_STATES:
> +The LIVEPATCH\_ACTION prefix has been dropped to easy reading and
> +does not include the LIVEPATCH\_STATES:
>  
> -<pre>
> -              /->\  
> -              \  /  
> - UNLOAD <--- CHECK ---> REPLACE|APPLY --> REVERT --\  
> -                \                                  |  
> -                 \-------------------<-------------/  
> +                 /->\
> +                 \  /
> +    UNLOAD <--- CHECK ---> REPLACE|APPLY --> REVERT --\
> +                   \                                  |
> +                    \-------------------<-------------/
>  
> -</pre>
> -## State transition table of LIVEPATCH_ACTION commands and LIVEPATCH_STATUS.
> +## State transition table of LIVEPATCH\_ACTION commands and 
> LIVEPATCH\_STATUS.
>  
>  Note that:
>  
> - - The CHECKED state is the starting one achieved with 
> *XEN_SYSCTL_LIVEPATCH_UPLOAD* hypercall.
> + - The CHECKED state is the starting one achieved with 
> *XEN\_SYSCTL\_LIVEPATCH\_UPLOAD* hypercall.
>   - The REVERT operation on success will automatically move to the CHECKED 
> state.
>   - There are two STATES: CHECKED and APPLIED.
>   - There are four actions (aka commands): APPLY, REPLACE, REVERT, and UNLOAD.
>  
>  The state transition table of valid states and action states:
>  
> -<pre>
> -
> -+---------+---------+--------------------------------+-------+--------+
> -| ACTION  | Current | Result                         | Next STATE:    |
> -| ACTION  | STATE   |                                |CHECKED|APPLIED |
> -+---------+----------+-------------------------------+-------+--------+
> -| UNLOAD  | CHECKED | Unload payload. Always works.  |       |        |
> -|         |         | No next states.                |       |        |
> -+---------+---------+--------------------------------+-------+--------+
> -| APPLY   | CHECKED | Apply payload (success).       |       |   x    |
> -+---------+---------+--------------------------------+-------+--------+
> -| APPLY   | CHECKED | Apply payload (error|timeout)  |   x   |        |
> -+---------+---------+--------------------------------+-------+--------+
> -| REPLACE | CHECKED | Revert payloads and apply new  |       |   x    |
> -|         |         | payload with success.          |       |        |
> -+---------+---------+--------------------------------+-------+--------+
> -| REPLACE | CHECKED | Revert payloads and apply new  |   x   |        |
> -|         |         | payload with error.            |       |        |
> -+---------+---------+--------------------------------+-------+--------+
> -| REVERT  | APPLIED | Revert payload (success).      |   x   |        |
> -+---------+---------+--------------------------------+-------+--------+
> -| REVERT  | APPLIED | Revert payload (error|timeout) |       |   x    |
> -+---------+---------+--------------------------------+-------+--------+
> -</pre>
> +    +---------+---------+--------------------------------+-------+--------+
> +    | ACTION  | Current | Result                         |   Next STATE:  |
> +    | ACTION  | STATE   |                                |CHECKED|APPLIED |
> +    +---------+----------+-------------------------------+-------+--------+
> +    | UNLOAD  | CHECKED | Unload payload. Always works.  |       |        |
> +    |         |         | No next states.                |       |        |
> +    +---------+---------+--------------------------------+-------+--------+
> +    | APPLY   | CHECKED | Apply payload (success).       |       |   x    |
> +    +---------+---------+--------------------------------+-------+--------+
> +    | APPLY   | CHECKED | Apply payload (error|timeout)  |   x   |        |
> +    +---------+---------+--------------------------------+-------+--------+
> +    | REPLACE | CHECKED | Revert payloads and apply new  |       |   x    |
> +    |         |         | payload with success.          |       |        |
> +    +---------+---------+--------------------------------+-------+--------+
> +    | REPLACE | CHECKED | Revert payloads and apply new  |   x   |        |
> +    |         |         | payload with error.            |       |        |
> +    +---------+---------+--------------------------------+-------+--------+
> +    | REVERT  | APPLIED | Revert payload (success).      |   x   |        |
> +    +---------+---------+--------------------------------+-------+--------+
> +    | REVERT  | APPLIED | Revert payload (error|timeout) |       |   x    |
> +    +---------+---------+--------------------------------+-------+--------+
>  
>  All the other state transitions are invalid.
>  
> @@ -770,10 +721,10 @@ All the other state transitions are invalid.
>  
>  The normal sequence of events is to:
>  
> - 1. *XEN_SYSCTL_LIVEPATCH_UPLOAD* to upload the payload. If there are errors 
> *STOP* here.
> - 2. *XEN_SYSCTL_LIVEPATCH_GET* to check the `->rc`. If *-XEN_EAGAIN* spin. 
> If zero go to next step.
> - 3. *XEN_SYSCTL_LIVEPATCH_ACTION* with *LIVEPATCH_ACTION_APPLY* to apply the 
> patch.
> - 4. *XEN_SYSCTL_LIVEPATCH_GET* to check the `->rc`. If in *-XEN_EAGAIN* 
> spin. If zero exit with success.
> + 1. *XEN\_SYSCTL\_LIVEPATCH\_UPLOAD* to upload the payload. If there are 
> errors *STOP* here.
> + 2. *XEN\_SYSCTL\_LIVEPATCH\_GET* to check the `->rc`. If *-XEN\_EAGAIN* 
> spin. If zero go to next step.
> + 3. *XEN\_SYSCTL\_LIVEPATCH\_ACTION* with *LIVEPATCH\_ACTION\_APPLY* to 
> apply the patch.
> + 4. *XEN\_SYSCTL\_LIVEPATCH\_GET* to check the `->rc`. If in *-XEN\_EAGAIN* 
> spin. If zero exit with success.
>  
>  
>  ## Addendum
> @@ -807,18 +758,18 @@ minimize the chance of the patch not being applied due 
> to safety
>  checks failing. Safety checks such as not patching code which
>  is on the stack - which can lead to corruption.
>  
> -#### Rendezvous code instead of stop_machine for patching
> +#### Rendezvous code instead of stop\_machine for patching
>  
>  The hypervisor's time rendezvous code runs synchronously across all CPUs
> -every second. Using the stop_machine to patch can stall the time rendezvous
> +every second. Using the `stop_machine` to patch can stall the time rendezvous
>  code and result in NMI. As such having the patching be done at the tail
>  of rendezvous code should avoid this problem.
>  
> -However the entrance point for that code is
> -do_softirq->timer_softirq_action->time_calibration
> -which ends up calling on_selected_cpus on remote CPUs.
> +However the entrance point for that code is `do_softirq ->
> +timer_softirq_action -> time_calibration` which ends up calling
> +`on_selected_cpus` on remote CPUs.
>  
> -The remote CPUs receive CALL_FUNCTION_VECTOR IPI and execute the
> +The remote CPUs receive CALL\_FUNCTION\_VECTOR IPI and execute the
>  desired function.
>  
>  #### Before entering the guest code.
> @@ -832,16 +783,16 @@ could be adjusted), combined with forcing all other 
> CPUs through the
>  hypervisor with IPIs, can be utilized to execute lockstep instructions
>  on all CPUs.
>  
> -The approach is similar in concept to stop_machine and the time rendezvous
> +The approach is similar in concept to `stop_machine` and the time rendezvous
>  but is time-bound. However the local CPU stack is much shorter and
>  a lot more deterministic.
>  
> -This is implemented in the Xen Project hypervisor.
> +This is implemented in the Xen hypervisor.
>  
>  ### Compiling the hypervisor code
>  
>  Hotpatch generation often requires support for compiling the target
> -with -ffunction-sections / -fdata-sections.  Changes would have to
> +with `-ffunction-sections` / `-fdata-sections`.  Changes would have to
>  be done to the linker scripts to support this.
>  
>  ### Generation of Live Patch ELF payloads
> @@ -866,7 +817,7 @@ and reorder it afterwards.
>  As found almost every patch (XSA) to a non-trivial function requires
>  additional entries in the exception table and/or the bug frames.
>  
> -This is implemented in the Xen Project hypervisor.
> +This is implemented in the Xen hypervisor.
>  
>  ### .rodata sections
>  
> @@ -882,18 +833,18 @@ To guard against that we must be prepared to do 
> patching similar to
>  trampoline patching or in-line depending on the flavour. If we can
>  do in-line patching we would need to:
>  
> - * alter `.rodata` to be writeable.
> - * inline patch.
> - * alter `.rodata` to be read-only.
> + * Alter `.rodata` to be writeable.
> + * Inline patch.
> + * Alter `.rodata` to be read-only.
>  
>  If are doing trampoline patching we would need to:
>  
> - * allocate a new memory location for the string.
> - * all locations which use this string will have to be updated to use the
> + * Allocate a new memory location for the string.
> + * All locations which use this string will have to be updated to use the
>     offset to the string.
> - * mark the region RO when we are done.
> + * Mark the region RO when we are done.
>  
> -The trampoline patching is implemented in the Xen Project hypervisor.
> +The trampoline patching is implemented in the Xen hypervisor.
>  
>  ### .bss and .data sections.
>  
> @@ -908,7 +859,7 @@ Patching in the new function will end up also patching in 
> the new .rodata
>  section and the new function will reference the new string in the new
>  .rodata section.
>  
> -This is implemented in the Xen Project hypervisor.
> +This is implemented in the Xen hypervisor.
>  
>  ### Security
>  
> @@ -941,7 +892,7 @@ The old code allows much more flexibility and an 
> additional guard,
>  but is more complex to implement.
>  
>  The second option which requires an build-id of the hypervisor
> -is implemented in the Xen Project hypervisor.
> +is implemented in the Xen hypervisor.
>  
>  Specifically each payload has two build-id ELF notes:
>   * The build-id of the payload itself (generated via --build-id).
> @@ -967,10 +918,10 @@ The implementation must also have a mechanism for (in 
> no particular order):
>     the stack, make sure the payload is built with same compiler as 
> hypervisor).
>     Specifically we want to make sure that live patching codepaths cannot be 
> patched.
>   * NOP out the code sequence if `new_size` is zero.
> - * Deal with other relocation types:  R_X86_64_[8,16,32,32S], 
> R_X86_64_PC[8,16,64]
> + * Deal with other relocation types:  R\_X86\_64\_[8,16,32,32S], 
> R\_X86\_64\_PC[8,16,64]
>     in payload file.
>  
> -### Handle inlined __LINE__
> +### Handle inlined \_\_LINE\_\_
>  
>  This problem is related to hotpatch construction
>  and potentially has influence on the design of the hotpatching
> @@ -1030,7 +981,7 @@ Options:
>  For BUG(), WARN(), etc., the line number is embedded into the bug frame, not
>  the function itself.
>  
> -Similar considerations are true to a lesser extent for __FILE__, but it
> +Similar considerations are true to a lesser extent for \_\_FILE\_\_, but it
>  could be argued that file renaming should be done outside of hotpatches.
>  
>  ## Signature checking requirements.
> @@ -1042,49 +993,46 @@ expecting such that it can properly do signature 
> verification.
>  
>  The signature is based on the all of the payloads continuously laid out
>  in memory. The signature is to be appended at the end of the ELF payload
> -prefixed with the string `'~Module signature appended~\n'`, followed by
> +prefixed with the string '`~Module signature appended~\n`', followed by
>  an signature header then followed by the signature, key identifier, and 
> signers
>  name.
>  
>  Specifically the signature header would be:
>  
> -<pre>
> -#define PKEY_ALGO_DSA       0  
> -#define PKEY_ALGO_RSA       1  
> -
> -#define PKEY_ID_PGP         0 /* OpenPGP generated key ID */  
> -#define PKEY_ID_X509        1 /* X.509 arbitrary subjectKeyIdentifier */  
> -
> -#define HASH_ALGO_MD4          0  
> -#define HASH_ALGO_MD5          1  
> -#define HASH_ALGO_SHA1         2  
> -#define HASH_ALGO_RIPE_MD_160  3  
> -#define HASH_ALGO_SHA256       4  
> -#define HASH_ALGO_SHA384       5  
> -#define HASH_ALGO_SHA512       6  
> -#define HASH_ALGO_SHA224       7  
> -#define HASH_ALGO_RIPE_MD_128  8  
> -#define HASH_ALGO_RIPE_MD_256  9  
> -#define HASH_ALGO_RIPE_MD_320 10  
> -#define HASH_ALGO_WP_256      11  
> -#define HASH_ALGO_WP_384      12  
> -#define HASH_ALGO_WP_512      13  
> -#define HASH_ALGO_TGR_128     14  
> -#define HASH_ALGO_TGR_160     15  
> -#define HASH_ALGO_TGR_192     16  
> -
> -
> -struct elf_payload_signature {  
> -     u8      algo;           /* Public-key crypto algorithm PKEY_ALGO_*. */  
> -     u8      hash;           /* Digest algorithm: HASH_ALGO_*. */  
> -     u8      id_type;        /* Key identifier type PKEY_ID*. */  
> -     u8      signer_len;     /* Length of signer's name */  
> -     u8      key_id_len;     /* Length of key identifier */  
> -     u8      __pad[3];  
> -     __be32  sig_len;        /* Length of signature data */  
> -};
> -
> -</pre>
> +    #define PKEY_ALGO_DSA       0
> +    #define PKEY_ALGO_RSA       1
> +
> +    #define PKEY_ID_PGP         0 /* OpenPGP generated key ID */
> +    #define PKEY_ID_X509        1 /* X.509 arbitrary subjectKeyIdentifier */
> +
> +    #define HASH_ALGO_MD4          0
> +    #define HASH_ALGO_MD5          1
> +    #define HASH_ALGO_SHA1         2
> +    #define HASH_ALGO_RIPE_MD_160  3
> +    #define HASH_ALGO_SHA256       4
> +    #define HASH_ALGO_SHA384       5
> +    #define HASH_ALGO_SHA512       6
> +    #define HASH_ALGO_SHA224       7
> +    #define HASH_ALGO_RIPE_MD_128  8
> +    #define HASH_ALGO_RIPE_MD_256  9
> +    #define HASH_ALGO_RIPE_MD_320 10
> +    #define HASH_ALGO_WP_256      11
> +    #define HASH_ALGO_WP_384      12
> +    #define HASH_ALGO_WP_512      13
> +    #define HASH_ALGO_TGR_128     14
> +    #define HASH_ALGO_TGR_160     15
> +    #define HASH_ALGO_TGR_192     16
> +
> +    struct elf_payload_signature {
> +         u8  algo;           /* Public-key crypto algorithm PKEY_ALGO_*. */
> +         u8  hash;           /* Digest algorithm: HASH_ALGO_*. */
> +         u8  id_type;        /* Key identifier type PKEY_ID*. */
> +         u8  signer_len;     /* Length of signer's name */
> +         u8  key_id_len;     /* Length of key identifier */
> +         u8  __pad[3];
> +         __be32      sig_len;        /* Length of signature data */
> +    };
> +
>  (Note that this has been borrowed from Linux module signature code.).
>  
>  
> @@ -1128,15 +1076,14 @@ at least five bytes if patching in trampoline.
>  Depending on compiler settings, there are several functions in Xen that
>  are smaller (without inter-function padding).
>  
> -<pre> 
> -readelf -sW xen-syms | grep " FUNC " | \
> -    awk '{ if ($3 < 5) print $3, $4, $5, $8 }'
> +    readelf -sW xen-syms | grep " FUNC " | \
> +        awk '{ if ($3 < 5) print $3, $4, $5, $8 }'
> +
> +    ...
> +    3 FUNC LOCAL wbinvd_ipi
> +    3 FUNC LOCAL shadow_l1_index
> +    ...
>  
> -...
> -3 FUNC LOCAL wbinvd_ipi
> -3 FUNC LOCAL shadow_l1_index
> -...
> -</pre>
>  A compile-time check for, e.g., a minimum alignment of functions or a
>  runtime check that verifies symbol size (+ padding to next symbols) for
>  that in the hypervisor is advised.


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.