Index: kernel/arch/ia32/include/arch/asm.h
===================================================================
--- kernel/arch/ia32/include/arch/asm.h	(revision 4b0206c7b08dfc91e29744cd62ce245f29ac2b62)
+++ kernel/arch/ia32/include/arch/asm.h	(revision 0f17bffb9edacd5345a8cb7bd518bccfb25c3e30)
@@ -87,4 +87,6 @@
 GEN_WRITE_REG(cr3)
 
+GEN_WRITE_REG(cr0)
+
 GEN_READ_REG(dr0)
 GEN_READ_REG(dr1)
@@ -232,51 +234,68 @@
 }
 
-/** Enable interrupts.
- *
- * Enable interrupts and return previous
- * value of EFLAGS.
- *
- * @return Old interrupt priority level.
- *
- */
-NO_TRACE static inline ipl_t interrupts_enable(void)
-{
-	ipl_t v;
-	
+NO_TRACE static inline uint32_t read_eflags(void)
+{
+	uint32_t eflags;
+
 	asm volatile (
 		"pushf\n"
 		"popl %[v]\n"
-		"sti\n"
-		: [v] "=r" (v)
-	);
-	
-	return v;
+		: [v] "=r" (eflags)
+	);
+	
+	return eflags;
+}
+
+NO_TRACE static inline void write_eflags(uint32_t eflags)
+{
+	asm volatile (
+		"pushl %[v]\n"
+		"popf\n"
+		:: [v] "r" (eflags)
+	);
+}
+
+/** Return interrupt priority level.
+ *
+ * @return Current interrupt priority level.
+ */
+NO_TRACE static inline ipl_t interrupts_read(void)
+{
+	return (ipl_t) read_eflags();
+}
+
+/** Enable interrupts.
+ *
+ * Enable interrupts and return the previous interrupt priority level.
+ *
+ * @return Old interrupt priority level.
+ */
+NO_TRACE static inline ipl_t interrupts_enable(void)
+{
+	ipl_t ipl = interrupts_read();
+	
+	asm volatile ("sti\n");
+	
+	return ipl;
 }
 
 /** Disable interrupts.
  *
- * Disable interrupts and return previous
- * value of EFLAGS.
+ * Disable interrupts and return the previous interrupt priority level.
  *
  * @return Old interrupt priority level.
- *
  */
 NO_TRACE static inline ipl_t interrupts_disable(void)
 {
-	ipl_t v;
-	
-	asm volatile (
-		"pushf\n"
-		"popl %[v]\n"
-		"cli\n"
-		: [v] "=r" (v)
-	);
-	
-	return v;
+	ipl_t ipl = interrupts_read();
+	
+	asm volatile ("cli\n");
+	
+	return ipl;
 }
 
 /** Restore interrupt priority level.
  *
- * Restore EFLAGS.
+ * Restore a saved interrupt priority level.
  *
  * @param ipl Saved interrupt priority level.
@@ -285,27 +304,5 @@
 NO_TRACE static inline void interrupts_restore(ipl_t ipl)
 {
-	asm volatile (
-		"pushl %[ipl]\n"
-		"popf\n"
-		:: [ipl] "r" (ipl)
-	);
-}
-
-/** Return interrupt priority level.
- *
- * @return EFLAFS.
- *
- */
-NO_TRACE static inline ipl_t interrupts_read(void)
-{
-	ipl_t v;
-	
-	asm volatile (
-		"pushf\n"
-		"popl %[v]\n"
-		: [v] "=r" (v)
-	);
-	
-	return v;
+	write_eflags((uint32_t) ipl);
 }
 
@@ -317,13 +314,5 @@
 NO_TRACE static inline bool interrupts_disabled(void)
 {
-	ipl_t v;
-	
-	asm volatile (
-		"pushf\n"
-		"popl %[v]\n"
-		: [v] "=r" (v)
-	);
-	
-	return ((v & EFLAGS_IF) == 0);
+	return ((read_eflags() & EFLAGS_IF) == 0);
 }
 
Index: kernel/arch/ia32/include/arch/cpu.h
===================================================================
--- kernel/arch/ia32/include/arch/cpu.h	(revision 4b0206c7b08dfc91e29744cd62ce245f29ac2b62)
+++ kernel/arch/ia32/include/arch/cpu.h	(revision 0f17bffb9edacd5345a8cb7bd518bccfb25c3e30)
@@ -36,16 +36,26 @@
 #define KERN_ia32_CPU_H_
 
