Index: kernel/arch/amd64/include/arch/mm/page.h
===================================================================
--- kernel/arch/amd64/include/arch/mm/page.h	(revision 71307541fd5ee1f557ff938fd3f52195abde393b)
+++ kernel/arch/amd64/include/arch/mm/page.h	(revision 6deab5a6cc081d9fefb96fd6b81bd44054678100)
@@ -192,5 +192,5 @@
 	unsigned int accessed : 1;
 	unsigned int dirty : 1;
-	unsigned int unused : 1;
+	unsigned int pat : 1;
 	unsigned int global : 1;
 	unsigned int soft_valid : 1;  /**< Valid content even if present bit is cleared. */
@@ -211,5 +211,6 @@
 	    p->writeable << PAGE_WRITE_SHIFT |
 	    (!p->no_execute) << PAGE_EXEC_SHIFT |
-	    p->global << PAGE_GLOBAL_SHIFT);
+	    p->global << PAGE_GLOBAL_SHIFT |
+	    p->page_write_through << PAGE_WRITE_COMBINE_SHIFT);
 }
 
@@ -225,5 +226,4 @@
 	pte_t *p = &pt[i];
 
-	p->page_cache_disable = !(flags & PAGE_CACHEABLE);
 	p->present = !(flags & PAGE_NOT_PRESENT);
 	p->uaccessible = (flags & PAGE_USER) != 0;
@@ -232,4 +232,14 @@
 	p->global = (flags & PAGE_GLOBAL) != 0;
 
+	if (flags & PAGE_WRITE_COMBINE) {
+		/* We have mapped PCD+PWT bits to write-combine mode via PAT MSR. */
+		/* (If PAT is unsupported, it will default to uncached.) */
+		p->page_cache_disable = 1;
+		p->page_write_through = 1;
+	} else {
+		p->page_cache_disable = !(flags & PAGE_CACHEABLE);
+		p->page_write_through = 0;
+	}
+
 	/*
 	 * Ensure that there is at least one bit set even if the present bit is cleared.
Index: kernel/arch/amd64/include/arch/mm/pat.h
===================================================================
--- kernel/arch/amd64/include/arch/mm/pat.h	(revision 6deab5a6cc081d9fefb96fd6b81bd44054678100)
+++ kernel/arch/amd64/include/arch/mm/pat.h	(revision 6deab5a6cc081d9fefb96fd6b81bd44054678100)
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2024 Jiří Zárevúcky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup kernel_amd64_mm
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_amd64_MM_PAT_H_
+#define KERN_amd64_MM_PAT_H_
+
+#include <arch/asm.h>
+#include <arch/cpuid.h>
+
+#define MSR_IA32_PAT  0x00000277
+
+typedef enum {
+	PAT_TYPE_UNCACHEABLE = 0,
+	PAT_TYPE_WRITE_COMBINING = 1,
+	PAT_TYPE_WRITE_THROUGH = 4,
+	PAT_TYPE_WRITE_PROTECTED = 5,
+	PAT_TYPE_WRITE_BACK = 6,
+	PAT_TYPE_UNCACHED  = 7,
+} pat_type_t;
+
+/**
+ * Assign caching type for a particular combination of PAT,
+ * PCD and PWT bits in PTE.
+ */
+static inline void pat_set_mapping(bool pat, bool pcd, bool pwt,
+    pat_type_t type)
+{
+	int index = pat << 2 | pcd << 1 | pwt;
+	int shift = index * 8;
+
+	uint64_t r = read_msr(MSR_IA32_PAT);
+	r &= ~(0xffull << shift);
+	r |= ((uint64_t) type) << shift;
+	write_msr(MSR_IA32_PAT, r);
+}
+
+static inline bool pat_supported(void)
+{
+	if (!has_cpuid())
+		return false;
+
+	cpu_info_t info;
+	cpuid(INTEL_CPUID_STANDARD, &info);
+
+	return (info.cpuid_edx & (1 << 16)) != 0;
+}
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/amd64/src/amd64.c
===================================================================
--- kernel/arch/amd64/src/amd64.c	(revision 71307541fd5ee1f557ff938fd3f52195abde393b)
+++ kernel/arch/amd64/src/amd64.c	(revision 6deab5a6cc081d9fefb96fd6b81bd44054678100)
@@ -60,4 +60,5 @@
 #include <arch/vreg.h>
 #include <arch/kseg.h>
+#include <arch/mm/pat.h>
 #include <genarch/pic/pic_ops.h>
 
@@ -115,4 +116,8 @@
 	/* Disable alignment check */
 	write_cr0(read_cr0() & ~CR0_AM);
