diff --git a/meta/recipes-core/libxml/libxml2/fix-tests.patch b/meta/recipes-core/libxml/libxml2/fix-tests.patch
new file mode 100644
index 00000000000..80678efcfee
--- /dev/null
+++ b/meta/recipes-core/libxml/libxml2/fix-tests.patch
@@ -0,0 +1,222 @@
+Backport the following patches to fix the reader2 and runsuite test cases:
+
+b92768cd tests: Enable "runsuite" test
+0ac8c15e python/tests/reader2: use absolute paths everywhere
+b9ba5e1d python/tests/reader2: always exit(1) if a test fails
+
+Upstream-Status: Backport
+Signed-off-by: Ross Burton <ross.burton@arm.com>
+
+diff --git a/python/tests/reader2.py b/python/tests/reader2.py
+index 65cecd47..6e6353b4 100755
+--- a/python/tests/reader2.py
++++ b/python/tests/reader2.py
+@@ -6,7 +6,6 @@
+ import sys
+ import glob
+ import os
+-import string
+ import libxml2
+ try:
+     import StringIO
+@@ -20,103 +19,104 @@ libxml2.debugMemory(1)
+ 
+ err = ""
+ basedir = os.path.dirname(os.path.realpath(__file__))
+-dir_prefix = os.path.join(basedir, "../../test/valid/")
++dir_prefix = os.path.realpath(os.path.join(basedir, "..", "..", "test", "valid"))
++
+ # This dictionary reflects the contents of the files
+ # ../../test/valid/*.xml.err that are not empty, except that
+ # the file paths in the messages start with ../../test/
+ 
+ expect = {
+     '766956':
+-"""../../test/valid/dtds/766956.dtd:2: parser error : PEReference: expecting ';'
++"""{0}/dtds/766956.dtd:2: parser error : PEReference: expecting ';'
+ %ä%ent;
+    ^
+-../../test/valid/dtds/766956.dtd:2: parser error : Content error in the external subset
++{0}/dtds/766956.dtd:2: parser error : Content error in the external subset
+ %ä%ent;
+         ^
+ Entity: line 1: 
+ value
+ ^
+-""",
++""".format(dir_prefix),
+     '781333':
+-"""../../test/valid/781333.xml:4: element a: validity error : Element a content does not follow the DTD, expecting ( ..., got 
++"""{0}/781333.xml:4: element a: validity error : Element a content does not follow the DTD, expecting ( ..., got 
+ <a/>
+     ^
+-../../test/valid/781333.xml:5: element a: validity error : Element a content does not follow the DTD, Expecting more child
++{0}/781333.xml:5: element a: validity error : Element a content does not follow the DTD, Expecting more child
+ 
+ ^
+-""",
++""".format(dir_prefix),
+     'cond_sect2':
+-"""../../test/valid/dtds/cond_sect2.dtd:15: parser error : All markup of the conditional section is not in the same entity
++"""{0}/dtds/cond_sect2.dtd:15: parser error : All markup of the conditional section is not in the same entity
+     %ent;
+          ^
+ Entity: line 1: 
+ ]]>
+ ^
+-../../test/valid/dtds/cond_sect2.dtd:17: parser error : Content error in the external subset
++{0}/dtds/cond_sect2.dtd:17: parser error : Content error in the external subset
+ 
+ ^
+-""",
++""".format(dir_prefix),
+     'rss':
+-"""../../test/valid/rss.xml:177: element rss: validity error : Element rss does not carry attribute version
++"""{0}/rss.xml:177: element rss: validity error : Element rss does not carry attribute version
+ </rss>
+       ^
+-""",
++""".format(dir_prefix),
+     't8':
+-"""../../test/valid/t8.xml:6: parser error : internal error: xmlParseInternalSubset: error detected in Markup declaration
++"""{0}/t8.xml:6: parser error : internal error: xmlParseInternalSubset: error detected in Markup declaration
+ 
+ %defroot; %defmiddle; %deftest;
+          ^
+ Entity: line 1: 
+ &lt;!ELEMENT root (middle) >
+ ^
+-../../test/valid/t8.xml:6: parser error : internal error: xmlParseInternalSubset: error detected in Markup declaration
++{0}/t8.xml:6: parser error : internal error: xmlParseInternalSubset: error detected in Markup declaration
+ 
+ %defroot; %defmiddle; %deftest;
+                      ^
+ Entity: line 1: 
+ &lt;!ELEMENT middle (test) >
+ ^
+-../../test/valid/t8.xml:6: parser error : internal error: xmlParseInternalSubset: error detected in Markup declaration
++{0}/t8.xml:6: parser error : internal error: xmlParseInternalSubset: error detected in Markup declaration
+ 
+ %defroot; %defmiddle; %deftest;
+                                ^
+ Entity: line 1: 
+ &lt;!ELEMENT test (#PCDATA) >
+ ^
+-""",
++""".format(dir_prefix),
+     't8a':
+-"""../../test/valid/t8a.xml:6: parser error : internal error: xmlParseInternalSubset: error detected in Markup declaration
++"""{0}/t8a.xml:6: parser error : internal error: xmlParseInternalSubset: error detected in Markup declaration
+ 
+ %defroot;%defmiddle;%deftest;
+          ^
+ Entity: line 1: 
+ &lt;!ELEMENT root (middle) >
+ ^
+-../../test/valid/t8a.xml:6: parser error : internal error: xmlParseInternalSubset: error detected in Markup declaration
++{0}/t8a.xml:6: parser error : internal error: xmlParseInternalSubset: error detected in Markup declaration
+ 
+ %defroot;%defmiddle;%deftest;
+                     ^
+ Entity: line 1: 
+ &lt;!ELEMENT middle (test) >
+ ^
+-../../test/valid/t8a.xml:6: parser error : internal error: xmlParseInternalSubset: error detected in Markup declaration
++{0}/t8a.xml:6: parser error : internal error: xmlParseInternalSubset: error detected in Markup declaration
+ 
+ %defroot;%defmiddle;%deftest;
+                              ^
+ Entity: line 1: 
+ &lt;!ELEMENT test (#PCDATA) >
+ ^
+-""",
++""".format(dir_prefix),
+     'xlink':
+-"""../../test/valid/xlink.xml:450: element termdef: validity error : ID dt-arc already defined
++"""{0}/xlink.xml:450: element termdef: validity error : ID dt-arc already defined
+ 	<p><termdef id="dt-arc" term="Arc">An <ter
+ 	                                  ^
+ validity error : attribute def line 199 references an unknown ID "dt-xlg"
+-""",
++""".format(dir_prefix),
+ }
+ 
+ # Add prefix_dir and extension to the keys
+-expect = {"{}{}.xml".format(dir_prefix, key): val for key, val in expect.items()}
++expect = {os.path.join(dir_prefix, key + ".xml"): val for key, val in expect.items()}
+ 
+ def callback(ctx, str):
+     global err
+@@ -124,11 +124,12 @@ def callback(ctx, str):
+ libxml2.registerErrorHandler(callback, "")
+ 
+ parsing_error_files = ["766956", "cond_sect2", "t8", "t8a"]
+-expect_parsing_error = ["{}{}.xml".format(dir_prefix, f) for f in parsing_error_files]
++expect_parsing_error = [os.path.join(dir_prefix, f + ".xml") for f in parsing_error_files]
+ 
+-valid_files = glob.glob(dir_prefix + "*.x*")
++valid_files = glob.glob(os.path.join(dir_prefix, "*.x*"))
+ assert valid_files, "found no valid files in '{}'".format(dir_prefix)
+ valid_files.sort()
++failures = 0
+ for file in valid_files:
+     err = ""
+     reader = libxml2.newTextReaderFilename(file)
+@@ -142,9 +143,15 @@ for file in valid_files:
+         #sys.exit(1)
+     if (err):
+         if not(file in expect and err == expect[file]):
++            failures += 1
+             print("Error: ", err)
+             if file in expect:
+                 print("Expected: ", expect[file])
++
++if failures:
++    print("Failed %d tests" % failures)
++    sys.exit(1)
++
+ #
+ # another separate test based on Stephane Bidoul one
+ #
+@@ -337,9 +344,11 @@ while reader.Read() == 1:
+ if res != expect:
+     print("test5 failed: unexpected output")
+     print(res)
++    sys.exit(1)
+ if err != "":
+     print("test5 failed: validation error found")
+     print(err)
++    sys.exit(1)
+ 
+ #
+ # cleanup
+diff --git a/runsuite.c b/runsuite.c
+index 483490a2..a522d24b 100644
+--- a/runsuite.c
++++ b/runsuite.c
+@@ -1054,13 +1054,18 @@ main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
+     old_tests = nb_tests;
+     old_leaks = nb_leaks;
+     xsdTest();
+-    if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
+-	printf("Ran %d tests, no errors\n", nb_tests - old_tests);
+-    else
+-	printf("Ran %d tests, %d errors, %d leaks\n",
+-	       nb_tests - old_tests,
+-	       nb_errors - old_errors,
+-	       nb_leaks - old_leaks);
++    printf("Ran %d tests, %d errors, %d leaks\n",
++           nb_tests - old_tests,
++           nb_errors - old_errors,
++           nb_leaks - old_leaks);
++    if (nb_errors - old_errors == 10) {
++        printf("10 errors were expected\n");
++        nb_errors = old_errors;
++    } else {
++        printf("10 errors were expected, got %d errors\n",
++               nb_errors - old_errors);
++        nb_errors = old_errors + 1;
++    }
+     old_errors = nb_errors;
+     old_tests = nb_tests;
+     old_leaks = nb_leaks;
diff --git a/meta/recipes-core/libxml/libxml2/run-ptest b/meta/recipes-core/libxml/libxml2/run-ptest
index d5c7bb5b02f..f252a78f179 100755
--- a/meta/recipes-core/libxml/libxml2/run-ptest
+++ b/meta/recipes-core/libxml/libxml2/run-ptest
@@ -5,7 +5,7 @@ set -e
 export LC_ALL=en_US.UTF-8
 
 # testModule isn't that useful and hard-codes buildtree, so we don't run that
-TESTS="runtest testrecurse testchar testdict testThreads runxmlconf testapi"
+TESTS="runtest runsuite testrecurse testchar testdict testThreads runxmlconf testapi"
 
 for T in $TESTS; do
     echo Running $T
diff --git a/meta/recipes-core/libxml/libxml2_2.10.3.bb b/meta/recipes-core/libxml/libxml2_2.10.3.bb
index 32b37aacdb5..645d102e785 100644
--- a/meta/recipes-core/libxml/libxml2_2.10.3.bb
+++ b/meta/recipes-core/libxml/libxml2_2.10.3.bb
@@ -16,6 +16,7 @@ inherit gnomebase
 SRC_URI += "http://www.w3.org/XML/Test/xmlts20080827.tar.gz;subdir=${BP};name=testtar \
            file://run-ptest \
            file://libxml-64bit.patch \
+           file://fix-tests.patch \
            file://install-tests.patch \
            file://libxml-m4-use-pkgconfig.patch \
            "