-#define EFLAGS_IF       (1 << 9)
-#define EFLAGS_DF       (1 << 10)
-#define EFLAGS_NT       (1 << 14)
-#define EFLAGS_RF       (1 << 16)
+#define EFLAGS_IF	(1 << 9)
+#define EFLAGS_DF	(1 << 10)
+#define EFLAGS_IOPL	(3 << 12)
+#define EFLAGS_NT	(1 << 14)
+#define EFLAGS_RF	(1 << 16)
 
-#define CR4_OSFXSR_MASK      (1 << 9)
-#define CR4_OSXMMEXCPT_MASK  (1 << 10)
+#define CR0_AM		(1 << 18)
+#define CR0_NW		(1 << 29)
+#define CR0_CD		(1 << 30)
+#define CR0_PG		(1 << 31)
+
+#define CR4_OSFXSR_MASK		(1 << 9)
+#define CR4_OSXMMEXCPT_MASK	(1 << 10)
+
+#define IA32_APIC_BASE_GE	(1 << 11)
+
+#define IA32_MSR_APIC_BASE	0x01b
 
 /* Support for SYSENTER and SYSEXIT */
-#define IA32_MSR_SYSENTER_CS   0x174U
-#define IA32_MSR_SYSENTER_ESP  0x175U
-#define IA32_MSR_SYSENTER_EIP  0x176U
+#define IA32_MSR_SYSENTER_CS	0x174
+#define IA32_MSR_SYSENTER_ESP	0x175
+#define IA32_MSR_SYSENTER_EIP	0x176
 
 #ifndef __ASM__
Index: kernel/arch/ia32/include/arch/smp/apic.h
===================================================================
--- kernel/arch/ia32/include/arch/smp/apic.h	(revision 4b0206c7b08dfc91e29744cd62ce245f29ac2b62)
+++ kernel/arch/ia32/include/arch/smp/apic.h	(revision 0f17bffb9edacd5345a8cb7bd518bccfb25c3e30)
@@ -36,4 +36,9 @@
 #define KERN_ia32_APIC_H_
 
+#define L_APIC_BASE	0xfee00000
+#define IO_APIC_BASE	0xfec00000
+
+#ifndef __ASM__
+
 #include <typedefs.h>
 #include <cpu.h>
@@ -364,4 +369,6 @@
 extern void io_apic_enable_irqs(uint16_t);
 
+#endif	/* __ASM__ */
+
 #endif
 
Index: kernel/arch/ia32/src/asm.S
===================================================================
--- kernel/arch/ia32/src/asm.S	(revision 4b0206c7b08dfc91e29744cd62ce245f29ac2b62)
+++ kernel/arch/ia32/src/asm.S	(revision 0f17bffb9edacd5345a8cb7bd518bccfb25c3e30)
@@ -36,4 +36,5 @@
 #include <arch/mm/page.h>
 #include <arch/istate_struct.h>
+#include <arch/smp/apic.h>
 
 .text
@@ -110,8 +111,8 @@
 FUNCTION_BEGIN(paging_on)
 	movl %cr0, %edx
-	orl $(1 << 31), %edx  /* paging on */
+	orl $CR0_PG, %edx  /* paging on */
 	
 	/* Clear Cache Disable and not Write Though */
-	andl $~((1 << 30) | (1 << 29)), %edx
+	andl $~(CR0_CD | CR0_NW), %edx
 	movl %edx, %cr0
 	jmp 0f
@@ -127,8 +128,7 @@
  */
 FUNCTION_BEGIN(enable_l_apic_in_msr)
-	movl $0x1b, %ecx
+	movl $IA32_MSR_APIC_BASE, %ecx
 	rdmsr
-	orl $(1 << 11), %eax
-	orl $(0xfee00000), %eax
+	orl $(L_APIC_BASE | IA32_APIC_BASE_GE), %eax
 	wrmsr
 	ret
Index: kernel/arch/ia32/src/pm.c
===================================================================
--- kernel/arch/ia32/src/pm.c	(revision 4b0206c7b08dfc91e29744cd62ce245f29ac2b62)
+++ kernel/arch/ia32/src/pm.c	(revision 0f17bffb9edacd5345a8cb7bd518bccfb25c3e30)
@@ -47,4 +47,5 @@
 #include <arch/boot/boot.h>
 #include <interrupt.h>
