diff --git a/repos/system_upgrade/common/actors/scancpu/libraries/scancpu.py b/repos/system_upgrade/common/actors/scancpu/libraries/scancpu.py
index 68f5623b34..e5555f99c6 100644
--- a/repos/system_upgrade/common/actors/scancpu/libraries/scancpu.py
+++ b/repos/system_upgrade/common/actors/scancpu/libraries/scancpu.py
@@ -17,6 +17,11 @@ def _get_lscpu_output():
     return ''
 
 
+def _get_cpu_flags(lscpu):
+    flags = lscpu.get('Flags', '')
+    return flags.split()
+
+
 def _get_cpu_entries_for(arch_prefix):
     result = []
     for message in api.consume(DeviceDriverDeprecationData):
@@ -137,4 +142,10 @@ def process():
     api.produce(*_find_deprecation_data_entries(lscpu))
     # Backwards compatibility
     machine_type = lscpu.get('Machine type')
-    api.produce(CPUInfo(machine_type=int(machine_type) if machine_type else None))
+    flags = _get_cpu_flags(lscpu)
+    api.produce(
+            CPUInfo(
+                machine_type=int(machine_type) if machine_type else None,
+                flags=flags
+                )
+            )
diff --git a/repos/system_upgrade/common/actors/scancpu/tests/test_scancpu.py b/repos/system_upgrade/common/actors/scancpu/tests/test_scancpu.py
index 44d4de879f..894fae08cc 100644
--- a/repos/system_upgrade/common/actors/scancpu/tests/test_scancpu.py
+++ b/repos/system_upgrade/common/actors/scancpu/tests/test_scancpu.py
@@ -1,14 +1,59 @@
 import os
 
+import pytest
+
 from leapp.libraries.actor import scancpu
 from leapp.libraries.common import testutils
+from leapp.libraries.common.config.architecture import (
+    ARCH_ARM64,
+    ARCH_PPC64LE,
+    ARCH_S390X,
+    ARCH_SUPPORTED,
+    ARCH_X86_64
+)
 from leapp.libraries.stdlib import api
 from leapp.models import CPUInfo
 
 CUR_DIR = os.path.dirname(os.path.abspath(__file__))
 
+LSCPU = {
+    ARCH_ARM64: {
+        "machine_type": None,
+        "flags": ['fp', 'asimd', 'evtstrm', 'aes', 'pmull', 'sha1', 'sha2', 'crc32', 'cpuid'],
+    },
+    ARCH_PPC64LE: {
+        "machine_type": None,
+        "flags": []
+    },
+    ARCH_S390X: {
+        "machine_type":
+            2827,
+        "flags": [
+            'esan3', 'zarch', 'stfle', 'msa', 'ldisp', 'eimm', 'dfp', 'edat', 'etf3eh', 'highgprs', 'te', 'vx', 'vxd',
+            'vxe', 'gs', 'vxe2', 'vxp', 'sort', 'dflt', 'sie'
+        ]
+    },
+    ARCH_X86_64: {
+        "machine_type":
+            None,
+        "flags": [
+            'fpu', 'vme', 'de', 'pse', 'tsc', 'msr', 'pae', 'mce', 'cx8', 'apic', 'sep', 'mtrr', 'pge', 'mca', 'cmov',
+            'pat', 'pse36', 'clflush', 'dts', 'acpi', 'mmx', 'fxsr', 'sse', 'sse2', 'ss', 'ht', 'tm', 'pbe', 'syscall',
+            'nx', 'pdpe1gb', 'rdtscp', 'lm', 'constant_tsc', 'arch_perfmon', 'pebs', 'bts', 'rep_good', 'nopl',
+            'xtopology', 'nonstop_tsc', 'cpuid', 'aperfmperf', 'pni', 'pclmulqdq', 'dtes64', 'monitor', 'ds_cpl',
+            'vmx', 'smx', 'est', 'tm2', 'ssse3', 'sdbg', 'fma', 'cx16', 'xtpr', 'pdcm', 'pcid', 'dca', 'sse4_1',
+            'sse4_2', 'x2apic', 'movbe', 'popcnt', 'tsc_deadline_timer', 'aes', 'xsave', 'avx', 'f16c', 'rdrand',
+            'lahf_lm', 'abm', 'cpuid_fault', 'epb', 'invpcid_single', 'pti', 'ssbd', 'ibrs', 'ibpb', 'stibp',
+            'tpr_shadow', 'vnmi', 'flexpriority', 'ept', 'vpid', 'ept_ad', 'fsgsbase', 'tsc_adjust', 'bmi1', 'avx2',
+            'smep', 'bmi2', 'erms', 'invpcid', 'cqm', 'xsaveopt', 'cqm_llc', 'cqm_occup_llc', 'dtherm', 'ida', 'arat',
+            'pln', 'pts', 'md_clear', 'flush_l1d'
+        ]
+    },
+}
+
 
 class mocked_get_cpuinfo(object):
