Virtualization is becoming a key technology for embedded systems designs, especially for applications with mixed-criticality and security levels. Consequently, safety-critical OSes are more susceptible to the most common malicious cyber-attacks such as code-reuse attacks (CRA) or return-oriented programming (ROP). The control-flow integrity (CFI) technique is one of the most efficient to counteract this kind of attacks. CFI is undoubtedly a powerful technique but scarcely applicable in real cases, especially for the overhead introduced to ensure complete graph enforcement. Processor designers recently started to provide hardware-based support to efficiently implement CFI, such as the pointer authentication (PA) feature provided by ARM starting from ARMv8.3-A processor architectures. These CFI mechanisms are also accompanied by support in the mainline codebase of popular compilers (such as GCC and LLVM) and the Linux operating system. As such, they are expected to establish widespread security mechanisms. Nevertheless, many commercial chips still do not support hardware-assisted CFI, even some of the ones that just entered the market. The lack of support of security mechanisms for legacy architecture is an issue when dealing with portable software. Our work focus on a solution to enable hardware-assisted CFI on heterogeneous platforms that include a field-programmable gate array (FPGA) fabric, such as the Xilinx Ultrascale+ and Versal called PAC-PL. PAC-PL comes with compiler- and OS-level support is compatible with ARM's PA, and enables hypervisor-centric attack-detection and recovery strategy. Improvement of keys management can be realized with little effort exploiting the capabilities of the virtualization extension offered by ARM, such as the TrustZone technology. PAC-PL was experimentally evaluated with state-of-the-art benchmarks in terms of run-time overhead, memory footprint, and FPGA resource consumption, resulting in a practical solution for implementing CFI. Our current investigations focus on performing a comprehensive comparison against full-software approaches and on improving the protection model to reduce the total overhead introduced by the mechanism, for instance, protecting only vulnerable sections of code and limiting the usage to a restricted set of functions.