Misc x86 fixes: fix a double-free bug, a binutils warning,
a header namespace clash and a bug in ib_prctl_set(). Signed-off-by: Ingo Molnar <mingo@kernel.org> -----BEGIN PGP SIGNATURE----- iQJFBAABCgAvFiEEBpT5eoXrXCwVQwEKEnMQ0APhK1gFAmO12PQRHG1pbmdvQGtl cm5lbC5vcmcACgkQEnMQ0APhK1hqkQ/8D3sOz3JfTAX8+w5xuWfumJJ+LbLNeRKf 11mwjj9cBHEXMh9JMUEx6Qufv0e6UJlphQhdLNnp02CGg4EKzyQs+e8MtXutShEb oWLAehzE574Ce0gpSQFT95W46TFKEQw4So1u5puYZFxenMsixXSe7aGFU/6jKREa uwTdcWKzB424DkRPXVvydmm48aUDhm2rG7b1Aso/xMP/ORcK48gESzeaOblf1iq9 q8fqlikd/THtJEQ82VoTdsQ5w2uHN5XTYQuBZZlONzKdpdq958ddnotz0VC+M8AX lTnNogNrI8Xvmbz0yBbAs9wPKV82klUvmMFSvz6ygS47hkTjydpzFrE2I6mm/Lae HizfV8i3mOknmf/S7lDw3p3cww909X/gI4iGL28x8MQR2+5j/H6ILJTVb62PvCS6 QCeyZhcF50mgww+vpmt5YVdxADbjfo5b83p7TmfEH5pmH4Uhy+85j/yR7on01rFI YMync4DvZHY+wnI8glEsKIB0yqEagyr7GJ3Nw0TUHrUy8auhZfihIXbelCZo6Kd2 R2mEMvRzhVb3kw89WubtYFWr+D+hvjhzqTcgXNEmsInlb6xWjEYA66aUE88EgRuL J493YA27z9qHxvMOSewIVoyRs6ve3rfwhG5C+QI5keK3ttJrx+irUnK8/XaMZv4/ JEn3DvQJ2sk= =yfLN -----END PGP SIGNATURE----- Merge tag 'x86-urgent-2023-01-04' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip Pull misc x86 fixes from Ingo Molnar: "Fix a double-free bug, a binutils warning, a header namespace clash and a bug in ib_prctl_set()" * tag 'x86-urgent-2023-01-04' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/bugs: Flush IBP in ib_prctl_set() x86/insn: Avoid namespace clash by separating instruction decoder MMIO type from MMIO trace type x86/asm: Fix an assembler warning with current binutils x86/kexec: Fix double-free of elf header buffer
This commit is contained in:
commit
512dee0c00
@ -386,8 +386,8 @@ static int handle_mmio(struct pt_regs *regs, struct ve_info *ve)
|
||||
{
|
||||
unsigned long *reg, val, vaddr;
|
||||
char buffer[MAX_INSN_SIZE];
|
||||
enum insn_mmio_type mmio;
|
||||
struct insn insn = {};
|
||||
enum mmio_type mmio;
|
||||
int size, extend_size;
|
||||
u8 extend_val = 0;
|
||||
|
||||
@ -402,10 +402,10 @@ static int handle_mmio(struct pt_regs *regs, struct ve_info *ve)
|
||||
return -EINVAL;
|
||||
|
||||
mmio = insn_decode_mmio(&insn, &size);
|
||||
if (WARN_ON_ONCE(mmio == MMIO_DECODE_FAILED))
|
||||
if (WARN_ON_ONCE(mmio == INSN_MMIO_DECODE_FAILED))
|
||||
return -EINVAL;
|
||||
|
||||
if (mmio != MMIO_WRITE_IMM && mmio != MMIO_MOVS) {
|
||||
if (mmio != INSN_MMIO_WRITE_IMM && mmio != INSN_MMIO_MOVS) {
|
||||
reg = insn_get_modrm_reg_ptr(&insn, regs);
|
||||
if (!reg)
|
||||
return -EINVAL;
|
||||
@ -426,23 +426,23 @@ static int handle_mmio(struct pt_regs *regs, struct ve_info *ve)
|
||||
|
||||
/* Handle writes first */
|
||||
switch (mmio) {
|
||||
case MMIO_WRITE:
|
||||
case INSN_MMIO_WRITE:
|
||||
memcpy(&val, reg, size);
|
||||
if (!mmio_write(size, ve->gpa, val))
|
||||
return -EIO;
|
||||
return insn.length;
|
||||
case MMIO_WRITE_IMM:
|
||||
case INSN_MMIO_WRITE_IMM:
|
||||
val = insn.immediate.value;
|
||||
if (!mmio_write(size, ve->gpa, val))
|
||||
return -EIO;
|
||||
return insn.length;
|
||||
case MMIO_READ:
|
||||
case MMIO_READ_ZERO_EXTEND:
|
||||
case MMIO_READ_SIGN_EXTEND:
|
||||
case INSN_MMIO_READ:
|
||||
case INSN_MMIO_READ_ZERO_EXTEND:
|
||||
case INSN_MMIO_READ_SIGN_EXTEND:
|
||||
/* Reads are handled below */
|
||||
break;
|
||||
case MMIO_MOVS:
|
||||
case MMIO_DECODE_FAILED:
|
||||
case INSN_MMIO_MOVS:
|
||||
case INSN_MMIO_DECODE_FAILED:
|
||||
/*
|
||||
* MMIO was accessed with an instruction that could not be
|
||||
* decoded or handled properly. It was likely not using io.h
|
||||
@ -459,15 +459,15 @@ static int handle_mmio(struct pt_regs *regs, struct ve_info *ve)
|
||||
return -EIO;
|
||||
|
||||
switch (mmio) {
|
||||
case MMIO_READ:
|
||||
case INSN_MMIO_READ:
|
||||
/* Zero-extend for 32-bit operation */
|
||||
extend_size = size == 4 ? sizeof(*reg) : 0;
|
||||
break;
|
||||
case MMIO_READ_ZERO_EXTEND:
|
||||
case INSN_MMIO_READ_ZERO_EXTEND:
|
||||
/* Zero extend based on operand size */
|
||||
extend_size = insn.opnd_bytes;
|
||||
break;
|
||||
case MMIO_READ_SIGN_EXTEND:
|
||||
case INSN_MMIO_READ_SIGN_EXTEND:
|
||||
/* Sign extend based on operand size */
|
||||
extend_size = insn.opnd_bytes;
|
||||
if (size == 1 && val & BIT(7))
|
||||
|
@ -32,16 +32,16 @@ int insn_fetch_from_user_inatomic(struct pt_regs *regs,
|
||||
bool insn_decode_from_regs(struct insn *insn, struct pt_regs *regs,
|
||||
unsigned char buf[MAX_INSN_SIZE], int buf_size);
|
||||
|
||||
enum mmio_type {
|
||||
MMIO_DECODE_FAILED,
|
||||
MMIO_WRITE,
|
||||
MMIO_WRITE_IMM,
|
||||
MMIO_READ,
|
||||
MMIO_READ_ZERO_EXTEND,
|
||||
MMIO_READ_SIGN_EXTEND,
|
||||
MMIO_MOVS,
|
||||
enum insn_mmio_type {
|
||||
INSN_MMIO_DECODE_FAILED,
|
||||
INSN_MMIO_WRITE,
|
||||
INSN_MMIO_WRITE_IMM,
|
||||
INSN_MMIO_READ,
|
||||
INSN_MMIO_READ_ZERO_EXTEND,
|
||||
INSN_MMIO_READ_SIGN_EXTEND,
|
||||
INSN_MMIO_MOVS,
|
||||
};
|
||||
|
||||
enum mmio_type insn_decode_mmio(struct insn *insn, int *bytes);
|
||||
enum insn_mmio_type insn_decode_mmio(struct insn *insn, int *bytes);
|
||||
|
||||
#endif /* _ASM_X86_INSN_EVAL_H */
|
||||
|
@ -1981,6 +1981,8 @@ static int ib_prctl_set(struct task_struct *task, unsigned long ctrl)
|
||||
if (ctrl == PR_SPEC_FORCE_DISABLE)
|
||||
task_set_spec_ib_force_disable(task);
|
||||
task_update_spec_tif(task);
|
||||
if (task == current)
|
||||
indirect_branch_prediction_barrier();
|
||||
break;
|
||||
default:
|
||||
return -ERANGE;
|
||||
|
@ -401,10 +401,8 @@ int crash_load_segments(struct kimage *image)
|
||||
kbuf.buf_align = ELF_CORE_HEADER_ALIGN;
|
||||
kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
|
||||
ret = kexec_add_buffer(&kbuf);
|
||||
if (ret) {
|
||||
vfree((void *)image->elf_headers);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
image->elf_load_addr = kbuf.mem;
|
||||
pr_debug("Loaded ELF headers at 0x%lx bufsz=0x%lx memsz=0x%lx\n",
|
||||
image->elf_load_addr, kbuf.bufsz, kbuf.memsz);
|
||||
|
@ -1536,32 +1536,32 @@ static enum es_result vc_handle_mmio_movs(struct es_em_ctxt *ctxt,
|
||||
static enum es_result vc_handle_mmio(struct ghcb *ghcb, struct es_em_ctxt *ctxt)
|
||||
{
|
||||
struct insn *insn = &ctxt->insn;
|
||||
enum insn_mmio_type mmio;
|
||||
unsigned int bytes = 0;
|
||||
enum mmio_type mmio;
|
||||
enum es_result ret;
|
||||
u8 sign_byte;
|
||||
long *reg_data;
|
||||
|
||||
mmio = insn_decode_mmio(insn, &bytes);
|
||||
if (mmio == MMIO_DECODE_FAILED)
|
||||
if (mmio == INSN_MMIO_DECODE_FAILED)
|
||||
return ES_DECODE_FAILED;
|
||||
|
||||
if (mmio != MMIO_WRITE_IMM && mmio != MMIO_MOVS) {
|
||||
if (mmio != INSN_MMIO_WRITE_IMM && mmio != INSN_MMIO_MOVS) {
|
||||
reg_data = insn_get_modrm_reg_ptr(insn, ctxt->regs);
|
||||
if (!reg_data)
|
||||
return ES_DECODE_FAILED;
|
||||
}
|
||||
|
||||
switch (mmio) {
|
||||
case MMIO_WRITE:
|
||||
case INSN_MMIO_WRITE:
|
||||
memcpy(ghcb->shared_buffer, reg_data, bytes);
|
||||
ret = vc_do_mmio(ghcb, ctxt, bytes, false);
|
||||
break;
|
||||
case MMIO_WRITE_IMM:
|
||||
case INSN_MMIO_WRITE_IMM:
|
||||
memcpy(ghcb->shared_buffer, insn->immediate1.bytes, bytes);
|
||||
ret = vc_do_mmio(ghcb, ctxt, bytes, false);
|
||||
break;
|
||||
case MMIO_READ:
|
||||
case INSN_MMIO_READ:
|
||||
ret = vc_do_mmio(ghcb, ctxt, bytes, true);
|
||||
if (ret)
|
||||
break;
|
||||
@ -1572,7 +1572,7 @@ static enum es_result vc_handle_mmio(struct ghcb *ghcb, struct es_em_ctxt *ctxt)
|
||||
|
||||
memcpy(reg_data, ghcb->shared_buffer, bytes);
|
||||
break;
|
||||
case MMIO_READ_ZERO_EXTEND:
|
||||
case INSN_MMIO_READ_ZERO_EXTEND:
|
||||
ret = vc_do_mmio(ghcb, ctxt, bytes, true);
|
||||
if (ret)
|
||||
break;
|
||||
@ -1581,7 +1581,7 @@ static enum es_result vc_handle_mmio(struct ghcb *ghcb, struct es_em_ctxt *ctxt)
|
||||
memset(reg_data, 0, insn->opnd_bytes);
|
||||
memcpy(reg_data, ghcb->shared_buffer, bytes);
|
||||
break;
|
||||
case MMIO_READ_SIGN_EXTEND:
|
||||
case INSN_MMIO_READ_SIGN_EXTEND:
|
||||
ret = vc_do_mmio(ghcb, ctxt, bytes, true);
|
||||
if (ret)
|
||||
break;
|
||||
@ -1600,7 +1600,7 @@ static enum es_result vc_handle_mmio(struct ghcb *ghcb, struct es_em_ctxt *ctxt)
|
||||
memset(reg_data, sign_byte, insn->opnd_bytes);
|
||||
memcpy(reg_data, ghcb->shared_buffer, bytes);
|
||||
break;
|
||||
case MMIO_MOVS:
|
||||
case INSN_MMIO_MOVS:
|
||||
ret = vc_handle_mmio_movs(ctxt, bytes);
|
||||
break;
|
||||
default:
|
||||
|
@ -1595,16 +1595,16 @@ bool insn_decode_from_regs(struct insn *insn, struct pt_regs *regs,
|
||||
* Returns:
|
||||
*
|
||||
* Type of the instruction. Size of the memory operand is stored in
|
||||
* @bytes. If decode failed, MMIO_DECODE_FAILED returned.
|
||||
* @bytes. If decode failed, INSN_MMIO_DECODE_FAILED returned.
|
||||
*/
|
||||
enum mmio_type insn_decode_mmio(struct insn *insn, int *bytes)
|
||||
enum insn_mmio_type insn_decode_mmio(struct insn *insn, int *bytes)
|
||||
{
|
||||
enum mmio_type type = MMIO_DECODE_FAILED;
|
||||
enum insn_mmio_type type = INSN_MMIO_DECODE_FAILED;
|
||||
|
||||
*bytes = 0;
|
||||
|
||||
if (insn_get_opcode(insn))
|
||||
return MMIO_DECODE_FAILED;
|
||||
return INSN_MMIO_DECODE_FAILED;
|
||||
|
||||
switch (insn->opcode.bytes[0]) {
|
||||
case 0x88: /* MOV m8,r8 */
|
||||
@ -1613,7 +1613,7 @@ enum mmio_type insn_decode_mmio(struct insn *insn, int *bytes)
|
||||
case 0x89: /* MOV m16/m32/m64, r16/m32/m64 */
|
||||
if (!*bytes)
|
||||
*bytes = insn->opnd_bytes;
|
||||
type = MMIO_WRITE;
|
||||
type = INSN_MMIO_WRITE;
|
||||
break;
|
||||
|
||||
case 0xc6: /* MOV m8, imm8 */
|
||||
@ -1622,7 +1622,7 @@ enum mmio_type insn_decode_mmio(struct insn *insn, int *bytes)
|
||||
case 0xc7: /* MOV m16/m32/m64, imm16/imm32/imm64 */
|
||||
if (!*bytes)
|
||||
*bytes = insn->opnd_bytes;
|
||||
type = MMIO_WRITE_IMM;
|
||||
type = INSN_MMIO_WRITE_IMM;
|
||||
break;
|
||||
|
||||
case 0x8a: /* MOV r8, m8 */
|
||||
@ -1631,7 +1631,7 @@ enum mmio_type insn_decode_mmio(struct insn *insn, int *bytes)
|
||||
case 0x8b: /* MOV r16/r32/r64, m16/m32/m64 */
|
||||
if (!*bytes)
|
||||
*bytes = insn->opnd_bytes;
|
||||
type = MMIO_READ;
|
||||
type = INSN_MMIO_READ;
|
||||
break;
|
||||
|
||||
case 0xa4: /* MOVS m8, m8 */
|
||||
@ -1640,7 +1640,7 @@ enum mmio_type insn_decode_mmio(struct insn *insn, int *bytes)
|
||||
case 0xa5: /* MOVS m16/m32/m64, m16/m32/m64 */
|
||||
if (!*bytes)
|
||||
*bytes = insn->opnd_bytes;
|
||||
type = MMIO_MOVS;
|
||||
type = INSN_MMIO_MOVS;
|
||||
break;
|
||||
|
||||
case 0x0f: /* Two-byte instruction */
|
||||
@ -1651,7 +1651,7 @@ enum mmio_type insn_decode_mmio(struct insn *insn, int *bytes)
|
||||
case 0xb7: /* MOVZX r32/r64, m16 */
|
||||
if (!*bytes)
|
||||
*bytes = 2;
|
||||
type = MMIO_READ_ZERO_EXTEND;
|
||||
type = INSN_MMIO_READ_ZERO_EXTEND;
|
||||
break;
|
||||
|
||||
case 0xbe: /* MOVSX r16/r32/r64, m8 */
|
||||
@ -1660,7 +1660,7 @@ enum mmio_type insn_decode_mmio(struct insn *insn, int *bytes)
|
||||
case 0xbf: /* MOVSX r32/r64, m16 */
|
||||
if (!*bytes)
|
||||
*bytes = 2;
|
||||
type = MMIO_READ_SIGN_EXTEND;
|
||||
type = INSN_MMIO_READ_SIGN_EXTEND;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -10,6 +10,6 @@
|
||||
*/
|
||||
SYM_FUNC_START(__iowrite32_copy)
|
||||
movl %edx,%ecx
|
||||
rep movsd
|
||||
rep movsl
|
||||
RET
|
||||
SYM_FUNC_END(__iowrite32_copy)
|
||||
|
Loading…
x
Reference in New Issue
Block a user