diff --git a/runner/executor.c b/runner/executor.c
index c4b99115e45beb725e8c8b576c59da84ca16ce24..a56cb5d66de19e172f2380806d166251ac066a0e 100644
--- a/runner/executor.c
+++ b/runner/executor.c
@@ -1031,6 +1031,9 @@ static int monitor_output(pid_t child,
 					fdatasync(outputs[_F_JOURNAL]);
 				}
 
+				if (status == IGT_EXIT_ABORT)
+					aborting = true;
+
 				if (time_spent)
 					*time_spent = time;
 			}
diff --git a/runner/json_tests_data/aborted-after-a-test/reference.json b/runner/json_tests_data/aborted-after-a-test/reference.json
index 583242c78a7c0987d0fb48a06157ff3d56c49446..0776f75822189cb479dfa262a42b539536290c9d 100644
--- a/runner/json_tests_data/aborted-after-a-test/reference.json
+++ b/runner/json_tests_data/aborted-after-a-test/reference.json
@@ -60,6 +60,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":4,
       "fail":1,
@@ -72,6 +73,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":4,
       "fail":1,
@@ -84,6 +86,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":1,
       "fail":0,
@@ -96,6 +99,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":1,
       "fail":0,
@@ -108,6 +112,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":2,
       "fail":0,
@@ -120,6 +125,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":1,
diff --git a/runner/json_tests_data/aborted-on-boot/reference.json b/runner/json_tests_data/aborted-on-boot/reference.json
index d354fbac13ea7ea5748771bd9cbb842bd2a4597e..75f1946605bfe1b0671c3d4e7e5e006938791a72 100644
--- a/runner/json_tests_data/aborted-on-boot/reference.json
+++ b/runner/json_tests_data/aborted-on-boot/reference.json
@@ -54,6 +54,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":5,
       "fail":1,
@@ -66,6 +67,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":5,
       "fail":1,
@@ -78,6 +80,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":2,
       "fail":0,
@@ -90,6 +93,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":1,
       "fail":0,
@@ -102,6 +106,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":2,
       "fail":0,
@@ -114,6 +119,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":1,
diff --git a/runner/json_tests_data/dmesg-escapes/reference.json b/runner/json_tests_data/dmesg-escapes/reference.json
index 70d6b3662cb8b24b13d2536db4a02f656a663c69..91c573106d98333dcb714be4c72ed16101ee9076 100644
--- a/runner/json_tests_data/dmesg-escapes/reference.json
+++ b/runner/json_tests_data/dmesg-escapes/reference.json
@@ -30,6 +30,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -42,6 +43,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -54,6 +56,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
diff --git a/runner/json_tests_data/dmesg-results/reference.json b/runner/json_tests_data/dmesg-results/reference.json
index 0edbae931b1454cebd3b7eddac9f4ad0a17ced98..e9e011853ae8c0d672a8036b1e4c86844d0e3049 100644
--- a/runner/json_tests_data/dmesg-results/reference.json
+++ b/runner/json_tests_data/dmesg-results/reference.json
@@ -81,6 +81,7 @@
       "dmesg-warn":2,
       "skip":2,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -93,6 +94,7 @@
       "dmesg-warn":2,
       "skip":2,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -105,6 +107,7 @@
       "dmesg-warn":1,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -117,6 +120,7 @@
       "dmesg-warn":1,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -129,6 +133,7 @@
       "dmesg-warn":0,
       "skip":2,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
diff --git a/runner/json_tests_data/dmesg-warn-level-one-piglit-style/reference.json b/runner/json_tests_data/dmesg-warn-level-one-piglit-style/reference.json
index 4ccb18ae504e7dcdec31683fbd46b3fb52d54e02..8d266cdfa90ad8d402d5f6eb6d08d3b59df09c1f 100644
--- a/runner/json_tests_data/dmesg-warn-level-one-piglit-style/reference.json
+++ b/runner/json_tests_data/dmesg-warn-level-one-piglit-style/reference.json
@@ -31,6 +31,7 @@
       "dmesg-warn":1,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -43,6 +44,7 @@
       "dmesg-warn":1,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -55,6 +57,7 @@
       "dmesg-warn":1,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
diff --git a/runner/json_tests_data/dmesg-warn-level-piglit-style/reference.json b/runner/json_tests_data/dmesg-warn-level-piglit-style/reference.json
index d706ee4cd39337f45beb16213f6141654cec5b3b..4a1e8b313aa94a361a72c72e548a5c9de3a79934 100644
--- a/runner/json_tests_data/dmesg-warn-level-piglit-style/reference.json
+++ b/runner/json_tests_data/dmesg-warn-level-piglit-style/reference.json
@@ -31,6 +31,7 @@
       "dmesg-warn":1,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -43,6 +44,7 @@
       "dmesg-warn":1,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -55,6 +57,7 @@
       "dmesg-warn":1,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
diff --git a/runner/json_tests_data/dmesg-warn-level/reference.json b/runner/json_tests_data/dmesg-warn-level/reference.json
index 11cc39d9a9ce64d830a49eb2f0b78c6b5197b711..400e9cfbc34b4c275f26db61f56dbd7e5d650931 100644
--- a/runner/json_tests_data/dmesg-warn-level/reference.json
+++ b/runner/json_tests_data/dmesg-warn-level/reference.json
@@ -31,6 +31,7 @@
       "dmesg-warn":1,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -43,6 +44,7 @@
       "dmesg-warn":1,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -55,6 +57,7 @@
       "dmesg-warn":1,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
diff --git a/runner/json_tests_data/dynamic-subtest-name-in-multiple-subtests/reference.json b/runner/json_tests_data/dynamic-subtest-name-in-multiple-subtests/reference.json
index 370fce4d77bf7a896d6478088ec3a257e7131d22..514de06a4f320b49bae0bd5eb986beb0126ce529 100644
--- a/runner/json_tests_data/dynamic-subtest-name-in-multiple-subtests/reference.json
+++ b/runner/json_tests_data/dynamic-subtest-name-in-multiple-subtests/reference.json
@@ -42,6 +42,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -54,6 +55,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -66,6 +68,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
diff --git a/runner/json_tests_data/dynamic-subtests/reference.json b/runner/json_tests_data/dynamic-subtests/reference.json
index ca8f6cd78177ff00d035d0a7cc48a55b65610e77..c013d2821b5457c78eb045a8f87798cca70a5c2e 100644
--- a/runner/json_tests_data/dynamic-subtests/reference.json
+++ b/runner/json_tests_data/dynamic-subtests/reference.json
@@ -90,6 +90,7 @@
       "dmesg-warn":0,
       "skip":1,
       "incomplete":1,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":2,
@@ -102,6 +103,7 @@
       "dmesg-warn":0,
       "skip":1,
       "incomplete":1,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":2,
@@ -114,6 +116,7 @@
       "dmesg-warn":0,
       "skip":1,
       "incomplete":1,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":2,
diff --git a/runner/json_tests_data/empty-result-files/reference.json b/runner/json_tests_data/empty-result-files/reference.json
index ef22560185e8f6acba4083a8c9541e45ab3a6e0b..f81ffb81c13b43f40262df77a503de7c6556d832 100644
--- a/runner/json_tests_data/empty-result-files/reference.json
+++ b/runner/json_tests_data/empty-result-files/reference.json
@@ -24,6 +24,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":1,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -36,6 +37,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":1,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -48,6 +50,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":1,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
diff --git a/runner/json_tests_data/incomplete-before-any-subtests/reference.json b/runner/json_tests_data/incomplete-before-any-subtests/reference.json
index b8a76dd7035a2780e9ff0e40d2624332c0ad311f..2a4bd45609b12a52d4d6ed6953962da7d468d9bd 100644
--- a/runner/json_tests_data/incomplete-before-any-subtests/reference.json
+++ b/runner/json_tests_data/incomplete-before-any-subtests/reference.json
@@ -49,6 +49,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":1,
+      "abort":0,
       "timeout":0,
       "notrun":4,
       "fail":0,
@@ -61,6 +62,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":1,
+      "abort":0,
       "timeout":0,
       "notrun":4,
       "fail":0,
@@ -73,6 +75,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":1,
+      "abort":0,
       "timeout":0,
       "notrun":1,
       "fail":0,