+#include <arch/cpu.h>
 
 /*
@@ -256,28 +257,4 @@
 }
 
-/* Clean IOPL(12,13) and NT(14) flags in EFLAGS register */
-static void clean_IOPL_NT_flags(void)
-{
-	asm volatile (
-		"pushfl\n"
-		"pop %%eax\n"
-		"and $0xffff8fff, %%eax\n"
-		"push %%eax\n"
-		"popfl\n"
-		::: "eax"
-	);
-}
-
-/* Clean AM(18) flag in CR0 register */
-static void clean_AM_flag(void)
-{
-	asm volatile (
-		"mov %%cr0, %%eax\n"
-		"and $0xfffbffff, %%eax\n"
-		"mov %%eax, %%cr0\n"
-		::: "eax"
-	);
-}
-
 void pm_init(void)
 {
@@ -326,6 +303,9 @@
 	tr_load(GDT_SELECTOR(TSS_DES));
 	
-	clean_IOPL_NT_flags();    /* Disable I/O on nonprivileged levels and clear NT flag. */
-	clean_AM_flag();          /* Disable alignment check */
+	/* Disable I/O on nonprivileged levels and clear NT flag. */
+	write_eflags(read_eflags() & ~(EFLAGS_IOPL | EFLAGS_NT));
+
+	/* Disable alignment check */
+	write_cr0(read_cr0() & ~CR0_AM);
 }
 
Index: kernel/arch/ia32/src/smp/apic.c
===================================================================
--- kernel/arch/ia32/src/smp/apic.c	(revision 4b0206c7b08dfc91e29744cd62ce245f29ac2b62)
+++ kernel/arch/ia32/src/smp/apic.c	(revision 0f17bffb9edacd5345a8cb7bd518bccfb25c3e30)
@@ -72,6 +72,6 @@
  *
  */
-volatile uint32_t *l_apic = (uint32_t *) UINT32_C(0xfee00000);
-volatile uint32_t *io_apic = (uint32_t *) UINT32_C(0xfec00000);
+volatile uint32_t *l_apic = (uint32_t *) L_APIC_BASE;
+volatile uint32_t *io_apic = (uint32_t *) IO_APIC_BASE;
 
 uint32_t apic_id_mask = 0;
Index: kernel/arch/ia32/src/userspace.c
===================================================================
--- kernel/arch/ia32/src/userspace.c	(revision 4b0206c7b08dfc91e29744cd62ce245f29ac2b62)
+++ kernel/arch/ia32/src/userspace.c	(revision 0f17bffb9edacd5345a8cb7bd518bccfb25c3e30)
@@ -39,4 +39,6 @@
 #include <abi/proc/uarg.h>
 #include <mm/as.h>
+#include <arch/cpu.h>
+#include <arch/asm.h>
 
 /** Enter userspace
@@ -47,16 +49,7 @@
 void userspace(uspace_arg_t *kernel_uarg)
 {
-	ipl_t ipl = interrupts_disable();
+	uint32_t eflags = read_eflags();
 	
 	asm volatile (
-		/*
-		 * Clear nested task flag.
-		 */
-		"pushfl\n"
-		"pop %%eax\n"
-		"and $0xffffbfff, %%eax\n"
-		"push %%eax\n"
-		"popfl\n"
-		
 		/* Set up GS register (virtual register segment) */
 		"movl %[vreg_des], %%gs\n"
@@ -64,5 +57,5 @@
 		"pushl %[udata_des]\n"
 		"pushl %[stack_top]\n"
-		"pushl %[ipl]\n"
+		"pushl %[eflags]\n"
 		"pushl %[utext_des]\n"
 		"pushl %[entry]\n"
@@ -74,8 +67,9 @@
 		"iret\n"
 		:
-		: [udata_des] "i" (GDT_SELECTOR(UDATA_DES) | PL_USER),
+		: [eflags_mask] "i" (~EFLAGS_NT),
+		  [udata_des] "i" (GDT_SELECTOR(UDATA_DES) | PL_USER),
 		  [stack_top] "r" ((uint8_t *) kernel_uarg->uspace_stack +
 		      kernel_uarg->uspace_stack_size),
-		  [ipl] "r" (ipl),
+		  [eflags] "r" ((eflags & ~(EFLAGS_NT)) | EFLAGS_IF),
 		  [utext_des] "i" (GDT_SELECTOR(UTEXT_DES) | PL_USER),
 		  [entry] "r" (kernel_uarg->uspace_entry),
