Commit 0efb0440 authored by Nadav Amit's avatar Nadav Amit Committed by Paolo Bonzini

KVM: x86: removing redundant eflags bits definitions

The eflags are redefined (using other defines) in emulate.c.
Use the definition from processor-flags.h as some mess already started.
No functional change.
Signed-off-by: default avatarNadav Amit <namit@cs.technion.ac.il>
Message-Id: <1427635984-8113-2-git-send-email-namit@cs.technion.ac.il>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 900efe20
...@@ -84,8 +84,6 @@ static inline gfn_t gfn_to_index(gfn_t gfn, gfn_t base_gfn, int level) ...@@ -84,8 +84,6 @@ static inline gfn_t gfn_to_index(gfn_t gfn, gfn_t base_gfn, int level)
#define SELECTOR_TI_MASK (1 << 2) #define SELECTOR_TI_MASK (1 << 2)
#define SELECTOR_RPL_MASK 0x03 #define SELECTOR_RPL_MASK 0x03
#define IOPL_SHIFT 12
#define KVM_PERMILLE_MMU_PAGES 20 #define KVM_PERMILLE_MMU_PAGES 20
#define KVM_MIN_ALLOC_MMU_PAGES 64 #define KVM_MIN_ALLOC_MMU_PAGES 64
#define KVM_MMU_HASH_SHIFT 10 #define KVM_MMU_HASH_SHIFT 10
......
...@@ -248,27 +248,7 @@ struct mode_dual { ...@@ -248,27 +248,7 @@ struct mode_dual {
struct opcode mode64; struct opcode mode64;
}; };
/* EFLAGS bit definitions. */
#define EFLG_ID (1<<21)
#define EFLG_VIP (1<<20)
#define EFLG_VIF (1<<19)
#define EFLG_AC (1<<18)
#define EFLG_VM (1<<17)
#define EFLG_RF (1<<16)
#define EFLG_IOPL (3<<12)
#define EFLG_NT (1<<14)
#define EFLG_OF (1<<11)
#define EFLG_DF (1<<10)
#define EFLG_IF (1<<9)
#define EFLG_TF (1<<8)
#define EFLG_SF (1<<7)
#define EFLG_ZF (1<<6)
#define EFLG_AF (1<<4)
#define EFLG_PF (1<<2)
#define EFLG_CF (1<<0)
#define EFLG_RESERVED_ZEROS_MASK 0xffc0802a #define EFLG_RESERVED_ZEROS_MASK 0xffc0802a
#define EFLG_RESERVED_ONE_MASK 2
enum x86_transfer_type { enum x86_transfer_type {
X86_TRANSFER_NONE, X86_TRANSFER_NONE,
...@@ -317,7 +297,8 @@ static void invalidate_registers(struct x86_emulate_ctxt *ctxt) ...@@ -317,7 +297,8 @@ static void invalidate_registers(struct x86_emulate_ctxt *ctxt)
* These EFLAGS bits are restored from saved value during emulation, and * These EFLAGS bits are restored from saved value during emulation, and
* any changes are written back to the saved value after emulation. * any changes are written back to the saved value after emulation.
*/ */
#define EFLAGS_MASK (EFLG_OF|EFLG_SF|EFLG_ZF|EFLG_AF|EFLG_PF|EFLG_CF) #define EFLAGS_MASK (X86_EFLAGS_OF|X86_EFLAGS_SF|X86_EFLAGS_ZF|X86_EFLAGS_AF|\
X86_EFLAGS_PF|X86_EFLAGS_CF)
#ifdef CONFIG_X86_64 #ifdef CONFIG_X86_64
#define ON64(x) x #define ON64(x) x
...@@ -1434,7 +1415,7 @@ static int pio_in_emulated(struct x86_emulate_ctxt *ctxt, ...@@ -1434,7 +1415,7 @@ static int pio_in_emulated(struct x86_emulate_ctxt *ctxt,
unsigned int in_page, n; unsigned int in_page, n;
unsigned int count = ctxt->rep_prefix ? unsigned int count = ctxt->rep_prefix ?
address_mask(ctxt, reg_read(ctxt, VCPU_REGS_RCX)) : 1; address_mask(ctxt, reg_read(ctxt, VCPU_REGS_RCX)) : 1;
in_page = (ctxt->eflags & EFLG_DF) ? in_page = (ctxt->eflags & X86_EFLAGS_DF) ?
offset_in_page(reg_read(ctxt, VCPU_REGS_RDI)) : offset_in_page(reg_read(ctxt, VCPU_REGS_RDI)) :
PAGE_SIZE - offset_in_page(reg_read(ctxt, VCPU_REGS_RDI)); PAGE_SIZE - offset_in_page(reg_read(ctxt, VCPU_REGS_RDI));
n = min3(in_page, (unsigned int)sizeof(rc->data) / size, count); n = min3(in_page, (unsigned int)sizeof(rc->data) / size, count);
...@@ -1447,7 +1428,7 @@ static int pio_in_emulated(struct x86_emulate_ctxt *ctxt, ...@@ -1447,7 +1428,7 @@ static int pio_in_emulated(struct x86_emulate_ctxt *ctxt,
} }
if (ctxt->rep_prefix && (ctxt->d & String) && if (ctxt->rep_prefix && (ctxt->d & String) &&
!(ctxt->eflags & EFLG_DF)) { !(ctxt->eflags & X86_EFLAGS_DF)) {
ctxt->dst.data = rc->data + rc->pos; ctxt->dst.data = rc->data + rc->pos;
ctxt->dst.type = OP_MEM_STR; ctxt->dst.type = OP_MEM_STR;
ctxt->dst.count = (rc->end - rc->pos) / size; ctxt->dst.count = (rc->end - rc->pos) / size;
...@@ -1813,32 +1794,34 @@ static int emulate_popf(struct x86_emulate_ctxt *ctxt, ...@@ -1813,32 +1794,34 @@ static int emulate_popf(struct x86_emulate_ctxt *ctxt,
{ {
int rc; int rc;
unsigned long val, change_mask; unsigned long val, change_mask;
int iopl = (ctxt->eflags & X86_EFLAGS_IOPL) >> IOPL_SHIFT; int iopl = (ctxt->eflags & X86_EFLAGS_IOPL) >> X86_EFLAGS_IOPL_BIT;
int cpl = ctxt->ops->cpl(ctxt); int cpl = ctxt->ops->cpl(ctxt);
rc = emulate_pop(ctxt, &val, len); rc = emulate_pop(ctxt, &val, len);
if (rc != X86EMUL_CONTINUE) if (rc != X86EMUL_CONTINUE)
return rc; return rc;
change_mask = EFLG_CF | EFLG_PF | EFLG_AF | EFLG_ZF | EFLG_SF | EFLG_OF change_mask = X86_EFLAGS_CF | X86_EFLAGS_PF | X86_EFLAGS_AF |
| EFLG_TF | EFLG_DF | EFLG_NT | EFLG_AC | EFLG_ID; X86_EFLAGS_ZF | X86_EFLAGS_SF | X86_EFLAGS_OF |
X86_EFLAGS_TF | X86_EFLAGS_DF | X86_EFLAGS_NT |
X86_EFLAGS_AC | X86_EFLAGS_ID;
switch(ctxt->mode) { switch(ctxt->mode) {
case X86EMUL_MODE_PROT64: case X86EMUL_MODE_PROT64:
case X86EMUL_MODE_PROT32: case X86EMUL_MODE_PROT32:
case X86EMUL_MODE_PROT16: case X86EMUL_MODE_PROT16:
if (cpl == 0) if (cpl == 0)
change_mask |= EFLG_IOPL; change_mask |= X86_EFLAGS_IOPL;
if (cpl <= iopl) if (cpl <= iopl)
change_mask |= EFLG_IF; change_mask |= X86_EFLAGS_IF;
break; break;
case X86EMUL_MODE_VM86: case X86EMUL_MODE_VM86:
if (iopl < 3) if (iopl < 3)
return emulate_gp(ctxt, 0); return emulate_gp(ctxt, 0);
change_mask |= EFLG_IF; change_mask |= X86_EFLAGS_IF;
break; break;
default: /* real mode */ default: /* real mode */
change_mask |= (EFLG_IOPL | EFLG_IF); change_mask |= (X86_EFLAGS_IOPL | X86_EFLAGS_IF);
break; break;
} }
...@@ -1939,7 +1922,7 @@ static int em_pusha(struct x86_emulate_ctxt *ctxt) ...@@ -1939,7 +1922,7 @@ static int em_pusha(struct x86_emulate_ctxt *ctxt)
static int em_pushf(struct x86_emulate_ctxt *ctxt) static int em_pushf(struct x86_emulate_ctxt *ctxt)
{ {
ctxt->src.val = (unsigned long)ctxt->eflags & ~EFLG_VM; ctxt->src.val = (unsigned long)ctxt->eflags & ~X86_EFLAGS_VM;
return em_push(ctxt); return em_push(ctxt);
} }
...@@ -1979,7 +1962,7 @@ static int __emulate_int_real(struct x86_emulate_ctxt *ctxt, int irq) ...@@ -1979,7 +1962,7 @@ static int __emulate_int_real(struct x86_emulate_ctxt *ctxt, int irq)
if (rc != X86EMUL_CONTINUE) if (rc != X86EMUL_CONTINUE)
return rc; return rc;
ctxt->eflags &= ~(EFLG_IF | EFLG_TF | EFLG_AC); ctxt->eflags &= ~(X86_EFLAGS_IF | X86_EFLAGS_TF | X86_EFLAGS_AC);
ctxt->src.val = get_segment_selector(ctxt, VCPU_SREG_CS); ctxt->src.val = get_segment_selector(ctxt, VCPU_SREG_CS);
rc = em_push(ctxt); rc = em_push(ctxt);
...@@ -2045,10 +2028,14 @@ static int emulate_iret_real(struct x86_emulate_ctxt *ctxt) ...@@ -2045,10 +2028,14 @@ static int emulate_iret_real(struct x86_emulate_ctxt *ctxt)
unsigned long temp_eip = 0; unsigned long temp_eip = 0;
unsigned long temp_eflags = 0; unsigned long temp_eflags = 0;
unsigned long cs = 0; unsigned long cs = 0;
unsigned long mask = EFLG_CF | EFLG_PF | EFLG_AF | EFLG_ZF | EFLG_SF | EFLG_TF | unsigned long mask = X86_EFLAGS_CF | X86_EFLAGS_PF | X86_EFLAGS_AF |
EFLG_IF | EFLG_DF | EFLG_OF | EFLG_IOPL | EFLG_NT | EFLG_RF | X86_EFLAGS_ZF | X86_EFLAGS_SF | X86_EFLAGS_TF |
EFLG_AC | EFLG_ID | (1 << 1); /* Last one is the reserved bit */ X86_EFLAGS_IF | X86_EFLAGS_DF | X86_EFLAGS_OF |
unsigned long vm86_mask = EFLG_VM | EFLG_VIF | EFLG_VIP; X86_EFLAGS_IOPL | X86_EFLAGS_NT | X86_EFLAGS_RF |
X86_EFLAGS_AC | X86_EFLAGS_ID |
X86_EFLAGS_FIXED_BIT;
unsigned long vm86_mask = X86_EFLAGS_VM | X86_EFLAGS_VIF |
X86_EFLAGS_VIP;
/* TODO: Add stack limit check */ /* TODO: Add stack limit check */
...@@ -2077,7 +2064,6 @@ static int emulate_iret_real(struct x86_emulate_ctxt *ctxt) ...@@ -2077,7 +2064,6 @@ static int emulate_iret_real(struct x86_emulate_ctxt *ctxt)
ctxt->_eip = temp_eip; ctxt->_eip = temp_eip;
if (ctxt->op_bytes == 4) if (ctxt->op_bytes == 4)
ctxt->eflags = ((temp_eflags & mask) | (ctxt->eflags & vm86_mask)); ctxt->eflags = ((temp_eflags & mask) | (ctxt->eflags & vm86_mask));
else if (ctxt->op_bytes == 2) { else if (ctxt->op_bytes == 2) {
...@@ -2086,7 +2072,7 @@ static int emulate_iret_real(struct x86_emulate_ctxt *ctxt) ...@@ -2086,7 +2072,7 @@ static int emulate_iret_real(struct x86_emulate_ctxt *ctxt)
} }
ctxt->eflags &= ~EFLG_RESERVED_ZEROS_MASK; /* Clear reserved zeros */ ctxt->eflags &= ~EFLG_RESERVED_ZEROS_MASK; /* Clear reserved zeros */
ctxt->eflags |= EFLG_RESERVED_ONE_MASK; ctxt->eflags |= X86_EFLAGS_FIXED_BIT;
ctxt->ops->set_nmi_mask(ctxt, false); ctxt->ops->set_nmi_mask(ctxt, false);
return rc; return rc;
...@@ -2168,12 +2154,12 @@ static int em_cmpxchg8b(struct x86_emulate_ctxt *ctxt) ...@@ -2168,12 +2154,12 @@ static int em_cmpxchg8b(struct x86_emulate_ctxt *ctxt)
((u32) (old >> 32) != (u32) reg_read(ctxt, VCPU_REGS_RDX))) { ((u32) (old >> 32) != (u32) reg_read(ctxt, VCPU_REGS_RDX))) {
*reg_write(ctxt, VCPU_REGS_RAX) = (u32) (old >> 0); *reg_write(ctxt, VCPU_REGS_RAX) = (u32) (old >> 0);
*reg_write(ctxt, VCPU_REGS_RDX) = (u32) (old >> 32); *reg_write(ctxt, VCPU_REGS_RDX) = (u32) (old >> 32);
ctxt->eflags &= ~EFLG_ZF; ctxt->eflags &= ~X86_EFLAGS_ZF;
} else { } else {
ctxt->dst.val64 = ((u64)reg_read(ctxt, VCPU_REGS_RCX) << 32) | ctxt->dst.val64 = ((u64)reg_read(ctxt, VCPU_REGS_RCX) << 32) |
(u32) reg_read(ctxt, VCPU_REGS_RBX); (u32) reg_read(ctxt, VCPU_REGS_RBX);
ctxt->eflags |= EFLG_ZF; ctxt->eflags |= X86_EFLAGS_ZF;
} }
return X86EMUL_CONTINUE; return X86EMUL_CONTINUE;
} }
...@@ -2245,7 +2231,7 @@ static int em_cmpxchg(struct x86_emulate_ctxt *ctxt) ...@@ -2245,7 +2231,7 @@ static int em_cmpxchg(struct x86_emulate_ctxt *ctxt)
ctxt->src.val = ctxt->dst.orig_val; ctxt->src.val = ctxt->dst.orig_val;
fastop(ctxt, em_cmp); fastop(ctxt, em_cmp);
if (ctxt->eflags & EFLG_ZF) { if (ctxt->eflags & X86_EFLAGS_ZF) {
/* Success: write back to memory; no update of EAX */ /* Success: write back to memory; no update of EAX */
ctxt->src.type = OP_NONE; ctxt->src.type = OP_NONE;
ctxt->dst.val = ctxt->src.orig_val; ctxt->dst.val = ctxt->src.orig_val;
...@@ -2404,14 +2390,14 @@ static int em_syscall(struct x86_emulate_ctxt *ctxt) ...@@ -2404,14 +2390,14 @@ static int em_syscall(struct x86_emulate_ctxt *ctxt)
ops->get_msr(ctxt, MSR_SYSCALL_MASK, &msr_data); ops->get_msr(ctxt, MSR_SYSCALL_MASK, &msr_data);
ctxt->eflags &= ~msr_data; ctxt->eflags &= ~msr_data;
ctxt->eflags |= EFLG_RESERVED_ONE_MASK; ctxt->eflags |= X86_EFLAGS_FIXED_BIT;
#endif #endif
} else { } else {
/* legacy mode */ /* legacy mode */
ops->get_msr(ctxt, MSR_STAR, &msr_data); ops->get_msr(ctxt, MSR_STAR, &msr_data);
ctxt->_eip = (u32)msr_data; ctxt->_eip = (u32)msr_data;
ctxt->eflags &= ~(EFLG_VM | EFLG_IF); ctxt->eflags &= ~(X86_EFLAGS_VM | X86_EFLAGS_IF);
} }
return X86EMUL_CONTINUE; return X86EMUL_CONTINUE;
...@@ -2448,7 +2434,7 @@ static int em_sysenter(struct x86_emulate_ctxt *ctxt) ...@@ -2448,7 +2434,7 @@ static int em_sysenter(struct x86_emulate_ctxt *ctxt)
if ((msr_data & 0xfffc) == 0x0) if ((msr_data & 0xfffc) == 0x0)
return emulate_gp(ctxt, 0); return emulate_gp(ctxt, 0);
ctxt->eflags &= ~(EFLG_VM | EFLG_IF); ctxt->eflags &= ~(X86_EFLAGS_VM | X86_EFLAGS_IF);
cs_sel = (u16)msr_data & ~SELECTOR_RPL_MASK; cs_sel = (u16)msr_data & ~SELECTOR_RPL_MASK;
ss_sel = cs_sel + 8; ss_sel = cs_sel + 8;
if (efer & EFER_LMA) { if (efer & EFER_LMA) {
...@@ -2535,7 +2521,7 @@ static bool emulator_bad_iopl(struct x86_emulate_ctxt *ctxt) ...@@ -2535,7 +2521,7 @@ static bool emulator_bad_iopl(struct x86_emulate_ctxt *ctxt)
return false; return false;
if (ctxt->mode == X86EMUL_MODE_VM86) if (ctxt->mode == X86EMUL_MODE_VM86)
return true; return true;
iopl = (ctxt->eflags & X86_EFLAGS_IOPL) >> IOPL_SHIFT; iopl = (ctxt->eflags & X86_EFLAGS_IOPL) >> X86_EFLAGS_IOPL_BIT;
return ctxt->ops->cpl(ctxt) > iopl; return ctxt->ops->cpl(ctxt) > iopl;
} }
...@@ -2977,7 +2963,7 @@ int emulator_task_switch(struct x86_emulate_ctxt *ctxt, ...@@ -2977,7 +2963,7 @@ int emulator_task_switch(struct x86_emulate_ctxt *ctxt,
static void string_addr_inc(struct x86_emulate_ctxt *ctxt, int reg, static void string_addr_inc(struct x86_emulate_ctxt *ctxt, int reg,
struct operand *op) struct operand *op)
{ {
int df = (ctxt->eflags & EFLG_DF) ? -op->count : op->count; int df = (ctxt->eflags & X86_EFLAGS_DF) ? -op->count : op->count;
register_address_increment(ctxt, reg, df * op->bytes); register_address_increment(ctxt, reg, df * op->bytes);
op->addr.mem.ea = register_address(ctxt, reg); op->addr.mem.ea = register_address(ctxt, reg);
...@@ -3516,7 +3502,8 @@ static int em_sahf(struct x86_emulate_ctxt *ctxt) ...@@ -3516,7 +3502,8 @@ static int em_sahf(struct x86_emulate_ctxt *ctxt)
{ {
u32 flags; u32 flags;
flags = EFLG_CF | EFLG_PF | EFLG_AF | EFLG_ZF | EFLG_SF; flags = X86_EFLAGS_CF | X86_EFLAGS_PF | X86_EFLAGS_AF | X86_EFLAGS_ZF |
X86_EFLAGS_SF;
flags &= *reg_rmw(ctxt, VCPU_REGS_RAX) >> 8; flags &= *reg_rmw(ctxt, VCPU_REGS_RAX) >> 8;
ctxt->eflags &= ~0xffUL; ctxt->eflags &= ~0xffUL;
...@@ -4772,9 +4759,9 @@ static bool string_insn_completed(struct x86_emulate_ctxt *ctxt) ...@@ -4772,9 +4759,9 @@ static bool string_insn_completed(struct x86_emulate_ctxt *ctxt)
if (((ctxt->b == 0xa6) || (ctxt->b == 0xa7) || if (((ctxt->b == 0xa6) || (ctxt->b == 0xa7) ||
(ctxt->b == 0xae) || (ctxt->b == 0xaf)) (ctxt->b == 0xae) || (ctxt->b == 0xaf))
&& (((ctxt->rep_prefix == REPE_PREFIX) && && (((ctxt->rep_prefix == REPE_PREFIX) &&
((ctxt->eflags & EFLG_ZF) == 0)) ((ctxt->eflags & X86_EFLAGS_ZF) == 0))
|| ((ctxt->rep_prefix == REPNE_PREFIX) && || ((ctxt->rep_prefix == REPNE_PREFIX) &&
((ctxt->eflags & EFLG_ZF) == EFLG_ZF)))) ((ctxt->eflags & X86_EFLAGS_ZF) == X86_EFLAGS_ZF))))
return true; return true;
return false; return false;
...@@ -4926,7 +4913,7 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt) ...@@ -4926,7 +4913,7 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
/* All REP prefixes have the same first termination condition */ /* All REP prefixes have the same first termination condition */
if (address_mask(ctxt, reg_read(ctxt, VCPU_REGS_RCX)) == 0) { if (address_mask(ctxt, reg_read(ctxt, VCPU_REGS_RCX)) == 0) {
ctxt->eip = ctxt->_eip; ctxt->eip = ctxt->_eip;
ctxt->eflags &= ~EFLG_RF; ctxt->eflags &= ~X86_EFLAGS_RF;
goto done; goto done;
} }
} }
...@@ -4976,9 +4963,9 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt) ...@@ -4976,9 +4963,9 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
} }
if (ctxt->rep_prefix && (ctxt->d & String)) if (ctxt->rep_prefix && (ctxt->d & String))
ctxt->eflags |= EFLG_RF; ctxt->eflags |= X86_EFLAGS_RF;
else else
ctxt->eflags &= ~EFLG_RF; ctxt->eflags &= ~X86_EFLAGS_RF;
if (ctxt->execute) { if (ctxt->execute) {
if (ctxt->d & Fastop) { if (ctxt->d & Fastop) {
...@@ -5027,7 +5014,7 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt) ...@@ -5027,7 +5014,7 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
rc = emulate_int(ctxt, ctxt->src.val); rc = emulate_int(ctxt, ctxt->src.val);
break; break;
case 0xce: /* into */ case 0xce: /* into */
if (ctxt->eflags & EFLG_OF) if (ctxt->eflags & X86_EFLAGS_OF)
rc = emulate_int(ctxt, 4); rc = emulate_int(ctxt, 4);
break; break;
case 0xe9: /* jmp rel */ case 0xe9: /* jmp rel */
...@@ -5040,19 +5027,19 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt) ...@@ -5040,19 +5027,19 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
break; break;
case 0xf5: /* cmc */ case 0xf5: /* cmc */
/* complement carry flag from eflags reg */ /* complement carry flag from eflags reg */
ctxt->eflags ^= EFLG_CF; ctxt->eflags ^= X86_EFLAGS_CF;
break; break;
case 0xf8: /* clc */ case 0xf8: /* clc */
ctxt->eflags &= ~EFLG_CF; ctxt->eflags &= ~X86_EFLAGS_CF;
break; break;
case 0xf9: /* stc */ case 0xf9: /* stc */
ctxt->eflags |= EFLG_CF; ctxt->eflags |= X86_EFLAGS_CF;
break; break;
case 0xfc: /* cld */ case 0xfc: /* cld */
ctxt->eflags &= ~EFLG_DF; ctxt->eflags &= ~X86_EFLAGS_DF;
break; break;
case 0xfd: /* std */ case 0xfd: /* std */
ctxt->eflags |= EFLG_DF; ctxt->eflags |= X86_EFLAGS_DF;
break; break;
default: default:
goto cannot_emulate; goto cannot_emulate;
...@@ -5113,7 +5100,7 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt) ...@@ -5113,7 +5100,7 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt)
} }
goto done; /* skip rip writeback */ goto done; /* skip rip writeback */
} }
ctxt->eflags &= ~EFLG_RF; ctxt->eflags &= ~X86_EFLAGS_RF;
} }
ctxt->eip = ctxt->_eip; ctxt->eip = ctxt->_eip;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment