/** @file write_protection.h @brief Disable/Enable write protection @details Copyright (c) 2024 Acronis International GmbH @author Denis Kopyrin ([email protected]) @since $Id: $ */ #pragma once #include "compat.h" // On 5.3.0 using the legal 'write_cp0' causes panic because WP is not disabled. // So let's just use out own 'write_cp0' that avoid silly checks. static inline void wp_cr0(unsigned long cr0) { #ifndef KERNEL_MOCK // cr0 is protected register in userspace __asm__ __volatile__ ("mov %0, %%cr0": "+r"(cr0)); #else gCR0 = cr0; #endif } static inline unsigned long disable_write_protect(void) { unsigned long cr0 = read_cr0(); DPRINTF("cr0=%lX WP=%lX", cr0, (unsigned long)X86_CR0_WP); if (cr0 & X86_CR0_WP) { wp_cr0(cr0 & ~X86_CR0_WP); } return cr0; } static inline void restore_write_protect(unsigned long saved_cr0) { unsigned long cr0 = read_cr0(); DPRINTF("cr0=%lX WP=%lX", cr0, (unsigned long)X86_CR0_WP); // restore WP-bit of cr0 to pre-disable state wp_cr0((cr0 & ~X86_CR0_WP) | (saved_cr0 & X86_CR0_WP)); }