Cleanup low-level arch code
Subsystems (2)
v7 cover Cleanup low-level arch code
Andrew et al,
This is 7th attempt to make mainly x86 arch code consistent with other architectures.
I withdrew your Reviewed-by from "x86: Cleanup PT_*_MASK flags" patch 09/11 due to couple of more than just nits changes.
PCD-ed ioremap() could be a follow-up update on top of this series.
Changes since v6:
- ioremap() PCD comment updated;
- PT_PSE_MASK renamed to PT_PAGE_SIZE_MASK;
- GENMASK_ULL used for PT_ADDR_MASK definition;
- missed x86/taskswitch2.c update added;
Changes since v5:
- ioremap() PCD comment added, the Reviewed-by preserved;
- page table flag names changed from PTE_* to PT_*_MASK;
Changes since v4:
- single instead of multiple pages allocation bug fixed in x86 ioremap();
- style fixes squashed into code movements for lib/x86/asm/page.h and
lib/x86/asm/barrier.h;
- #ifndef __ASSEMBLY__ added to lib/x86/asm/page.h;
Changes since v3:
- x86 PAGE_* constants and PTE_* flags cleaned up;
- missing Reviewed-bys restored;
- missing headers to lib/x86/asm/page.h and lib/x86/asm/barriers.h added
(I did not remove already given Reviewed-bys from these);
Changes since v2:
- x86 ioremap() address arithmetics nonsense fixed;
- x86 virt_to_phys() and phys_to_virt() implementations left intact;
- separate overrides of virt_to_phys() and phys_to_virt() added;
- unsigned long size specifier removed from PAGE_SIZE constant;
Changes since v1:
- arm compilation error fixed;
- disabling memory re-ordering for generic memory barriers added;
Alexander Gordeev (11):
Remove unused and unnecessary PHYS32 macro
Move phys_addr_t type definition to lib/libcflat.h
x86: Introduce lib/x86/asm/page.h
x86: Introduce lib/x86/asm/io.h
x86: Introduce lib/x86/asm/barrier.h
io: Separate overrides of virt_to_phys() and phys_to_virt()
io: Disallow memory re-ordering for generic memory barriers
x86: Cleanup PAGE_* constants
x86: Cleanup PT_*_MASK flags
io: Make ioremap() prototype conform to Linux one
x86: io: Factor out ioremap()
arm/selftest.c | 1 -
lib/alloc.h | 5 -----
lib/arm/asm/page.h | 2 --
lib/asm-generic/io.h | 13 +++++++++----
lib/libcflat.h | 2 ++
lib/powerpc/asm/setup.h | 1 -
lib/ppc64/asm/io.h | 2 ++
lib/x86/asm/barrier.h | 13 +++++++++++++
lib/x86/{ => asm}/io.h | 18 ++++++++++++++++--
lib/x86/asm/page.h | 45 +++++++++++++++++++++++++++++++++++++++++++++
lib/x86/asm/pci.h | 2 +-
lib/x86/io.c | 18 +++++++++++++++++-
lib/x86/smp.h | 4 ----
lib/x86/vm.c | 37 ++++++++++---------------------------
lib/x86/vm.h | 25 ++-----------------------
x86/access.c | 14 ++------------
x86/asyncpf.c | 2 +-
x86/eventinj.c | 17 ++++++-----------
x86/hypercall.c | 2 +-
x86/hyperv.c | 1 +
x86/hyperv.h | 1 -
x86/hyperv_stimer.c | 2 +-
x86/hyperv_synic.c | 1 -
x86/init.c | 2 +-
x86/kvmclock.c | 1 +
x86/pku.c | 2 +-
x86/rmap_chain.c | 2 +-
x86/smap.c | 6 +++---
x86/svm.c | 1 -
x86/taskswitch2.c | 2 +-
x86/vmexit.c | 11 ++---------
x86/vmx.c | 1 -
x86/vmx.h | 2 +-
x86/vmx_tests.c | 1 -
34 files changed, 140 insertions(+), 119 deletions(-)
create mode 100644 lib/x86/asm/barrier.h
rename lib/x86/{ => asm}/io.h (74%)
create mode 100644 lib/x86/asm/page.hSignature · 1 line
1.8.3.1
PATCH v7 1/11 Remove unused and unnecessary PHYS32 macro
--- lib/alloc.h | 4 ---- 1 file changed, 4 deletions(-)
lib/alloc.h +0 -4
@@ -58,11 +58,7 @@ static inline void *memalign(size_t alignment, size_t size)return alloc_ops->memalign (alignment, size); } -#ifdef PHYS32 -typedef u32 phys_addr_t ; -#else typedef u64 phys_addr_t ; -#endif #define INVALID_PHYS_ADDR (~(phys_addr_t)0)/*
Signature · 1 line
1.8.3.1
PATCH v7 2/11 Move phys_addr_t type definition to lib/libcflat.h
In reply to Alexander GordeevThis change leads to removing '#include <alloc.h>'s from several places that only included alloc.h to get the typedef.
--- arm/selftest.c | 1 - lib/alloc.h | 1 - lib/arm/asm/page.h | 2 -- lib/libcflat.h | 2 ++ lib/powerpc/asm/setup.h | 1 - 5 files changed, 2 insertions(+), 5 deletions(-)
arm/selftest.c +0 -1
@@ -7,7 +7,6 @@*/ #include <libcflat.h> #include <util.h> -#include <alloc.h> #include <devicetree.h> #include <asm/setup.h> #include <asm/ptrace.h>
lib/alloc.h +0 -1
@@ -58,7 +58,6 @@ static inline void *memalign(size_t alignment, size_t size)return alloc_ops->memalign (alignment, size); } -typedef u64 phys_addr_t ;#define INVALID_PHYS_ADDR (~(phys_addr_t)0)/*
lib/arm/asm/page.h +0 -2
@@ -16,8 +16,6 @@#define PAGE_ALIGN (addr) ALIGN(addr, PAGE_SIZE) -#include <alloc.h> -typedef u64 pteval_t ;typedef u64 pmdval_t ;typedef u64 pgdval_t ;
lib/libcflat.h +2 -0
@@ -60,6 +60,8 @@ typedef _Bool bool;#define PRIx64 __PRI64_PREFIX "x"#define PRIxPTR __PRIPTR_PREFIX "x" +typedef u64 phys_addr_t ; +extern void puts (const char *s);extern void exit (int code);extern void abort (void );
lib/powerpc/asm/setup.h +0 -1
@@ -6,7 +6,6 @@* This work is licensed under the terms of the GNU LGPL, version 2. */ #include <libcflat.h> -#include <alloc.h> /* phys_addr_t */ #define NR_CPUS 8/* arbitrarily set for now */ extern u32 cpus[NR_CPUS ];
Signature · 1 line
1.8.3.1
PATCH v7 3/11 x86: Introduce lib/x86/asm/page.h
In reply to Alexander GordeevMake x86 consistent with other architectures and put memory page specific defines to lib/x86/asm/page.h
--- lib/x86/asm/page.h | 33 +++++++++++++++++++++++++++++++++ lib/x86/vm.c | 17 ----------------- lib/x86/vm.h | 14 +------------- 3 files changed, 34 insertions(+), 30 deletions(-) create mode 100644 lib/x86/asm/page.h
lib/x86/asm/page.h new file +33 -0
@@ -0,0 +1,33 @@ +#ifndef _ASM_X86_PAGE_H_ +#define _ASM_X86_PAGE_H_ +/* +* Copyright (C) 2016, Red Hat Inc, Alexander Gordeev <[email protected]> +* +* This work is licensed under the terms of the GNU LGPL, version 2. +*/ + + +#define PAGE_SIZE 4096ul +#ifdef __x86_64__ +#define LARGE_PAGE_SIZE (512 * PAGE_SIZE) +#else +#define LARGE_PAGE_SIZE (1024 * PAGE_SIZE) +#endif + +#define PTE_PRESENT (1ull << 0) +#define PTE_WRITE (1ull << 1) +#define PTE_USER (1ull << 2) +#define PTE_PSE (1ull << 7) +#define PTE_ADDR (0xffffffffff000ull) + +#ifdef __x86_64__ +#define PAGE_LEVEL 4 +#define PGDIR_WIDTH 9 +#define PGDIR_MASK 511 +#else +#define PAGE_LEVEL 2 +#define PGDIR_WIDTH 10 +#define PGDIR_MASK 1023 +#endif + +#endif
lib/x86/vm.c +0 -17
@@ -2,13 +2,6 @@#include "vm.h" #include "libcflat.h" -#define PAGE_SIZE 4096ul -#ifdef __x86_64__ -#define LARGE_PAGE_SIZE (512 * PAGE_SIZE) -#else -#define LARGE_PAGE_SIZE (1024 * PAGE_SIZE) -#endif -static void *free =0 ;static void *vfree_top =0 ;
@@ -44,16 +37,6 @@ void free_page(void *page)extern char edata;static unsigned long end_of_memory; -#ifdef __x86_64__ -#define PAGE_LEVEL 4 -#define PGDIR_WIDTH 9 -#define PGDIR_MASK 511 -#else -#define PAGE_LEVEL 2 -#define PGDIR_WIDTH 10 -#define PGDIR_MASK 1023 -#endif - unsigned long *install_pte(unsigned long *cr3, int pte_level, void *virt,
lib/x86/vm.h +1 -13
@@ -2,19 +2,7 @@#define VM_H #include "processor.h" - -#define PAGE_SIZE 4096ul -#ifdef __x86_64__ -#define LARGE_PAGE_SIZE (512 * PAGE_SIZE) -#else -#define LARGE_PAGE_SIZE (1024 * PAGE_SIZE) -#endif - -#define PTE_PRESENT (1ull << 0) -#define PTE_PSE (1ull << 7) -#define PTE_WRITE (1ull << 1) -#define PTE_USER (1ull << 2) -#define PTE_ADDR (0xffffffffff000ull) +#include "asm/page.h" void setup_vm ();
Signature · 1 line
1.8.3.1
PATCH v7 4/11 x86: Introduce lib/x86/asm/io.h
In reply to Alexander GordeevMake x86 consistent with other architectures and put IO specific defines to lib/x86/asm/io.h
---
lib/x86/{ => asm}/io.h | 14 ++++++++++++--
lib/x86/asm/pci.h | 2 +-
lib/x86/io.c | 2 +-
lib/x86/vm.h | 11 +----------
x86/eventinj.c | 7 +------
x86/hyperv.c | 1 +
x86/hyperv.h | 1 -
x86/hyperv_stimer.c | 1 -
x86/hyperv_synic.c | 1 -
x86/init.c | 2 +-
x86/svm.c | 1 -
x86/vmexit.c | 1 -
x86/vmx.c | 1 -
x86/vmx_tests.c | 1 -
14 files changed, 18 insertions(+), 28 deletions(-)
rename lib/x86/{ => asm}/io.h (79%)lib/x86/asm/io.h renamed from lib/x86/io.h +12 -2
@@ -1,5 +1,5 @@ -#ifndef IO_H -#define IO_H +#ifndef _ASM_X86_IO_H_ +#define _ASM_X86_IO_H_static inline unsigned char inb (unsigned short port) {
@@ -37,4 +37,14 @@ static inline void outl(unsigned int value, unsigned short port) asm volatile("outl %0, %w1" : : "a"(value), "Nd"(port)); } +static inline unsigned long virt_to_phys (const void *virt) +{ +return (unsigned long )virt; +} + +static inline void *phys_to_virt (unsigned long phys) +{ +return (void *)phys; +} +#endif
lib/x86/asm/pci.h +1 -1
@@ -7,7 +7,7 @@*/ #include "libcflat.h" #include "pci.h" -#include "x86/io.h" +#include "x86/asm/io.h" static inline uint32_t pci_config_read (pcidevaddr_t dev,uint8_t reg) {
lib/x86/io.c +1 -1
@@ -1,6 +1,6 @@#include "libcflat.h" #include "smp.h" -#include "io.h" +#include "asm/io.h" #ifndef USE_SERIAL #define USE_SERIAL #endif
lib/x86/vm.h +1 -10
@@ -3,6 +3,7 @@#include "processor.h" #include "asm/page.h" +#include "asm/io.h" void setup_vm ();
@@ -27,14 +28,4 @@ unsigned long *install_large_page(unsigned long *cr3,unsigned long phys, void *virt);unsigned long *install_page (unsigned long *cr3,unsigned long phys,void *virt); -static inline unsigned long virt_to_phys (const void *virt) -{ -return (unsigned long )virt; -} - -static inline void *phys_to_virt (unsigned long phys) -{ -return (void *)phys; -} -#endif
x86/eventinj.c +1 -6
@@ -16,11 +16,6 @@ static inline void io_delay(void) { } -static inline void outl (int addr,int val) -{ - asmvolatile ("outl %1, %w0" : :"d" (addr),"a" (val)); -} -void apic_self_ipi (u8 v) { apic_icr_write(APIC_DEST_SELF | APIC_DEST_PHYSICAL | APIC_DM_FIXED |
@@ -32,7 +27,7 @@ void apic_self_nmi(void)apic_icr_write (APIC_DEST_PHYSICAL |APIC_DM_NMI |APIC_INT_ASSERT ,0 ); } -#define flush_phys_addr (__s) outl(0xe4, __s) +#define flush_phys_addr (__s) outl(__s, 0xe4)#define flush_stack () do { \ int __l; \ flush_phys_addr(virt_to_phys(&__l)); \
x86/hyperv.c +1 -0
@@ -1,4 +1,5 @@#include "hyperv.h" +#include "asm/io.h" static void synic_ctl (u8 ctl,u8 vcpu_id,u8 sint) {
x86/hyperv.h +0 -1
@@ -3,7 +3,6 @@#include "libcflat.h" #include "processor.h" -#include "io.h" #define HYPERV_CPUID_FEATURES 0x40000003
x86/hyperv_stimer.c +0 -1
@@ -5,7 +5,6 @@#include "vm.h" #include "apic.h" #include "desc.h" -#include "io.h" #include "smp.h" #include "atomic.h" #include "hyperv.h"
x86/hyperv_synic.c +0 -1
@@ -5,7 +5,6 @@#include "vm.h" #include "apic.h" #include "desc.h" -#include "io.h" #include "smp.h" #include "atomic.h" #include "hyperv.h"
x86/init.c +1 -1
@@ -1,6 +1,6 @@#include "libcflat.h" #include "apic.h" -#include "io.h" +#include "asm/io.h" #define KBD_CCMD_READ_OUTPORT 0xD0/* read output port */ #define KBD_CCMD_WRITE_OUTPORT 0xD1/* write output port */
x86/svm.c +0 -1
@@ -6,7 +6,6 @@#include "vm.h" #include "smp.h" #include "types.h" -#include "io.h" /* for the nested page table*/ u64 *pml4e;
x86/vmexit.c +0 -1
@@ -6,7 +6,6 @@#include "x86/vm.h" #include "x86/desc.h" #include "x86/acpi.h" -#include "x86/io.h" struct test {void (*func)(void );
x86/vmx.c +0 -1
@@ -35,7 +35,6 @@#include "vmx.h" #include "msr.h" #include "smp.h" -#include "io.h" u64 *vmxon_region;struct vmcs *vmcs_root;
x86/vmx_tests.c +0 -1
@@ -7,7 +7,6 @@#include "msr.h" #include "processor.h" #include "vm.h" -#include "io.h" #include "fwcfg.h" #include "isr.h" #include "apic.h"
Signature · 1 line
1.8.3.1
PATCH v7 5/11 x86: Introduce lib/x86/asm/barrier.h
In reply to Alexander GordeevMake x86 consistent with other architectures and put memory barrier defines to lib/x86/asm/barrier.h
--- lib/x86/asm/barrier.h | 13 +++++++++++++ lib/x86/smp.h | 4 ---- x86/hyperv_stimer.c | 1 + x86/kvmclock.c | 1 + 4 files changed, 15 insertions(+), 4 deletions(-) create mode 100644 lib/x86/asm/barrier.h
lib/x86/asm/barrier.h new file +13 -0
@@ -0,0 +1,13 @@ +#ifndef _ASM_X86_BARRIER_H_ +#define _ASM_X86_BARRIER_H_ +/* +* Copyright (C) 2016, Red Hat Inc, Alexander Gordeev <[email protected]> +* +* This work is licensed under the terms of the GNU LGPL, version 2. +*/ + +#define mb () asm volatile("mfence":::"memory") +#define rmb () asm volatile("lfence":::"memory") +#define wmb () asm volatile("sfence":::"memory") + +#endif
lib/x86/smp.h +0 -4
@@ -2,10 +2,6 @@#define __SMP_H#include <asm/spinlock.h> -#define mb () asm volatile("mfence":::"memory") -#define rmb () asm volatile("lfence":::"memory") -#define wmb () asm volatile("sfence" ::: "memory") -void smp_init (void );int cpu_count (void );
x86/hyperv_stimer.c +1 -0
@@ -8,6 +8,7 @@#include "smp.h" #include "atomic.h" #include "hyperv.h" +#include "asm/barrier.h" #define MAX_CPUS 4
x86/kvmclock.c +1 -0
@@ -3,6 +3,7 @@#include "atomic.h" #include "processor.h" #include "kvmclock.h" +#include "asm/barrier.h" #define unlikely (x) __builtin_expect(!!(x), 0)#define likely (x) __builtin_expect(!!(x), 1)
Signature · 1 line
1.8.3.1
PATCH v7 6/11 io: Separate overrides of virt_to_phys() and phys_to_virt()
In reply to Alexander GordeevGeneric implementations of virt_to_phys() and phys_to_virt() are currently covered by a single "virt_to_phys" macro. Introduce additional macro "phys_to_virt" to allow separate overrides.
--- lib/asm-generic/io.h | 2 ++ 1 file changed, 2 insertions(+)
lib/asm-generic/io.h +2 -0
@@ -165,7 +165,9 @@ static inline unsigned long virt_to_phys(volatile void *address) {return __pa ((unsigned long )address); } +#endif +#ifndef phys_to_virtstatic inline void *phys_to_virt (unsigned long address) {return __va (address);
Signature · 1 line
1.8.3.1
PATCH v7 7/11 io: Disallow memory re-ordering for generic memory barriers
In reply to Alexander Gordeev--- lib/asm-generic/io.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
lib/asm-generic/io.h +5 -2
@@ -127,11 +127,14 @@ static inline u64 __bswap64(u64 x) ({ u64 __r = !__cpu_is_be() ? __bswap64(x) : ((u64)x); __r; })#define cpu_to_be64 be64_to_cpu +#ifndef mb +#define mb () asm volatile("":::"memory") +#endif #ifndef rmb -#define rmb () do { } while (0) +#define rmb () asm volatile("":::"memory")#endif #ifndef wmb -#define wmb () do { } while (0) +#define wmb () asm volatile("":::"memory")#endif #define readb (addr) \
Signature · 1 line
1.8.3.1
PATCH v7 8/11 x86: Cleanup PAGE_* constants
In reply to Alexander Gordeev--- lib/x86/asm/page.h | 10 +++++++++- x86/access.c | 4 +--- x86/vmx.h | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-)
lib/x86/asm/page.h +9 -1
@@ -7,7 +7,14 @@*/ -#define PAGE_SIZE 4096ul +#include <linux/const.h> + +#define PAGE_SHIFT 12 +#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) +#define PAGE_MASK (~(PAGE_SIZE-1)) + +#ifndef __ASSEMBLY__ +#ifdef __x86_64__#define LARGE_PAGE_SIZE (512 * PAGE_SIZE)#else
@@ -30,4 +37,5 @@#define PGDIR_MASK 1023#endif +#endif /* !__ASSEMBLY__ */ #endif
x86/access.c +1 -3
@@ -2,6 +2,7 @@#include "libcflat.h" #include "desc.h" #include "processor.h" +#include "asm/page.h" #define smp_id () 0
@@ -15,9 +16,6 @@ static int cpuid_7_ebx;static int cpuid_7_ecx;static int invalid_mask; -#define PAGE_SIZE ((pt_element_t)4096) -#define PAGE_MASK (~(PAGE_SIZE-1)) -#define PT_BASE_ADDR_MASK ((pt_element_t)((((pt_element_t)1 << 40) - 1) & PAGE_MASK))#define PT_PSE_BASE_ADDR_MASK (PT_BASE_ADDR_MASK & ~(1ull << 21))
x86/vmx.h +1 -1
@@ -4,6 +4,7 @@#include "libcflat.h" #include "processor.h" #include "bitops.h" +#include "asm/page.h" struct vmcs {u32 revision_id;/* vmcs revision identifier */
@@ -476,7 +477,6 @@ enum Ctrl1 {#define EPT_PGDIR_ENTRIES (1 << EPT_PGDIR_WIDTH)#define EPT_LEVEL_SHIFT (level) (((level)-1) * EPT_PGDIR_WIDTH + 12)#define EPT_ADDR_MASK GENMASK_ULL(51, 12) -#define PAGE_MASK (~(PAGE_SIZE-1))#define PAGE_MASK_2M (~(PAGE_SIZE_2M-1))#define EPT_VLT_RD 1
Signature · 1 line
1.8.3.1
PATCH v7 9/11 x86: Cleanup PT_*_MASK flags
In reply to Alexander Gordeev--- lib/x86/asm/page.h | 14 +++++++++----- lib/x86/vm.c | 20 ++++++++++---------- x86/access.c | 10 +--------- x86/asyncpf.c | 2 +- x86/eventinj.c | 10 +++++----- x86/hypercall.c | 2 +- x86/pku.c | 2 +- x86/rmap_chain.c | 2 +- x86/smap.c | 6 +++--- x86/taskswitch2.c | 2 +- 10 files changed, 33 insertions(+), 37 deletions(-)
lib/x86/asm/page.h +9 -5
@@ -8,6 +8,7 @@#include <linux/const.h> +#include <bitops.h> #define PAGE_SHIFT 12#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
@@ -21,11 +22,14 @@#define LARGE_PAGE_SIZE (1024 * PAGE_SIZE)#endif -#define PTE_PRESENT (1ull << 0) -#define PTE_WRITE (1ull << 1) -#define PTE_USER (1ull << 2) -#define PTE_PSE (1ull << 7) -#define PTE_ADDR (0xffffffffff000ull) +#define PT_PRESENT_MASK (1ull << 0) +#define PT_WRITABLE_MASK (1ull << 1) +#define PT_USER_MASK (1ull << 2) +#define PT_ACCESSED_MASK (1ull << 5) +#define PT_DIRTY_MASK (1ull << 6) +#define PT_PAGE_SIZE_MASK (1ull << 7) +#define PT_NX_MASK (1ull << 63) +#define PT_ADDR_MASK GENMASK_ULL(51, 12)#ifdef __x86_64__#define PAGE_LEVEL 4
lib/x86/vm.c +10 -10
@@ -49,16 +49,16 @@ unsigned long *install_pte(unsigned long *cr3,for (level =PAGE_LEVEL ; level > pte_level; --level) { offset = ((unsigned long )virt >> ((level-1 ) *PGDIR_WIDTH +12 )) &PGDIR_MASK ; -if (!(pt[offset] &PTE_PRESENT )) { +if (!(pt[offset] &PT_PRESENT_MASK )) {unsigned long *new_pt = pt_page;if (!new_pt) new_pt =alloc_page ();else pt_page =0 ;memset (new_pt,0 ,PAGE_SIZE ); - pt[offset] =virt_to_phys (new_pt) |PTE_PRESENT |PTE_WRITE |PTE_USER ; + pt[offset] =virt_to_phys (new_pt) |PT_PRESENT_MASK |PT_WRITABLE_MASK |PT_USER_MASK ; } - pt =phys_to_virt (pt[offset] &0xffffffffff000ull ); + pt =phys_to_virt (pt[offset] &PT_ADDR_MASK ); } offset = ((unsigned long )virt >> ((level-1 ) *PGDIR_WIDTH +12 )) &PGDIR_MASK ; pt[offset] = pte;
@@ -74,11 +74,11 @@ unsigned long *get_pte(unsigned long *cr3, void *virt)for (level =PAGE_LEVEL ; level >1 ; --level) { offset = ((unsigned long )virt >> (((level-1 ) *PGDIR_WIDTH ) +12 )) &PGDIR_MASK ; pte = pt[offset]; -if (!(pte &PTE_PRESENT )) +if (!(pte &PT_PRESENT_MASK ))return NULL ; -if (level ==2 && (pte &PTE_PSE )) +if (level ==2 && (pte &PT_PAGE_SIZE_MASK ))return &pt[offset]; - pt =phys_to_virt (pte &0xffffffffff000ull ); + pt =phys_to_virt (pte &PT_ADDR_MASK ); } offset = ((unsigned long )virt >> (((level-1 ) *PGDIR_WIDTH ) +12 )) &PGDIR_MASK ;return &pt[offset];
@@ -89,14 +89,14 @@ unsigned long *install_large_page(unsigned long *cr3, void *virt) {return install_pte (cr3,2 , virt, - phys |PTE_PRESENT |PTE_WRITE |PTE_USER |PTE_PSE ,0 ); + phys |PT_PRESENT_MASK |PT_WRITABLE_MASK |PT_USER_MASK |PT_PAGE_SIZE_MASK ,0 ); }unsigned long *install_page (unsigned long *cr3,unsigned long phys,void *virt) { -return install_pte (cr3,1 , virt, phys |PTE_PRESENT |PTE_WRITE |PTE_USER ,0 ); +return install_pte (cr3,1 , virt, phys |PT_PRESENT_MASK |PT_WRITABLE_MASK |PT_USER_MASK ,0 ); }
@@ -178,7 +178,7 @@ void *vmalloc(unsigned long size)uint64_t virt_to_phys_cr3 (void *mem) { -return (*get_pte (phys_to_virt (read_cr3 ()), mem) &PTE_ADDR ) + ((ulong )mem & (PAGE_SIZE -1 )); +return (*get_pte (phys_to_virt (read_cr3 ()), mem) &PT_ADDR_MASK ) + ((ulong )mem & (PAGE_SIZE -1 )); }void vfree (void *mem)
@@ -186,7 +186,7 @@ void vfree(void *mem)unsigned long size = ((unsigned long *)mem)[-1 ];while (size) { -free_page (phys_to_virt (*get_pte (phys_to_virt (read_cr3 ()), mem) &PTE_ADDR )); +free_page (phys_to_virt (*get_pte (phys_to_virt (read_cr3 ()), mem) &PT_ADDR_MASK )); mem +=PAGE_SIZE ; size -=PAGE_SIZE ; }
x86/access.c +1 -9
@@ -19,14 +19,6 @@ static int invalid_mask;#define PT_BASE_ADDR_MASK ((pt_element_t)((((pt_element_t)1 << 40) - 1) & PAGE_MASK))#define PT_PSE_BASE_ADDR_MASK (PT_BASE_ADDR_MASK & ~(1ull << 21)) -#define PT_PRESENT_MASK ((pt_element_t)1 << 0) -#define PT_WRITABLE_MASK ((pt_element_t)1 << 1) -#define PT_USER_MASK ((pt_element_t)1 << 2) -#define PT_ACCESSED_MASK ((pt_element_t)1 << 5) -#define PT_DIRTY_MASK ((pt_element_t)1 << 6) -#define PT_PSE_MASK ((pt_element_t)1 << 7) -#define PT_NX_MASK ((pt_element_t)1 << 63) -#define CR0_WP_MASK (1UL << 16)#define CR4_SMEP_MASK (1UL << 20)
@@ -493,7 +485,7 @@ void __ac_setup_specific_pages(ac_test_t *at, ac_pool_t *pool, u64 pd_page, pte |=2ull <<59 ; }else { pte = at->phys &PT_PSE_BASE_ADDR_MASK ; - pte |=PT_PSE_MASK ; + pte |=PT_PAGE_SIZE_MASK ;if (F (AC_PKU_PKEY )) pte |=1ull <<59 ; }
x86/asyncpf.c +1 -1
@@ -69,7 +69,7 @@ static void pf_isr(struct ex_regs *r)report ("Got present #PF token %x\n" , true,read_cr2 ());if ((uint32_t )read_cr2 () == ~0 )break ; -install_pte (phys_to_virt (read_cr3 ()),1 , virt, phys |PTE_PRESENT |PTE_WRITE ,0 ); +install_pte (phys_to_virt (read_cr3 ()),1 , virt, phys |PT_PRESENT_MASK |PT_WRITABLE_MASK ,0 );write_cr3 (read_cr3 ()); phys =0 ;break ;
x86/eventinj.c +5 -5
@@ -52,7 +52,7 @@ void do_pf_tss(void) {printf ("PF running\n" );install_pte (phys_to_virt (read_cr3 ()),1 , stack_va, - stack_phys |PTE_PRESENT |PTE_WRITE ,0 ); + stack_phys |PT_PRESENT_MASK |PT_WRITABLE_MASK ,0 );invlpg (stack_va); }
@@ -363,7 +363,7 @@ int main()printf ("Try to divide by 0\n" );/* install read only pte */ install_pte (phys_to_virt (read_cr3 ()),1 , stack_va, - stack_phys |PTE_PRESENT ,0 ); + stack_phys |PT_PRESENT_MASK ,0 );invlpg (stack_va);flush_phys_addr (stack_phys);switch_stack (stack_va +4095 );
@@ -382,7 +382,7 @@ int main()set_idt_sel (33 ,NP_SEL );/* install read only pte */ install_pte (phys_to_virt (read_cr3 ()),1 , stack_va, - stack_phys |PTE_PRESENT ,0 ); + stack_phys |PT_PRESENT_MASK ,0 );invlpg (stack_va);flush_idt_page ();flush_phys_addr (stack_phys);
@@ -398,8 +398,8 @@ int main()/* use shadowed stack during interrupt delivery */ for (i =0 ; i <4096 /sizeof (ulong); i++) {if (!cr3[i]) { - cr3[i] =virt_to_phys (pt) |PTE_PRESENT |PTE_WRITE ; - pt[0 ] =virt_to_phys (pt) |PTE_PRESENT |PTE_WRITE ; + cr3[i] =virt_to_phys (pt) |PT_PRESENT_MASK |PT_WRITABLE_MASK ; + pt[0 ] =virt_to_phys (pt) |PT_PRESENT_MASK |PT_WRITABLE_MASK ;#ifndef __x86_64__ ((ulong *)(i<<22 ))[1 ] =0 ;#else
x86/hypercall.c +1 -1
@@ -65,7 +65,7 @@ int main(int ac, char **av)u8 *topmost = (void *) ((1ul <<47 ) -PAGE_SIZE );install_pte (phys_to_virt (read_cr3 ()),1 , topmost, -virt_to_phys (data1) |PTE_PRESENT |PTE_WRITE ,0 ); +virt_to_phys (data1) |PT_PRESENT_MASK |PT_WRITABLE_MASK ,0 );memset (topmost,0xcc ,PAGE_SIZE ); topmost[4093 ] =0x0f ; topmost[4094 ] =0x01 ;
x86/pku.c +1 -1
@@ -77,7 +77,7 @@ int main(int ac, char **av)wrmsr (MSR_EFER ,rdmsr (MSR_EFER ) |EFER_LMA );for (i =0 ; i <USER_BASE ; i +=PAGE_SIZE ) { - *get_pte (phys_to_virt (read_cr3 ()),phys_to_virt (i)) &= ~PTE_USER ; + *get_pte (phys_to_virt (read_cr3 ()),phys_to_virt (i)) &= ~PT_USER_MASK ; *get_pte (phys_to_virt (read_cr3 ()),phys_to_virt (i)) |= ((unsigned long )pkey <<PTE_PKEY_BIT );invlpg ((void *)i); }
x86/rmap_chain.c +1 -1
@@ -36,7 +36,7 @@ int main (void) virt_addr +=PAGE_SIZE ;install_pte (phys_to_virt (read_cr3 ()),1 , virt_addr, -0 |PTE_PRESENT |PTE_WRITE , target_page); +0 |PT_PRESENT_MASK |PT_WRITABLE_MASK , target_page); *(unsigned long *)virt_addr =0 ;printf ("PASS\n" );
x86/smap.c +3 -3
@@ -62,7 +62,7 @@ static void check_smap_nowp(void) { test =0x99 ; - *get_pte (phys_to_virt (read_cr3 ()),USER_ADDR (test)) &= ~PTE_WRITE ; + *get_pte (phys_to_virt (read_cr3 ()),USER_ADDR (test)) &= ~PT_WRITABLE_MASK ;write_cr4 (read_cr4 () & ~X86_CR4_SMAP );write_cr0 (read_cr0 () & ~X86_CR0_WP );
@@ -81,7 +81,7 @@ static void check_smap_nowp(void)report ("read from user page with SMAP=1, AC=0, WP=0, PTE.U=1 && PTE.W=0" , pf_count ==1 && save ==0x99 );/* Undo changes */ - *get_pte (phys_to_virt (read_cr3 ()),USER_ADDR (test)) |=PTE_WRITE ; + *get_pte (phys_to_virt (read_cr3 ()),USER_ADDR (test)) |=PT_WRITABLE_MASK ;write_cr0 (read_cr0 () |X86_CR0_WP );write_cr3 (read_cr3 ());
@@ -102,7 +102,7 @@ int main(int ac, char **av)// Map first 16MB as supervisor pages for (i =0 ; i <USER_BASE ; i +=PAGE_SIZE ) { - *get_pte (phys_to_virt (read_cr3 ()),phys_to_virt (i)) &= ~PTE_USER ; + *get_pte (phys_to_virt (read_cr3 ()),phys_to_virt (i)) &= ~PT_USER_MASK ;invlpg ((void *)i); }
x86/taskswitch2.c +1 -1
@@ -67,7 +67,7 @@ void do_pf_tss(ulong *error_code)if (*error_code ==0x2 )/* write access, not present */ test_count++;install_pte (phys_to_virt (read_cr3 ()),1 , fault_addr, - fault_phys |PTE_PRESENT |PTE_WRITE ,0 ); + fault_phys |PT_PRESENT_MASK |PT_WRITABLE_MASK ,0 ); }extern void pf_tss (void );
Signature · 1 line
1.8.3.1
Re: [kvm-unit-tests PATCH v7 09/11] x86: Cleanup PT_*_MASK flags
Quoted 35 lines · Alexander Gordeev
Cc Andrew Jones <[email protected]>Cc Thomas Huth <[email protected]>Cc Radim Krčmář <[email protected]>Signed-off-by Alexander Gordeev <[email protected]>--- lib/x86/asm/page.h | 14 +++++++++----- lib/x86/vm.c | 20 ++++++++++---------- x86/access.c | 10 +--------- x86/asyncpf.c | 2 +- x86/eventinj.c | 10 +++++----- x86/hypercall.c | 2 +- x86/pku.c | 2 +- x86/rmap_chain.c | 2 +- x86/smap.c | 6 +++--- x86/taskswitch2.c | 2 +- 10 files changed, 33 insertions(+), 37 deletions(-)lib/x86/asm/page.h +1
-2@@ -8,6 +8,7 @@#include <linux/const.h> +#include <bitops.h> #define PAGE_SHIFT 12#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)@@ -21,11 +22,14 @@#define LARGE_PAGE_SIZE (1024 * PAGE_SIZE)#endif -#define PTE_PRESENT (1ull << 0) -#define PTE_WRITE (1ull << 1)
lib/x86/asm/page.h line 31
Quoted 10 lines
lib/x86/asm/page.h +7
-3-#define PTE_USER (1ull << 2) -#define PTE_PSE (1ull << 7) -#define PTE_ADDR (0xffffffffff000ull) +#define PT_PRESENT_MASK (1ull << 0) +#define PT_WRITABLE_MASK (1ull << 1) +#define PT_USER_MASK (1ull << 2) +#define PT_ACCESSED_MASK (1ull << 5) +#define PT_DIRTY_MASK (1ull << 6) +#define PT_PAGE_SIZE_MASK (1ull << 7) +#define PT_NX_MASK (1ull << 63)
This is PT64_NX_MASK in arch/x86/kvm/mmu.h (as I pointed out before), but whatever.
Quoted 251 lines
lib/x86/asm/page.h +1
-0+#define PT_ADDR_MASK GENMASK_ULL(51, 12)#ifdef __x86_64__#define PAGE_LEVEL 4lib/x86/vm.c +10
-10@@ -49,16 +49,16 @@ unsigned long *install_pte(unsigned long *cr3,for (level =PAGE_LEVEL ; level > pte_level; --level) { offset = ((unsigned long )virt >> ((level-1 ) *PGDIR_WIDTH +12 )) &PGDIR_MASK ; -if (!(pt[offset] &PTE_PRESENT )) { +if (!(pt[offset] &PT_PRESENT_MASK )) {unsigned long *new_pt = pt_page;if (!new_pt) new_pt =alloc_page ();else pt_page =0 ;memset (new_pt,0 ,PAGE_SIZE ); - pt[offset] =virt_to_phys (new_pt) |PTE_PRESENT |PTE_WRITE |PTE_USER ; + pt[offset] =virt_to_phys (new_pt) |PT_PRESENT_MASK |PT_WRITABLE_MASK |PT_USER_MASK ; } - pt =phys_to_virt (pt[offset] &0xffffffffff000ull ); + pt =phys_to_virt (pt[offset] &PT_ADDR_MASK ); } offset = ((unsigned long )virt >> ((level-1 ) *PGDIR_WIDTH +12 )) &PGDIR_MASK ; pt[offset] = pte;@@ -74,11 +74,11 @@ unsigned long *get_pte(unsigned long *cr3, void *virt)for (level =PAGE_LEVEL ; level >1 ; --level) { offset = ((unsigned long )virt >> (((level-1 ) *PGDIR_WIDTH ) +12 )) &PGDIR_MASK ; pte = pt[offset]; -if (!(pte &PTE_PRESENT )) +if (!(pte &PT_PRESENT_MASK ))return NULL ; -if (level ==2 && (pte &PTE_PSE )) +if (level ==2 && (pte &PT_PAGE_SIZE_MASK ))return &pt[offset]; - pt =phys_to_virt (pte &0xffffffffff000ull ); + pt =phys_to_virt (pte &PT_ADDR_MASK ); } offset = ((unsigned long )virt >> (((level-1 ) *PGDIR_WIDTH ) +12 )) &PGDIR_MASK ;return &pt[offset];@@ -89,14 +89,14 @@ unsigned long *install_large_page(unsigned long *cr3, void *virt) {return install_pte (cr3,2 , virt, - phys |PTE_PRESENT |PTE_WRITE |PTE_USER |PTE_PSE ,0 ); + phys |PT_PRESENT_MASK |PT_WRITABLE_MASK |PT_USER_MASK |PT_PAGE_SIZE_MASK ,0 ); }unsigned long *install_page (unsigned long *cr3,unsigned long phys,void *virt) { -return install_pte (cr3,1 , virt, phys |PTE_PRESENT |PTE_WRITE |PTE_USER ,0 ); +return install_pte (cr3,1 , virt, phys |PT_PRESENT_MASK |PT_WRITABLE_MASK |PT_USER_MASK ,0 ); }@@ -178,7 +178,7 @@ void *vmalloc(unsigned long size)uint64_t virt_to_phys_cr3 (void *mem) { -return (*get_pte (phys_to_virt (read_cr3 ()), mem) &PTE_ADDR ) + ((ulong )mem & (PAGE_SIZE -1 )); +return (*get_pte (phys_to_virt (read_cr3 ()), mem) &PT_ADDR_MASK ) + ((ulong )mem & (PAGE_SIZE -1 )); }void vfree (void *mem)@@ -186,7 +186,7 @@ void vfree(void *mem)unsigned long size = ((unsigned long *)mem)[-1 ];while (size) { -free_page (phys_to_virt (*get_pte (phys_to_virt (read_cr3 ()), mem) &PTE_ADDR )); +free_page (phys_to_virt (*get_pte (phys_to_virt (read_cr3 ()), mem) &PT_ADDR_MASK )); mem +=PAGE_SIZE ; size -=PAGE_SIZE ; }x86/access.c +1
-9@@ -19,14 +19,6 @@ static int invalid_mask;#define PT_BASE_ADDR_MASK ((pt_element_t)((((pt_element_t)1 << 40) - 1) & PAGE_MASK))#define PT_PSE_BASE_ADDR_MASK (PT_BASE_ADDR_MASK & ~(1ull << 21)) -#define PT_PRESENT_MASK ((pt_element_t)1 << 0) -#define PT_WRITABLE_MASK ((pt_element_t)1 << 1) -#define PT_USER_MASK ((pt_element_t)1 << 2) -#define PT_ACCESSED_MASK ((pt_element_t)1 << 5) -#define PT_DIRTY_MASK ((pt_element_t)1 << 6) -#define PT_PSE_MASK ((pt_element_t)1 << 7) -#define PT_NX_MASK ((pt_element_t)1 << 63) -#define CR0_WP_MASK (1UL << 16)#define CR4_SMEP_MASK (1UL << 20)@@ -493,7 +485,7 @@ void __ac_setup_specific_pages(ac_test_t *at, ac_pool_t *pool, u64 pd_page, pte |=2ull <<59 ; }else { pte = at->phys &PT_PSE_BASE_ADDR_MASK ; - pte |=PT_PSE_MASK ; + pte |=PT_PAGE_SIZE_MASK ;if (F (AC_PKU_PKEY )) pte |=1ull <<59 ; }x86/asyncpf.c +1
-1@@ -69,7 +69,7 @@ static void pf_isr(struct ex_regs *r)report ("Got present #PF token %x\n" , true,read_cr2 ());if ((uint32_t )read_cr2 () == ~0 )break ; -install_pte (phys_to_virt (read_cr3 ()),1 , virt, phys |PTE_PRESENT |PTE_WRITE ,0 ); +install_pte (phys_to_virt (read_cr3 ()),1 , virt, phys |PT_PRESENT_MASK |PT_WRITABLE_MASK ,0 );write_cr3 (read_cr3 ()); phys =0 ;break ;x86/eventinj.c +5
-5@@ -52,7 +52,7 @@ void do_pf_tss(void) {printf ("PF running\n" );install_pte (phys_to_virt (read_cr3 ()),1 , stack_va, - stack_phys |PTE_PRESENT |PTE_WRITE ,0 ); + stack_phys |PT_PRESENT_MASK |PT_WRITABLE_MASK ,0 );invlpg (stack_va); }@@ -363,7 +363,7 @@ int main()printf ("Try to divide by 0\n" );/* install read only pte */ install_pte (phys_to_virt (read_cr3 ()),1 , stack_va, - stack_phys |PTE_PRESENT ,0 ); + stack_phys |PT_PRESENT_MASK ,0 );invlpg (stack_va);flush_phys_addr (stack_phys);switch_stack (stack_va +4095 );@@ -382,7 +382,7 @@ int main()set_idt_sel (33 ,NP_SEL );/* install read only pte */ install_pte (phys_to_virt (read_cr3 ()),1 , stack_va, - stack_phys |PTE_PRESENT ,0 ); + stack_phys |PT_PRESENT_MASK ,0 );invlpg (stack_va);flush_idt_page ();flush_phys_addr (stack_phys);@@ -398,8 +398,8 @@ int main()/* use shadowed stack during interrupt delivery */ for (i =0 ; i <4096 /sizeof (ulong); i++) {if (!cr3[i]) { - cr3[i] =virt_to_phys (pt) |PTE_PRESENT |PTE_WRITE ; - pt[0 ] =virt_to_phys (pt) |PTE_PRESENT |PTE_WRITE ; + cr3[i] =virt_to_phys (pt) |PT_PRESENT_MASK |PT_WRITABLE_MASK ; + pt[0 ] =virt_to_phys (pt) |PT_PRESENT_MASK |PT_WRITABLE_MASK ;#ifndef __x86_64__ ((ulong *)(i<<22 ))[1 ] =0 ;#else x86/hypercall.c +1
-1@@ -65,7 +65,7 @@ int main(int ac, char **av)u8 *topmost = (void *) ((1ul <<47 ) -PAGE_SIZE );install_pte (phys_to_virt (read_cr3 ()),1 , topmost, -virt_to_phys (data1) |PTE_PRESENT |PTE_WRITE ,0 ); +virt_to_phys (data1) |PT_PRESENT_MASK |PT_WRITABLE_MASK ,0 );memset (topmost,0xcc ,PAGE_SIZE ); topmost[4093 ] =0x0f ; topmost[4094 ] =0x01 ;x86/pku.c +1
-1@@ -77,7 +77,7 @@ int main(int ac, char **av)wrmsr (MSR_EFER ,rdmsr (MSR_EFER ) |EFER_LMA );for (i =0 ; i <USER_BASE ; i +=PAGE_SIZE ) { - *get_pte (phys_to_virt (read_cr3 ()),phys_to_virt (i)) &= ~PTE_USER ; + *get_pte (phys_to_virt (read_cr3 ()),phys_to_virt (i)) &= ~PT_USER_MASK ; *get_pte (phys_to_virt (read_cr3 ()),phys_to_virt (i)) |= ((unsigned long )pkey <<PTE_PKEY_BIT );invlpg ((void *)i); }x86/rmap_chain.c +1
-1@@ -36,7 +36,7 @@ int main (void) virt_addr +=PAGE_SIZE ;install_pte (phys_to_virt (read_cr3 ()),1 , virt_addr, -0 |PTE_PRESENT |PTE_WRITE , target_page); +0 |PT_PRESENT_MASK |PT_WRITABLE_MASK , target_page); *(unsigned long *)virt_addr =0 ;printf ("PASS\n" );x86/smap.c +3
-3@@ -62,7 +62,7 @@ static void check_smap_nowp(void) { test =0x99 ; - *get_pte (phys_to_virt (read_cr3 ()),USER_ADDR (test)) &= ~PTE_WRITE ; + *get_pte (phys_to_virt (read_cr3 ()),USER_ADDR (test)) &= ~PT_WRITABLE_MASK ;write_cr4 (read_cr4 () & ~X86_CR4_SMAP );write_cr0 (read_cr0 () & ~X86_CR0_WP );@@ -81,7 +81,7 @@ static void check_smap_nowp(void)report ("read from user page with SMAP=1, AC=0, WP=0, PTE.U=1 && PTE.W=0" , pf_count ==1 && save ==0x99 );/* Undo changes */ - *get_pte (phys_to_virt (read_cr3 ()),USER_ADDR (test)) |=PTE_WRITE ; + *get_pte (phys_to_virt (read_cr3 ()),USER_ADDR (test)) |=PT_WRITABLE_MASK ;write_cr0 (read_cr0 () |X86_CR0_WP );write_cr3 (read_cr3 ());@@ -102,7 +102,7 @@ int main(int ac, char **av)// Map first 16MB as supervisor pages for (i =0 ; i <USER_BASE ; i +=PAGE_SIZE ) { - *get_pte (phys_to_virt (read_cr3 ()),phys_to_virt (i)) &= ~PTE_USER ; + *get_pte (phys_to_virt (read_cr3 ()),phys_to_virt (i)) &= ~PT_USER_MASK ;invlpg ((void *)i); }x86/taskswitch2.c +1
-1@@ -67,7 +67,7 @@ void do_pf_tss(ulong *error_code)if (*error_code ==0x2 )/* write access, not present */ test_count++;install_pte (phys_to_virt (read_cr3 ()),1 , fault_addr, - fault_phys |PTE_PRESENT |PTE_WRITE ,0 ); + fault_phys |PT_PRESENT_MASK |PT_WRITABLE_MASK ,0 ); }extern void pf_tss (void );Signature · 6 lines
1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH v8 9/11 x86: Cleanup PT_*_MASK flags
--- lib/x86/asm/page.h | 14 +++++++++----- lib/x86/vm.c | 20 ++++++++++---------- x86/access.c | 14 +++----------- x86/asyncpf.c | 2 +- x86/eventinj.c | 10 +++++----- x86/hypercall.c | 2 +- x86/pku.c | 2 +- x86/rmap_chain.c | 2 +- x86/smap.c | 6 +++--- x86/taskswitch2.c | 2 +- 10 files changed, 35 insertions(+), 39 deletions(-)
lib/x86/asm/page.h +9 -5
@@ -8,6 +8,7 @@#include <linux/const.h> +#include <bitops.h> #define PAGE_SHIFT 12#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
@@ -21,11 +22,14 @@#define LARGE_PAGE_SIZE (1024 * PAGE_SIZE)#endif -#define PTE_PRESENT (1ull << 0) -#define PTE_WRITE (1ull << 1) -#define PTE_USER (1ull << 2) -#define PTE_PSE (1ull << 7) -#define PTE_ADDR (0xffffffffff000ull) +#define PT_PRESENT_MASK (1ull << 0) +#define PT_WRITABLE_MASK (1ull << 1) +#define PT_USER_MASK (1ull << 2) +#define PT_ACCESSED_MASK (1ull << 5) +#define PT_DIRTY_MASK (1ull << 6) +#define PT_PAGE_SIZE_MASK (1ull << 7) +#define PT64_NX_MASK (1ull << 63) +#define PT_ADDR_MASK GENMASK_ULL(51, 12)#ifdef __x86_64__#define PAGE_LEVEL 4
lib/x86/vm.c +10 -10
@@ -49,16 +49,16 @@ unsigned long *install_pte(unsigned long *cr3,for (level =PAGE_LEVEL ; level > pte_level; --level) { offset = ((unsigned long )virt >> ((level-1 ) *PGDIR_WIDTH +12 )) &PGDIR_MASK ; -if (!(pt[offset] &PTE_PRESENT )) { +if (!(pt[offset] &PT_PRESENT_MASK )) {unsigned long *new_pt = pt_page;if (!new_pt) new_pt =alloc_page ();else pt_page =0 ;memset (new_pt,0 ,PAGE_SIZE ); - pt[offset] =virt_to_phys (new_pt) |PTE_PRESENT |PTE_WRITE |PTE_USER ; + pt[offset] =virt_to_phys (new_pt) |PT_PRESENT_MASK |PT_WRITABLE_MASK |PT_USER_MASK ; } - pt =phys_to_virt (pt[offset] &0xffffffffff000ull ); + pt =phys_to_virt (pt[offset] &PT_ADDR_MASK ); } offset = ((unsigned long )virt >> ((level-1 ) *PGDIR_WIDTH +12 )) &PGDIR_MASK ; pt[offset] = pte;
@@ -74,11 +74,11 @@ unsigned long *get_pte(unsigned long *cr3, void *virt)for (level =PAGE_LEVEL ; level >1 ; --level) { offset = ((unsigned long )virt >> (((level-1 ) *PGDIR_WIDTH ) +12 )) &PGDIR_MASK ; pte = pt[offset]; -if (!(pte &PTE_PRESENT )) +if (!(pte &PT_PRESENT_MASK ))return NULL ; -if (level ==2 && (pte &PTE_PSE )) +if (level ==2 && (pte &PT_PAGE_SIZE_MASK ))return &pt[offset]; - pt =phys_to_virt (pte &0xffffffffff000ull ); + pt =phys_to_virt (pte &PT_ADDR_MASK ); } offset = ((unsigned long )virt >> (((level-1 ) *PGDIR_WIDTH ) +12 )) &PGDIR_MASK ;return &pt[offset];
@@ -89,14 +89,14 @@ unsigned long *install_large_page(unsigned long *cr3, void *virt) {return install_pte (cr3,2 , virt, - phys |PTE_PRESENT |PTE_WRITE |PTE_USER |PTE_PSE ,0 ); + phys |PT_PRESENT_MASK |PT_WRITABLE_MASK |PT_USER_MASK |PT_PAGE_SIZE_MASK ,0 ); }unsigned long *install_page (unsigned long *cr3,unsigned long phys,void *virt) { -return install_pte (cr3,1 , virt, phys |PTE_PRESENT |PTE_WRITE |PTE_USER ,0 ); +return install_pte (cr3,1 , virt, phys |PT_PRESENT_MASK |PT_WRITABLE_MASK |PT_USER_MASK ,0 ); }
@@ -178,7 +178,7 @@ void *vmalloc(unsigned long size)uint64_t virt_to_phys_cr3 (void *mem) { -return (*get_pte (phys_to_virt (read_cr3 ()), mem) &PTE_ADDR ) + ((ulong )mem & (PAGE_SIZE -1 )); +return (*get_pte (phys_to_virt (read_cr3 ()), mem) &PT_ADDR_MASK ) + ((ulong )mem & (PAGE_SIZE -1 )); }void vfree (void *mem)
@@ -186,7 +186,7 @@ void vfree(void *mem)unsigned long size = ((unsigned long *)mem)[-1 ];while (size) { -free_page (phys_to_virt (*get_pte (phys_to_virt (read_cr3 ()), mem) &PTE_ADDR )); +free_page (phys_to_virt (*get_pte (phys_to_virt (read_cr3 ()), mem) &PT_ADDR_MASK )); mem +=PAGE_SIZE ; size -=PAGE_SIZE ; }
x86/access.c +3 -11
@@ -19,14 +19,6 @@ static int invalid_mask;#define PT_BASE_ADDR_MASK ((pt_element_t)((((pt_element_t)1 << 40) - 1) & PAGE_MASK))#define PT_PSE_BASE_ADDR_MASK (PT_BASE_ADDR_MASK & ~(1ull << 21)) -#define PT_PRESENT_MASK ((pt_element_t)1 << 0) -#define PT_WRITABLE_MASK ((pt_element_t)1 << 1) -#define PT_USER_MASK ((pt_element_t)1 << 2) -#define PT_ACCESSED_MASK ((pt_element_t)1 << 5) -#define PT_DIRTY_MASK ((pt_element_t)1 << 6) -#define PT_PSE_MASK ((pt_element_t)1 << 7) -#define PT_NX_MASK ((pt_element_t)1 << 63) -#define CR0_WP_MASK (1UL << 16)#define CR4_SMEP_MASK (1UL << 20)
@@ -493,7 +485,7 @@ void __ac_setup_specific_pages(ac_test_t *at, ac_pool_t *pool, u64 pd_page, pte |=2ull <<59 ; }else { pte = at->phys &PT_PSE_BASE_ADDR_MASK ; - pte |=PT_PSE_MASK ; + pte |=PT_PAGE_SIZE_MASK ;if (F (AC_PKU_PKEY )) pte |=1ull <<59 ; }
@@ -508,7 +500,7 @@ void __ac_setup_specific_pages(ac_test_t *at, ac_pool_t *pool, u64 pd_page,if (F (AC_PDE_DIRTY )) pte |=PT_DIRTY_MASK ;if (F (AC_PDE_NX )) - pte |=PT_NX_MASK ; + pte |=PT64_NX_MASK ;if (F (AC_PDE_BIT51 )) pte |=1ull <<51 ;if (F (AC_PDE_BIT13 ))
@@ -530,7 +522,7 @@ void __ac_setup_specific_pages(ac_test_t *at, ac_pool_t *pool, u64 pd_page,if (F (AC_PTE_DIRTY )) pte |=PT_DIRTY_MASK ;if (F (AC_PTE_NX )) - pte |=PT_NX_MASK ; + pte |=PT64_NX_MASK ;if (F (AC_PTE_BIT51 )) pte |=1ull <<51 ; at->ptep = &vroot[index];
x86/asyncpf.c +1 -1
@@ -69,7 +69,7 @@ static void pf_isr(struct ex_regs *r)report ("Got present #PF token %x\n" , true,read_cr2 ());if ((uint32_t )read_cr2 () == ~0 )break ; -install_pte (phys_to_virt (read_cr3 ()),1 , virt, phys |PTE_PRESENT |PTE_WRITE ,0 ); +install_pte (phys_to_virt (read_cr3 ()),1 , virt, phys |PT_PRESENT_MASK |PT_WRITABLE_MASK ,0 );write_cr3 (read_cr3 ()); phys =0 ;break ;
x86/eventinj.c +5 -5
@@ -52,7 +52,7 @@ void do_pf_tss(void) {printf ("PF running\n" );install_pte (phys_to_virt (read_cr3 ()),1 , stack_va, - stack_phys |PTE_PRESENT |PTE_WRITE ,0 ); + stack_phys |PT_PRESENT_MASK |PT_WRITABLE_MASK ,0 );invlpg (stack_va); }
@@ -363,7 +363,7 @@ int main()printf ("Try to divide by 0\n" );/* install read only pte */ install_pte (phys_to_virt (read_cr3 ()),1 , stack_va, - stack_phys |PTE_PRESENT ,0 ); + stack_phys |PT_PRESENT_MASK ,0 );invlpg (stack_va);flush_phys_addr (stack_phys);switch_stack (stack_va +4095 );
@@ -382,7 +382,7 @@ int main()set_idt_sel (33 ,NP_SEL );/* install read only pte */ install_pte (phys_to_virt (read_cr3 ()),1 , stack_va, - stack_phys |PTE_PRESENT ,0 ); + stack_phys |PT_PRESENT_MASK ,0 );invlpg (stack_va);flush_idt_page ();flush_phys_addr (stack_phys);
@@ -398,8 +398,8 @@ int main()/* use shadowed stack during interrupt delivery */ for (i =0 ; i <4096 /sizeof (ulong); i++) {if (!cr3[i]) { - cr3[i] =virt_to_phys (pt) |PTE_PRESENT |PTE_WRITE ; - pt[0 ] =virt_to_phys (pt) |PTE_PRESENT |PTE_WRITE ; + cr3[i] =virt_to_phys (pt) |PT_PRESENT_MASK |PT_WRITABLE_MASK ; + pt[0 ] =virt_to_phys (pt) |PT_PRESENT_MASK |PT_WRITABLE_MASK ;#ifndef __x86_64__ ((ulong *)(i<<22 ))[1 ] =0 ;#else
x86/hypercall.c +1 -1
@@ -65,7 +65,7 @@ int main(int ac, char **av)u8 *topmost = (void *) ((1ul <<47 ) -PAGE_SIZE );install_pte (phys_to_virt (read_cr3 ()),1 , topmost, -virt_to_phys (data1) |PTE_PRESENT |PTE_WRITE ,0 ); +virt_to_phys (data1) |PT_PRESENT_MASK |PT_WRITABLE_MASK ,0 );memset (topmost,0xcc ,PAGE_SIZE ); topmost[4093 ] =0x0f ; topmost[4094 ] =0x01 ;
x86/pku.c +1 -1
@@ -77,7 +77,7 @@ int main(int ac, char **av)wrmsr (MSR_EFER ,rdmsr (MSR_EFER ) |EFER_LMA );for (i =0 ; i <USER_BASE ; i +=PAGE_SIZE ) { - *get_pte (phys_to_virt (read_cr3 ()),phys_to_virt (i)) &= ~PTE_USER ; + *get_pte (phys_to_virt (read_cr3 ()),phys_to_virt (i)) &= ~PT_USER_MASK ; *get_pte (phys_to_virt (read_cr3 ()),phys_to_virt (i)) |= ((unsigned long )pkey <<PTE_PKEY_BIT );invlpg ((void *)i); }
x86/rmap_chain.c +1 -1
@@ -36,7 +36,7 @@ int main (void) virt_addr +=PAGE_SIZE ;install_pte (phys_to_virt (read_cr3 ()),1 , virt_addr, -0 |PTE_PRESENT |PTE_WRITE , target_page); +0 |PT_PRESENT_MASK |PT_WRITABLE_MASK , target_page); *(unsigned long *)virt_addr =0 ;printf ("PASS\n" );
x86/smap.c +3 -3
@@ -62,7 +62,7 @@ static void check_smap_nowp(void) { test =0x99 ; - *get_pte (phys_to_virt (read_cr3 ()),USER_ADDR (test)) &= ~PTE_WRITE ; + *get_pte (phys_to_virt (read_cr3 ()),USER_ADDR (test)) &= ~PT_WRITABLE_MASK ;write_cr4 (read_cr4 () & ~X86_CR4_SMAP );write_cr0 (read_cr0 () & ~X86_CR0_WP );
@@ -81,7 +81,7 @@ static void check_smap_nowp(void)report ("read from user page with SMAP=1, AC=0, WP=0, PTE.U=1 && PTE.W=0" , pf_count ==1 && save ==0x99 );/* Undo changes */ - *get_pte (phys_to_virt (read_cr3 ()),USER_ADDR (test)) |=PTE_WRITE ; + *get_pte (phys_to_virt (read_cr3 ()),USER_ADDR (test)) |=PT_WRITABLE_MASK ;write_cr0 (read_cr0 () |X86_CR0_WP );write_cr3 (read_cr3 ());
@@ -102,7 +102,7 @@ int main(int ac, char **av)// Map first 16MB as supervisor pages for (i =0 ; i <USER_BASE ; i +=PAGE_SIZE ) { - *get_pte (phys_to_virt (read_cr3 ()),phys_to_virt (i)) &= ~PTE_USER ; + *get_pte (phys_to_virt (read_cr3 ()),phys_to_virt (i)) &= ~PT_USER_MASK ;invlpg ((void *)i); }
x86/taskswitch2.c +1 -1
@@ -67,7 +67,7 @@ void do_pf_tss(ulong *error_code)if (*error_code ==0x2 )/* write access, not present */ test_count++;install_pte (phys_to_virt (read_cr3 ()),1 , fault_addr, - fault_phys |PTE_PRESENT |PTE_WRITE ,0 ); + fault_phys |PT_PRESENT_MASK |PT_WRITABLE_MASK ,0 ); }extern void pf_tss (void );
Signature · 1 line
1.8.3.1
PATCH v7 10/11 io: Make ioremap() prototype conform to Linux one
In reply to Alexander GordeevThis update also adds missing __iomem specificator which has been used by existing IO accessors.
--- lib/asm-generic/io.h | 4 ++-- lib/ppc64/asm/io.h | 2 ++ lib/x86/asm/io.h | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-)
lib/asm-generic/io.h +2 -2
@@ -156,10 +156,10 @@ static inline u64 __bswap64(u64 x) ({ wmb(); __raw_writeq(cpu_to_le64(b), addr); })#ifndef ioremap -static inline void *ioremap(u64 phys_addr, size_t size __unused) +static inline void __iomem *ioremap(phys_addr_t phys_addr, size_t size __unused) {assert (sizeof (long ) ==8 || !(phys_addr >>32 )); -return (void *)(unsigned long )phys_addr; +return (void __iomem *)(unsigned long )phys_addr; }#endif
lib/ppc64/asm/io.h +2 -0
@@ -9,5 +9,7 @@#error Undefined byte order#endif +#define __iomem +#include <asm-generic/io.h> #endif
lib/x86/asm/io.h +2 -0
@@ -1,6 +1,8 @@#ifndef _ASM_X86_IO_H_#define _ASM_X86_IO_H_ +#define __iomem +static inline unsigned char inb (unsigned short port) {unsigned char value;
Signature · 1 line
1.8.3.1
PATCH v7 11/11 x86: io: Factor out ioremap()
In reply to Alexander Gordeev--- lib/x86/asm/io.h | 2 ++ lib/x86/io.c | 16 ++++++++++++++++ x86/vmexit.c | 10 ++-------- 3 files changed, 20 insertions(+), 8 deletions(-)
lib/x86/asm/io.h +2 -0
@@ -49,4 +49,6 @@ static inline void *phys_to_virt(unsigned long phys) return (void *)phys; } +void __iomem *ioremap (phys_addr_t phys_addr,size_t size); +#endif
lib/x86/io.c +16 -0
@@ -1,6 +1,8 @@#include "libcflat.h" +#include "vm.h" #include "smp.h" #include "asm/io.h" +#include "asm/page.h" #ifndef USE_SERIAL #define USE_SERIAL #endif
@@ -81,3 +83,17 @@ void exit(int code) asmvolatile ("out %0, %1" : :"a" (code),"d" ((short )0xf4 ));#endif } + +void __iomem *ioremap (phys_addr_t phys_addr,size_t size) +{ +phys_addr_t base = phys_addr &PAGE_MASK ; +phys_addr_t offset = phys_addr - base; + +/* +* The kernel sets PTEs for an ioremap() with page cache disabled, +* but we do not do that right now. It would make sense that I/O +* mappings would be uncached - and may help us find bugs when we +* properly map that way. +*/ +return vmap (phys_addr, size) + offset; +}
x86/vmexit.c +2 -8
@@ -371,8 +371,7 @@ int main(int ac, char **av) {struct fadt_descriptor_rev1 *fadt;int i; -unsigned long membar =0 , base, offset; -void *m; +unsigned long membar =0 ;pcidevaddr_t pcidev;smp_init ();
@@ -394,12 +393,7 @@ int main(int ac, char **av) }if (pci_bar_is_memory (pcidev, i)) { membar =pci_bar_addr (pcidev, i); - base = membar & ~4095 ; - offset = membar - base; - m =alloc_vpages (1 ); - -install_page ((void *)read_cr3 (), base, m); - pci_test.memaddr = m + offset; + pci_test.memaddr =ioremap (membar,PAGE_SIZE ); }else { pci_test.iobar =pci_bar_addr (pcidev, i); }
Signature · 1 line
1.8.3.1
Re: [kvm-unit-tests PATCH v7 11/11] x86: io: Factor out ioremap()
Quoted 41 lines · Alexander Gordeev
Cc Andrew Jones <[email protected]>Cc Thomas Huth <[email protected]>Cc Radim Krčmář <[email protected]>Reviewed-by Andrew Jones <[email protected]>Signed-off-by Alexander Gordeev <[email protected]>--- lib/x86/asm/io.h | 2 ++ lib/x86/io.c | 16 ++++++++++++++++ x86/vmexit.c | 10 ++-------- 3 files changed, 20 insertions(+), 8 deletions(-)lib/x86/asm/io.h +2
-0@@ -49,4 +49,6 @@ static inline void *phys_to_virt(unsigned long phys) return (void *)phys; } +void __iomem *ioremap (phys_addr_t phys_addr,size_t size); +#endif lib/x86/io.c +4
-0@@ -1,6 +1,8 @@#include "libcflat.h" +#include "vm.h" #include "smp.h" #include "asm/io.h" +#include "asm/page.h" #ifndef USE_SERIAL #define USE_SERIAL #endif @@ -81,3 +83,17 @@ void exit(int code) asmvolatile ("out %0, %1" : :"a" (code),"d" ((short )0xf4 ));#endif } + +void __iomem *ioremap (phys_addr_t phys_addr,size_t size)
lib/x86/io.c void exit(int code) · line 97
Quoted 10 lines
lib/x86/io.c +10
-0+{ +phys_addr_t base = phys_addr &PAGE_MASK ; +phys_addr_t offset = phys_addr - base; + +/* +* The kernel sets PTEs for an ioremap() with page cache disabled, +* but we do not do that right now. It would make sense that I/O +* mappings would be uncached - and may help us find bugs when we +* properly map that way. +*/
YAY!
Quoted 37 lines
lib/x86/io.c +2
-0+return vmap (phys_addr, size) + offset; +}x86/vmexit.c +2
-8@@ -371,8 +371,7 @@ int main(int ac, char **av) {struct fadt_descriptor_rev1 *fadt;int i; -unsigned long membar =0 , base, offset; -void *m; +unsigned long membar =0 ;pcidevaddr_t pcidev;smp_init ();@@ -394,12 +393,7 @@ int main(int ac, char **av) }if (pci_bar_is_memory (pcidev, i)) { membar =pci_bar_addr (pcidev, i); - base = membar & ~4095 ; - offset = membar - base; - m =alloc_vpages (1 ); - -install_page ((void *)read_cr3 (), base, m); - pci_test.memaddr = m + offset; + pci_test.memaddr =ioremap (membar,PAGE_SIZE ); }else { pci_test.iobar =pci_bar_addr (pcidev, i); }Signature · 6 lines
1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 8 lines · Alexander Gordeev
Andrew et al,
This is 7th attempt to make mainly x86 arch code consistent with other architectures.
I withdrew your Reviewed-by from "x86: Cleanup PT_*_MASK flags" patch 09/11 due to couple of more than just nits changes.
Quoted 7 lines
PCD-ed
ioremap()could be a follow-up update on top of this series.Changes since v6:
-ioremap()PCD comment updated;
-PT_PSE_MASKrenamed toPT_PAGE_SIZE_MASK;
-GENMASK_ULLused forPT_ADDR_MASKdefinition;
- missedx86/taskswitch2.cupdate added;
I guess you found this by compiling 32bit x86. Good. Did you make sure both 32 and 64 bit can compile with each patch applied one at a time? If so, then (at least as far as I'm concerned) this series looks good to go.
Radim, can you take a look and consider it for merge?
Thanks,
drew
Quoted 92 lines
Changes since v5:
-ioremap()PCD comment added, the Reviewed-by preserved;
- page table flag names changed from PTE_* to PT_*_MASK;Changes since v4:
- single instead of multiple pages allocation bug fixed in x86ioremap();
- style fixes squashed into code movements forlib/x86/asm/page.handlib/x86/asm/barrier.h;- #ifndef
__ASSEMBLY__added tolib/x86/asm/page.h;Changes since v3:
- x86 PAGE_* constants and PTE_* flags cleaned up;
- missing Reviewed-bys restored;
- missing headers tolib/x86/asm/page.handlib/x86/asm/barriers.hadded(I did not remove already given Reviewed-bys from these);Changes since v2:
- x86ioremap()address arithmetics nonsense fixed;
- x86virt_to_phys()andphys_to_virt()implementations left intact;
- separate overrides ofvirt_to_phys()andphys_to_virt()added;
- unsigned long size specifier removed fromPAGE_SIZEconstant;Changes since v1:
- arm compilation error fixed;
- disabling memory re-ordering for generic memory barriers added;Cc Andrew Jones <[email protected]>Cc Thomas Huth <[email protected]>Cc Radim Krčmář <[email protected]>Alexander Gordeev (11):
Remove unused and unnecessary PHYS32 macro
Movephys_addr_ttype definition tolib/libcflat.h
x86: Introducelib/x86/asm/page.h
x86: Introducelib/x86/asm/io.h
x86: Introducelib/x86/asm/barrier.h
io: Separate overrides ofvirt_to_phys()andphys_to_virt()
io: Disallow memory re-ordering for generic memory barriers
x86: Cleanup PAGE_* constants
x86: Cleanup PT_*_MASK flags
io: Makeioremap()prototype conform to Linux one
x86: io: Factor outioremap()arm/selftest.c | 1 - lib/alloc.h | 5 ----- lib/arm/asm/page.h | 2 -- lib/asm-generic/io.h | 13 +++++++++---- lib/libcflat.h | 2 ++ lib/powerpc/asm/setup.h | 1 - lib/ppc64/asm/io.h | 2 ++ lib/x86/asm/barrier.h | 13 +++++++++++++ lib/x86/{ => asm}/io.h | 18 ++++++++++++++++-- lib/x86/asm/page.h | 45 +++++++++++++++++++++++++++++++++++++++++++++ lib/x86/asm/pci.h | 2 +- lib/x86/io.c | 18 +++++++++++++++++- lib/x86/smp.h | 4 ---- lib/x86/vm.c | 37 ++++++++++--------------------------- lib/x86/vm.h | 25 ++----------------------- x86/access.c | 14 ++------------ x86/asyncpf.c | 2 +- x86/eventinj.c | 17 ++++++----------- x86/hypercall.c | 2 +- x86/hyperv.c | 1 + x86/hyperv.h | 1 - x86/hyperv_stimer.c | 2 +- x86/hyperv_synic.c | 1 - x86/init.c | 2 +- x86/kvmclock.c | 1 + x86/pku.c | 2 +- x86/rmap_chain.c | 2 +- x86/smap.c | 6 +++--- x86/svm.c | 1 - x86/taskswitch2.c | 2 +- x86/vmexit.c | 11 ++--------- x86/vmx.c | 1 - x86/vmx.h | 2 +- x86/vmx_tests.c | 1 - 34 files changed, 140 insertions(+), 119 deletions(-) create mode 100644 lib/x86/asm/barrier.h rename lib/x86/{ => asm}/io.h (74%) create mode 100644 lib/x86/asm/page.hSignature · 6 lines
1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 10 lines · Andrew Jones
Quoted 5 lines
Changes since v6:
-ioremap()PCD comment updated;
-PT_PSE_MASKrenamed toPT_PAGE_SIZE_MASK;
-GENMASK_ULLused forPT_ADDR_MASKdefinition;
- missedx86/taskswitch2.cupdate added;I guess you found this by compiling 32bit x86. Good. Did you make sure both 32 and 64 bit can compile with each patch applied one at a time? If so, then (at least as far as I'm concerned) this series looks good to go.
Yes, I rechecked per-patch compiles.
Quoted 1 line
Radim, can you take a look and consider it for merge?
I also reposted v8 of 09/11 with PT64_NX_MASK instead of PT_NX_MASK.
Quoted 2 lines
Thanks,
drew