mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-07 22:03:14 +00:00
x86: Remove toolchain check for X32 ABI capability
Commit 0bf6276392
("x32: Warn and disable rather than error if
binutils too old") added a small test in arch/x86/Makefile because
binutils 2.22 or newer is needed to properly support elf32-x86-64. This
check is no longer necessary, as the minimum supported version of
binutils is 2.23, which is enforced at configuration time with
scripts/min-tool-version.sh.
Remove this check and replace all uses of CONFIG_X86_X32 with
CONFIG_X86_X32_ABI, as two symbols are no longer necessary.
[nathan: Rebase, fix up a few places where CONFIG_X86_X32 was still
used, and simplify commit message to satisfy -tip requirements]
Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
Signed-off-by: Nathan Chancellor <nathan@kernel.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/r/20220314194842.3452-2-nathan@kernel.org
This commit is contained in:
parent
ed53a0d971
commit
83a44a4f47
@ -2861,7 +2861,7 @@ config IA32_AOUT
|
|||||||
help
|
help
|
||||||
Support old a.out binaries in the 32bit emulation.
|
Support old a.out binaries in the 32bit emulation.
|
||||||
|
|
||||||
config X86_X32
|
config X86_X32_ABI
|
||||||
bool "x32 ABI for 64-bit mode"
|
bool "x32 ABI for 64-bit mode"
|
||||||
depends on X86_64
|
depends on X86_64
|
||||||
help
|
help
|
||||||
@ -2870,10 +2870,6 @@ config X86_X32
|
|||||||
full 64-bit register file and wide data path while leaving
|
full 64-bit register file and wide data path while leaving
|
||||||
pointers at 32 bits for smaller memory footprint.
|
pointers at 32 bits for smaller memory footprint.
|
||||||
|
|
||||||
You will need a recent binutils (2.22 or later) with
|
|
||||||
elf32_x86_64 support enabled to compile a kernel with this
|
|
||||||
option set.
|
|
||||||
|
|
||||||
config COMPAT_32
|
config COMPAT_32
|
||||||
def_bool y
|
def_bool y
|
||||||
depends on IA32_EMULATION || X86_32
|
depends on IA32_EMULATION || X86_32
|
||||||
@ -2882,7 +2878,7 @@ config COMPAT_32
|
|||||||
|
|
||||||
config COMPAT
|
config COMPAT
|
||||||
def_bool y
|
def_bool y
|
||||||
depends on IA32_EMULATION || X86_X32
|
depends on IA32_EMULATION || X86_X32_ABI
|
||||||
|
|
||||||
if COMPAT
|
if COMPAT
|
||||||
config COMPAT_FOR_U64_ALIGNMENT
|
config COMPAT_FOR_U64_ALIGNMENT
|
||||||
|
@ -152,22 +152,6 @@ else
|
|||||||
KBUILD_CFLAGS += -mcmodel=kernel
|
KBUILD_CFLAGS += -mcmodel=kernel
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifdef CONFIG_X86_X32
|
|
||||||
x32_ld_ok := $(call try-run,\
|
|
||||||
/bin/echo -e '1: .quad 1b' | \
|
|
||||||
$(CC) $(KBUILD_AFLAGS) -c -x assembler -o "$$TMP" - && \
|
|
||||||
$(OBJCOPY) -O elf32-x86-64 "$$TMP" "$$TMP.o" && \
|
|
||||||
$(LD) -m elf32_x86_64 "$$TMP.o" -o "$$TMP",y,n)
|
|
||||||
ifeq ($(x32_ld_ok),y)
|
|
||||||
CONFIG_X86_X32_ABI := y
|
|
||||||
KBUILD_AFLAGS += -DCONFIG_X86_X32_ABI
|
|
||||||
KBUILD_CFLAGS += -DCONFIG_X86_X32_ABI
|
|
||||||
else
|
|
||||||
$(warning CONFIG_X86_X32 enabled but no binutils support)
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
export CONFIG_X86_X32_ABI
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# If the function graph tracer is used with mcount instead of fentry,
|
# If the function graph tracer is used with mcount instead of fentry,
|
||||||
# '-maccumulate-outgoing-args' is needed to prevent a GCC bug
|
# '-maccumulate-outgoing-args' is needed to prevent a GCC bug
|
||||||
|
@ -67,7 +67,7 @@ uapisyshdr-y += unistd_32.h unistd_64.h unistd_x32.h
|
|||||||
syshdr-y += syscalls_32.h
|
syshdr-y += syscalls_32.h
|
||||||
syshdr-$(CONFIG_X86_64) += unistd_32_ia32.h unistd_64_x32.h
|
syshdr-$(CONFIG_X86_64) += unistd_32_ia32.h unistd_64_x32.h
|
||||||
syshdr-$(CONFIG_X86_64) += syscalls_64.h
|
syshdr-$(CONFIG_X86_64) += syscalls_64.h
|
||||||
syshdr-$(CONFIG_X86_X32) += syscalls_x32.h
|
syshdr-$(CONFIG_X86_X32_ABI) += syscalls_x32.h
|
||||||
syshdr-$(CONFIG_XEN) += xen-hypercalls.h
|
syshdr-$(CONFIG_XEN) += xen-hypercalls.h
|
||||||
|
|
||||||
uapisyshdr-y := $(addprefix $(uapi)/, $(uapisyshdr-y))
|
uapisyshdr-y := $(addprefix $(uapi)/, $(uapisyshdr-y))
|
||||||
|
@ -159,7 +159,7 @@ extern long __ia32_sys_ni_syscall(const struct pt_regs *regs);
|
|||||||
#endif /* CONFIG_IA32_EMULATION */
|
#endif /* CONFIG_IA32_EMULATION */
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_X86_X32
|
#ifdef CONFIG_X86_X32_ABI
|
||||||
/*
|
/*
|
||||||
* For the x32 ABI, we need to create a stub for compat_sys_*() which is aware
|
* For the x32 ABI, we need to create a stub for compat_sys_*() which is aware
|
||||||
* of the x86-64-style parameter ordering of x32 syscalls. The syscalls common
|
* of the x86-64-style parameter ordering of x32 syscalls. The syscalls common
|
||||||
@ -177,12 +177,12 @@ extern long __ia32_sys_ni_syscall(const struct pt_regs *regs);
|
|||||||
|
|
||||||
#define __X32_COMPAT_SYS_NI(name) \
|
#define __X32_COMPAT_SYS_NI(name) \
|
||||||
__SYS_NI(x64, compat_sys_##name)
|
__SYS_NI(x64, compat_sys_##name)
|
||||||
#else /* CONFIG_X86_X32 */
|
#else /* CONFIG_X86_X32_ABI */
|
||||||
#define __X32_COMPAT_SYS_STUB0(name)
|
#define __X32_COMPAT_SYS_STUB0(name)
|
||||||
#define __X32_COMPAT_SYS_STUBx(x, name, ...)
|
#define __X32_COMPAT_SYS_STUBx(x, name, ...)
|
||||||
#define __X32_COMPAT_COND_SYSCALL(name)
|
#define __X32_COMPAT_COND_SYSCALL(name)
|
||||||
#define __X32_COMPAT_SYS_NI(name)
|
#define __X32_COMPAT_SYS_NI(name)
|
||||||
#endif /* CONFIG_X86_X32 */
|
#endif /* CONFIG_X86_X32_ABI */
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_COMPAT
|
||||||
|
@ -37,7 +37,7 @@ struct vdso_image {
|
|||||||
extern const struct vdso_image vdso_image_64;
|
extern const struct vdso_image vdso_image_64;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_X86_X32
|
#ifdef CONFIG_X86_X32_ABI
|
||||||
extern const struct vdso_image vdso_image_x32;
|
extern const struct vdso_image vdso_image_x32;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -681,7 +681,7 @@ void set_personality_64bit(void)
|
|||||||
|
|
||||||
static void __set_personality_x32(void)
|
static void __set_personality_x32(void)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_X86_X32
|
#ifdef CONFIG_X86_X32_ABI
|
||||||
if (current->mm)
|
if (current->mm)
|
||||||
current->mm->context.flags = 0;
|
current->mm->context.flags = 0;
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
|
|||||||
#else
|
#else
|
||||||
if (flags & FUSE_IOCTL_COMPAT) {
|
if (flags & FUSE_IOCTL_COMPAT) {
|
||||||
inarg.flags |= FUSE_IOCTL_32BIT;
|
inarg.flags |= FUSE_IOCTL_32BIT;
|
||||||
#ifdef CONFIG_X86_X32
|
#ifdef CONFIG_X86_X32_ABI
|
||||||
if (in_x32_syscall())
|
if (in_x32_syscall())
|
||||||
inarg.flags |= FUSE_IOCTL_COMPAT_X32;
|
inarg.flags |= FUSE_IOCTL_COMPAT_X32;
|
||||||
#endif
|
#endif
|
||||||
|
@ -217,7 +217,7 @@ xfs_compat_ioc_fsbulkstat(
|
|||||||
inumbers_fmt_pf inumbers_func = xfs_fsinumbers_fmt_compat;
|
inumbers_fmt_pf inumbers_func = xfs_fsinumbers_fmt_compat;
|
||||||
bulkstat_one_fmt_pf bs_one_func = xfs_fsbulkstat_one_fmt_compat;
|
bulkstat_one_fmt_pf bs_one_func = xfs_fsbulkstat_one_fmt_compat;
|
||||||
|
|
||||||
#ifdef CONFIG_X86_X32
|
#ifdef CONFIG_X86_X32_ABI
|
||||||
if (in_x32_syscall()) {
|
if (in_x32_syscall()) {
|
||||||
/*
|
/*
|
||||||
* ... but on x32 the input xfs_fsop_bulkreq has pointers
|
* ... but on x32 the input xfs_fsop_bulkreq has pointers
|
||||||
|
@ -150,7 +150,7 @@ struct snd_ctl_elem_value32 {
|
|||||||
unsigned char reserved[128];
|
unsigned char reserved[128];
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_X86_X32
|
#ifdef CONFIG_X86_X32_ABI
|
||||||
/* x32 has a different alignment for 64bit values from ia32 */
|
/* x32 has a different alignment for 64bit values from ia32 */
|
||||||
struct snd_ctl_elem_value_x32 {
|
struct snd_ctl_elem_value_x32 {
|
||||||
struct snd_ctl_elem_id id;
|
struct snd_ctl_elem_id id;
|
||||||
@ -162,7 +162,7 @@ struct snd_ctl_elem_value_x32 {
|
|||||||
} value;
|
} value;
|
||||||
unsigned char reserved[128];
|
unsigned char reserved[128];
|
||||||
};
|
};
|
||||||
#endif /* CONFIG_X86_X32 */
|
#endif /* CONFIG_X86_X32_ABI */
|
||||||
|
|
||||||
/* get the value type and count of the control */
|
/* get the value type and count of the control */
|
||||||
static int get_ctl_type(struct snd_card *card, struct snd_ctl_elem_id *id,
|
static int get_ctl_type(struct snd_card *card, struct snd_ctl_elem_id *id,
|
||||||
@ -347,7 +347,7 @@ static int snd_ctl_elem_write_user_compat(struct snd_ctl_file *file,
|
|||||||
return ctl_elem_write_user(file, data32, &data32->value);
|
return ctl_elem_write_user(file, data32, &data32->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_X86_X32
|
#ifdef CONFIG_X86_X32_ABI
|
||||||
static int snd_ctl_elem_read_user_x32(struct snd_card *card,
|
static int snd_ctl_elem_read_user_x32(struct snd_card *card,
|
||||||
struct snd_ctl_elem_value_x32 __user *data32)
|
struct snd_ctl_elem_value_x32 __user *data32)
|
||||||
{
|
{
|
||||||
@ -359,7 +359,7 @@ static int snd_ctl_elem_write_user_x32(struct snd_ctl_file *file,
|
|||||||
{
|
{
|
||||||
return ctl_elem_write_user(file, data32, &data32->value);
|
return ctl_elem_write_user(file, data32, &data32->value);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_X86_X32 */
|
#endif /* CONFIG_X86_X32_ABI */
|
||||||
|
|
||||||
/* add or replace a user control */
|
/* add or replace a user control */
|
||||||
static int snd_ctl_elem_add_compat(struct snd_ctl_file *file,
|
static int snd_ctl_elem_add_compat(struct snd_ctl_file *file,
|
||||||
@ -418,10 +418,10 @@ enum {
|
|||||||
SNDRV_CTL_IOCTL_ELEM_WRITE32 = _IOWR('U', 0x13, struct snd_ctl_elem_value32),
|
SNDRV_CTL_IOCTL_ELEM_WRITE32 = _IOWR('U', 0x13, struct snd_ctl_elem_value32),
|
||||||
SNDRV_CTL_IOCTL_ELEM_ADD32 = _IOWR('U', 0x17, struct snd_ctl_elem_info32),
|
SNDRV_CTL_IOCTL_ELEM_ADD32 = _IOWR('U', 0x17, struct snd_ctl_elem_info32),
|
||||||
SNDRV_CTL_IOCTL_ELEM_REPLACE32 = _IOWR('U', 0x18, struct snd_ctl_elem_info32),
|
SNDRV_CTL_IOCTL_ELEM_REPLACE32 = _IOWR('U', 0x18, struct snd_ctl_elem_info32),
|
||||||
#ifdef CONFIG_X86_X32
|
#ifdef CONFIG_X86_X32_ABI
|
||||||
SNDRV_CTL_IOCTL_ELEM_READ_X32 = _IOWR('U', 0x12, struct snd_ctl_elem_value_x32),
|
SNDRV_CTL_IOCTL_ELEM_READ_X32 = _IOWR('U', 0x12, struct snd_ctl_elem_value_x32),
|
||||||
SNDRV_CTL_IOCTL_ELEM_WRITE_X32 = _IOWR('U', 0x13, struct snd_ctl_elem_value_x32),
|
SNDRV_CTL_IOCTL_ELEM_WRITE_X32 = _IOWR('U', 0x13, struct snd_ctl_elem_value_x32),
|
||||||
#endif /* CONFIG_X86_X32 */
|
#endif /* CONFIG_X86_X32_ABI */
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline long snd_ctl_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
|
static inline long snd_ctl_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
|
||||||
@ -460,12 +460,12 @@ static inline long snd_ctl_ioctl_compat(struct file *file, unsigned int cmd, uns
|
|||||||
return snd_ctl_elem_add_compat(ctl, argp, 0);
|
return snd_ctl_elem_add_compat(ctl, argp, 0);
|
||||||
case SNDRV_CTL_IOCTL_ELEM_REPLACE32:
|
case SNDRV_CTL_IOCTL_ELEM_REPLACE32:
|
||||||
return snd_ctl_elem_add_compat(ctl, argp, 1);
|
return snd_ctl_elem_add_compat(ctl, argp, 1);
|
||||||
#ifdef CONFIG_X86_X32
|
#ifdef CONFIG_X86_X32_ABI
|
||||||
case SNDRV_CTL_IOCTL_ELEM_READ_X32:
|
case SNDRV_CTL_IOCTL_ELEM_READ_X32:
|
||||||
return snd_ctl_elem_read_user_x32(ctl->card, argp);
|
return snd_ctl_elem_read_user_x32(ctl->card, argp);
|
||||||
case SNDRV_CTL_IOCTL_ELEM_WRITE_X32:
|
case SNDRV_CTL_IOCTL_ELEM_WRITE_X32:
|
||||||
return snd_ctl_elem_write_user_x32(ctl, argp);
|
return snd_ctl_elem_write_user_x32(ctl, argp);
|
||||||
#endif /* CONFIG_X86_X32 */
|
#endif /* CONFIG_X86_X32_ABI */
|
||||||
}
|
}
|
||||||
|
|
||||||
down_read(&snd_ioctl_rwsem);
|
down_read(&snd_ioctl_rwsem);
|
||||||
|
@ -147,13 +147,13 @@ static int snd_pcm_ioctl_channel_info_compat(struct snd_pcm_substream *substream
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_X86_X32
|
#ifdef CONFIG_X86_X32_ABI
|
||||||
/* X32 ABI has the same struct as x86-64 for snd_pcm_channel_info */
|
/* X32 ABI has the same struct as x86-64 for snd_pcm_channel_info */
|
||||||
static int snd_pcm_channel_info_user(struct snd_pcm_substream *substream,
|
static int snd_pcm_channel_info_user(struct snd_pcm_substream *substream,
|
||||||
struct snd_pcm_channel_info __user *src);
|
struct snd_pcm_channel_info __user *src);
|
||||||
#define snd_pcm_ioctl_channel_info_x32(s, p) \
|
#define snd_pcm_ioctl_channel_info_x32(s, p) \
|
||||||
snd_pcm_channel_info_user(s, p)
|
snd_pcm_channel_info_user(s, p)
|
||||||
#endif /* CONFIG_X86_X32 */
|
#endif /* CONFIG_X86_X32_ABI */
|
||||||
|
|
||||||
struct compat_snd_pcm_status64 {
|
struct compat_snd_pcm_status64 {
|
||||||
snd_pcm_state_t state;
|
snd_pcm_state_t state;
|
||||||
@ -375,7 +375,7 @@ static int snd_pcm_ioctl_xfern_compat(struct snd_pcm_substream *substream,
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_X86_X32
|
#ifdef CONFIG_X86_X32_ABI
|
||||||
/* X32 ABI has 64bit timespec and 64bit alignment */
|
/* X32 ABI has 64bit timespec and 64bit alignment */
|
||||||
struct snd_pcm_mmap_status_x32 {
|
struct snd_pcm_mmap_status_x32 {
|
||||||
snd_pcm_state_t state;
|
snd_pcm_state_t state;
|
||||||
@ -468,7 +468,7 @@ static int snd_pcm_ioctl_sync_ptr_x32(struct snd_pcm_substream *substream,
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_X86_X32 */
|
#endif /* CONFIG_X86_X32_ABI */
|
||||||
|
|
||||||
#ifdef __BIG_ENDIAN
|
#ifdef __BIG_ENDIAN
|
||||||
typedef char __pad_before_u32[4];
|
typedef char __pad_before_u32[4];
|
||||||
@ -560,10 +560,10 @@ enum {
|
|||||||
SNDRV_PCM_IOCTL_READN_FRAMES32 = _IOR('A', 0x53, struct snd_xfern32),
|
SNDRV_PCM_IOCTL_READN_FRAMES32 = _IOR('A', 0x53, struct snd_xfern32),
|
||||||
SNDRV_PCM_IOCTL_STATUS_COMPAT64 = _IOR('A', 0x20, struct compat_snd_pcm_status64),
|
SNDRV_PCM_IOCTL_STATUS_COMPAT64 = _IOR('A', 0x20, struct compat_snd_pcm_status64),
|
||||||
SNDRV_PCM_IOCTL_STATUS_EXT_COMPAT64 = _IOWR('A', 0x24, struct compat_snd_pcm_status64),
|
SNDRV_PCM_IOCTL_STATUS_EXT_COMPAT64 = _IOWR('A', 0x24, struct compat_snd_pcm_status64),
|
||||||
#ifdef CONFIG_X86_X32
|
#ifdef CONFIG_X86_X32_ABI
|
||||||
SNDRV_PCM_IOCTL_CHANNEL_INFO_X32 = _IOR('A', 0x32, struct snd_pcm_channel_info),
|
SNDRV_PCM_IOCTL_CHANNEL_INFO_X32 = _IOR('A', 0x32, struct snd_pcm_channel_info),
|
||||||
SNDRV_PCM_IOCTL_SYNC_PTR_X32 = _IOWR('A', 0x23, struct snd_pcm_sync_ptr_x32),
|
SNDRV_PCM_IOCTL_SYNC_PTR_X32 = _IOWR('A', 0x23, struct snd_pcm_sync_ptr_x32),
|
||||||
#endif /* CONFIG_X86_X32 */
|
#endif /* CONFIG_X86_X32_ABI */
|
||||||
};
|
};
|
||||||
|
|
||||||
static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
|
static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
|
||||||
@ -607,10 +607,10 @@ static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned l
|
|||||||
case __SNDRV_PCM_IOCTL_SYNC_PTR32:
|
case __SNDRV_PCM_IOCTL_SYNC_PTR32:
|
||||||
return snd_pcm_common_ioctl(file, substream, cmd, argp);
|
return snd_pcm_common_ioctl(file, substream, cmd, argp);
|
||||||
case __SNDRV_PCM_IOCTL_SYNC_PTR64:
|
case __SNDRV_PCM_IOCTL_SYNC_PTR64:
|
||||||
#ifdef CONFIG_X86_X32
|
#ifdef CONFIG_X86_X32_ABI
|
||||||
if (in_x32_syscall())
|
if (in_x32_syscall())
|
||||||
return snd_pcm_ioctl_sync_ptr_x32(substream, argp);
|
return snd_pcm_ioctl_sync_ptr_x32(substream, argp);
|
||||||
#endif /* CONFIG_X86_X32 */
|
#endif /* CONFIG_X86_X32_ABI */
|
||||||
return snd_pcm_ioctl_sync_ptr_buggy(substream, argp);
|
return snd_pcm_ioctl_sync_ptr_buggy(substream, argp);
|
||||||
case SNDRV_PCM_IOCTL_HW_REFINE32:
|
case SNDRV_PCM_IOCTL_HW_REFINE32:
|
||||||
return snd_pcm_ioctl_hw_params_compat(substream, 1, argp);
|
return snd_pcm_ioctl_hw_params_compat(substream, 1, argp);
|
||||||
@ -642,10 +642,10 @@ static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned l
|
|||||||
return snd_pcm_status_user_compat64(substream, argp, false);
|
return snd_pcm_status_user_compat64(substream, argp, false);
|
||||||
case SNDRV_PCM_IOCTL_STATUS_EXT_COMPAT64:
|
case SNDRV_PCM_IOCTL_STATUS_EXT_COMPAT64:
|
||||||
return snd_pcm_status_user_compat64(substream, argp, true);
|
return snd_pcm_status_user_compat64(substream, argp, true);
|
||||||
#ifdef CONFIG_X86_X32
|
#ifdef CONFIG_X86_X32_ABI
|
||||||
case SNDRV_PCM_IOCTL_CHANNEL_INFO_X32:
|
case SNDRV_PCM_IOCTL_CHANNEL_INFO_X32:
|
||||||
return snd_pcm_ioctl_channel_info_x32(substream, argp);
|
return snd_pcm_ioctl_channel_info_x32(substream, argp);
|
||||||
#endif /* CONFIG_X86_X32 */
|
#endif /* CONFIG_X86_X32_ABI */
|
||||||
}
|
}
|
||||||
|
|
||||||
return -ENOIOCTLCMD;
|
return -ENOIOCTLCMD;
|
||||||
|
Loading…
Reference in New Issue
Block a user