@@ -85,6 +88,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":1,
       "fail":0,
@@ -97,6 +101,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":2,
       "fail":0,
diff --git a/runner/json_tests_data/normal-run/reference.json b/runner/json_tests_data/normal-run/reference.json
index 982038f98829101a458c8e88326ef6f04bba0603..0a00b1ca8a1e5133b055f353990f62144cf96039 100644
--- a/runner/json_tests_data/normal-run/reference.json
+++ b/runner/json_tests_data/normal-run/reference.json
@@ -78,6 +78,7 @@
       "dmesg-warn":0,
       "skip":2,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":1,
@@ -90,6 +91,7 @@
       "dmesg-warn":0,
       "skip":2,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":1,
@@ -102,6 +104,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":1,
@@ -114,6 +117,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -126,6 +130,7 @@
       "dmesg-warn":0,
       "skip":2,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
diff --git a/runner/json_tests_data/notrun-results-multiple-mode/reference.json b/runner/json_tests_data/notrun-results-multiple-mode/reference.json
index 492c0a9e6b7ed72b5c044421f0391586298e0ff5..3f8b7fb09edd10df2adcde75360f58a812bc8aee 100644
--- a/runner/json_tests_data/notrun-results-multiple-mode/reference.json
+++ b/runner/json_tests_data/notrun-results-multiple-mode/reference.json
@@ -48,6 +48,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":3,
       "fail":0,
@@ -60,6 +61,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":3,
       "fail":0,
@@ -72,6 +74,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":1,
       "fail":0,
@@ -84,6 +87,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":2,
       "fail":0,
diff --git a/runner/json_tests_data/notrun-results/reference.json b/runner/json_tests_data/notrun-results/reference.json
index 49a2f693de20462df55eed4712fa0f9766014c99..800de38c54af9988fe7cb594919a29317619d3ba 100644
--- a/runner/json_tests_data/notrun-results/reference.json
+++ b/runner/json_tests_data/notrun-results/reference.json
@@ -54,6 +54,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":4,
       "fail":0,
@@ -66,6 +67,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":4,
       "fail":0,
@@ -78,6 +80,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":1,
       "fail":0,
@@ -90,6 +93,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":1,
       "fail":0,
@@ -102,6 +106,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":2,
       "fail":0,
diff --git a/runner/json_tests_data/piglit-style-dmesg/reference.json b/runner/json_tests_data/piglit-style-dmesg/reference.json
index 45d6108ee259a5b9c5ac34c82c900d7e759e41b6..bf5d86ee392d7f94066eac322af31765365d809b 100644
--- a/runner/json_tests_data/piglit-style-dmesg/reference.json
+++ b/runner/json_tests_data/piglit-style-dmesg/reference.json
@@ -78,6 +78,7 @@
       "dmesg-warn":0,
       "skip":2,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -90,6 +91,7 @@
       "dmesg-warn":0,
       "skip":2,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -102,6 +104,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -114,6 +117,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -126,6 +130,7 @@
       "dmesg-warn":0,
       "skip":2,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
diff --git a/runner/json_tests_data/unprintable-characters/reference.json b/runner/json_tests_data/unprintable-characters/reference.json
index d3add1ebf628fb0dc83a0550b057392b66a4f37f..88c62c34d1a8bf489c5cb095f7c88f2fafb9cbc1 100644
--- a/runner/json_tests_data/unprintable-characters/reference.json
+++ b/runner/json_tests_data/unprintable-characters/reference.json
@@ -30,6 +30,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -42,6 +43,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -54,6 +56,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -69,4 +72,4 @@
       }
     }
   }
-}
\ No newline at end of file
+}
diff --git a/runner/json_tests_data/warnings-with-dmesg-warns/reference.json b/runner/json_tests_data/warnings-with-dmesg-warns/reference.json
index fa571703a2ef8ce2abc8c8955b8b8931a67f107c..bd0bb3a3dd43764be2e1e6ee73e257bf4430c0ba 100644
--- a/runner/json_tests_data/warnings-with-dmesg-warns/reference.json
+++ b/runner/json_tests_data/warnings-with-dmesg-warns/reference.json
@@ -79,6 +79,7 @@
       "dmesg-warn":1,
       "skip":2,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -91,6 +92,7 @@
       "dmesg-warn":1,
       "skip":2,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -103,6 +105,7 @@
       "dmesg-warn":1,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -115,6 +118,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -127,6 +131,7 @@
       "dmesg-warn":0,
       "skip":2,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
