?
/**
@file write_protection.h
@brief Disable/Enable write protection
@details Copyright (c) 2024 Acronis International GmbH
@author Denis Kopyrin (Denis.Kopyrin@acronis.com)
@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));
}