+
     def __init__(self, filename):
         self.filename = filename
 
@@ -22,24 +67,25 @@ def __call__(self):
             return '\n'.join(fp.read().splitlines())
 
 
-def test_machine_type(monkeypatch):
+@pytest.mark.parametrize("arch", ARCH_SUPPORTED)
+def test_scancpu(monkeypatch, arch):
 
-    # cpuinfo doesn't contain a machine field
-    mocked_cpuinfo = mocked_get_cpuinfo('lscpu_x86_64')
+    mocked_cpuinfo = mocked_get_cpuinfo('lscpu_' + arch)
     monkeypatch.setattr(scancpu, '_get_lscpu_output', mocked_cpuinfo)
     monkeypatch.setattr(api, 'produce', testutils.produce_mocked())
-    current_actor = testutils.CurrentActorMocked(arch=testutils.architecture.ARCH_X86_64)
+    current_actor = testutils.CurrentActorMocked(arch=arch)
     monkeypatch.setattr(api, 'current_actor', current_actor)
-    scancpu.process()
-    assert api.produce.called == 1
-    assert CPUInfo() == api.produce.model_instances[0]
 
-    # cpuinfo contains a machine field
-    api.produce.called = 0
-    api.produce.model_instances = []
-    current_actor = testutils.CurrentActorMocked(arch=testutils.architecture.ARCH_S390X)
-    monkeypatch.setattr(api, 'current_actor', current_actor)
-    mocked_cpuinfo.filename = 'lscpu_s390x'
     scancpu.process()
+
+    expected = CPUInfo(machine_type=LSCPU[arch]["machine_type"], flags=LSCPU[arch]["flags"])
+    produced = api.produce.model_instances[0]
+
     assert api.produce.called == 1
-    assert CPUInfo(machine_type=2827) == api.produce.model_instances[0]
+
+    # Produced what was expected
+    assert expected.machine_type == produced.machine_type
+    assert sorted(expected.flags) == sorted(produced.flags)
+
+    # Did not produce anything extra
+    assert expected == produced
diff --git a/repos/system_upgrade/common/models/cpuinfo.py b/repos/system_upgrade/common/models/cpuinfo.py
index e3e528386f..ee24556391 100644
--- a/repos/system_upgrade/common/models/cpuinfo.py
+++ b/repos/system_upgrade/common/models/cpuinfo.py
@@ -32,8 +32,8 @@ class CPUInfo(Model):
     # byte_order = fields.StringEnum(['Little Endian', 'Big Endian'])
     # """ Byte order of the CPU: 'Little Endian' or 'Big Endian' """
 
-    # flags = fields.List(fields.String(), default=[])
-    # """ Specifies flags/features of the CPU. """
+    flags = fields.List(fields.String(), default=[])
+    """ Specifies flags/features of the CPU. """
 
     # hypervisor = fields.Nullable(fields.String())
     # hypervisor_vendor = fields.Nullable(fields.String())