diff --git a/runner/json_tests_data/warnings/reference.json b/runner/json_tests_data/warnings/reference.json
index 53e0c3c74f39e13d5e9270ee4852faa9b15d6199..a2b79da9e081935819617a207fbb9068a59a29ef 100644
--- a/runner/json_tests_data/warnings/reference.json
+++ b/runner/json_tests_data/warnings/reference.json
@@ -78,6 +78,7 @@
       "dmesg-warn":0,
       "skip":2,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -90,6 +91,7 @@
       "dmesg-warn":0,
       "skip":2,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -102,6 +104,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -114,6 +117,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -126,6 +130,7 @@
       "dmesg-warn":0,
       "skip":2,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
diff --git a/runner/resultgen.c b/runner/resultgen.c
index 611d36cb63f718438b19e9554dfb9829c9826f2f..fe59aafeb918294e4eb76146ae50b8c26e54c359 100644
--- a/runner/resultgen.c
+++ b/runner/resultgen.c
@@ -645,6 +645,23 @@ static void process_dynamic_subtest_output(const char *piglit_name,
 					     &dynresulttext, &dyntime,
 					     dyn_result_idx < 0 ? NULL : matches.items[dyn_result_idx].where,
 					     dynend);
+
+			/*
+			 * If a dynamic subsubtest is considered incomplete we
+			 * need to check parent's status first, to be sure that
+			 * the binary hasn't aborted (exit code). If it has
+			 * aborted then we have to attribute this status to our
+			 * subsubtest.
+			 */
+			if (!strcmp(dynresulttext, "incomplete")) {
+				struct json_object *parent_subtest;
+
+				if (json_object_object_get_ex(tests, piglit_name, &parent_subtest) &&
+				    json_object_object_get_ex(parent_subtest, "result", &parent_subtest) &&
+				    !strcmp(json_object_get_string(parent_subtest), "abort"))
+					dynresulttext = "abort";
+			}
+
 			set_result(current_dynamic_test, dynresulttext);
 			set_runtime(current_dynamic_test, dyntime);
 		}
@@ -1078,6 +1095,8 @@ static const char *result_from_exitcode(int exitcode)
 		return "pass";
 	case IGT_EXIT_INVALID:
 		return "skip";
+	case IGT_EXIT_ABORT:
+		return "abort";
 	case INCOMPLETE_EXITCODE:
 		return "incomplete";
 	default:
@@ -1154,6 +1173,17 @@ static void fill_from_journal(int fd,
 		}
 	}
 
