Commit c02197fc authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'powerpc-6.8-3' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux

Pull powerpc fixes from Michael Ellerman:
 "This is a bit of a big batch for rc4, but just due to holiday hangover
  and because I didn't send any fixes last week due to a late revert
  request. I think next week should be back to normal.

   - Fix ftrace bug on boot caused by exit text sections with
     '-fpatchable-function-entry'

   - Fix accuracy of stolen time on pseries since the switch to
     VIRT_CPU_ACCOUNTING_GEN

   - Fix a crash in the IOMMU code when doing DLPAR remove

   - Set pt_regs->link on scv entry to fix BPF stack unwinding

   - Add missing PPC_FEATURE_BOOKE on 64-bit e5500/e6500, which broke
     gdb

   - Fix boot on some 6xx platforms with STRICT_KERNEL_RWX enabled

   - Fix build failures with KASAN enabled and 32KB stack size

   - Some other minor fixes

  Thanks to Arnd Bergmann, Benjamin Gray, Christophe Leroy, David
  Engraf, Gaurav Batra, Jason Gunthorpe, Jiangfeng Xiao, Matthias
  Schiffer, Nathan Lynch, Naveen N Rao, Nicholas Piggin, Nysal Jan K.A,
  R Nageswara Sastry, Shivaprasad G Bhat, Shrikanth Hegde, Spoorthy,
  Srikar Dronamraju, and Venkat Rao Bagalkote"

* tag 'powerpc-6.8-3' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux:
  powerpc/iommu: Fix the missing iommu_group_put() during platform domain attach
  powerpc/pseries: fix accuracy of stolen time
  powerpc/ftrace: Ignore ftrace locations in exit text sections
  powerpc/cputable: Add missing PPC_FEATURE_BOOKE on PPC64 Book-E
  powerpc/kasan: Limit KASAN thread size increase to 32KB
  Revert "powerpc/pseries/iommu: Fix iommu initialisation during DLPAR add"
  powerpc: 85xx: mark local functions static
  powerpc: udbg_memcons: mark functions static
  powerpc/kasan: Fix addr error caused by page alignment
  powerpc/6xx: set High BAT Enable flag on G2_LE cores
  selftests/powerpc/papr_vpd: Check devfd before get_system_loc_code()
  powerpc/64: Set task pt_regs->link to the LR value on scv entry
  powerpc/pseries/iommu: Fix iommu initialisation during DLPAR add
  powerpc/pseries/papr-sysparm: use u8 arrays for payloads
parents f2667e0c 0846dd77
...@@ -20,14 +20,6 @@ ...@@ -20,14 +20,6 @@
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
extern void _mcount(void); extern void _mcount(void);
static inline unsigned long ftrace_call_adjust(unsigned long addr)
{
if (IS_ENABLED(CONFIG_ARCH_USING_PATCHABLE_FUNCTION_ENTRY))
addr += MCOUNT_INSN_SIZE;
return addr;
}
unsigned long prepare_ftrace_return(unsigned long parent, unsigned long ip, unsigned long prepare_ftrace_return(unsigned long parent, unsigned long ip,
unsigned long sp); unsigned long sp);
...@@ -142,8 +134,10 @@ static inline u8 this_cpu_get_ftrace_enabled(void) { return 1; } ...@@ -142,8 +134,10 @@ static inline u8 this_cpu_get_ftrace_enabled(void) { return 1; }
#ifdef CONFIG_FUNCTION_TRACER #ifdef CONFIG_FUNCTION_TRACER
extern unsigned int ftrace_tramp_text[], ftrace_tramp_init[]; extern unsigned int ftrace_tramp_text[], ftrace_tramp_init[];
void ftrace_free_init_tramp(void); void ftrace_free_init_tramp(void);
unsigned long ftrace_call_adjust(unsigned long addr);
#else #else
static inline void ftrace_free_init_tramp(void) { } static inline void ftrace_free_init_tramp(void) { }
static inline unsigned long ftrace_call_adjust(unsigned long addr) { return addr; }
#endif #endif
#endif /* !__ASSEMBLY__ */ #endif /* !__ASSEMBLY__ */
......
...@@ -32,7 +32,7 @@ typedef struct { ...@@ -32,7 +32,7 @@ typedef struct {
*/ */
struct papr_sysparm_buf { struct papr_sysparm_buf {
__be16 len; __be16 len;
char val[PAPR_SYSPARM_MAX_OUTPUT]; u8 val[PAPR_SYSPARM_MAX_OUTPUT];
}; };
struct papr_sysparm_buf *papr_sysparm_buf_alloc(void); struct papr_sysparm_buf *papr_sysparm_buf_alloc(void);
......
...@@ -617,6 +617,8 @@ ...@@ -617,6 +617,8 @@
#endif #endif
#define SPRN_HID2 0x3F8 /* Hardware Implementation Register 2 */ #define SPRN_HID2 0x3F8 /* Hardware Implementation Register 2 */
#define SPRN_HID2_GEKKO 0x398 /* Gekko HID2 Register */ #define SPRN_HID2_GEKKO 0x398 /* Gekko HID2 Register */
#define SPRN_HID2_G2_LE 0x3F3 /* G2_LE HID2 Register */
#define HID2_G2_LE_HBE (1<<18) /* High BAT Enable (G2_LE) */
#define SPRN_IABR 0x3F2 /* Instruction Address Breakpoint Register */ #define SPRN_IABR 0x3F2 /* Instruction Address Breakpoint Register */
#define SPRN_IABR2 0x3FA /* 83xx */ #define SPRN_IABR2 0x3FA /* 83xx */
#define SPRN_IBCR 0x135 /* 83xx Insn Breakpoint Control Reg */ #define SPRN_IBCR 0x135 /* 83xx Insn Breakpoint Control Reg */
......
...@@ -14,6 +14,7 @@ typedef struct func_desc func_desc_t; ...@@ -14,6 +14,7 @@ typedef struct func_desc func_desc_t;
extern char __head_end[]; extern char __head_end[];
extern char __srwx_boundary[]; extern char __srwx_boundary[];
extern char __exittext_begin[], __exittext_end[];
/* Patch sites */ /* Patch sites */
extern s32 patch__call_flush_branch_caches1; extern s32 patch__call_flush_branch_caches1;
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#ifdef __KERNEL__ #ifdef __KERNEL__
#ifdef CONFIG_KASAN #if defined(CONFIG_KASAN) && CONFIG_THREAD_SHIFT < 15
#define MIN_THREAD_SHIFT (CONFIG_THREAD_SHIFT + 1) #define MIN_THREAD_SHIFT (CONFIG_THREAD_SHIFT + 1)
#else #else
#define MIN_THREAD_SHIFT CONFIG_THREAD_SHIFT #define MIN_THREAD_SHIFT CONFIG_THREAD_SHIFT
......
...@@ -14,7 +14,7 @@ enum { ...@@ -14,7 +14,7 @@ enum {
struct papr_sysparm_io_block { struct papr_sysparm_io_block {
__u32 parameter; __u32 parameter;
__u16 length; __u16 length;
char data[PAPR_SYSPARM_MAX_OUTPUT]; __u8 data[PAPR_SYSPARM_MAX_OUTPUT];
}; };
/** /**
......
...@@ -26,6 +26,15 @@ BEGIN_FTR_SECTION ...@@ -26,6 +26,15 @@ BEGIN_FTR_SECTION
bl __init_fpu_registers bl __init_fpu_registers
END_FTR_SECTION_IFCLR(CPU_FTR_FPU_UNAVAILABLE) END_FTR_SECTION_IFCLR(CPU_FTR_FPU_UNAVAILABLE)
bl setup_common_caches bl setup_common_caches
/*
* This assumes that all cores using __setup_cpu_603 with
* MMU_FTR_USE_HIGH_BATS are G2_LE compatible
*/
BEGIN_MMU_FTR_SECTION
bl setup_g2_le_hid2
END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
mtlr r5 mtlr r5
blr blr
_GLOBAL(__setup_cpu_604) _GLOBAL(__setup_cpu_604)
...@@ -115,6 +124,16 @@ SYM_FUNC_START_LOCAL(setup_604_hid0) ...@@ -115,6 +124,16 @@ SYM_FUNC_START_LOCAL(setup_604_hid0)
blr blr
SYM_FUNC_END(setup_604_hid0) SYM_FUNC_END(setup_604_hid0)
/* Enable high BATs for G2_LE and derivatives like e300cX */
SYM_FUNC_START_LOCAL(setup_g2_le_hid2)
mfspr r11,SPRN_HID2_G2_LE
oris r11,r11,HID2_G2_LE_HBE@h
mtspr SPRN_HID2_G2_LE,r11
sync
isync
blr
SYM_FUNC_END(setup_g2_le_hid2)
/* 7400 <= rev 2.7 and 7410 rev = 1.0 suffer from some /* 7400 <= rev 2.7 and 7410 rev = 1.0 suffer from some
* erratas we work around here. * erratas we work around here.
* Moto MPC710CE.pdf describes them, those are errata * Moto MPC710CE.pdf describes them, those are errata
...@@ -495,4 +514,3 @@ _GLOBAL(__restore_cpu_setup) ...@@ -495,4 +514,3 @@ _GLOBAL(__restore_cpu_setup)
mtcr r7 mtcr r7
blr blr
_ASM_NOKPROBE_SYMBOL(__restore_cpu_setup) _ASM_NOKPROBE_SYMBOL(__restore_cpu_setup)
...@@ -8,7 +8,8 @@ ...@@ -8,7 +8,8 @@
#ifdef CONFIG_PPC64 #ifdef CONFIG_PPC64
#define COMMON_USER_BOOKE (PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | \ #define COMMON_USER_BOOKE (PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | \
PPC_FEATURE_HAS_FPU | PPC_FEATURE_64) PPC_FEATURE_HAS_FPU | PPC_FEATURE_64 | \
PPC_FEATURE_BOOKE)
#else #else
#define COMMON_USER_BOOKE (PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | \ #define COMMON_USER_BOOKE (PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | \
PPC_FEATURE_BOOKE) PPC_FEATURE_BOOKE)
......
...@@ -52,7 +52,8 @@ _ASM_NOKPROBE_SYMBOL(system_call_vectored_\name) ...@@ -52,7 +52,8 @@ _ASM_NOKPROBE_SYMBOL(system_call_vectored_\name)
mr r10,r1 mr r10,r1
ld r1,PACAKSAVE(r13) ld r1,PACAKSAVE(r13)
std r10,0(r1) std r10,0(r1)
std r11,_NIP(r1) std r11,_LINK(r1)
std r11,_NIP(r1) /* Saved LR is also the next instruction */
std r12,_MSR(r1) std r12,_MSR(r1)
std r0,GPR0(r1) std r0,GPR0(r1)
std r10,GPR1(r1) std r10,GPR1(r1)
...@@ -70,7 +71,6 @@ _ASM_NOKPROBE_SYMBOL(system_call_vectored_\name) ...@@ -70,7 +71,6 @@ _ASM_NOKPROBE_SYMBOL(system_call_vectored_\name)
std r9,GPR13(r1) std r9,GPR13(r1)
SAVE_NVGPRS(r1) SAVE_NVGPRS(r1)
std r11,_XER(r1) std r11,_XER(r1)
std r11,_LINK(r1)
std r11,_CTR(r1) std r11,_CTR(r1)
li r11,\trapnr li r11,\trapnr
......
...@@ -1289,8 +1289,10 @@ spapr_tce_platform_iommu_attach_dev(struct iommu_domain *platform_domain, ...@@ -1289,8 +1289,10 @@ spapr_tce_platform_iommu_attach_dev(struct iommu_domain *platform_domain,
struct iommu_table_group *table_group; struct iommu_table_group *table_group;
/* At first attach the ownership is already set */ /* At first attach the ownership is already set */
if (!domain) if (!domain) {
iommu_group_put(grp);
return 0; return 0;
}
table_group = iommu_group_get_iommudata(grp); table_group = iommu_group_get_iommudata(grp);
/* /*
......
...@@ -27,10 +27,22 @@ ...@@ -27,10 +27,22 @@
#include <asm/ftrace.h> #include <asm/ftrace.h>
#include <asm/syscall.h> #include <asm/syscall.h>
#include <asm/inst.h> #include <asm/inst.h>
#include <asm/sections.h>
#define NUM_FTRACE_TRAMPS 2 #define NUM_FTRACE_TRAMPS 2
static unsigned long ftrace_tramps[NUM_FTRACE_TRAMPS]; static unsigned long ftrace_tramps[NUM_FTRACE_TRAMPS];
unsigned long ftrace_call_adjust(unsigned long addr)
{
if (addr >= (unsigned long)__exittext_begin && addr < (unsigned long)__exittext_end)
return 0;
if (IS_ENABLED(CONFIG_ARCH_USING_PATCHABLE_FUNCTION_ENTRY))
addr += MCOUNT_INSN_SIZE;
return addr;
}
static ppc_inst_t ftrace_create_branch_inst(unsigned long ip, unsigned long addr, int link) static ppc_inst_t ftrace_create_branch_inst(unsigned long ip, unsigned long addr, int link)
{ {
ppc_inst_t op; ppc_inst_t op;
......
...@@ -37,6 +37,11 @@ ...@@ -37,6 +37,11 @@
#define NUM_FTRACE_TRAMPS 8 #define NUM_FTRACE_TRAMPS 8
static unsigned long ftrace_tramps[NUM_FTRACE_TRAMPS]; static unsigned long ftrace_tramps[NUM_FTRACE_TRAMPS];
unsigned long ftrace_call_adjust(unsigned long addr)
{
return addr;
}
static ppc_inst_t static ppc_inst_t
ftrace_call_replace(unsigned long ip, unsigned long addr, int link) ftrace_call_replace(unsigned long ip, unsigned long addr, int link)
{ {
......
...@@ -281,7 +281,9 @@ SECTIONS ...@@ -281,7 +281,9 @@ SECTIONS
* to deal with references from __bug_table * to deal with references from __bug_table
*/ */
.exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
__exittext_begin = .;
EXIT_TEXT EXIT_TEXT
__exittext_end = .;
} }
. = ALIGN(PAGE_SIZE); . = ALIGN(PAGE_SIZE);
......
...@@ -64,6 +64,7 @@ int __init __weak kasan_init_region(void *start, size_t size) ...@@ -64,6 +64,7 @@ int __init __weak kasan_init_region(void *start, size_t size)
if (ret) if (ret)
return ret; return ret;
k_start = k_start & PAGE_MASK;
block = memblock_alloc(k_end - k_start, PAGE_SIZE); block = memblock_alloc(k_end - k_start, PAGE_SIZE);
if (!block) if (!block)
return -ENOMEM; return -ENOMEM;
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
#include "mpc85xx.h" #include "mpc85xx.h"
void __init mpc8536_ds_pic_init(void) static void __init mpc8536_ds_pic_init(void)
{ {
struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN, struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN,
0, 256, " OpenPIC "); 0, 256, " OpenPIC ");
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
#include "mpc85xx.h" #include "mpc85xx.h"
void __init mvme2500_pic_init(void) static void __init mvme2500_pic_init(void)
{ {
struct mpic *mpic = mpic_alloc(NULL, 0, struct mpic *mpic = mpic_alloc(NULL, 0,
MPIC_BIG_ENDIAN | MPIC_SINGLE_DEST_CPU, MPIC_BIG_ENDIAN | MPIC_SINGLE_DEST_CPU,
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
#include "mpc85xx.h" #include "mpc85xx.h"
void __init p1010_rdb_pic_init(void) static void __init p1010_rdb_pic_init(void)
{ {
struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN | struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN |
MPIC_SINGLE_DEST_CPU, MPIC_SINGLE_DEST_CPU,
......
...@@ -370,7 +370,7 @@ static void p1022ds_set_monitor_port(enum fsl_diu_monitor_port port) ...@@ -370,7 +370,7 @@ static void p1022ds_set_monitor_port(enum fsl_diu_monitor_port port)
* *
* @pixclock: the wavelength, in picoseconds, of the clock * @pixclock: the wavelength, in picoseconds, of the clock
*/ */
void p1022ds_set_pixel_clock(unsigned int pixclock) static void p1022ds_set_pixel_clock(unsigned int pixclock)
{ {
struct device_node *guts_np = NULL; struct device_node *guts_np = NULL;
struct ccsr_guts __iomem *guts; struct ccsr_guts __iomem *guts;
...@@ -418,7 +418,7 @@ void p1022ds_set_pixel_clock(unsigned int pixclock) ...@@ -418,7 +418,7 @@ void p1022ds_set_pixel_clock(unsigned int pixclock)
/** /**
* p1022ds_valid_monitor_port: set the monitor port for sysfs * p1022ds_valid_monitor_port: set the monitor port for sysfs
*/ */
enum fsl_diu_monitor_port static enum fsl_diu_monitor_port
p1022ds_valid_monitor_port(enum fsl_diu_monitor_port port) p1022ds_valid_monitor_port(enum fsl_diu_monitor_port port)
{ {
switch (port) { switch (port) {
...@@ -432,7 +432,7 @@ p1022ds_valid_monitor_port(enum fsl_diu_monitor_port port) ...@@ -432,7 +432,7 @@ p1022ds_valid_monitor_port(enum fsl_diu_monitor_port port)
#endif #endif
void __init p1022_ds_pic_init(void) static void __init p1022_ds_pic_init(void)
{ {
struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN | struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN |
MPIC_SINGLE_DEST_CPU, MPIC_SINGLE_DEST_CPU,
......
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
* *
* @pixclock: the wavelength, in picoseconds, of the clock * @pixclock: the wavelength, in picoseconds, of the clock
*/ */
void p1022rdk_set_pixel_clock(unsigned int pixclock) static void p1022rdk_set_pixel_clock(unsigned int pixclock)
{ {
struct device_node *guts_np = NULL; struct device_node *guts_np = NULL;
struct ccsr_guts __iomem *guts; struct ccsr_guts __iomem *guts;
...@@ -88,7 +88,7 @@ void p1022rdk_set_pixel_clock(unsigned int pixclock) ...@@ -88,7 +88,7 @@ void p1022rdk_set_pixel_clock(unsigned int pixclock)
/** /**
* p1022rdk_valid_monitor_port: set the monitor port for sysfs * p1022rdk_valid_monitor_port: set the monitor port for sysfs
*/ */
enum fsl_diu_monitor_port static enum fsl_diu_monitor_port
p1022rdk_valid_monitor_port(enum fsl_diu_monitor_port port) p1022rdk_valid_monitor_port(enum fsl_diu_monitor_port port)
{ {
return FSL_DIU_PORT_DVI; return FSL_DIU_PORT_DVI;
...@@ -96,7 +96,7 @@ p1022rdk_valid_monitor_port(enum fsl_diu_monitor_port port) ...@@ -96,7 +96,7 @@ p1022rdk_valid_monitor_port(enum fsl_diu_monitor_port port)
#endif #endif
void __init p1022_rdk_pic_init(void) static void __init p1022_rdk_pic_init(void)
{ {
struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN | struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN |
MPIC_SINGLE_DEST_CPU, MPIC_SINGLE_DEST_CPU,
......
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
#include <linux/of_irq.h> #include <linux/of_irq.h>
#include <linux/io.h> #include <linux/io.h>
#include "socrates_fpga_pic.h"
/* /*
* The FPGA supports 9 interrupt sources, which can be routed to 3 * The FPGA supports 9 interrupt sources, which can be routed to 3
* interrupt request lines of the MPIC. The line to be used can be * interrupt request lines of the MPIC. The line to be used can be
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
#define MPC85xx_L2CTL_L2I 0x40000000 /* L2 flash invalidate */ #define MPC85xx_L2CTL_L2I 0x40000000 /* L2 flash invalidate */
#define MPC85xx_L2CTL_L2SIZ_MASK 0x30000000 /* L2 SRAM size (R/O) */ #define MPC85xx_L2CTL_L2SIZ_MASK 0x30000000 /* L2 SRAM size (R/O) */
void __init xes_mpc85xx_pic_init(void) static void __init xes_mpc85xx_pic_init(void)
{ {
struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN, struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN,
0, 256, " OpenPIC "); 0, 256, " OpenPIC ");
......
...@@ -662,8 +662,12 @@ u64 pseries_paravirt_steal_clock(int cpu) ...@@ -662,8 +662,12 @@ u64 pseries_paravirt_steal_clock(int cpu)
{ {
struct lppaca *lppaca = &lppaca_of(cpu); struct lppaca *lppaca = &lppaca_of(cpu);
return be64_to_cpu(READ_ONCE(lppaca->enqueue_dispatch_tb)) + /*
be64_to_cpu(READ_ONCE(lppaca->ready_enqueue_tb)); * VPA steal time counters are reported at TB frequency. Hence do a
* conversion to ns before returning
*/
return tb_to_ns(be64_to_cpu(READ_ONCE(lppaca->enqueue_dispatch_tb)) +
be64_to_cpu(READ_ONCE(lppaca->ready_enqueue_tb)));
} }
#endif #endif
......
...@@ -41,7 +41,7 @@ struct memcons memcons = { ...@@ -41,7 +41,7 @@ struct memcons memcons = {
.input_end = &memcons_input[CONFIG_PPC_MEMCONS_INPUT_SIZE], .input_end = &memcons_input[CONFIG_PPC_MEMCONS_INPUT_SIZE],
}; };
void memcons_putc(char c) static void memcons_putc(char c)
{ {
char *new_output_pos; char *new_output_pos;
...@@ -54,7 +54,7 @@ void memcons_putc(char c) ...@@ -54,7 +54,7 @@ void memcons_putc(char c)
memcons.output_pos = new_output_pos; memcons.output_pos = new_output_pos;
} }
int memcons_getc_poll(void) static int memcons_getc_poll(void)
{ {
char c; char c;
char *new_input_pos; char *new_input_pos;
...@@ -77,7 +77,7 @@ int memcons_getc_poll(void) ...@@ -77,7 +77,7 @@ int memcons_getc_poll(void)
return -1; return -1;
} }
int memcons_getc(void) static int memcons_getc(void)
{ {
int c; int c;
......
...@@ -263,10 +263,10 @@ static int papr_vpd_system_loc_code(void) ...@@ -263,10 +263,10 @@ static int papr_vpd_system_loc_code(void)
off_t size; off_t size;
int fd; int fd;
SKIP_IF_MSG(get_system_loc_code(&lc),
"Cannot determine system location code");
SKIP_IF_MSG(devfd < 0 && errno == ENOENT, SKIP_IF_MSG(devfd < 0 && errno == ENOENT,
DEVPATH " not present"); DEVPATH " not present");
SKIP_IF_MSG(get_system_loc_code(&lc),
"Cannot determine system location code");
FAIL_IF(devfd < 0); FAIL_IF(devfd < 0);
......
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