diff --git a/repos/system_upgrade/el8toel9/actors/checkmicroarchitecture/actor.py b/repos/system_upgrade/el8toel9/actors/checkmicroarchitecture/actor.py
new file mode 100644
index 0000000000..98ffea808b
--- /dev/null
+++ b/repos/system_upgrade/el8toel9/actors/checkmicroarchitecture/actor.py
@@ -0,0 +1,63 @@
+import leapp.libraries.actor.checkmicroarchitecture as checkmicroarchitecture
+from leapp.actors import Actor
+from leapp.models import CPUInfo
+from leapp.reporting import Report
+from leapp.tags import ChecksPhaseTag, IPUWorkflowTag
+
+
+class CheckMicroarchitecture(Actor):
+    """
+    Inhibit if RHEL9 microarchitecture requirements are not satisfied
+
+
+    As per `x86-64-ABI`_ In addition to the AMD64 baseline architecture, several
+    micro-architecture levels implemented by later CPU modules have been
+    defined, starting at level ``x86-64-v2``. The levels are cumulative in the
+    sense that features from previous levels are implicitly included in later
+    levels.
+
+    RHEL9 has a higher CPU requirement than older versions, it now requires a
+    CPU compatible with ``x86-64-v2`` instruction set or higher.
+
+    .. table:: Required CPU features by microarchitecure level with a
+               corresponding flag as shown by ``lscpu``.
+
+        +------------+-------------+--------------------+
+        | Version    | CPU Feature | flag (lscpu)       |
+        +============+=============+====================+
+        | (baseline) | CMOV        | cmov               |
+        |            | CX8         | cx8                |
+        |            | FPU         | fpu                |
+        |            | FXSR        | fxsr               |
+        |            | MMX         | mmx                |
+        |            | OSFXSR      | (common with FXSR) |
+        |            | SCE         | syscall            |
+        |            | SSE         | sse                |
+        |            | SSE2        | sse2               |
+        +------------+-------------+--------------------+
+        | x86-64-v2  | CMPXCHG16B  | cx16               |
+        |            | LAHF-SAHF   | lahf_lm            |
+        |            | POPCNT      | popcnt             |
+        |            | SSE3        | pni                |
+        |            | SSE4_1      | sse4_1             |
+        |            | SSE4_2      | sse4_2             |
+        |            | SSSE3       | ssse3              |
+        +------------+-------------+--------------------+
+        | ...        |             |                    |
+        +------------+-------------+--------------------+
+
+    Note: To get the corresponding flag for the CPU feature consult the file
+    ``/arch/x86/include/asm/cpufeatures.h`` in the linux kernel.
+
+
+    .. _x86-64-ABI: https://gitlab.com/x86-psABIs/x86-64-ABI.git
+
+    """
+
+    name = 'check_microarchitecture'
+    consumes = (CPUInfo,)
+    produces = (Report,)
+    tags = (ChecksPhaseTag, IPUWorkflowTag,)
+
+    def process(self):
+        checkmicroarchitecture.process()
diff --git a/repos/system_upgrade/el8toel9/actors/checkmicroarchitecture/libraries/checkmicroarchitecture.py b/repos/system_upgrade/el8toel9/actors/checkmicroarchitecture/libraries/checkmicroarchitecture.py
new file mode 100644
index 0000000000..0f1f1fcae1
--- /dev/null
+++ b/repos/system_upgrade/el8toel9/actors/checkmicroarchitecture/libraries/checkmicroarchitecture.py
@@ -0,0 +1,47 @@
+from leapp import reporting
+from leapp.libraries.common.config.architecture import ARCH_X86_64, matches_architecture
+from leapp.libraries.stdlib import api
+from leapp.models import CPUInfo
+
+X86_64_BASELINE_FLAGS = ['cmov', 'cx8', 'fpu', 'fxsr', 'mmx', 'syscall', 'sse', 'sse2']
+X86_64_V2_FLAGS = ['cx16', 'lahf_lm', 'popcnt', 'pni', 'sse4_1', 'sse4_2', 'ssse3']
+
+
+def _inhibit_upgrade(missing_flags):
+    title = 'Current x86-64 microarchitecture is unsupported in RHEL9'
+    summary = ('RHEL9 has a higher CPU requirement than older versions, it now requires a CPU '
+               'compatible with x86-64-v2 instruction set or higher.\n\n'
+               'Missings flags detected are: {}\n'.format(', '.join(missing_flags)))
+
+    reporting.create_report([
+        reporting.Title(title),
+        reporting.Summary(summary),
+        reporting.ExternalLink(title='Building Red Hat Enterprise Linux 9 for the x86-64-v2 microarchitecture level',
+                               url=('https://developers.redhat.com/blog/2021/01/05/'
+                                    'building-red-hat-enterprise-linux-9-for-the-x86-64-v2-microarchitecture-level')),
+        reporting.Severity(reporting.Severity.HIGH),
+        reporting.Groups([reporting.Groups.INHIBITOR]),
+        reporting.Groups([reporting.Groups.SANITY]),
+        reporting.Remediation(hint=('If case of using virtualization, virtualization platforms often allow '
+                                    'configuring a minimum denominator CPU model for compatibility when migrating '
+                                    'between different CPU models. Ensure that minimum requirements are not below '
+                                    'that of RHEL9\n')),
+    ])
+
+
+def process():
+    """
+    Check whether the processor matches the required microarchitecture.
+    """
+
+    if not matches_architecture(ARCH_X86_64):
+        api.current_logger().info('Architecture not x86-64. Skipping microarchitecture test.')
+        return
+
+    cpuinfo = next(api.consume(CPUInfo))
+
+    required_flags = X86_64_BASELINE_FLAGS + X86_64_V2_FLAGS
+    missing_flags = [flag for flag in required_flags if flag not in cpuinfo.flags]
+    api.current_logger().debug('Required flags missing: %s', missing_flags)
+    if missing_flags:
+        _inhibit_upgrade(missing_flags)
diff --git a/repos/system_upgrade/el8toel9/actors/checkmicroarchitecture/tests/test_checkmicroarchitecture.py b/repos/system_upgrade/el8toel9/actors/checkmicroarchitecture/tests/test_checkmicroarchitecture.py
new file mode 100644
index 0000000000..b7c850d9a0
--- /dev/null
+++ b/repos/system_upgrade/el8toel9/actors/checkmicroarchitecture/tests/test_checkmicroarchitecture.py
@@ -0,0 +1,65 @@
+import pytest
+
+from leapp import reporting
+from leapp.libraries.actor import checkmicroarchitecture
+from leapp.libraries.common.config.architecture import ARCH_SUPPORTED, ARCH_X86_64
+from leapp.libraries.common.testutils import create_report_mocked, CurrentActorMocked, logger_mocked
+from leapp.libraries.stdlib import api
+from leapp.models import CPUInfo
+from leapp.utils.report import is_inhibitor
+
+
+@pytest.mark.parametrize("arch", [arch for arch in ARCH_SUPPORTED if not arch == ARCH_X86_64])
+def test_not_x86_64_passes(monkeypatch, arch):
+    """
+    Test no report is generated on an architecture different from x86-64
+    """
+
+    monkeypatch.setattr(reporting, "create_report", create_report_mocked())
+    monkeypatch.setattr(api, 'current_logger', logger_mocked())
+    monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(arch=arch))
+
+    checkmicroarchitecture.process()
+
+    assert 'Architecture not x86-64. Skipping microarchitecture test.' in api.current_logger.infomsg
+    assert not reporting.create_report.called
+
+
+def test_valid_microarchitecture(monkeypatch):
+    """
+    Test no report is generated on a valid microarchitecture
+    """
+
+    monkeypatch.setattr(reporting, "create_report", create_report_mocked())
+    monkeypatch.setattr(api, 'current_logger', logger_mocked())
+
+    required_flags = checkmicroarchitecture.X86_64_BASELINE_FLAGS + checkmicroarchitecture.X86_64_V2_FLAGS
+    monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(arch=ARCH_X86_64,
+                                                                 msgs=[CPUInfo(flags=required_flags)]))
+
+    checkmicroarchitecture.process()
+
+    assert 'Architecture not x86-64. Skipping microarchitecture test.' not in api.current_logger.infomsg
+    assert not reporting.create_report.called
+
+
+def test_invalid_microarchitecture(monkeypatch):
+    """
+    Test report is generated on x86-64 architecture with invalid microarchitecture and the upgrade is inhibited
+    """
+
+    monkeypatch.setattr(reporting, "create_report", create_report_mocked())
+    monkeypatch.setattr(api, 'current_logger', logger_mocked())
+    monkeypatch.setattr(api, 'current_actor', CurrentActorMocked(arch=ARCH_X86_64, msgs=[CPUInfo()]))
+
+    checkmicroarchitecture.process()
+
+    produced_title = reporting.create_report.report_fields.get('title')
+    produced_summary = reporting.create_report.report_fields.get('summary')
+
+    assert 'Architecture not x86-64. Skipping microarchitecture test.' not in api.current_logger().infomsg
+    assert reporting.create_report.called == 1
+    assert 'microarchitecture is unsupported' in produced_title
+    assert 'RHEL9 has a higher CPU requirement' in produced_summary
+    assert reporting.create_report.report_fields['severity'] == reporting.Severity.HIGH
+    assert is_inhibitor(reporting.create_report.report_fields)