+	if (subtests->size && exitcode == IGT_EXIT_ABORT) {
+		char *last_subtest = subtests->subs[subtests->size - 1].name;
+		char subtest_piglit_name[256];
+		struct json_object *subtest_obj;
+
+		generate_piglit_name(entry->binary, last_subtest, subtest_piglit_name, sizeof(subtest_piglit_name));
+		subtest_obj = get_or_create_json_object(tests, subtest_piglit_name);
+
+		set_result(subtest_obj, "abort");
+	}
+
 	if (subtests->size == 0) {
 		char *subtestname = NULL;
 		char piglit_name[256];
@@ -1322,6 +1352,7 @@ static struct json_object *get_totals_object(struct json_object *totals,
 	json_object_object_add(obj, "dmesg-warn", json_object_new_int(0));
 	json_object_object_add(obj, "skip", json_object_new_int(0));
 	json_object_object_add(obj, "incomplete", json_object_new_int(0));
+	json_object_object_add(obj, "abort", json_object_new_int(0));
 	json_object_object_add(obj, "timeout", json_object_new_int(0));
 	json_object_object_add(obj, "notrun", json_object_new_int(0));
 	json_object_object_add(obj, "fail", json_object_new_int(0));
diff --git a/runner/runner_tests.c b/runner/runner_tests.c
index 139ee9fd20aae07a2426af9919cef3f1ae5c7010..60e009607aaab80d6eec68af7c5e8d82bdde7148 100644
--- a/runner/runner_tests.c
+++ b/runner/runner_tests.c
@@ -28,9 +28,10 @@ static const char testdatadir[] = TESTDATA_DIRECTORY;
  * that test binaries without subtests should still be counted as one
  * for this macro.
  */
-#define NUM_TESTDATA_SUBTESTS 6
+#define NUM_TESTDATA_SUBTESTS 15
+#define NUM_TESTDATA_ABORT_SUBTESTS 9
 /* The total number of test binaries in runner/testdata/ */
-#define NUM_TESTDATA_BINARIES 4
+#define NUM_TESTDATA_BINARIES 8
 
 static const char *igt_get_result(struct json_object *tests, const char* testname)
 {
@@ -954,6 +955,7 @@ igt_main
 			struct execute_state state;
 			const char *argv[] = { "runner",
 					       "--dry-run",
+					       "-x", "^abort",
 					       testdatadir,
 					       dirname,
 			};
@@ -964,7 +966,7 @@ igt_main
 			igt_assert(initialize_execute_state(&state, settings, list));
 			igt_assert_eq(state.next, 0);
 			igt_assert(state.dry);
-			igt_assert_eq(list->size, NUM_TESTDATA_SUBTESTS);
+			igt_assert_eq(list->size, NUM_TESTDATA_SUBTESTS - NUM_TESTDATA_ABORT_SUBTESTS);
 
 			igt_assert_f((dirfd = open(dirname, O_DIRECTORY | O_RDONLY)) >= 0,
 				     "Dry run initialization didn't create the results directory.\n");
@@ -985,7 +987,7 @@ igt_main
 			igt_assert(initialize_execute_state_from_resume(dirfd, &state, settings, list));
 			igt_assert_eq(state.next, 0);
 			igt_assert(!state.dry);
-			igt_assert_eq(list->size, NUM_TESTDATA_SUBTESTS);
+			igt_assert_eq(list->size, NUM_TESTDATA_SUBTESTS - NUM_TESTDATA_ABORT_SUBTESTS);
 			/* initialize_execute_state_from_resume() closes the dirfd */
 			igt_assert_f((dirfd = open(dirname, O_DIRECTORY | O_RDONLY)) >= 0,
 				     "Dry run resume somehow deleted the results directory.\n");
@@ -1512,7 +1514,7 @@ igt_main
 			struct execute_state state;
 			struct json_object *results, *tests;
 			const char *argv[] = { "runner",
-					       "-t", "dynamic",
+					       "-t", "^dynamic$",
 					       testdatadir,
 					       dirname,
 			};
@@ -1541,6 +1543,284 @@ igt_main
 		}
 	}
 
+	igt_subtest_group {
+		struct job_list *list = malloc(sizeof(*list));
+		volatile int dirfd = -1;
+		char dirname[] = "tmpdirXXXXXX";
+
+		igt_fixture {
+			igt_require(mkdtemp(dirname) != NULL);
+			rmdir(dirname);
+
+			init_job_list(list);
+		}
+
+		igt_subtest("execute-abort-simple") {
+			struct execute_state state;
+			struct json_object *results, *tests;
+			const char *argv[] = { "runner",
+					       "-t", "^abort-simple$",
+					       testdatadir,
+					       dirname,
+			};
+
+			igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
+			igt_assert(create_job_list(list, settings));
+			igt_assert(initialize_execute_state(&state, settings, list));
+			igt_assert(!execute(&state, settings, list)); /* false = signal abort */
+
+			igt_assert_f((dirfd = open(dirname, O_DIRECTORY | O_RDONLY)) >= 0,
+				     "Execute didn't create the results directory\n");
+			igt_assert_f((results = generate_results_json(dirfd)) != NULL,
+				     "Results parsing failed\n");
+
+			igt_assert(json_object_object_get_ex(results, "tests", &tests));
+
+			igt_assert_eqstr(igt_get_result(tests, "igt@abort-simple"), "abort");
+
+			igt_assert_eq(json_object_put(results), 1);
+		}
+
+		igt_fixture {
+			close(dirfd);
+			clear_directory(dirname);
+			free_job_list(list);
+		}
+	}
+
+	igt_subtest_group {
+		struct job_list *list = malloc(sizeof(*list));
+		volatile int dirfd = -1;
+
+		for (int multiple = 0; multiple <= 1; ++multiple) {
+			char dirname[] = "tmpdirXXXXXX";
+
+			igt_fixture {
+				igt_require(mkdtemp(dirname) != NULL);
+				rmdir(dirname);
+
+				init_job_list(list);
+			}
+
+			igt_subtest_f("execute-abort%s", multiple ? "-multiple" : "") {
+				struct execute_state state;
+				struct json_object *results, *tests;
+				const char *argv[] = { "runner",
+						       "-t", "^abort$",
+						       multiple ? "--multiple-mode" : "--sync",
+						       testdatadir,
+						       dirname,
+				};
+
+				igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
+				igt_assert(create_job_list(list, settings));
+				igt_assert(initialize_execute_state(&state, settings, list));
+				igt_assert(!execute(&state, settings, list)); /* false = signal abort */
+
+				igt_assert_f((dirfd = open(dirname, O_DIRECTORY | O_RDONLY)) >= 0,
+					     "Execute didn't create the results directory\n");
+				igt_assert_f((results = generate_results_json(dirfd)) != NULL,
+					     "Results parsing failed\n");
+
+				igt_assert(json_object_object_get_ex(results, "tests", &tests));
+
+				igt_assert_eqstr(igt_get_result(tests, "igt@abort@a-subtest"), "pass");
+				igt_assert_eqstr(igt_get_result(tests, "igt@abort@b-subtest"), "abort");
+
+				if (multiple) /* no notrun injection for multiple mode */
+					igt_assert_no_result_for(tests, "igt@abort@c-subtest");
+				else
+					igt_assert_eqstr(igt_get_result(tests, "igt@abort@c-subtest"), "notrun");
+
+				igt_assert_eq(json_object_put(results), 1);
+			}
+
+			igt_fixture {
+				close(dirfd);
+				clear_directory(dirname);
+				free_job_list(list);
+			}
+		}
+	}
+
+	igt_subtest_group {
+		struct job_list *list = malloc(sizeof(*list));
+		volatile int dirfd = -1;
+
+		for (int multiple = 0; multiple <= 1; ++multiple) {
+			char dirname[] = "tmpdirXXXXXX";
+
+			igt_fixture {
+				igt_require(mkdtemp(dirname) != NULL);
+				rmdir(dirname);
+
+				init_job_list(list);
+			}
+
+			igt_subtest_f("execute-abort-fixture%s", multiple ? "-multiple" : "") {
+				struct execute_state state;
+				struct json_object *results, *tests;
+				const char *argv[] = { "runner", multiple ? "--multiple-mode" : "--sync",
+						       "-t", "^abort-fixture$",
+						       testdatadir,
+						       dirname,
+				};
+
+				igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
+				igt_assert(create_job_list(list, settings));
+				igt_assert(initialize_execute_state(&state, settings, list));
+				igt_assert(!execute(&state, settings, list)); /* false = signal abort */
+
+				igt_assert_f((dirfd = open(dirname, O_DIRECTORY | O_RDONLY)) >= 0,
+					     "Execute didn't create the results directory\n");
+				igt_assert_f((results = generate_results_json(dirfd)) != NULL,
+					     "Results parsing failed\n");
+
+				igt_assert(json_object_object_get_ex(results, "tests", &tests));
+
+				if (multiple) {
+					/*
+					 * running the whole binary via -t, no
+					 * way of blaming the particular subtest
+					 */
+					igt_assert_eqstr(igt_get_result(tests, "igt@abort-fixture"), "abort");
+					igt_assert_no_result_for(tests, "igt@abort-fixture@a-subtest");
+					igt_assert_no_result_for(tests, "igt@abort-fixture@b-subtest");
+				} else {
+					igt_assert_eqstr(igt_get_result(tests, "igt@abort-fixture@a-subtest"), "abort");
+					igt_assert_eqstr(igt_get_result(tests, "igt@abort-fixture@b-subtest"), "notrun");
+				}
+
+				igt_assert_eq(json_object_put(results), 1);
+			}
+
+			igt_fixture {
+				close(dirfd);
+				clear_directory(dirname);
+				free_job_list(list);
+			}
+		}
+	}
+
+	igt_subtest_group {
+		struct job_list *list = malloc(sizeof(*list));
+		volatile int dirfd = -1;
+
+		for (int multiple = 0; multiple <= 1; ++multiple) {
+			char dirname[] = "tmpdirXXXXXX";
+			char filename[] = "tmplistXXXXXX";
+			const char testlisttext[] = "igt@abort-fixture@b-subtest\n"
+				"igt@abort-fixture@a-subtest\n";
+
+			igt_fixture {
+				int fd;
+				igt_require((fd = mkstemp(filename)) >= 0);
+				igt_require(write(fd, testlisttext, strlen(testlisttext)) == strlen(testlisttext));
+				close(fd);
+				igt_require(mkdtemp(dirname) != NULL);
+				rmdir(dirname);
+
+				init_job_list(list);
+			}
+
+			igt_subtest_f("execute-abort-fixture-testlist%s", multiple ? "-multiple" : "") {
+				struct execute_state state;
+				struct json_object *results, *tests;
+				const char *argv[] = { "runner", multiple ? "--multiple-mode" : "--sync",
+						       "--test-list", filename,
+						       testdatadir,
+						       dirname,
+				};
+
+				igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
+				igt_assert(create_job_list(list, settings));
+				igt_assert(initialize_execute_state(&state, settings, list));
+				igt_assert(!execute(&state, settings, list)); /* false = signal abort */
+
+				igt_assert_f((dirfd = open(dirname, O_DIRECTORY | O_RDONLY)) >= 0,
+					     "Execute didn't create the results directory\n");
+				igt_assert_f((results = generate_results_json(dirfd)) != NULL,
+					     "Results parsing failed\n");
+
+				igt_assert(json_object_object_get_ex(results, "tests", &tests));
+
+				if (multiple) /* multiple mode = no notruns */
+					igt_assert_no_result_for(tests, "igt@abort-fixture@a-subtest");
+				else
+					igt_assert_eqstr(igt_get_result(tests, "igt@abort-fixture@a-subtest"), "notrun");
+
+
+				igt_assert_eqstr(igt_get_result(tests, "igt@abort-fixture@b-subtest"), "abort");
+
+				igt_assert_eq(json_object_put(results), 1);
+			}
+
+			igt_fixture {
+				unlink(filename);
+				close(dirfd);
+				clear_directory(dirname);
+				free_job_list(list);
+			}
+		}
+	}
+
+	igt_subtest_group {
+		struct job_list *list = malloc(sizeof(*list));
+		volatile int dirfd = -1;
+
+		for (int multiple = 0; multiple <= 1; ++multiple) {
+			char dirname[] = "tmpdirXXXXXX";
+
+			igt_fixture {
+				igt_require(mkdtemp(dirname) != NULL);
+				rmdir(dirname);
+
+				init_job_list(list);
+			}
+
+			igt_subtest_f("execute-abort-dynamic%s", multiple ? "-multiple" : "") {
+				struct execute_state state;
+				struct json_object *results, *tests;
+				const char *argv[] = { "runner", multiple ? "--multiple-mode" : "--sync",
+						       "-t", "^abort-dynamic$",
+						       testdatadir,
+						       dirname,
+				};
+
+				igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
+				igt_assert(create_job_list(list, settings));
+				igt_assert(initialize_execute_state(&state, settings, list));
+				igt_assert(!execute(&state, settings, list)); /* false = signal abort */
+
+				igt_assert_f((dirfd = open(dirname, O_DIRECTORY | O_RDONLY)) >= 0,
+					     "Execute didn't create the results directory\n");
+				igt_assert_f((results = generate_results_json(dirfd)) != NULL,
+					     "Results parsing failed\n");
+
+				igt_assert(json_object_object_get_ex(results, "tests", &tests));
+
+				igt_assert_eqstr(igt_get_result(tests, "igt@abort-dynamic@a-subtest@dynamic-1"), "pass");
+				igt_assert_eqstr(igt_get_result(tests, "igt@abort-dynamic@b-subtest@dynamic-1"), "pass");
+				igt_assert_eqstr(igt_get_result(tests, "igt@abort-dynamic@b-subtest@dynamic-2"), "abort");
+
+				igt_assert_no_result_for(tests, "igt@abort-dynamic@b-subtest@dynamic-3");
+
+				if (multiple) /* multiple mode = no notruns */
+					igt_assert_no_result_for(tests, "igt@abort-dynamic@c-subtest");
+				else
+					igt_assert_eqstr(igt_get_result(tests, "igt@abort-dynamic@c-subtest"), "notrun");
+
+				igt_assert_eq(json_object_put(results), 1);
+			}
+
+			igt_fixture {
+				close(dirfd);
+				clear_directory(dirname);
+				free_job_list(list);
+			}
+		}
+	}
+
 	igt_subtest("file-descriptor-leakage") {
 		int i;
 
diff --git a/runner/testdata/abort-dynamic.c b/runner/testdata/abort-dynamic.c
new file mode 100644
index 0000000000000000000000000000000000000000..66cf13a7d18c97cd9daac4b9e475ae451ae121cb
--- /dev/null
+++ b/runner/testdata/abort-dynamic.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright © 2020 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "igt.h"
+
+igt_main
+{
+	igt_subtest_with_dynamic("a-subtest") {
+		igt_dynamic("dynamic-1")
+			;
+	}
+
+	igt_subtest_with_dynamic("b-subtest") {
+		igt_dynamic("dynamic-1")
+			;
+
+		igt_dynamic("dynamic-2")
+			igt_abort_on_f(true, "I'm out!\n");
+
+		igt_dynamic("dynamic-3")
+			;
+	}
+
+	igt_subtest("c-subtest")
+		;
+}
diff --git a/runner/testdata/abort-fixture.c b/runner/testdata/abort-fixture.c
new file mode 100644
index 0000000000000000000000000000000000000000..6a1cb98664683294a2fc4f4d5f967f227e33e206
--- /dev/null
+++ b/runner/testdata/abort-fixture.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright © 2020 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "igt.h"
+
+igt_main
+{
+	igt_fixture {
+		igt_abort_on_f(true, "I'm out!\n");
+	}
+
+	igt_subtest("a-subtest")
+		;
+
+	igt_subtest("b-subtest")
+		;
+}
diff --git a/runner/testdata/abort-simple.c b/runner/testdata/abort-simple.c
new file mode 100644
index 0000000000000000000000000000000000000000..94eef72caa3d73e2d0c362e5725ce7335c2e0d80
--- /dev/null
+++ b/runner/testdata/abort-simple.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright © 2020 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "igt.h"
+
+igt_simple_main
+{
+	igt_abort_on_f(true, "I'm out!\n");
+}
diff --git a/runner/testdata/abort.c b/runner/testdata/abort.c
new file mode 100644
index 0000000000000000000000000000000000000000..074946a4f55644e0135f4163a10a13a195331b6e
--- /dev/null
+++ b/runner/testdata/abort.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright © 2020 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "igt.h"
+
+igt_main
+{
+	igt_subtest("a-subtest")
+		;
+
+	igt_subtest("b-subtest")
+		igt_abort_on_f(true, "I'm out!\n");
+
+	igt_subtest("c-subtest")
+		;
+}
diff --git a/runner/testdata/meson.build b/runner/testdata/meson.build
index 631ba5b9b54516b759b20445097ab14975167bec..1f8225918af3fb4176c68c9fea35d3b75cba23d3 100644
--- a/runner/testdata/meson.build
+++ b/runner/testdata/meson.build
@@ -3,6 +3,10 @@ testdata_progs = [ 'successtest',
 		   'no-subtests',
 		   'skippers',
 		   'dynamic',
+		   'abort',
+		   'abort-dynamic',
+		   'abort-fixture',
+		   'abort-simple',
 		 ]
 
 testdata_executables = []