+
+	/* Use PCD+PWT bit combination in PTE to mean write-combining mode. */
+	if (pat_supported())
+		pat_set_mapping(false, true, true, PAT_TYPE_WRITE_COMBINING);
 
 	if (config.cpu_active == 1) {
Index: kernel/arch/ia32/include/arch/mm/page.h
===================================================================
--- kernel/arch/ia32/include/arch/mm/page.h	(revision 71307541fd5ee1f557ff938fd3f52195abde393b)
+++ kernel/arch/ia32/include/arch/mm/page.h	(revision 6deab5a6cc081d9fefb96fd6b81bd44054678100)
@@ -190,5 +190,6 @@
 	    p->writeable << PAGE_WRITE_SHIFT |
 	    1 << PAGE_EXEC_SHIFT |
-	    p->global << PAGE_GLOBAL_SHIFT);
+	    p->global << PAGE_GLOBAL_SHIFT |
+	    p->page_write_through << PAGE_WRITE_COMBINE_SHIFT);
 }
 
@@ -197,9 +198,18 @@
 	pte_t *p = &pt[i];
 
-	p->page_cache_disable = !(flags & PAGE_CACHEABLE);
 	p->present = !(flags & PAGE_NOT_PRESENT);
 	p->uaccessible = (flags & PAGE_USER) != 0;
 	p->writeable = (flags & PAGE_WRITE) != 0;
 	p->global = (flags & PAGE_GLOBAL) != 0;
+
+	if (flags & PAGE_WRITE_COMBINE) {
+		/* We have mapped PCD+PWT bits to write-combine mode via PAT MSR. */
+		/* (If PAT is unsupported, it will default to uncached.) */
+		p->page_cache_disable = 1;
+		p->page_write_through = 1;
+	} else {
+		p->page_cache_disable = !(flags & PAGE_CACHEABLE);
+		p->page_write_through = 0;
+	}
 
 	/*
Index: kernel/arch/ia32/include/arch/mm/pat.h
===================================================================
--- kernel/arch/ia32/include/arch/mm/pat.h	(revision 6deab5a6cc081d9fefb96fd6b81bd44054678100)
+++ kernel/arch/ia32/include/arch/mm/pat.h	(revision 6deab5a6cc081d9fefb96fd6b81bd44054678100)
@@ -0,0 +1,1 @@
+../../../../amd64/include/arch/mm/pat.h
Index: kernel/arch/ia32/src/ia32.c
===================================================================
--- kernel/arch/ia32/src/ia32.c	(revision 71307541fd5ee1f557ff938fd3f52195abde393b)
+++ kernel/arch/ia32/src/ia32.c	(revision 6deab5a6cc081d9fefb96fd6b81bd44054678100)
@@ -61,4 +61,5 @@
 #include <arch/pm.h>
 #include <arch/vreg.h>
+#include <arch/mm/pat.h>
 
 #ifdef CONFIG_SMP
@@ -104,4 +105,8 @@
 {
 	pm_init();
+
+	/* Use PCD+PWT bit combination in PTE to mean write-combining mode. */
+	if (pat_supported())
+		pat_set_mapping(false, true, true, PAT_TYPE_WRITE_COMBINING);
 
 	if (config.cpu_active == 1) {
Index: kernel/genarch/src/fb/fb.c
===================================================================
--- kernel/genarch/src/fb/fb.c	(revision 71307541fd5ee1f557ff938fd3f52195abde393b)
+++ kernel/genarch/src/fb/fb.c	(revision 6deab5a6cc081d9fefb96fd6b81bd44054678100)
@@ -633,5 +633,5 @@
 
 	instance->addr = (uint8_t *) km_map((uintptr_t) props->addr, fbsize,
-	    KM_NATURAL_ALIGNMENT, PAGE_WRITE | PAGE_NOT_CACHEABLE);
+	    KM_NATURAL_ALIGNMENT, PAGE_WRITE | PAGE_WRITE_COMBINE);
 	if (!instance->addr) {
 		LOG("Unable to map framebuffer.");
Index: kernel/generic/include/mm/mm.h
===================================================================
--- kernel/generic/include/mm/mm.h	(revision 71307541fd5ee1f557ff938fd3f52195abde393b)
+++ kernel/generic/include/mm/mm.h	(revision 6deab5a6cc081d9fefb96fd6b81bd44054678100)
@@ -46,4 +46,5 @@
 #define PAGE_EXEC_SHIFT			5
 #define PAGE_GLOBAL_SHIFT		6
+#define PAGE_WRITE_COMBINE_SHIFT  7
 
 #define PAGE_NOT_CACHEABLE		(0 << PAGE_CACHEABLE_SHIFT)
@@ -62,4 +63,6 @@
 #define PAGE_GLOBAL			(1 << PAGE_GLOBAL_SHIFT)
 
+#define PAGE_WRITE_COMBINE  (1 << PAGE_WRITE_COMBINE_SHIFT)
+
 #endif
 
