diff --git a/docs/misc/livepatch.markdown b/docs/misc/livepatch.markdown
index 54a6b850cb..c2c4acd3d3 100644
--- a/docs/misc/livepatch.markdown
+++ b/docs/misc/livepatch.markdown
@@ -279,6 +279,10 @@ It may also have some architecture-specific sections. For example:
  * Exception tables.
  * Relocations for each of these sections.
 
+Note that on ARM 32 the sections SHOULD be four byte aligned. Otherwise
+we risk hitting Data Abort exception as un-aligned manipulation of data is
+prohibited on ARM 32.
+
 The Xen Live Patch core code loads the payload as a standard ELF binary, relocates it
 and handles the architecture-specifc sections as needed. This process is much
 like what the Linux kernel module loader does.
@@ -341,7 +345,7 @@ The size of the structure is 64 bytes on 64-bit hypervisors. It will be
 * `opaque` **MUST** be zero.
 
 The size of the `livepatch_func` array is determined from the ELF section
-size.
+size.  On ARM32 this section must by four-byte aligned.
 
 When applying the patch the hypervisor iterates over each `livepatch_func`
 structure and the core code inserts a trampoline at `old_addr` to `new_addr`.
diff --git a/xen/arch/arm/arm32/livepatch.c b/xen/arch/arm/arm32/livepatch.c
index 41378a54ae..d48820f8ba 100644
--- a/xen/arch/arm/arm32/livepatch.c
+++ b/xen/arch/arm/arm32/livepatch.c
@@ -112,6 +112,12 @@ bool arch_livepatch_symbol_deny(const struct livepatch_elf *elf,
     return false;
 }
 
+bool arch_livepatch_verify_alignment(const struct livepatch_elf_sec *sec)
+{
+    /* Unaligned access on ARM 32 will crash with Data Abort. */
+    return (uint32_t)sec->load_addr % sizeof(uint32_t);
+};
+
 static s32 get_addend(unsigned char type, void *dest)
 {
     s32 addend = 0;
@@ -266,6 +272,15 @@ int arch_livepatch_perform(struct livepatch_elf *elf,
                     elf->name, symndx);
             return -EINVAL;
         }
+
+        if ( !use_rela )
+            addend = get_addend(type, dest);
+        else if ( (uint32_t)dest % sizeof(uint32_t) )
+        {
+            dprintk(XENLOG_ERR, LIVEPATCH "%s: dest=%p (%s) is not aligned properly!\n",
+                    elf->name, dest, base->name);
+            return -EINVAL;
+        }
         else if ( !elf->sym[symndx].sym )
         {
             dprintk(XENLOG_ERR, LIVEPATCH "%s: No relative symbol@%u\n",
diff --git a/xen/arch/arm/arm64/livepatch.c b/xen/arch/arm/arm64/livepatch.c
index 2247b925a0..7b36210ccd 100644
--- a/xen/arch/arm/arm64/livepatch.c
+++ b/xen/arch/arm/arm64/livepatch.c
@@ -86,6 +86,12 @@ bool arch_livepatch_symbol_deny(const struct livepatch_elf *elf,
     return false;
 }
 
+bool arch_livepatch_verify_alignment(const struct livepatch_elf_sec *sec)
+{
+    /* Unaligned access on ARM 64 is OK. */
+    return false;
+}
+
 enum aarch64_reloc_op {
     RELOC_OP_NONE,
     RELOC_OP_ABS,
diff --git a/xen/arch/x86/livepatch.c b/xen/arch/x86/livepatch.c
index 406eb910cc..b3cbdac9b7 100644
--- a/xen/arch/x86/livepatch.c
+++ b/xen/arch/x86/livepatch.c
@@ -148,6 +148,12 @@ bool arch_livepatch_symbol_deny(const struct livepatch_elf *elf,
     return false;
 }
 
+bool arch_livepatch_verify_alignment(const struct livepatch_elf_sec *sec)
+{
+    /* Unaligned access on x86 is fine. */
+    return false;
+}
+
 int arch_livepatch_perform_rel(struct livepatch_elf *elf,
                                const struct livepatch_elf_sec *base,
                                const struct livepatch_elf_sec *rela)
diff --git a/xen/common/livepatch.c b/xen/common/livepatch.c
index 40ff6b3a27..13d8f25a4b 100644
--- a/xen/common/livepatch.c
+++ b/xen/common/livepatch.c
@@ -472,6 +472,13 @@ static int check_section(const struct livepatch_elf *elf,
         return -EINVAL;
     }
 
+    if ( arch_livepatch_verify_alignment(sec) )
+    {
+        dprintk(XENLOG_ERR, LIVEPATCH "%s: %s is not aligned properly!\n",
+               elf->name, sec->name);
+        return -EINVAL;
+    }
+
     return 0;
 }
 
@@ -501,7 +508,12 @@ static int check_special_sections(const struct livepatch_elf *elf)
                     elf->name, names[i]);
             return -EINVAL;
         }
-
+        if ( arch_livepatch_verify_alignment(sec) )
+        {
+            dprintk(XENLOG_ERR, LIVEPATCH "%s: %s is not aligned properly!\n",
+                    elf->name, names[i]);
+            return -EINVAL;
+        }
         if ( test_and_set_bit(i, found) )
         {
             dprintk(XENLOG_ERR, LIVEPATCH "%s: %s was seen more than once!\n",
diff --git a/xen/include/xen/livepatch.h b/xen/include/xen/livepatch.h
index 98ec01216b..e9bab87f28 100644
--- a/xen/include/xen/livepatch.h
+++ b/xen/include/xen/livepatch.h
@@ -76,6 +76,7 @@ void arch_livepatch_init(void);
 #include <asm/livepatch.h>
 int arch_livepatch_verify_func(const struct livepatch_func *func);
 
+bool arch_livepatch_verify_alignment(const struct livepatch_elf_sec *sec);
 static inline
 unsigned int livepatch_insn_len(const struct livepatch_func *func)
 {
