Re: [RFC patch 3/7] printk: Use clock MONOTONIC for timestamps
Hello Thomas, On (11/15/17 19:15), Thomas Gleixner wrote: > local_clock() cannot be reliably correlated to CLOCK_MONOTONIC, which is > used by user space, e.g. systemd, to create correlation timestamps. > > There are multiple reasons: > > - CLOCK_MONOTONIC is NTP adjusted, local_clock() not. Depending on the >calibration accuracy and uptime significant drift can be observed. > > - CLOCK_MONOTONIC does not advance across suspend/resume for historical >reasons. local_clock() might or might not depending on the properties of >the underlying hardware counter. > > Use the NMI safe accessor to clock MONOTONIC instead of local_clock(). The > access might be slower than local_clock(), but printk is not such a > performance critical hotpath that it matters. > > Visible change: > > The early boot timestamps are jiffies based longer than with local_clock() > depending on the platform. During suspend/resume the timestamp may become > stale when the underlying clocksource hardware is not flagged with > CLOCKSOURCE_SUSPEND_ACCESS_OK. > > A horrible follow up patch demonstrates how that could be mitigated. > > Signed-off-by: Thomas Gleixner> --- > kernel/printk/printk.c |4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > a silly nitpick, I suppose we can do -#include +#include -ss
Re: [RFC patch 3/7] printk: Use clock MONOTONIC for timestamps
Hello Thomas, On (11/15/17 19:15), Thomas Gleixner wrote: > local_clock() cannot be reliably correlated to CLOCK_MONOTONIC, which is > used by user space, e.g. systemd, to create correlation timestamps. > > There are multiple reasons: > > - CLOCK_MONOTONIC is NTP adjusted, local_clock() not. Depending on the >calibration accuracy and uptime significant drift can be observed. > > - CLOCK_MONOTONIC does not advance across suspend/resume for historical >reasons. local_clock() might or might not depending on the properties of >the underlying hardware counter. > > Use the NMI safe accessor to clock MONOTONIC instead of local_clock(). The > access might be slower than local_clock(), but printk is not such a > performance critical hotpath that it matters. > > Visible change: > > The early boot timestamps are jiffies based longer than with local_clock() > depending on the platform. During suspend/resume the timestamp may become > stale when the underlying clocksource hardware is not flagged with > CLOCKSOURCE_SUSPEND_ACCESS_OK. > > A horrible follow up patch demonstrates how that could be mitigated. > > Signed-off-by: Thomas Gleixner > --- > kernel/printk/printk.c |4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > a silly nitpick, I suppose we can do -#include +#include -ss
Re: [PATCH] s390/ap_bus: Convert timers to use timer_setup()
On Thu, Nov 2, 2017 at 11:29 PM, Martin Schwidefskywrote: > On Thu, 2 Nov 2017 16:36:53 -0700 > Kees Cook wrote: > >> On Wed, Oct 25, 2017 at 11:38 PM, Martin Schwidefsky >> wrote: >> > On Wed, 25 Oct 2017 03:27:37 -0700 >> > Kees Cook wrote: >> > >> >> In preparation for unconditionally passing the struct timer_list pointer >> >> to >> >> all timer callbacks, switch to using the new timer_setup() and >> >> from_timer() >> >> to pass the timer pointer explicitly. >> >> >> >> Cc: Harald Freudenberger >> >> Cc: Martin Schwidefsky >> >> Cc: Heiko Carstens >> >> Cc: linux-s...@vger.kernel.org >> >> Signed-off-by: Kees Cook >> >> --- >> >> drivers/s390/crypto/ap_bus.c | 10 +- >> >> drivers/s390/crypto/ap_bus.h | 2 +- >> >> drivers/s390/crypto/ap_queue.c | 2 +- >> >> 3 files changed, 7 insertions(+), 7 deletions(-) >> > >> > Parked for the second part of the s390 updates for the next merge window. >> > Thanks. >> >> Thanks for getting these staged. I just wanted to check with you, >> since I don't see these in -next anywhere yet: >> >> s390: qdio: Convert timers to use timer_setup() >> s390/sclp: Convert timers to use timer_setup() >> s390/cio: Convert timers to use timer_setup() >> s390/scsi: Convert timers to use timer_setup() >> s390/ap_bus: Convert timers to use timer_setup() >> >> Are all of these expected to land for -rc1? (Would it help to carry >> them in the timer tree?) I've got tree-wide changes ready to go once >> all these conversions have landed. > > These patches are parked on a private branches. The features branch > on s390/linux is the one that is used for -next AND for the upstream > merge. And since I do not want to rebase that branch the timer_setup > patches are not in -next as well. > > Four of you patches are safe with me, the s390/scsi patch is in > Steffens patch queue. All good I would say. Hi, I saw s390 get merged for -rc1, but none of these timer_setup() conversions were included. Given the possible short merge window, what's the state of these? I can't do the bulk API changes at the end of -rc1 without the s390 timer patches. Anything I can help with? Thanks! -Kees -- Kees Cook Pixel Security
Re: [PATCH] s390/ap_bus: Convert timers to use timer_setup()
On Thu, Nov 2, 2017 at 11:29 PM, Martin Schwidefsky wrote: > On Thu, 2 Nov 2017 16:36:53 -0700 > Kees Cook wrote: > >> On Wed, Oct 25, 2017 at 11:38 PM, Martin Schwidefsky >> wrote: >> > On Wed, 25 Oct 2017 03:27:37 -0700 >> > Kees Cook wrote: >> > >> >> In preparation for unconditionally passing the struct timer_list pointer >> >> to >> >> all timer callbacks, switch to using the new timer_setup() and >> >> from_timer() >> >> to pass the timer pointer explicitly. >> >> >> >> Cc: Harald Freudenberger >> >> Cc: Martin Schwidefsky >> >> Cc: Heiko Carstens >> >> Cc: linux-s...@vger.kernel.org >> >> Signed-off-by: Kees Cook >> >> --- >> >> drivers/s390/crypto/ap_bus.c | 10 +- >> >> drivers/s390/crypto/ap_bus.h | 2 +- >> >> drivers/s390/crypto/ap_queue.c | 2 +- >> >> 3 files changed, 7 insertions(+), 7 deletions(-) >> > >> > Parked for the second part of the s390 updates for the next merge window. >> > Thanks. >> >> Thanks for getting these staged. I just wanted to check with you, >> since I don't see these in -next anywhere yet: >> >> s390: qdio: Convert timers to use timer_setup() >> s390/sclp: Convert timers to use timer_setup() >> s390/cio: Convert timers to use timer_setup() >> s390/scsi: Convert timers to use timer_setup() >> s390/ap_bus: Convert timers to use timer_setup() >> >> Are all of these expected to land for -rc1? (Would it help to carry >> them in the timer tree?) I've got tree-wide changes ready to go once >> all these conversions have landed. > > These patches are parked on a private branches. The features branch > on s390/linux is the one that is used for -next AND for the upstream > merge. And since I do not want to rebase that branch the timer_setup > patches are not in -next as well. > > Four of you patches are safe with me, the s390/scsi patch is in > Steffens patch queue. All good I would say. Hi, I saw s390 get merged for -rc1, but none of these timer_setup() conversions were included. Given the possible short merge window, what's the state of these? I can't do the bulk API changes at the end of -rc1 without the s390 timer patches. Anything I can help with? Thanks! -Kees -- Kees Cook Pixel Security
[PATCH] kbuild: define KBUILD_MODNAME even if multiple modules share objects
Currently, KBUILD_MODNAME is defined only when $(modname) contains just one word. If an object is shared between multiple modules, undefined KBUILD_MODNAME causes a build error. A simple test case is as follows: obj-m += foo.o obj-m += bar.o foo-objs := foo-bar-common.o foo-main.o bar-objs := foo-bar-common.o bar-main.o In this case, we do not know what to define for KBUILD_MODNAME when compiling foo-bar-common.o ("foo" or "bar" ?), so one reasonable solution is let it fall back to $(basetarget) (= "foo-bar-common"). It would be better to avoid such a design where possible, but we already have such a case, for example, drivers/net/ethernet/cavium/liquidio/Makefile I slightly refactored implementation; we can check $(word 2, $(modname)) instead of $(filter 1,$(words $(modname))). Signed-off-by: Masahiro Yamada--- scripts/Makefile.lib | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 5fbc46d..9f9a7df 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -86,8 +86,7 @@ subdir-ym := $(addprefix $(obj)/,$(subdir-ym)) # differ in different configs. name-fix = $(squote)$(quote)$(subst $(comma),_,$(subst -,_,$1))$(quote)$(squote) basename_flags = -DKBUILD_BASENAME=$(call name-fix,$(basetarget)) -modname_flags = $(if $(filter 1,$(words $(modname))),\ - -DKBUILD_MODNAME=$(call name-fix,$(modname))) +modname_flags = -DKBUILD_MODNAME=$(call name-fix,$(if $(word 2,$(modname)),$(basetarget),$(modname))) orig_c_flags = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) \ $(ccflags-y) $(CFLAGS_$(basetarget).o) -- 2.7.4
[PATCH 04/10] x86: jailhouse: Enable PMTIMER
From: Jan KiszkaJailhouse exposes the PMTIMER as only reference clock to all cells. Pick up its address from the setup data. Allow to enable the Linux support of it by relaxing its strict dependency on ACPI. Signed-off-by: Jan Kiszka --- arch/x86/Kconfig| 1 + arch/x86/kernel/jailhouse.c | 4 drivers/acpi/Kconfig| 32 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index c5f4f4683b51..6976c035ea63 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -785,6 +785,7 @@ config KVM_DEBUG_FS config JAILHOUSE_GUEST bool "Jailhouse non-root cell support" depends on PARAVIRT && X86_64 + select X86_PM_TIMER ---help--- This option allows to run Linux as guest in a Jailhouse non-root cell. You can leave this option disabled if you only want to start diff --git a/arch/x86/kernel/jailhouse.c b/arch/x86/kernel/jailhouse.c index ce9416c70656..f7e99f7a8873 100644 --- a/arch/x86/kernel/jailhouse.c +++ b/arch/x86/kernel/jailhouse.c @@ -10,6 +10,7 @@ * the COPYING file in the top-level directory. */ +#include #include #include #include @@ -66,6 +67,9 @@ static void __init jailhouse_init_platform(void) data->compatible_version > SETUP_REQUIRED_VERSION) panic("Jailhouse: Unsupported setup data structure"); + pmtmr_ioport = data->pm_timer_address; + pr_debug("Jailhouse: PM-Timer IO Port: %#x\n", pmtmr_ioport); + #ifdef CONFIG_X86_X2APIC /* * Register x2APIC handlers early. We need them when running diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 91477d5ab422..c054f9b4f1eb 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -361,22 +361,6 @@ config ACPI_PCI_SLOT i.e., segment/bus/device/function tuples, with physical slots in the system. If you are unsure, say N. -config X86_PM_TIMER - bool "Power Management Timer Support" if EXPERT - depends on X86 - default y - help - The Power Management Timer is available on all ACPI-capable, - in most cases even if ACPI is unusable or blacklisted. - - This timing source is not affected by power management features - like aggressive processor idling, throttling, frequency and/or - voltage scaling, unlike the commonly used Time Stamp Counter - (TSC) timing source. - - You should nearly always say Y here because many modern - systems require this timer. - config ACPI_CONTAINER bool "Container and Module Devices" default (ACPI_HOTPLUG_MEMORY || ACPI_HOTPLUG_CPU) @@ -558,3 +542,19 @@ config TPS68470_PMIC_OPREGION using this, are probed. endif # ACPI + +config X86_PM_TIMER + bool "Power Management Timer Support" if EXPERT + depends on X86 && (ACPI || JAILHOUSE_GUEST) + default y + help + The Power Management Timer is available on all ACPI-capable, + in most cases even if ACPI is unusable or blacklisted. + + This timing source is not affected by power management features + like aggressive processor idling, throttling, frequency and/or + voltage scaling, unlike the commonly used Time Stamp Counter + (TSC) timing source. + + You should nearly always say Y here because many modern + systems require this timer. -- 2.12.3
[PATCH] kbuild: define KBUILD_MODNAME even if multiple modules share objects
Currently, KBUILD_MODNAME is defined only when $(modname) contains just one word. If an object is shared between multiple modules, undefined KBUILD_MODNAME causes a build error. A simple test case is as follows: obj-m += foo.o obj-m += bar.o foo-objs := foo-bar-common.o foo-main.o bar-objs := foo-bar-common.o bar-main.o In this case, we do not know what to define for KBUILD_MODNAME when compiling foo-bar-common.o ("foo" or "bar" ?), so one reasonable solution is let it fall back to $(basetarget) (= "foo-bar-common"). It would be better to avoid such a design where possible, but we already have such a case, for example, drivers/net/ethernet/cavium/liquidio/Makefile I slightly refactored implementation; we can check $(word 2, $(modname)) instead of $(filter 1,$(words $(modname))). Signed-off-by: Masahiro Yamada --- scripts/Makefile.lib | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 5fbc46d..9f9a7df 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -86,8 +86,7 @@ subdir-ym := $(addprefix $(obj)/,$(subdir-ym)) # differ in different configs. name-fix = $(squote)$(quote)$(subst $(comma),_,$(subst -,_,$1))$(quote)$(squote) basename_flags = -DKBUILD_BASENAME=$(call name-fix,$(basetarget)) -modname_flags = $(if $(filter 1,$(words $(modname))),\ - -DKBUILD_MODNAME=$(call name-fix,$(modname))) +modname_flags = -DKBUILD_MODNAME=$(call name-fix,$(if $(word 2,$(modname)),$(basetarget),$(modname))) orig_c_flags = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) \ $(ccflags-y) $(CFLAGS_$(basetarget).o) -- 2.7.4
[PATCH 04/10] x86: jailhouse: Enable PMTIMER
From: Jan Kiszka Jailhouse exposes the PMTIMER as only reference clock to all cells. Pick up its address from the setup data. Allow to enable the Linux support of it by relaxing its strict dependency on ACPI. Signed-off-by: Jan Kiszka --- arch/x86/Kconfig| 1 + arch/x86/kernel/jailhouse.c | 4 drivers/acpi/Kconfig| 32 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index c5f4f4683b51..6976c035ea63 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -785,6 +785,7 @@ config KVM_DEBUG_FS config JAILHOUSE_GUEST bool "Jailhouse non-root cell support" depends on PARAVIRT && X86_64 + select X86_PM_TIMER ---help--- This option allows to run Linux as guest in a Jailhouse non-root cell. You can leave this option disabled if you only want to start diff --git a/arch/x86/kernel/jailhouse.c b/arch/x86/kernel/jailhouse.c index ce9416c70656..f7e99f7a8873 100644 --- a/arch/x86/kernel/jailhouse.c +++ b/arch/x86/kernel/jailhouse.c @@ -10,6 +10,7 @@ * the COPYING file in the top-level directory. */ +#include #include #include #include @@ -66,6 +67,9 @@ static void __init jailhouse_init_platform(void) data->compatible_version > SETUP_REQUIRED_VERSION) panic("Jailhouse: Unsupported setup data structure"); + pmtmr_ioport = data->pm_timer_address; + pr_debug("Jailhouse: PM-Timer IO Port: %#x\n", pmtmr_ioport); + #ifdef CONFIG_X86_X2APIC /* * Register x2APIC handlers early. We need them when running diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 91477d5ab422..c054f9b4f1eb 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -361,22 +361,6 @@ config ACPI_PCI_SLOT i.e., segment/bus/device/function tuples, with physical slots in the system. If you are unsure, say N. -config X86_PM_TIMER - bool "Power Management Timer Support" if EXPERT - depends on X86 - default y - help - The Power Management Timer is available on all ACPI-capable, - in most cases even if ACPI is unusable or blacklisted. - - This timing source is not affected by power management features - like aggressive processor idling, throttling, frequency and/or - voltage scaling, unlike the commonly used Time Stamp Counter - (TSC) timing source. - - You should nearly always say Y here because many modern - systems require this timer. - config ACPI_CONTAINER bool "Container and Module Devices" default (ACPI_HOTPLUG_MEMORY || ACPI_HOTPLUG_CPU) @@ -558,3 +542,19 @@ config TPS68470_PMIC_OPREGION using this, are probed. endif # ACPI + +config X86_PM_TIMER + bool "Power Management Timer Support" if EXPERT + depends on X86 && (ACPI || JAILHOUSE_GUEST) + default y + help + The Power Management Timer is available on all ACPI-capable, + in most cases even if ACPI is unusable or blacklisted. + + This timing source is not affected by power management features + like aggressive processor idling, throttling, frequency and/or + voltage scaling, unlike the commonly used Time Stamp Counter + (TSC) timing source. + + You should nearly always say Y here because many modern + systems require this timer. -- 2.12.3
[PATCH 07/10] x86: jailhouse: Silence ACPI warning
From: Jan KiszkaJailhouse support does not depend on ACPI, and does not even use it. But if it should be enabled, avoid warning about its absence in the platform. Signed-off-by: Jan Kiszka --- arch/x86/kernel/jailhouse.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/arch/x86/kernel/jailhouse.c b/arch/x86/kernel/jailhouse.c index cfe8ae0c33a2..c1ed7fcd7bfa 100644 --- a/arch/x86/kernel/jailhouse.c +++ b/arch/x86/kernel/jailhouse.c @@ -180,6 +180,12 @@ static void __init jailhouse_init_platform(void) smp_found_config = 1; early_memunmap(data, sizeof(*data)); + + /* +* Avoid that the kernel complains about missing ACPI tables - there +* are none in a non-root cell. +*/ + disable_acpi(); } bool jailhouse_paravirt(void) -- 2.12.3
[PATCH 09/10] x86: jailhouse: Wire up IOAPIC for legacy UART ports
From: Jan KiszkaThe typical I/O interrupts in non-root cells are MSI-based. However, the platform UARTs do not support MSI. In order to run a non-root cell that shall be use one of them, we need to register the standard IOAPIC and set 1:1 routing for IRQ 3 and 4. If an IOAPIC is not available, the boot loader clears standard_ioapic in the setup data, and we skip the registration. If we should not be allowed to use one of those pins, Jailhouse will simply ignore our accesses. Signed-off-by: Jan Kiszka --- arch/x86/kernel/jailhouse.c | 20 1 file changed, 20 insertions(+) diff --git a/arch/x86/kernel/jailhouse.c b/arch/x86/kernel/jailhouse.c index 0bcca175c35e..05459ea0ecc7 100644 --- a/arch/x86/kernel/jailhouse.c +++ b/arch/x86/kernel/jailhouse.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -148,6 +149,14 @@ static unsigned int x2apic_get_apic_id(unsigned long id) static void __init jailhouse_init_platform(void) { + struct ioapic_domain_cfg ioapic_cfg = { + .type = IOAPIC_DOMAIN_STRICT, + .ops = _ioapic_irqdomain_ops, + }; + struct mpc_intsrc mp_irq = { + .type = MP_INTSRC, + .irqtype = mp_INT, + }; u64 pa_data = boot_params.hdr.setup_data; struct jailhouse_setup_data *data; unsigned int cpu; @@ -189,6 +198,17 @@ static void __init jailhouse_init_platform(void) boot_cpu_apic_version); smp_found_config = 1; + if (data->standard_ioapic) { + mp_register_ioapic(0, 0xfec0, gsi_top, _cfg); + + /* Register 1:1 mapping for legacy UART IRQs 3 and 4 */ + mp_irq.srcbusirq = mp_irq.dstirq = 3; + mp_save_irq(_irq); + + mp_irq.srcbusirq = mp_irq.dstirq = 4; + mp_save_irq(_irq); + } + early_memunmap(data, sizeof(*data)); /* -- 2.12.3
[PATCH 07/10] x86: jailhouse: Silence ACPI warning
From: Jan Kiszka Jailhouse support does not depend on ACPI, and does not even use it. But if it should be enabled, avoid warning about its absence in the platform. Signed-off-by: Jan Kiszka --- arch/x86/kernel/jailhouse.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/arch/x86/kernel/jailhouse.c b/arch/x86/kernel/jailhouse.c index cfe8ae0c33a2..c1ed7fcd7bfa 100644 --- a/arch/x86/kernel/jailhouse.c +++ b/arch/x86/kernel/jailhouse.c @@ -180,6 +180,12 @@ static void __init jailhouse_init_platform(void) smp_found_config = 1; early_memunmap(data, sizeof(*data)); + + /* +* Avoid that the kernel complains about missing ACPI tables - there +* are none in a non-root cell. +*/ + disable_acpi(); } bool jailhouse_paravirt(void) -- 2.12.3
[PATCH 09/10] x86: jailhouse: Wire up IOAPIC for legacy UART ports
From: Jan Kiszka The typical I/O interrupts in non-root cells are MSI-based. However, the platform UARTs do not support MSI. In order to run a non-root cell that shall be use one of them, we need to register the standard IOAPIC and set 1:1 routing for IRQ 3 and 4. If an IOAPIC is not available, the boot loader clears standard_ioapic in the setup data, and we skip the registration. If we should not be allowed to use one of those pins, Jailhouse will simply ignore our accesses. Signed-off-by: Jan Kiszka --- arch/x86/kernel/jailhouse.c | 20 1 file changed, 20 insertions(+) diff --git a/arch/x86/kernel/jailhouse.c b/arch/x86/kernel/jailhouse.c index 0bcca175c35e..05459ea0ecc7 100644 --- a/arch/x86/kernel/jailhouse.c +++ b/arch/x86/kernel/jailhouse.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -148,6 +149,14 @@ static unsigned int x2apic_get_apic_id(unsigned long id) static void __init jailhouse_init_platform(void) { + struct ioapic_domain_cfg ioapic_cfg = { + .type = IOAPIC_DOMAIN_STRICT, + .ops = _ioapic_irqdomain_ops, + }; + struct mpc_intsrc mp_irq = { + .type = MP_INTSRC, + .irqtype = mp_INT, + }; u64 pa_data = boot_params.hdr.setup_data; struct jailhouse_setup_data *data; unsigned int cpu; @@ -189,6 +198,17 @@ static void __init jailhouse_init_platform(void) boot_cpu_apic_version); smp_found_config = 1; + if (data->standard_ioapic) { + mp_register_ioapic(0, 0xfec0, gsi_top, _cfg); + + /* Register 1:1 mapping for legacy UART IRQs 3 and 4 */ + mp_irq.srcbusirq = mp_irq.dstirq = 3; + mp_save_irq(_irq); + + mp_irq.srcbusirq = mp_irq.dstirq = 4; + mp_save_irq(_irq); + } + early_memunmap(data, sizeof(*data)); /* -- 2.12.3
[PATCH 05/10] x86: jailhouse: Set up timekeeping
From: Jan KiszkaCalibrate the TSC and, where necessary, the APIC timer against the TMTIMER. We need our own implementation as neither the PIC nor the HPET are available, and the standard calibration routines try to make use of them. Signed-off-by: Jan Kiszka --- arch/x86/include/asm/tsc.h | 3 ++ arch/x86/kernel/jailhouse.c | 82 + arch/x86/kernel/tsc.c | 14 3 files changed, 92 insertions(+), 7 deletions(-) diff --git a/arch/x86/include/asm/tsc.h b/arch/x86/include/asm/tsc.h index cf5d53c3f9ea..be92e0c8ac17 100644 --- a/arch/x86/include/asm/tsc.h +++ b/arch/x86/include/asm/tsc.h @@ -71,4 +71,7 @@ extern void tsc_restore_sched_clock_state(void); unsigned long cpu_khz_from_msr(void); +u64 tsc_read_refs(u64 *ref, int hpet); +unsigned long tsc_calc_pmtimer_ref(u64 deltatsc, u64 pm1, u64 pm2); + #endif /* _ASM_X86_TSC_H */ diff --git a/arch/x86/kernel/jailhouse.c b/arch/x86/kernel/jailhouse.c index f7e99f7a8873..8e5b2f0c8a34 100644 --- a/arch/x86/kernel/jailhouse.c +++ b/arch/x86/kernel/jailhouse.c @@ -50,6 +50,83 @@ static uint32_t __init jailhouse_detect(void) return jailhouse_cpuid_base(); } +#define MAX_RETRIES5 +#define SMI_TRESHOLD 5 + +static unsigned long apic_timer_access(u64 *pmt, bool setup) +{ + unsigned long ret = 0; + unsigned int n; + u64 t1, t2; + + for (n = 0; n < MAX_RETRIES; n++) { + t1 = get_cycles(); + *pmt = acpi_pm_read_early(); + if (setup) + apic_write(APIC_TMICT, 0x); + else + ret = apic_read(APIC_TMCCT); + t2 = get_cycles(); + + if ((t2 - t1) < SMI_TRESHOLD * 2) + return ret; + } + + panic("Jailhouse: SMI disturbed APIC timer calibration"); +} + +static void jailhouse_timer_init(void) +{ + u64 divided_apic_freq; + unsigned long tmr; + u64 start, end; + + if (boot_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER)) + return; + + apic_write(APIC_LVTT, APIC_LVT_MASKED); + apic_write(APIC_TDCR, APIC_TDR_DIV_16); + + apic_timer_access(, true); + while ((acpi_pm_read_early() - start) < 10) + cpu_relax(); + tmr = apic_timer_access(, false); + + divided_apic_freq = + tsc_calc_pmtimer_ref((0xU - tmr) * 100, start, end); + + lapic_timer_frequency = divided_apic_freq * 16; + apic_write(APIC_TMICT, 0); +} + +static unsigned long jailhouse_calibrate_cpu(void) +{ + u64 tsc1, tsc2, pm1, pm2; + unsigned long flags; + + local_irq_save(flags); + + tsc1 = tsc_read_refs(, 0); + while ((get_cycles() - tsc1) < 5000) + cpu_relax(); + tsc2 = tsc_read_refs(, 0); + + local_irq_restore(flags); + + /* Check, whether the sampling succeeded (SMI?) */ + if (tsc1 == ULLONG_MAX || tsc2 == ULLONG_MAX) { + pr_err("Jailhouse: TSC calibration against PMTIMER failed\n"); + return 0; + } + + return tsc_calc_pmtimer_ref((tsc2 - tsc1) * 100, pm1, pm2); +} + +static unsigned long jailhouse_calibrate_tsc(void) +{ + return 0; +} + static unsigned int x2apic_get_apic_id(unsigned long id) { return id; @@ -61,6 +138,11 @@ static void __init jailhouse_init_platform(void) struct jailhouse_setup_data *data; unsigned int cpu; + x86_init.timers.timer_init = jailhouse_timer_init; + + x86_platform.calibrate_cpu = jailhouse_calibrate_cpu; + x86_platform.calibrate_tsc = jailhouse_calibrate_tsc; + data = early_memremap(pa_data, sizeof(*data)); if (data->header.type != SETUP_JAILHOUSE || diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 8ea117f8142e..a61000cc4f21 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -286,7 +286,7 @@ __setup("tsc=", tsc_setup); /* * Read TSC and the reference counters. Take care of SMI disturbance */ -static u64 tsc_read_refs(u64 *p, int hpet) +u64 tsc_read_refs(u64 *p, int hpet) { u64 t1, t2; int i; @@ -307,7 +307,7 @@ static u64 tsc_read_refs(u64 *p, int hpet) /* * Calculate the TSC frequency from HPET reference */ -static unsigned long calc_hpet_ref(u64 deltatsc, u64 hpet1, u64 hpet2) +static unsigned long tsc_calc_hpet_ref(u64 deltatsc, u64 hpet1, u64 hpet2) { u64 tmp; @@ -324,7 +324,7 @@ static unsigned long calc_hpet_ref(u64 deltatsc, u64 hpet1, u64 hpet2) /* * Calculate the TSC frequency from PMTimer reference */ -static unsigned long calc_pmtimer_ref(u64 deltatsc, u64 pm1, u64 pm2) +unsigned long tsc_calc_pmtimer_ref(u64 deltatsc, u64 pm1, u64 pm2) { u64 tmp; @@ -728,9 +728,9 @@ unsigned long native_calibrate_cpu(void) tsc2 = (tsc2 - tsc1) * 100LL;
[PATCH 05/10] x86: jailhouse: Set up timekeeping
From: Jan Kiszka Calibrate the TSC and, where necessary, the APIC timer against the TMTIMER. We need our own implementation as neither the PIC nor the HPET are available, and the standard calibration routines try to make use of them. Signed-off-by: Jan Kiszka --- arch/x86/include/asm/tsc.h | 3 ++ arch/x86/kernel/jailhouse.c | 82 + arch/x86/kernel/tsc.c | 14 3 files changed, 92 insertions(+), 7 deletions(-) diff --git a/arch/x86/include/asm/tsc.h b/arch/x86/include/asm/tsc.h index cf5d53c3f9ea..be92e0c8ac17 100644 --- a/arch/x86/include/asm/tsc.h +++ b/arch/x86/include/asm/tsc.h @@ -71,4 +71,7 @@ extern void tsc_restore_sched_clock_state(void); unsigned long cpu_khz_from_msr(void); +u64 tsc_read_refs(u64 *ref, int hpet); +unsigned long tsc_calc_pmtimer_ref(u64 deltatsc, u64 pm1, u64 pm2); + #endif /* _ASM_X86_TSC_H */ diff --git a/arch/x86/kernel/jailhouse.c b/arch/x86/kernel/jailhouse.c index f7e99f7a8873..8e5b2f0c8a34 100644 --- a/arch/x86/kernel/jailhouse.c +++ b/arch/x86/kernel/jailhouse.c @@ -50,6 +50,83 @@ static uint32_t __init jailhouse_detect(void) return jailhouse_cpuid_base(); } +#define MAX_RETRIES5 +#define SMI_TRESHOLD 5 + +static unsigned long apic_timer_access(u64 *pmt, bool setup) +{ + unsigned long ret = 0; + unsigned int n; + u64 t1, t2; + + for (n = 0; n < MAX_RETRIES; n++) { + t1 = get_cycles(); + *pmt = acpi_pm_read_early(); + if (setup) + apic_write(APIC_TMICT, 0x); + else + ret = apic_read(APIC_TMCCT); + t2 = get_cycles(); + + if ((t2 - t1) < SMI_TRESHOLD * 2) + return ret; + } + + panic("Jailhouse: SMI disturbed APIC timer calibration"); +} + +static void jailhouse_timer_init(void) +{ + u64 divided_apic_freq; + unsigned long tmr; + u64 start, end; + + if (boot_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER)) + return; + + apic_write(APIC_LVTT, APIC_LVT_MASKED); + apic_write(APIC_TDCR, APIC_TDR_DIV_16); + + apic_timer_access(, true); + while ((acpi_pm_read_early() - start) < 10) + cpu_relax(); + tmr = apic_timer_access(, false); + + divided_apic_freq = + tsc_calc_pmtimer_ref((0xU - tmr) * 100, start, end); + + lapic_timer_frequency = divided_apic_freq * 16; + apic_write(APIC_TMICT, 0); +} + +static unsigned long jailhouse_calibrate_cpu(void) +{ + u64 tsc1, tsc2, pm1, pm2; + unsigned long flags; + + local_irq_save(flags); + + tsc1 = tsc_read_refs(, 0); + while ((get_cycles() - tsc1) < 5000) + cpu_relax(); + tsc2 = tsc_read_refs(, 0); + + local_irq_restore(flags); + + /* Check, whether the sampling succeeded (SMI?) */ + if (tsc1 == ULLONG_MAX || tsc2 == ULLONG_MAX) { + pr_err("Jailhouse: TSC calibration against PMTIMER failed\n"); + return 0; + } + + return tsc_calc_pmtimer_ref((tsc2 - tsc1) * 100, pm1, pm2); +} + +static unsigned long jailhouse_calibrate_tsc(void) +{ + return 0; +} + static unsigned int x2apic_get_apic_id(unsigned long id) { return id; @@ -61,6 +138,11 @@ static void __init jailhouse_init_platform(void) struct jailhouse_setup_data *data; unsigned int cpu; + x86_init.timers.timer_init = jailhouse_timer_init; + + x86_platform.calibrate_cpu = jailhouse_calibrate_cpu; + x86_platform.calibrate_tsc = jailhouse_calibrate_tsc; + data = early_memremap(pa_data, sizeof(*data)); if (data->header.type != SETUP_JAILHOUSE || diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 8ea117f8142e..a61000cc4f21 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -286,7 +286,7 @@ __setup("tsc=", tsc_setup); /* * Read TSC and the reference counters. Take care of SMI disturbance */ -static u64 tsc_read_refs(u64 *p, int hpet) +u64 tsc_read_refs(u64 *p, int hpet) { u64 t1, t2; int i; @@ -307,7 +307,7 @@ static u64 tsc_read_refs(u64 *p, int hpet) /* * Calculate the TSC frequency from HPET reference */ -static unsigned long calc_hpet_ref(u64 deltatsc, u64 hpet1, u64 hpet2) +static unsigned long tsc_calc_hpet_ref(u64 deltatsc, u64 hpet1, u64 hpet2) { u64 tmp; @@ -324,7 +324,7 @@ static unsigned long calc_hpet_ref(u64 deltatsc, u64 hpet1, u64 hpet2) /* * Calculate the TSC frequency from PMTimer reference */ -static unsigned long calc_pmtimer_ref(u64 deltatsc, u64 pm1, u64 pm2) +unsigned long tsc_calc_pmtimer_ref(u64 deltatsc, u64 pm1, u64 pm2) { u64 tmp; @@ -728,9 +728,9 @@ unsigned long native_calibrate_cpu(void) tsc2 = (tsc2 - tsc1) * 100LL; if (hpet) - tsc2 =
[PATCH 01/10] x86/apic: Install an empty physflat_init_apic_ldr
From: Jan KiszkaAs the comment already stated, there is no need for setting up LDR in physflat mode as it remains unused. flat_init_apic_ldr only served as a placeholder for a nop operation so far, causing no harm. That will change when running over the Jailhouse hypervisor. Here we must not touch LDR in a way that destroys the mapping originally set up by the Linux root cell. Jailhouse enforces this setting in order to efficiently validate any IPI requests sent by a cell. Avoid a needless clash caused by flat_init_apic_ldr by installing a true nop handler. Signed-off-by: Jan Kiszka --- arch/x86/kernel/apic/apic_flat_64.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/apic/apic_flat_64.c b/arch/x86/kernel/apic/apic_flat_64.c index aa85690e9b64..34bfdfe29a04 100644 --- a/arch/x86/kernel/apic/apic_flat_64.c +++ b/arch/x86/kernel/apic/apic_flat_64.c @@ -218,6 +218,11 @@ static int physflat_acpi_madt_oem_check(char *oem_id, char *oem_table_id) return 0; } +void physflat_init_apic_ldr(void) +{ + /* LDR is not used in physflat mode. */ +} + static void physflat_send_IPI_allbutself(int vector) { default_send_IPI_mask_allbutself_phys(cpu_online_mask, vector); @@ -251,8 +256,7 @@ static struct apic apic_physflat __ro_after_init = { .dest_logical = 0, .check_apicid_used = NULL, - /* not needed, but shouldn't hurt: */ - .init_apic_ldr = flat_init_apic_ldr, + .init_apic_ldr = physflat_init_apic_ldr, .ioapic_phys_id_map = NULL, .setup_apic_routing = NULL, -- 2.12.3
[PATCH 01/10] x86/apic: Install an empty physflat_init_apic_ldr
From: Jan Kiszka As the comment already stated, there is no need for setting up LDR in physflat mode as it remains unused. flat_init_apic_ldr only served as a placeholder for a nop operation so far, causing no harm. That will change when running over the Jailhouse hypervisor. Here we must not touch LDR in a way that destroys the mapping originally set up by the Linux root cell. Jailhouse enforces this setting in order to efficiently validate any IPI requests sent by a cell. Avoid a needless clash caused by flat_init_apic_ldr by installing a true nop handler. Signed-off-by: Jan Kiszka --- arch/x86/kernel/apic/apic_flat_64.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/apic/apic_flat_64.c b/arch/x86/kernel/apic/apic_flat_64.c index aa85690e9b64..34bfdfe29a04 100644 --- a/arch/x86/kernel/apic/apic_flat_64.c +++ b/arch/x86/kernel/apic/apic_flat_64.c @@ -218,6 +218,11 @@ static int physflat_acpi_madt_oem_check(char *oem_id, char *oem_table_id) return 0; } +void physflat_init_apic_ldr(void) +{ + /* LDR is not used in physflat mode. */ +} + static void physflat_send_IPI_allbutself(int vector) { default_send_IPI_mask_allbutself_phys(cpu_online_mask, vector); @@ -251,8 +256,7 @@ static struct apic apic_physflat __ro_after_init = { .dest_logical = 0, .check_apicid_used = NULL, - /* not needed, but shouldn't hurt: */ - .init_apic_ldr = flat_init_apic_ldr, + .init_apic_ldr = physflat_init_apic_ldr, .ioapic_phys_id_map = NULL, .setup_apic_routing = NULL, -- 2.12.3
[PATCH 03/10] x86: jailhouse: Enable APIC and SMP support
From: Jan KiszkaRegister the APIC which Jailhouse always exposes at 0xfee0 if in xAPIC mode or via MSRs as x2APIC. The latter is only available if it was already activated because there is no virtualization to switch its mode during runtime. Jailhouse requires the APIC to be operated in phys-flat mode. Ensure that this mode is selected by Linux. The available CPUs are taken from the setup data structure that the loader filled and registered with the kernel. Signed-off-by: Jan Kiszka --- arch/x86/kernel/apic/apic_flat_64.c | 4 +++- arch/x86/kernel/jailhouse.c | 34 ++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/apic/apic_flat_64.c b/arch/x86/kernel/apic/apic_flat_64.c index 34bfdfe29a04..56d22b4f9ffd 100644 --- a/arch/x86/kernel/apic/apic_flat_64.c +++ b/arch/x86/kernel/apic/apic_flat_64.c @@ -19,6 +19,7 @@ #include #include #include +#include #include @@ -235,7 +236,8 @@ static void physflat_send_IPI_all(int vector) static int physflat_probe(void) { - if (apic == _physflat || num_possible_cpus() > 8) + if (apic == _physflat || num_possible_cpus() > 8 || + jailhouse_paravirt()) return 1; return 0; diff --git a/arch/x86/kernel/jailhouse.c b/arch/x86/kernel/jailhouse.c index bc0f49a6172d..ce9416c70656 100644 --- a/arch/x86/kernel/jailhouse.c +++ b/arch/x86/kernel/jailhouse.c @@ -11,6 +11,7 @@ */ #include +#include #include #include #include @@ -48,10 +49,16 @@ static uint32_t __init jailhouse_detect(void) return jailhouse_cpuid_base(); } +static unsigned int x2apic_get_apic_id(unsigned long id) +{ +return id; +} + static void __init jailhouse_init_platform(void) { u64 pa_data = boot_params.hdr.setup_data; struct jailhouse_setup_data *data; + unsigned int cpu; data = early_memremap(pa_data, sizeof(*data)); @@ -59,6 +66,23 @@ static void __init jailhouse_init_platform(void) data->compatible_version > SETUP_REQUIRED_VERSION) panic("Jailhouse: Unsupported setup data structure"); +#ifdef CONFIG_X86_X2APIC + /* +* Register x2APIC handlers early. We need them when running +* register_lapic_address. +*/ + if (x2apic_enabled()) { + apic->read = native_apic_msr_read; + apic->write = native_apic_msr_write; + apic->get_apic_id = x2apic_get_apic_id; + } +#endif + register_lapic_address(0xfee0); + for (cpu = 0; cpu < data->num_cpus; cpu++) + generic_processor_info(data->cpu_ids[cpu], + boot_cpu_apic_version); + smp_found_config = 1; + early_memunmap(data, sizeof(*data)); } @@ -67,10 +91,20 @@ bool jailhouse_paravirt(void) return jailhouse_cpuid_base() != 0; } +static bool jailhouse_x2apic_available(void) +{ + /* +* The x2APIC is only available if the root cell enabled it. Jailhouse +* does not support switching between xAPIC and x2APIC. +*/ + return x2apic_enabled(); +} + const struct hypervisor_x86 x86_hyper_jailhouse __refconst = { .name = "Jailhouse", .detect = jailhouse_detect, .init = { .init_platform = jailhouse_init_platform, + .x2apic_available = jailhouse_x2apic_available, }, }; -- 2.12.3
[PATCH 03/10] x86: jailhouse: Enable APIC and SMP support
From: Jan Kiszka Register the APIC which Jailhouse always exposes at 0xfee0 if in xAPIC mode or via MSRs as x2APIC. The latter is only available if it was already activated because there is no virtualization to switch its mode during runtime. Jailhouse requires the APIC to be operated in phys-flat mode. Ensure that this mode is selected by Linux. The available CPUs are taken from the setup data structure that the loader filled and registered with the kernel. Signed-off-by: Jan Kiszka --- arch/x86/kernel/apic/apic_flat_64.c | 4 +++- arch/x86/kernel/jailhouse.c | 34 ++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/apic/apic_flat_64.c b/arch/x86/kernel/apic/apic_flat_64.c index 34bfdfe29a04..56d22b4f9ffd 100644 --- a/arch/x86/kernel/apic/apic_flat_64.c +++ b/arch/x86/kernel/apic/apic_flat_64.c @@ -19,6 +19,7 @@ #include #include #include +#include #include @@ -235,7 +236,8 @@ static void physflat_send_IPI_all(int vector) static int physflat_probe(void) { - if (apic == _physflat || num_possible_cpus() > 8) + if (apic == _physflat || num_possible_cpus() > 8 || + jailhouse_paravirt()) return 1; return 0; diff --git a/arch/x86/kernel/jailhouse.c b/arch/x86/kernel/jailhouse.c index bc0f49a6172d..ce9416c70656 100644 --- a/arch/x86/kernel/jailhouse.c +++ b/arch/x86/kernel/jailhouse.c @@ -11,6 +11,7 @@ */ #include +#include #include #include #include @@ -48,10 +49,16 @@ static uint32_t __init jailhouse_detect(void) return jailhouse_cpuid_base(); } +static unsigned int x2apic_get_apic_id(unsigned long id) +{ +return id; +} + static void __init jailhouse_init_platform(void) { u64 pa_data = boot_params.hdr.setup_data; struct jailhouse_setup_data *data; + unsigned int cpu; data = early_memremap(pa_data, sizeof(*data)); @@ -59,6 +66,23 @@ static void __init jailhouse_init_platform(void) data->compatible_version > SETUP_REQUIRED_VERSION) panic("Jailhouse: Unsupported setup data structure"); +#ifdef CONFIG_X86_X2APIC + /* +* Register x2APIC handlers early. We need them when running +* register_lapic_address. +*/ + if (x2apic_enabled()) { + apic->read = native_apic_msr_read; + apic->write = native_apic_msr_write; + apic->get_apic_id = x2apic_get_apic_id; + } +#endif + register_lapic_address(0xfee0); + for (cpu = 0; cpu < data->num_cpus; cpu++) + generic_processor_info(data->cpu_ids[cpu], + boot_cpu_apic_version); + smp_found_config = 1; + early_memunmap(data, sizeof(*data)); } @@ -67,10 +91,20 @@ bool jailhouse_paravirt(void) return jailhouse_cpuid_base() != 0; } +static bool jailhouse_x2apic_available(void) +{ + /* +* The x2APIC is only available if the root cell enabled it. Jailhouse +* does not support switching between xAPIC and x2APIC. +*/ + return x2apic_enabled(); +} + const struct hypervisor_x86 x86_hyper_jailhouse __refconst = { .name = "Jailhouse", .detect = jailhouse_detect, .init = { .init_platform = jailhouse_init_platform, + .x2apic_available = jailhouse_x2apic_available, }, }; -- 2.12.3
[PATCH V1 2/4] usb: serial: f81534: add auto RTS direction support
The F81532/534 had auto RTS direction support for RS485 mode. We'll read it from internal Flash with address 0x2f01~0x2f04 for 4 ports. There are 4 conditions below: 0: F81534_PORT_CONF_RS232. 1: F81534_PORT_CONF_RS485. 2: value error, default to F81534_PORT_CONF_RS232. 3: F81534_PORT_CONF_RS485_INVERT. F81532/534 Clock register (offset +08h) Bit0: UART Enable (always on) Bit2-1: Clock source selector 00: 1.846MHz. 01: 18.46MHz. 10: 24MHz. 11: 14.77MHz. Bit4: Auto direction(RTS) control (RTS pin Low when TX) Bit5: Invert direction(RTS) when Bit4 enabled (RTS pin high when TX) Signed-off-by: Ji-Ze Hong (Peter Hong)--- drivers/usb/serial/f81534.c | 54 +++-- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/drivers/usb/serial/f81534.c b/drivers/usb/serial/f81534.c index 76c676ef5f0d..b2d10309c335 100644 --- a/drivers/usb/serial/f81534.c +++ b/drivers/usb/serial/f81534.c @@ -102,11 +102,16 @@ #define F81534_DEFAULT_BAUD_RATE 9600 +#define F81534_PORT_CONF_RS232 0 +#define F81534_PORT_CONF_RS485 BIT(0) +#define F81534_PORT_CONF_RS485_INVERT (BIT(0) | BIT(1)) #define F81534_PORT_CONF_DISABLE_PORT BIT(3) #define F81534_PORT_CONF_NOT_EXIST_PORTBIT(7) #define F81534_PORT_UNAVAILABLE\ (F81534_PORT_CONF_DISABLE_PORT | F81534_PORT_CONF_NOT_EXIST_PORT) +#define F81534_UART_MODE_MASK (BIT(0) | BIT(1)) + #define F81534_1X_RXTRIGGER0xc3 #define F81534_8X_RXTRIGGER0xcf @@ -119,6 +124,8 @@ * 01: 18.46MHz. * 10: 24MHz. * 11: 14.77MHz. + * Bit4: Auto direction(RTS) control (RTS pin Low when TX) + * Bit5: Invert direction(RTS) when Bit4 enabled (RTS pin high when TX) */ #define F81534_CLK_1_846_MHZ BIT(0) @@ -126,6 +133,9 @@ #define F81534_CLK_24_MHZ (BIT(0) | BIT(2)) #define F81534_CLK_14_77_MHZ (BIT(0) | BIT(1) | BIT(2)) +#define F81534_CLK_RS485_MODE BIT(4) +#define F81534_CLK_RS485_INVERTBIT(5) + static const struct usb_device_id f81534_id_table[] = { { USB_DEVICE(FINTEK_VENDOR_ID_1, FINTEK_DEVICE_ID) }, { USB_DEVICE(FINTEK_VENDOR_ID_2, FINTEK_DEVICE_ID) }, @@ -485,16 +495,20 @@ static int f81534_set_port_config(struct usb_serial_port *port, struct tty_struct *tty, u32 baudrate, u32 old_baudrate, u8 lcr) { struct f81534_port_private *port_priv = usb_get_serial_port_data(port); + struct f81534_serial_private *serial_priv; u32 divisor; int status; int idx; u8 value; + u8 tmp; static u32 const baudrate_table[] = {115200, 921600, 1152000, 150}; static u8 const clock_table[] = {F81534_CLK_1_846_MHZ, F81534_CLK_14_77_MHZ, F81534_CLK_18_46_MHZ, F81534_CLK_24_MHZ}; + serial_priv = usb_get_serial_data(port->serial); + do { for (idx = 0; idx < ARRAY_SIZE(baudrate_table); ++idx) { if (baudrate <= baudrate_table[idx] && @@ -520,8 +534,25 @@ static int f81534_set_port_config(struct usb_serial_port *port, } while (1); port_priv->baud_base = baudrate_table[idx]; - status = f81534_set_port_register(port, F81534_CLOCK_REG, - clock_table[idx]); + tmp = serial_priv->conf_data[port_priv->phy_num]; + + switch (tmp & F81534_UART_MODE_MASK) { + case F81534_PORT_CONF_RS485_INVERT: + value = F81534_CLK_RS485_MODE | F81534_CLK_RS485_INVERT; + break; + case F81534_PORT_CONF_RS485: + value = F81534_CLK_RS485_MODE; + break; + + default: + /* fall through, default RS232 Mode */ + case F81534_PORT_CONF_RS232: + value = 0; + break; + } + + value |= clock_table[idx]; + status = f81534_set_port_register(port, F81534_CLOCK_REG, value); if (status) { dev_err(>dev, "CLOCK_REG setting failed\n"); return status; @@ -1270,9 +1301,12 @@ static void f81534_lsr_worker(struct work_struct *work) static int f81534_port_probe(struct usb_serial_port *port) { + struct f81534_serial_private *serial_priv; struct f81534_port_private *port_priv; int ret; + u8 value; + serial_priv = usb_get_serial_data(port->serial); port_priv = devm_kzalloc(>dev, sizeof(*port_priv), GFP_KERNEL); if (!port_priv) return -ENOMEM; @@ -1304,6 +1338,22 @@ static int f81534_port_probe(struct usb_serial_port *port) if (ret) return ret; + value =
[PATCH 10/10] x86: jailhouse: Initialize PCI support
From: Jan KiszkaWith this change, PCI devices can be detected and used inside a non-root cell. Signed-off-by: Jan Kiszka --- arch/x86/kernel/jailhouse.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/arch/x86/kernel/jailhouse.c b/arch/x86/kernel/jailhouse.c index 05459ea0ecc7..e573ea8b0a5f 100644 --- a/arch/x86/kernel/jailhouse.c +++ b/arch/x86/kernel/jailhouse.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -211,6 +212,15 @@ static void __init jailhouse_init_platform(void) early_memunmap(data, sizeof(*data)); + pci_probe = 0; + pci_direct_init(1); + + /* +* There are no bridges on the virtual PCI root bus under Jailhouse, +* thus no other way to discover all devices than a full scan. +*/ + pcibios_last_bus = 0xff; + /* * Avoid that the kernel complains about missing ACPI tables - there * are none in a non-root cell. -- 2.12.3
[PATCH V1 2/4] usb: serial: f81534: add auto RTS direction support
The F81532/534 had auto RTS direction support for RS485 mode. We'll read it from internal Flash with address 0x2f01~0x2f04 for 4 ports. There are 4 conditions below: 0: F81534_PORT_CONF_RS232. 1: F81534_PORT_CONF_RS485. 2: value error, default to F81534_PORT_CONF_RS232. 3: F81534_PORT_CONF_RS485_INVERT. F81532/534 Clock register (offset +08h) Bit0: UART Enable (always on) Bit2-1: Clock source selector 00: 1.846MHz. 01: 18.46MHz. 10: 24MHz. 11: 14.77MHz. Bit4: Auto direction(RTS) control (RTS pin Low when TX) Bit5: Invert direction(RTS) when Bit4 enabled (RTS pin high when TX) Signed-off-by: Ji-Ze Hong (Peter Hong) --- drivers/usb/serial/f81534.c | 54 +++-- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/drivers/usb/serial/f81534.c b/drivers/usb/serial/f81534.c index 76c676ef5f0d..b2d10309c335 100644 --- a/drivers/usb/serial/f81534.c +++ b/drivers/usb/serial/f81534.c @@ -102,11 +102,16 @@ #define F81534_DEFAULT_BAUD_RATE 9600 +#define F81534_PORT_CONF_RS232 0 +#define F81534_PORT_CONF_RS485 BIT(0) +#define F81534_PORT_CONF_RS485_INVERT (BIT(0) | BIT(1)) #define F81534_PORT_CONF_DISABLE_PORT BIT(3) #define F81534_PORT_CONF_NOT_EXIST_PORTBIT(7) #define F81534_PORT_UNAVAILABLE\ (F81534_PORT_CONF_DISABLE_PORT | F81534_PORT_CONF_NOT_EXIST_PORT) +#define F81534_UART_MODE_MASK (BIT(0) | BIT(1)) + #define F81534_1X_RXTRIGGER0xc3 #define F81534_8X_RXTRIGGER0xcf @@ -119,6 +124,8 @@ * 01: 18.46MHz. * 10: 24MHz. * 11: 14.77MHz. + * Bit4: Auto direction(RTS) control (RTS pin Low when TX) + * Bit5: Invert direction(RTS) when Bit4 enabled (RTS pin high when TX) */ #define F81534_CLK_1_846_MHZ BIT(0) @@ -126,6 +133,9 @@ #define F81534_CLK_24_MHZ (BIT(0) | BIT(2)) #define F81534_CLK_14_77_MHZ (BIT(0) | BIT(1) | BIT(2)) +#define F81534_CLK_RS485_MODE BIT(4) +#define F81534_CLK_RS485_INVERTBIT(5) + static const struct usb_device_id f81534_id_table[] = { { USB_DEVICE(FINTEK_VENDOR_ID_1, FINTEK_DEVICE_ID) }, { USB_DEVICE(FINTEK_VENDOR_ID_2, FINTEK_DEVICE_ID) }, @@ -485,16 +495,20 @@ static int f81534_set_port_config(struct usb_serial_port *port, struct tty_struct *tty, u32 baudrate, u32 old_baudrate, u8 lcr) { struct f81534_port_private *port_priv = usb_get_serial_port_data(port); + struct f81534_serial_private *serial_priv; u32 divisor; int status; int idx; u8 value; + u8 tmp; static u32 const baudrate_table[] = {115200, 921600, 1152000, 150}; static u8 const clock_table[] = {F81534_CLK_1_846_MHZ, F81534_CLK_14_77_MHZ, F81534_CLK_18_46_MHZ, F81534_CLK_24_MHZ}; + serial_priv = usb_get_serial_data(port->serial); + do { for (idx = 0; idx < ARRAY_SIZE(baudrate_table); ++idx) { if (baudrate <= baudrate_table[idx] && @@ -520,8 +534,25 @@ static int f81534_set_port_config(struct usb_serial_port *port, } while (1); port_priv->baud_base = baudrate_table[idx]; - status = f81534_set_port_register(port, F81534_CLOCK_REG, - clock_table[idx]); + tmp = serial_priv->conf_data[port_priv->phy_num]; + + switch (tmp & F81534_UART_MODE_MASK) { + case F81534_PORT_CONF_RS485_INVERT: + value = F81534_CLK_RS485_MODE | F81534_CLK_RS485_INVERT; + break; + case F81534_PORT_CONF_RS485: + value = F81534_CLK_RS485_MODE; + break; + + default: + /* fall through, default RS232 Mode */ + case F81534_PORT_CONF_RS232: + value = 0; + break; + } + + value |= clock_table[idx]; + status = f81534_set_port_register(port, F81534_CLOCK_REG, value); if (status) { dev_err(>dev, "CLOCK_REG setting failed\n"); return status; @@ -1270,9 +1301,12 @@ static void f81534_lsr_worker(struct work_struct *work) static int f81534_port_probe(struct usb_serial_port *port) { + struct f81534_serial_private *serial_priv; struct f81534_port_private *port_priv; int ret; + u8 value; + serial_priv = usb_get_serial_data(port->serial); port_priv = devm_kzalloc(>dev, sizeof(*port_priv), GFP_KERNEL); if (!port_priv) return -ENOMEM; @@ -1304,6 +1338,22 @@ static int f81534_port_probe(struct usb_serial_port *port) if (ret) return ret; + value = serial_priv->conf_data[port_priv->phy_num]; +
[PATCH 10/10] x86: jailhouse: Initialize PCI support
From: Jan Kiszka With this change, PCI devices can be detected and used inside a non-root cell. Signed-off-by: Jan Kiszka --- arch/x86/kernel/jailhouse.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/arch/x86/kernel/jailhouse.c b/arch/x86/kernel/jailhouse.c index 05459ea0ecc7..e573ea8b0a5f 100644 --- a/arch/x86/kernel/jailhouse.c +++ b/arch/x86/kernel/jailhouse.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -211,6 +212,15 @@ static void __init jailhouse_init_platform(void) early_memunmap(data, sizeof(*data)); + pci_probe = 0; + pci_direct_init(1); + + /* +* There are no bridges on the virtual PCI root bus under Jailhouse, +* thus no other way to discover all devices than a full scan. +*/ + pcibios_last_bus = 0xff; + /* * Avoid that the kernel complains about missing ACPI tables - there * are none in a non-root cell. -- 2.12.3
[PATCH V1 4/4] usb: serial: f81534: add H/W disable port support
The F81532/534 can be disable port by manufacturer with following H/W design. 1: Connect DCD/DSR/CTS/RI pin to ground. 2: Connect RX pin to ground. In driver, we'll implements some detect method likes following: 1: Read MSR. 2: Turn MCR LOOP bit on, off and read LSR after delay with 60ms. It'll contain BREAK status in LSR. Signed-off-by: Ji-Ze Hong (Peter Hong)--- drivers/usb/serial/f81534.c | 74 + 1 file changed, 74 insertions(+) diff --git a/drivers/usb/serial/f81534.c b/drivers/usb/serial/f81534.c index 30b966d71ae8..18bd2a478199 100644 --- a/drivers/usb/serial/f81534.c +++ b/drivers/usb/serial/f81534.c @@ -751,6 +751,74 @@ static int f81534_find_config_idx(struct usb_serial *serial, u8 *index) } /* + * The F81532/534 will not report serial port to USB serial subsystem when + * H/W DCD/DSR/CTS/RI/RX pin connected to ground. + * + * To detect RX pin status, we'll enable MCR interal loopback, disable it and + * delayed for 60ms. It connected to ground If LSR register report UART_LSR_BI. + */ +static int f81534_check_port_hw_disabled(struct usb_serial *serial, int phy) +{ + int status; + u8 old_mcr; + u8 msr; + u8 lsr; + u8 msr_mask; + + msr_mask = UART_MSR_DCD | UART_MSR_RI | UART_MSR_DSR | UART_MSR_CTS; + + status = f81534_get_register(serial, + F81534_MODEM_STATUS_REG + phy * 0x10, ); + if (status) + return status; + + if ((msr & msr_mask) != msr_mask) + return 0; + + status = f81534_set_register(serial, + F81534_FIFO_CONTROL_REG + phy * 0x10, + UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | + UART_FCR_CLEAR_XMIT); + if (status) + return status; + + status = f81534_get_register(serial, + F81534_MODEM_CONTROL_REG + phy * 0x10, + _mcr); + if (status) + return status; + + status = f81534_set_register(serial, + F81534_MODEM_CONTROL_REG + phy * 0x10, + UART_MCR_LOOP); + if (status) + return status; + + status = f81534_set_register(serial, + F81534_MODEM_CONTROL_REG + phy * 0x10, 0x0); + if (status) + return status; + + msleep(60); + + status = f81534_get_register(serial, + F81534_LINE_STATUS_REG + phy * 0x10, ); + if (status) + return status; + + status = f81534_set_register(serial, + F81534_MODEM_CONTROL_REG + phy * 0x10, + old_mcr); + if (status) + return status; + + if ((lsr & UART_LSR_BI) == UART_LSR_BI) + return -ENODEV; + + return 0; +} + +/* * We had 2 generation of F81532/534 IC. All has an internal storage. * * 1st is pure USB-to-TTL RS232 IC and designed for 4 ports only, no any @@ -832,6 +900,9 @@ static int f81534_calc_num_ports(struct usb_serial *serial, /* New style, find all possible ports */ for (i = 0; i < F81534_NUM_PORT; ++i) { + if (f81534_check_port_hw_disabled(serial, i)) + continue; + if (setting[i] & F81534_PORT_UNAVAILABLE) continue; @@ -1306,6 +1377,9 @@ static int f81534_attach(struct usb_serial *serial) /* Assign phy-to-logic mapping */ for (i = 0; i < F81534_NUM_PORT; ++i) { + if (f81534_check_port_hw_disabled(serial, i)) + serial_priv->conf_data[i] |= F81534_PORT_UNAVAILABLE; + if (serial_priv->conf_data[i] & F81534_PORT_UNAVAILABLE) continue; -- 2.7.4
[PATCH V1 4/4] usb: serial: f81534: add H/W disable port support
The F81532/534 can be disable port by manufacturer with following H/W design. 1: Connect DCD/DSR/CTS/RI pin to ground. 2: Connect RX pin to ground. In driver, we'll implements some detect method likes following: 1: Read MSR. 2: Turn MCR LOOP bit on, off and read LSR after delay with 60ms. It'll contain BREAK status in LSR. Signed-off-by: Ji-Ze Hong (Peter Hong) --- drivers/usb/serial/f81534.c | 74 + 1 file changed, 74 insertions(+) diff --git a/drivers/usb/serial/f81534.c b/drivers/usb/serial/f81534.c index 30b966d71ae8..18bd2a478199 100644 --- a/drivers/usb/serial/f81534.c +++ b/drivers/usb/serial/f81534.c @@ -751,6 +751,74 @@ static int f81534_find_config_idx(struct usb_serial *serial, u8 *index) } /* + * The F81532/534 will not report serial port to USB serial subsystem when + * H/W DCD/DSR/CTS/RI/RX pin connected to ground. + * + * To detect RX pin status, we'll enable MCR interal loopback, disable it and + * delayed for 60ms. It connected to ground If LSR register report UART_LSR_BI. + */ +static int f81534_check_port_hw_disabled(struct usb_serial *serial, int phy) +{ + int status; + u8 old_mcr; + u8 msr; + u8 lsr; + u8 msr_mask; + + msr_mask = UART_MSR_DCD | UART_MSR_RI | UART_MSR_DSR | UART_MSR_CTS; + + status = f81534_get_register(serial, + F81534_MODEM_STATUS_REG + phy * 0x10, ); + if (status) + return status; + + if ((msr & msr_mask) != msr_mask) + return 0; + + status = f81534_set_register(serial, + F81534_FIFO_CONTROL_REG + phy * 0x10, + UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | + UART_FCR_CLEAR_XMIT); + if (status) + return status; + + status = f81534_get_register(serial, + F81534_MODEM_CONTROL_REG + phy * 0x10, + _mcr); + if (status) + return status; + + status = f81534_set_register(serial, + F81534_MODEM_CONTROL_REG + phy * 0x10, + UART_MCR_LOOP); + if (status) + return status; + + status = f81534_set_register(serial, + F81534_MODEM_CONTROL_REG + phy * 0x10, 0x0); + if (status) + return status; + + msleep(60); + + status = f81534_get_register(serial, + F81534_LINE_STATUS_REG + phy * 0x10, ); + if (status) + return status; + + status = f81534_set_register(serial, + F81534_MODEM_CONTROL_REG + phy * 0x10, + old_mcr); + if (status) + return status; + + if ((lsr & UART_LSR_BI) == UART_LSR_BI) + return -ENODEV; + + return 0; +} + +/* * We had 2 generation of F81532/534 IC. All has an internal storage. * * 1st is pure USB-to-TTL RS232 IC and designed for 4 ports only, no any @@ -832,6 +900,9 @@ static int f81534_calc_num_ports(struct usb_serial *serial, /* New style, find all possible ports */ for (i = 0; i < F81534_NUM_PORT; ++i) { + if (f81534_check_port_hw_disabled(serial, i)) + continue; + if (setting[i] & F81534_PORT_UNAVAILABLE) continue; @@ -1306,6 +1377,9 @@ static int f81534_attach(struct usb_serial *serial) /* Assign phy-to-logic mapping */ for (i = 0; i < F81534_NUM_PORT; ++i) { + if (f81534_check_port_hw_disabled(serial, i)) + serial_priv->conf_data[i] |= F81534_PORT_UNAVAILABLE; + if (serial_priv->conf_data[i] & F81534_PORT_UNAVAILABLE) continue; -- 2.7.4
[PATCH V1 1/4] usb: serial: f81534: add high baud rate support
The F81532/534 had 4 clocksource 1.846/18.46/14.77/24MHz and baud rates can be up to 1.5Mbits with 24MHz. F81532/534 Clock register (offset +08h) Bit0: UART Enable (always on) Bit2-1: Clock source selector 00: 1.846MHz. 01: 18.46MHz. 10: 24MHz. 11: 14.77MHz. Signed-off-by: Ji-Ze Hong (Peter Hong)--- drivers/usb/serial/f81534.c | 84 - 1 file changed, 68 insertions(+), 16 deletions(-) diff --git a/drivers/usb/serial/f81534.c b/drivers/usb/serial/f81534.c index cb8214860192..76c676ef5f0d 100644 --- a/drivers/usb/serial/f81534.c +++ b/drivers/usb/serial/f81534.c @@ -45,6 +45,7 @@ #define F81534_MODEM_CONTROL_REG (0x04 + F81534_UART_BASE_ADDRESS) #define F81534_LINE_STATUS_REG (0x05 + F81534_UART_BASE_ADDRESS) #define F81534_MODEM_STATUS_REG(0x06 + F81534_UART_BASE_ADDRESS) +#define F81534_CLOCK_REG (0x08 + F81534_UART_BASE_ADDRESS) #define F81534_CONFIG1_REG (0x09 + F81534_UART_BASE_ADDRESS) #define F81534_DEF_CONF_ADDRESS_START 0x3000 @@ -61,7 +62,7 @@ /* Default URB timeout for USB operations */ #define F81534_USB_MAX_RETRY 10 -#define F81534_USB_TIMEOUT 1000 +#define F81534_USB_TIMEOUT 2000 #define F81534_SET_GET_REGISTER0xA0 #define F81534_NUM_PORT4 @@ -100,7 +101,6 @@ #define F81534_CMD_READ0x03 #define F81534_DEFAULT_BAUD_RATE 9600 -#define F81534_MAX_BAUDRATE115200 #define F81534_PORT_CONF_DISABLE_PORT BIT(3) #define F81534_PORT_CONF_NOT_EXIST_PORTBIT(7) @@ -110,6 +110,22 @@ #define F81534_1X_RXTRIGGER0xc3 #define F81534_8X_RXTRIGGER0xcf +/* + * F81532/534 Clock registers (offset +08h) + * + * Bit0: UART Enable (always on) + * Bit2-1: Clock source selector + * 00: 1.846MHz. + * 01: 18.46MHz. + * 10: 24MHz. + * 11: 14.77MHz. + */ + +#define F81534_CLK_1_846_MHZ BIT(0) +#define F81534_CLK_18_46_MHZ (BIT(0) | BIT(1)) +#define F81534_CLK_24_MHZ (BIT(0) | BIT(2)) +#define F81534_CLK_14_77_MHZ (BIT(0) | BIT(1) | BIT(2)) + static const struct usb_device_id f81534_id_table[] = { { USB_DEVICE(FINTEK_VENDOR_ID_1, FINTEK_DEVICE_ID) }, { USB_DEVICE(FINTEK_VENDOR_ID_2, FINTEK_DEVICE_ID) }, @@ -133,6 +149,7 @@ struct f81534_port_private { struct usb_serial_port *port; unsigned long tx_empty; spinlock_t msr_lock; + u32 baud_base; u8 shadow_mcr; u8 shadow_lcr; u8 shadow_msr; @@ -464,13 +481,51 @@ static u32 f81534_calc_baud_divisor(u32 baudrate, u32 clockrate) return DIV_ROUND_CLOSEST(clockrate, baudrate); } -static int f81534_set_port_config(struct usb_serial_port *port, u32 baudrate, - u8 lcr) +static int f81534_set_port_config(struct usb_serial_port *port, + struct tty_struct *tty, u32 baudrate, u32 old_baudrate, u8 lcr) { struct f81534_port_private *port_priv = usb_get_serial_port_data(port); u32 divisor; int status; + int idx; u8 value; + static u32 const baudrate_table[] = {115200, 921600, 1152000, + 150}; + static u8 const clock_table[] = {F81534_CLK_1_846_MHZ, + F81534_CLK_14_77_MHZ, F81534_CLK_18_46_MHZ, + F81534_CLK_24_MHZ}; + + do { + for (idx = 0; idx < ARRAY_SIZE(baudrate_table); ++idx) { + if (baudrate <= baudrate_table[idx] && + baudrate_table[idx] % baudrate == 0) + break; + } + + /* Found acceptable baud rate */ + if (idx != ARRAY_SIZE(baudrate_table)) + break; + + if (baudrate == old_baudrate && + old_baudrate != F81534_DEFAULT_BAUD_RATE) + old_baudrate = F81534_DEFAULT_BAUD_RATE; + + dev_warn(>dev, + "baudrate: %d not supported, change to: %d\n", + baudrate, old_baudrate); + + baudrate = old_baudrate; + tty_encode_baud_rate(tty, baudrate, baudrate); + + } while (1); + + port_priv->baud_base = baudrate_table[idx]; + status = f81534_set_port_register(port, F81534_CLOCK_REG, + clock_table[idx]); + if (status) { + dev_err(>dev, "CLOCK_REG setting failed\n"); + return status; + } if (baudrate <= 1200) value = F81534_1X_RXTRIGGER;/* 128 FIFO & TL: 1x */ @@ -486,7 +541,7 @@
[PATCH V1 1/4] usb: serial: f81534: add high baud rate support
The F81532/534 had 4 clocksource 1.846/18.46/14.77/24MHz and baud rates can be up to 1.5Mbits with 24MHz. F81532/534 Clock register (offset +08h) Bit0: UART Enable (always on) Bit2-1: Clock source selector 00: 1.846MHz. 01: 18.46MHz. 10: 24MHz. 11: 14.77MHz. Signed-off-by: Ji-Ze Hong (Peter Hong) --- drivers/usb/serial/f81534.c | 84 - 1 file changed, 68 insertions(+), 16 deletions(-) diff --git a/drivers/usb/serial/f81534.c b/drivers/usb/serial/f81534.c index cb8214860192..76c676ef5f0d 100644 --- a/drivers/usb/serial/f81534.c +++ b/drivers/usb/serial/f81534.c @@ -45,6 +45,7 @@ #define F81534_MODEM_CONTROL_REG (0x04 + F81534_UART_BASE_ADDRESS) #define F81534_LINE_STATUS_REG (0x05 + F81534_UART_BASE_ADDRESS) #define F81534_MODEM_STATUS_REG(0x06 + F81534_UART_BASE_ADDRESS) +#define F81534_CLOCK_REG (0x08 + F81534_UART_BASE_ADDRESS) #define F81534_CONFIG1_REG (0x09 + F81534_UART_BASE_ADDRESS) #define F81534_DEF_CONF_ADDRESS_START 0x3000 @@ -61,7 +62,7 @@ /* Default URB timeout for USB operations */ #define F81534_USB_MAX_RETRY 10 -#define F81534_USB_TIMEOUT 1000 +#define F81534_USB_TIMEOUT 2000 #define F81534_SET_GET_REGISTER0xA0 #define F81534_NUM_PORT4 @@ -100,7 +101,6 @@ #define F81534_CMD_READ0x03 #define F81534_DEFAULT_BAUD_RATE 9600 -#define F81534_MAX_BAUDRATE115200 #define F81534_PORT_CONF_DISABLE_PORT BIT(3) #define F81534_PORT_CONF_NOT_EXIST_PORTBIT(7) @@ -110,6 +110,22 @@ #define F81534_1X_RXTRIGGER0xc3 #define F81534_8X_RXTRIGGER0xcf +/* + * F81532/534 Clock registers (offset +08h) + * + * Bit0: UART Enable (always on) + * Bit2-1: Clock source selector + * 00: 1.846MHz. + * 01: 18.46MHz. + * 10: 24MHz. + * 11: 14.77MHz. + */ + +#define F81534_CLK_1_846_MHZ BIT(0) +#define F81534_CLK_18_46_MHZ (BIT(0) | BIT(1)) +#define F81534_CLK_24_MHZ (BIT(0) | BIT(2)) +#define F81534_CLK_14_77_MHZ (BIT(0) | BIT(1) | BIT(2)) + static const struct usb_device_id f81534_id_table[] = { { USB_DEVICE(FINTEK_VENDOR_ID_1, FINTEK_DEVICE_ID) }, { USB_DEVICE(FINTEK_VENDOR_ID_2, FINTEK_DEVICE_ID) }, @@ -133,6 +149,7 @@ struct f81534_port_private { struct usb_serial_port *port; unsigned long tx_empty; spinlock_t msr_lock; + u32 baud_base; u8 shadow_mcr; u8 shadow_lcr; u8 shadow_msr; @@ -464,13 +481,51 @@ static u32 f81534_calc_baud_divisor(u32 baudrate, u32 clockrate) return DIV_ROUND_CLOSEST(clockrate, baudrate); } -static int f81534_set_port_config(struct usb_serial_port *port, u32 baudrate, - u8 lcr) +static int f81534_set_port_config(struct usb_serial_port *port, + struct tty_struct *tty, u32 baudrate, u32 old_baudrate, u8 lcr) { struct f81534_port_private *port_priv = usb_get_serial_port_data(port); u32 divisor; int status; + int idx; u8 value; + static u32 const baudrate_table[] = {115200, 921600, 1152000, + 150}; + static u8 const clock_table[] = {F81534_CLK_1_846_MHZ, + F81534_CLK_14_77_MHZ, F81534_CLK_18_46_MHZ, + F81534_CLK_24_MHZ}; + + do { + for (idx = 0; idx < ARRAY_SIZE(baudrate_table); ++idx) { + if (baudrate <= baudrate_table[idx] && + baudrate_table[idx] % baudrate == 0) + break; + } + + /* Found acceptable baud rate */ + if (idx != ARRAY_SIZE(baudrate_table)) + break; + + if (baudrate == old_baudrate && + old_baudrate != F81534_DEFAULT_BAUD_RATE) + old_baudrate = F81534_DEFAULT_BAUD_RATE; + + dev_warn(>dev, + "baudrate: %d not supported, change to: %d\n", + baudrate, old_baudrate); + + baudrate = old_baudrate; + tty_encode_baud_rate(tty, baudrate, baudrate); + + } while (1); + + port_priv->baud_base = baudrate_table[idx]; + status = f81534_set_port_register(port, F81534_CLOCK_REG, + clock_table[idx]); + if (status) { + dev_err(>dev, "CLOCK_REG setting failed\n"); + return status; + } if (baudrate <= 1200) value = F81534_1X_RXTRIGGER;/* 128 FIFO & TL: 1x */ @@ -486,7 +541,7 @@ static int
[PATCH V1 3/4] usb: serial: f81534: add output pin control
The F81532/534 had 3 output pin (M0/SD, M1, M2) with open-drain mode to control transceiver. We'll read it from internal Flash with address 0x2f05~0x2f08 for 4 ports. The value is range from 0 to 7. The M0/SD is MSB of this value. For a examples, If read value is 6, we'll write M0/SD, M1, M2 as 1, 1, 0. Register mapping for output value: Port 0: M2: 0x2ae8 bit7, M1: 0x2a90 bit5, M0/SD: 0x2a90 bit4 Port 1: M2: 0x2ae8 bit6, M1: 0x2ae8 bit0, M0/SD: 0x2ae8 bit3 Port 2: M2: 0x2a90 bit0, M1: 0x2ae8 bit2, M0/SD: 0x2a80 bit6 Port 3: M2: 0x2a90 bit3, M1: 0x2a90 bit2, M0/SD: 0x2a90 bit1 Signed-off-by: Ji-Ze Hong (Peter Hong)--- drivers/usb/serial/f81534.c | 67 - 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/drivers/usb/serial/f81534.c b/drivers/usb/serial/f81534.c index b2d10309c335..30b966d71ae8 100644 --- a/drivers/usb/serial/f81534.c +++ b/drivers/usb/serial/f81534.c @@ -56,6 +56,7 @@ #define F81534_CUSTOM_NO_CUSTOM_DATA 0xff #define F81534_CUSTOM_VALID_TOKEN 0xf0 #define F81534_CONF_OFFSET 1 +#define F81534_CONF_GPIO_OFFSET4 #define F81534_MAX_DATA_BLOCK 64 #define F81534_MAX_BUS_RETRY 20 @@ -166,6 +167,23 @@ struct f81534_port_private { u8 phy_num; }; +struct f81534_pin_data { + const u16 reg_addr; + const u16 reg_mask; +}; + +struct f81534_port_out_pin { + struct f81534_pin_data pin[3]; +}; + +/* Pin output value for M2/M1/M0(SD) */ +static const struct f81534_port_out_pin f81534_port_out_pins[] = { +{{{0x2ae8, BIT(7)}, {0x2a90, BIT(5)}, {0x2a90, BIT(4) } } }, +{{{0x2ae8, BIT(6)}, {0x2ae8, BIT(0)}, {0x2ae8, BIT(3) } } }, +{{{0x2a90, BIT(0)}, {0x2ae8, BIT(2)}, {0x2a80, BIT(6) } } }, +{{{0x2a90, BIT(3)}, {0x2a90, BIT(2)}, {0x2a90, BIT(1) } } }, +}; + static int f81534_logic_to_phy_port(struct usb_serial *serial, struct usb_serial_port *port) { @@ -271,6 +289,22 @@ static int f81534_get_register(struct usb_serial *serial, u16 reg, u8 *data) return status; } +static int f81534_set_mask_register(struct usb_serial *serial, u16 reg, + u8 mask, u8 data) +{ + int status; + u8 tmp; + + status = f81534_get_register(serial, reg, ); + if (status) + return status; + + tmp &= ~mask; + tmp |= (mask & data); + + return f81534_set_register(serial, reg, tmp); +} + static int f81534_set_port_register(struct usb_serial_port *port, u16 reg, u8 data) { @@ -1299,6 +1333,37 @@ static void f81534_lsr_worker(struct work_struct *work) dev_warn(>dev, "read LSR failed: %d\n", status); } +static int f81534_set_port_output_pin(struct usb_serial_port *port) +{ + struct f81534_serial_private *serial_priv; + struct f81534_port_private *port_priv; + struct usb_serial *serial; + const struct f81534_port_out_pin *pins; + int status; + int i; + u8 value; + u8 idx; + + serial = port->serial; + serial_priv = usb_get_serial_data(serial); + port_priv = usb_get_serial_port_data(port); + + idx = F81534_CONF_GPIO_OFFSET + port_priv->phy_num; + value = serial_priv->conf_data[idx]; + pins = _port_out_pins[port_priv->phy_num]; + + for (i = 0; i < ARRAY_SIZE(pins->pin); ++i) { + status = f81534_set_mask_register(serial, + pins->pin[i].reg_addr, pins->pin[i].reg_mask, + value & BIT(i) ? pins->pin[i].reg_mask : 0); + if (status) + return status; + } + + dev_info(>dev, "Output pin (M0/M1/M2): %d\n", value); + return 0; +} + static int f81534_port_probe(struct usb_serial_port *port) { struct f81534_serial_private *serial_priv; @@ -1354,7 +1419,7 @@ static int f81534_port_probe(struct usb_serial_port *port) break; } - return 0; + return f81534_set_port_output_pin(port); } static int f81534_port_remove(struct usb_serial_port *port) -- 2.7.4
[PATCH V1 3/4] usb: serial: f81534: add output pin control
The F81532/534 had 3 output pin (M0/SD, M1, M2) with open-drain mode to control transceiver. We'll read it from internal Flash with address 0x2f05~0x2f08 for 4 ports. The value is range from 0 to 7. The M0/SD is MSB of this value. For a examples, If read value is 6, we'll write M0/SD, M1, M2 as 1, 1, 0. Register mapping for output value: Port 0: M2: 0x2ae8 bit7, M1: 0x2a90 bit5, M0/SD: 0x2a90 bit4 Port 1: M2: 0x2ae8 bit6, M1: 0x2ae8 bit0, M0/SD: 0x2ae8 bit3 Port 2: M2: 0x2a90 bit0, M1: 0x2ae8 bit2, M0/SD: 0x2a80 bit6 Port 3: M2: 0x2a90 bit3, M1: 0x2a90 bit2, M0/SD: 0x2a90 bit1 Signed-off-by: Ji-Ze Hong (Peter Hong) --- drivers/usb/serial/f81534.c | 67 - 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/drivers/usb/serial/f81534.c b/drivers/usb/serial/f81534.c index b2d10309c335..30b966d71ae8 100644 --- a/drivers/usb/serial/f81534.c +++ b/drivers/usb/serial/f81534.c @@ -56,6 +56,7 @@ #define F81534_CUSTOM_NO_CUSTOM_DATA 0xff #define F81534_CUSTOM_VALID_TOKEN 0xf0 #define F81534_CONF_OFFSET 1 +#define F81534_CONF_GPIO_OFFSET4 #define F81534_MAX_DATA_BLOCK 64 #define F81534_MAX_BUS_RETRY 20 @@ -166,6 +167,23 @@ struct f81534_port_private { u8 phy_num; }; +struct f81534_pin_data { + const u16 reg_addr; + const u16 reg_mask; +}; + +struct f81534_port_out_pin { + struct f81534_pin_data pin[3]; +}; + +/* Pin output value for M2/M1/M0(SD) */ +static const struct f81534_port_out_pin f81534_port_out_pins[] = { +{{{0x2ae8, BIT(7)}, {0x2a90, BIT(5)}, {0x2a90, BIT(4) } } }, +{{{0x2ae8, BIT(6)}, {0x2ae8, BIT(0)}, {0x2ae8, BIT(3) } } }, +{{{0x2a90, BIT(0)}, {0x2ae8, BIT(2)}, {0x2a80, BIT(6) } } }, +{{{0x2a90, BIT(3)}, {0x2a90, BIT(2)}, {0x2a90, BIT(1) } } }, +}; + static int f81534_logic_to_phy_port(struct usb_serial *serial, struct usb_serial_port *port) { @@ -271,6 +289,22 @@ static int f81534_get_register(struct usb_serial *serial, u16 reg, u8 *data) return status; } +static int f81534_set_mask_register(struct usb_serial *serial, u16 reg, + u8 mask, u8 data) +{ + int status; + u8 tmp; + + status = f81534_get_register(serial, reg, ); + if (status) + return status; + + tmp &= ~mask; + tmp |= (mask & data); + + return f81534_set_register(serial, reg, tmp); +} + static int f81534_set_port_register(struct usb_serial_port *port, u16 reg, u8 data) { @@ -1299,6 +1333,37 @@ static void f81534_lsr_worker(struct work_struct *work) dev_warn(>dev, "read LSR failed: %d\n", status); } +static int f81534_set_port_output_pin(struct usb_serial_port *port) +{ + struct f81534_serial_private *serial_priv; + struct f81534_port_private *port_priv; + struct usb_serial *serial; + const struct f81534_port_out_pin *pins; + int status; + int i; + u8 value; + u8 idx; + + serial = port->serial; + serial_priv = usb_get_serial_data(serial); + port_priv = usb_get_serial_port_data(port); + + idx = F81534_CONF_GPIO_OFFSET + port_priv->phy_num; + value = serial_priv->conf_data[idx]; + pins = _port_out_pins[port_priv->phy_num]; + + for (i = 0; i < ARRAY_SIZE(pins->pin); ++i) { + status = f81534_set_mask_register(serial, + pins->pin[i].reg_addr, pins->pin[i].reg_mask, + value & BIT(i) ? pins->pin[i].reg_mask : 0); + if (status) + return status; + } + + dev_info(>dev, "Output pin (M0/M1/M2): %d\n", value); + return 0; +} + static int f81534_port_probe(struct usb_serial_port *port) { struct f81534_serial_private *serial_priv; @@ -1354,7 +1419,7 @@ static int f81534_port_probe(struct usb_serial_port *port) break; } - return 0; + return f81534_set_port_output_pin(port); } static int f81534_port_remove(struct usb_serial_port *port) -- 2.7.4
Re: [GIT PULL] usercopy whitelisting for v4.15-rc1
On Sun, Nov 12, 2017 at 11:29 PM, Kees Cookwrote: > Please pull these hardened usercopy whitelisting changes for v4.15-rc1. > This significantly narrows the areas of memory that can be copied to/from > userspace in the face of usercopy bugs. Just wanted to make sure this pull request was still on your radar. Let me know if you want me to do a full resend. Thanks! -Kees > The following changes since commit 9e66317d3c92ddaab330c125dfe9d06eee268aff: > > Linux 4.14-rc3 (2017-10-01 14:54:54 -0700) > > are available in the git repository at: > > https://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git > tags/usercopy-v4.15-rc1 > > for you to fetch changes up to 3889a28c449c01cebe166e413a58742002c2352b: > > lkdtm: Update usercopy tests for whitelisting (2017-11-08 15:40:04 -0800) > > > Currently, hardened usercopy performs dynamic bounds checking on slab > cache objects. This is good, but still leaves a lot of kernel memory > available to be copied to/from userspace in the face of bugs. To further > restrict what memory is available for copying, this creates a way to > whitelist specific areas of a given slab cache object for copying to/from > userspace, allowing much finer granularity of access control. Slab caches > that are never exposed to userspace can declare no whitelist for their > objects, thereby keeping them unavailable to userspace via dynamic copy > operations. (Note, an implicit form of whitelisting is the use of constant > sizes in usercopy operations and get_user()/put_user(); these bypass > hardened usercopy checks since these sizes cannot change at runtime.) > > > David Windsor (23): > usercopy: Prepare for usercopy whitelisting > usercopy: Enforce slab cache usercopy region boundaries > usercopy: Mark kmalloc caches as usercopy caches > dcache: Define usercopy region in dentry_cache slab cache > vfs: Define usercopy region in names_cache slab caches > vfs: Copy struct mount.mnt_id to userspace using put_user() > ext4: Define usercopy region in ext4_inode_cache slab cache > ext2: Define usercopy region in ext2_inode_cache slab cache > jfs: Define usercopy region in jfs_ip slab cache > befs: Define usercopy region in befs_inode_cache slab cache > exofs: Define usercopy region in exofs_inode_cache slab cache > orangefs: Define usercopy region in orangefs_inode_cache slab cache > ufs: Define usercopy region in ufs_inode_cache slab cache > vxfs: Define usercopy region in vxfs_inode slab cache > cifs: Define usercopy region in cifs_request slab cache > scsi: Define usercopy region in scsi_sense_cache slab cache > net: Define usercopy region in struct proto slab cache > ip: Define usercopy region in IP proto slab cache > caif: Define usercopy region in caif proto slab cache > sctp: Define usercopy region in SCTP proto slab cache > sctp: Copy struct sctp_sock.autoclose to userspace using put_user() > fork: Define usercopy region in mm_struct slab caches > fork: Define usercopy region in thread_stack slab caches > > Kees Cook (8): > net: Restrict unwhitelisted proto caches to size 0 > fork: Provide usercopy whitelisting for task_struct > x86: Implement thread_struct whitelist for hardened usercopy > arm64: Implement thread_struct whitelist for hardened usercopy > arm: Implement thread_struct whitelist for hardened usercopy > usercopy: Allow for temporary fallback for non-whitelisted usercopy > usercopy: Restrict non-usercopy caches to size 0 > lkdtm: Update usercopy tests for whitelisting > > Paolo Bonzini (2): > kvm: whitelist struct kvm_vcpu_arch > kvm: x86: fix KVM_XEN_HVM_CONFIG ioctl > > arch/Kconfig | 11 + > arch/arm/Kconfig | 1 + > arch/arm/include/asm/processor.h | 7 +++ > arch/arm64/Kconfig | 1 + > arch/arm64/include/asm/processor.h | 8 > arch/x86/Kconfig | 1 + > arch/x86/include/asm/processor.h | 8 > arch/x86/kvm/x86.c | 7 +-- > drivers/misc/lkdtm.h | 4 +- > drivers/misc/lkdtm_core.c | 4 +- > drivers/misc/lkdtm_usercopy.c | 88 > +- > drivers/scsi/scsi_lib.c| 9 ++-- > fs/befs/linuxvfs.c | 14 +++--- > fs/cifs/cifsfs.c | 10 +++-- > fs/dcache.c| 9 ++-- > fs/exofs/super.c | 7 ++- > fs/ext2/super.c| 12 +++--- > fs/ext4/super.c| 12 +++--- > fs/fhandle.c | 3 +- > fs/freevxfs/vxfs_super.c | 8 +++- > fs/jfs/super.c | 8 ++-- > fs/orangefs/super.c
Re: [GIT PULL] usercopy whitelisting for v4.15-rc1
On Sun, Nov 12, 2017 at 11:29 PM, Kees Cook wrote: > Please pull these hardened usercopy whitelisting changes for v4.15-rc1. > This significantly narrows the areas of memory that can be copied to/from > userspace in the face of usercopy bugs. Just wanted to make sure this pull request was still on your radar. Let me know if you want me to do a full resend. Thanks! -Kees > The following changes since commit 9e66317d3c92ddaab330c125dfe9d06eee268aff: > > Linux 4.14-rc3 (2017-10-01 14:54:54 -0700) > > are available in the git repository at: > > https://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git > tags/usercopy-v4.15-rc1 > > for you to fetch changes up to 3889a28c449c01cebe166e413a58742002c2352b: > > lkdtm: Update usercopy tests for whitelisting (2017-11-08 15:40:04 -0800) > > > Currently, hardened usercopy performs dynamic bounds checking on slab > cache objects. This is good, but still leaves a lot of kernel memory > available to be copied to/from userspace in the face of bugs. To further > restrict what memory is available for copying, this creates a way to > whitelist specific areas of a given slab cache object for copying to/from > userspace, allowing much finer granularity of access control. Slab caches > that are never exposed to userspace can declare no whitelist for their > objects, thereby keeping them unavailable to userspace via dynamic copy > operations. (Note, an implicit form of whitelisting is the use of constant > sizes in usercopy operations and get_user()/put_user(); these bypass > hardened usercopy checks since these sizes cannot change at runtime.) > > > David Windsor (23): > usercopy: Prepare for usercopy whitelisting > usercopy: Enforce slab cache usercopy region boundaries > usercopy: Mark kmalloc caches as usercopy caches > dcache: Define usercopy region in dentry_cache slab cache > vfs: Define usercopy region in names_cache slab caches > vfs: Copy struct mount.mnt_id to userspace using put_user() > ext4: Define usercopy region in ext4_inode_cache slab cache > ext2: Define usercopy region in ext2_inode_cache slab cache > jfs: Define usercopy region in jfs_ip slab cache > befs: Define usercopy region in befs_inode_cache slab cache > exofs: Define usercopy region in exofs_inode_cache slab cache > orangefs: Define usercopy region in orangefs_inode_cache slab cache > ufs: Define usercopy region in ufs_inode_cache slab cache > vxfs: Define usercopy region in vxfs_inode slab cache > cifs: Define usercopy region in cifs_request slab cache > scsi: Define usercopy region in scsi_sense_cache slab cache > net: Define usercopy region in struct proto slab cache > ip: Define usercopy region in IP proto slab cache > caif: Define usercopy region in caif proto slab cache > sctp: Define usercopy region in SCTP proto slab cache > sctp: Copy struct sctp_sock.autoclose to userspace using put_user() > fork: Define usercopy region in mm_struct slab caches > fork: Define usercopy region in thread_stack slab caches > > Kees Cook (8): > net: Restrict unwhitelisted proto caches to size 0 > fork: Provide usercopy whitelisting for task_struct > x86: Implement thread_struct whitelist for hardened usercopy > arm64: Implement thread_struct whitelist for hardened usercopy > arm: Implement thread_struct whitelist for hardened usercopy > usercopy: Allow for temporary fallback for non-whitelisted usercopy > usercopy: Restrict non-usercopy caches to size 0 > lkdtm: Update usercopy tests for whitelisting > > Paolo Bonzini (2): > kvm: whitelist struct kvm_vcpu_arch > kvm: x86: fix KVM_XEN_HVM_CONFIG ioctl > > arch/Kconfig | 11 + > arch/arm/Kconfig | 1 + > arch/arm/include/asm/processor.h | 7 +++ > arch/arm64/Kconfig | 1 + > arch/arm64/include/asm/processor.h | 8 > arch/x86/Kconfig | 1 + > arch/x86/include/asm/processor.h | 8 > arch/x86/kvm/x86.c | 7 +-- > drivers/misc/lkdtm.h | 4 +- > drivers/misc/lkdtm_core.c | 4 +- > drivers/misc/lkdtm_usercopy.c | 88 > +- > drivers/scsi/scsi_lib.c| 9 ++-- > fs/befs/linuxvfs.c | 14 +++--- > fs/cifs/cifsfs.c | 10 +++-- > fs/dcache.c| 9 ++-- > fs/exofs/super.c | 7 ++- > fs/ext2/super.c| 12 +++--- > fs/ext4/super.c| 12 +++--- > fs/fhandle.c | 3 +- > fs/freevxfs/vxfs_super.c | 8 +++- > fs/jfs/super.c | 8 ++-- > fs/orangefs/super.c| 15 --- >
[PATCH 02/10] x86: jailhouse: Add infrastructure for running in non-root cell
From: Jan KiszkaThe Jailhouse hypervisor is able to statically partition a multicore system into multiple so-called cells. Linux is used as boot loader and continues to run in the root cell after Jailhouse is enabled. Linux can also run in non-root cells. Jailhouse does not emulate usual x86 devices. It also provides no complex ACPI but basic platform information that the boot loader forwards via setup data. This adds the infrastructure to detect when running in a non-root cell so that the platform can be configured as required in succeeding steps. Support is limited to x86-64 so far, primarily because no boot loader stub exists for i386 and, thus, we wouldn't be able to test the 32-bit path. Signed-off-by: Jan Kiszka --- arch/x86/Kconfig | 12 ++ arch/x86/include/asm/hypervisor.h | 1 + arch/x86/include/asm/jailhouse_para.h | 27 + arch/x86/kernel/Makefile | 2 + arch/x86/kernel/cpu/hypervisor.c | 4 ++ arch/x86/kernel/jailhouse.c | 76 +++ 6 files changed, 122 insertions(+) create mode 100644 arch/x86/include/asm/jailhouse_para.h create mode 100644 arch/x86/kernel/jailhouse.c diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index df3276d6bfe3..c5f4f4683b51 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -782,6 +782,18 @@ config KVM_DEBUG_FS Statistics are displayed in debugfs filesystem. Enabling this option may incur significant overhead. +config JAILHOUSE_GUEST + bool "Jailhouse non-root cell support" + depends on PARAVIRT && X86_64 + ---help--- + This option allows to run Linux as guest in a Jailhouse non-root + cell. You can leave this option disabled if you only want to start + Jailhouse and run Linux afterwards in the root cell. + + You likely also want to disable CONFIG_SUSPEND and CONFIG_SERIO to + avoid access to I/O resources that are usually not assigned to the + non-root cell. + config PARAVIRT_TIME_ACCOUNTING bool "Paravirtual steal time accounting" depends on PARAVIRT diff --git a/arch/x86/include/asm/hypervisor.h b/arch/x86/include/asm/hypervisor.h index 1b0a5abcd8ae..376085cb6244 100644 --- a/arch/x86/include/asm/hypervisor.h +++ b/arch/x86/include/asm/hypervisor.h @@ -37,6 +37,7 @@ enum x86_hypervisor_type { X86_HYPER_XEN_PV, X86_HYPER_XEN_HVM, X86_HYPER_KVM, + X86_HYPER_JAILHOUSE, }; struct hypervisor_x86 { diff --git a/arch/x86/include/asm/jailhouse_para.h b/arch/x86/include/asm/jailhouse_para.h new file mode 100644 index ..06a5f41d5451 --- /dev/null +++ b/arch/x86/include/asm/jailhouse_para.h @@ -0,0 +1,27 @@ +/* + * Jailhouse paravirt_ops implementation + * + * Copyright (c) Siemens AG, 2015-2017 + * + * Authors: + * Jan Kiszka + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + */ + +#ifndef _ASM_X86_JAILHOUSE_PARA_H +#define _ASM_X86_JAILHOUSE_PARA_H + +#include + +#ifdef CONFIG_JAILHOUSE_GUEST +bool jailhouse_paravirt(void); +#else +static inline bool jailhouse_paravirt(void) +{ + return false; +} +#endif + +#endif /* _ASM_X86_JAILHOUSE_PARA_H */ diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 81bb565f4497..aed9296dccd3 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -112,6 +112,8 @@ obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= paravirt-spinlocks.o obj-$(CONFIG_PARAVIRT_CLOCK) += pvclock.o obj-$(CONFIG_X86_PMEM_LEGACY_DEVICE) += pmem.o +obj-$(CONFIG_JAILHOUSE_GUEST) += jailhouse.o + obj-$(CONFIG_EISA) += eisa.o obj-$(CONFIG_PCSPKR_PLATFORM) += pcspeaker.o diff --git a/arch/x86/kernel/cpu/hypervisor.c b/arch/x86/kernel/cpu/hypervisor.c index bea8d3e24f50..479ca4728de0 100644 --- a/arch/x86/kernel/cpu/hypervisor.c +++ b/arch/x86/kernel/cpu/hypervisor.c @@ -31,6 +31,7 @@ extern const struct hypervisor_x86 x86_hyper_ms_hyperv; extern const struct hypervisor_x86 x86_hyper_xen_pv; extern const struct hypervisor_x86 x86_hyper_xen_hvm; extern const struct hypervisor_x86 x86_hyper_kvm; +extern const struct hypervisor_x86 x86_hyper_jailhouse; static const __initconst struct hypervisor_x86 * const hypervisors[] = { @@ -45,6 +46,9 @@ static const __initconst struct hypervisor_x86 * const hypervisors[] = #ifdef CONFIG_KVM_GUEST _hyper_kvm, #endif +#ifdef CONFIG_JAILHOUSE_GUEST + _hyper_jailhouse, +#endif }; enum x86_hypervisor_type x86_hyper_type; diff --git a/arch/x86/kernel/jailhouse.c b/arch/x86/kernel/jailhouse.c new file mode 100644 index ..bc0f49a6172d --- /dev/null +++ b/arch/x86/kernel/jailhouse.c @@ -0,0 +1,76 @@ +/* + * Jailhouse paravirt_ops implementation + * + * Copyright (c) Siemens AG, 2015-2017 + * + * Authors: + * Jan Kiszka
[PATCH 02/10] x86: jailhouse: Add infrastructure for running in non-root cell
From: Jan Kiszka The Jailhouse hypervisor is able to statically partition a multicore system into multiple so-called cells. Linux is used as boot loader and continues to run in the root cell after Jailhouse is enabled. Linux can also run in non-root cells. Jailhouse does not emulate usual x86 devices. It also provides no complex ACPI but basic platform information that the boot loader forwards via setup data. This adds the infrastructure to detect when running in a non-root cell so that the platform can be configured as required in succeeding steps. Support is limited to x86-64 so far, primarily because no boot loader stub exists for i386 and, thus, we wouldn't be able to test the 32-bit path. Signed-off-by: Jan Kiszka --- arch/x86/Kconfig | 12 ++ arch/x86/include/asm/hypervisor.h | 1 + arch/x86/include/asm/jailhouse_para.h | 27 + arch/x86/kernel/Makefile | 2 + arch/x86/kernel/cpu/hypervisor.c | 4 ++ arch/x86/kernel/jailhouse.c | 76 +++ 6 files changed, 122 insertions(+) create mode 100644 arch/x86/include/asm/jailhouse_para.h create mode 100644 arch/x86/kernel/jailhouse.c diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index df3276d6bfe3..c5f4f4683b51 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -782,6 +782,18 @@ config KVM_DEBUG_FS Statistics are displayed in debugfs filesystem. Enabling this option may incur significant overhead. +config JAILHOUSE_GUEST + bool "Jailhouse non-root cell support" + depends on PARAVIRT && X86_64 + ---help--- + This option allows to run Linux as guest in a Jailhouse non-root + cell. You can leave this option disabled if you only want to start + Jailhouse and run Linux afterwards in the root cell. + + You likely also want to disable CONFIG_SUSPEND and CONFIG_SERIO to + avoid access to I/O resources that are usually not assigned to the + non-root cell. + config PARAVIRT_TIME_ACCOUNTING bool "Paravirtual steal time accounting" depends on PARAVIRT diff --git a/arch/x86/include/asm/hypervisor.h b/arch/x86/include/asm/hypervisor.h index 1b0a5abcd8ae..376085cb6244 100644 --- a/arch/x86/include/asm/hypervisor.h +++ b/arch/x86/include/asm/hypervisor.h @@ -37,6 +37,7 @@ enum x86_hypervisor_type { X86_HYPER_XEN_PV, X86_HYPER_XEN_HVM, X86_HYPER_KVM, + X86_HYPER_JAILHOUSE, }; struct hypervisor_x86 { diff --git a/arch/x86/include/asm/jailhouse_para.h b/arch/x86/include/asm/jailhouse_para.h new file mode 100644 index ..06a5f41d5451 --- /dev/null +++ b/arch/x86/include/asm/jailhouse_para.h @@ -0,0 +1,27 @@ +/* + * Jailhouse paravirt_ops implementation + * + * Copyright (c) Siemens AG, 2015-2017 + * + * Authors: + * Jan Kiszka + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + */ + +#ifndef _ASM_X86_JAILHOUSE_PARA_H +#define _ASM_X86_JAILHOUSE_PARA_H + +#include + +#ifdef CONFIG_JAILHOUSE_GUEST +bool jailhouse_paravirt(void); +#else +static inline bool jailhouse_paravirt(void) +{ + return false; +} +#endif + +#endif /* _ASM_X86_JAILHOUSE_PARA_H */ diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 81bb565f4497..aed9296dccd3 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -112,6 +112,8 @@ obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= paravirt-spinlocks.o obj-$(CONFIG_PARAVIRT_CLOCK) += pvclock.o obj-$(CONFIG_X86_PMEM_LEGACY_DEVICE) += pmem.o +obj-$(CONFIG_JAILHOUSE_GUEST) += jailhouse.o + obj-$(CONFIG_EISA) += eisa.o obj-$(CONFIG_PCSPKR_PLATFORM) += pcspeaker.o diff --git a/arch/x86/kernel/cpu/hypervisor.c b/arch/x86/kernel/cpu/hypervisor.c index bea8d3e24f50..479ca4728de0 100644 --- a/arch/x86/kernel/cpu/hypervisor.c +++ b/arch/x86/kernel/cpu/hypervisor.c @@ -31,6 +31,7 @@ extern const struct hypervisor_x86 x86_hyper_ms_hyperv; extern const struct hypervisor_x86 x86_hyper_xen_pv; extern const struct hypervisor_x86 x86_hyper_xen_hvm; extern const struct hypervisor_x86 x86_hyper_kvm; +extern const struct hypervisor_x86 x86_hyper_jailhouse; static const __initconst struct hypervisor_x86 * const hypervisors[] = { @@ -45,6 +46,9 @@ static const __initconst struct hypervisor_x86 * const hypervisors[] = #ifdef CONFIG_KVM_GUEST _hyper_kvm, #endif +#ifdef CONFIG_JAILHOUSE_GUEST + _hyper_jailhouse, +#endif }; enum x86_hypervisor_type x86_hyper_type; diff --git a/arch/x86/kernel/jailhouse.c b/arch/x86/kernel/jailhouse.c new file mode 100644 index ..bc0f49a6172d --- /dev/null +++ b/arch/x86/kernel/jailhouse.c @@ -0,0 +1,76 @@ +/* + * Jailhouse paravirt_ops implementation + * + * Copyright (c) Siemens AG, 2015-2017 + * + * Authors: + * Jan Kiszka + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING
[PATCH 06/10] x86: jailhouse: Avoid access of unsupported platform resources
From: Jan KiszkaWe don't have CMOS access, thus we can't set the warm-reset vectors in do_boot_cpu. There is no RTC, thus also no wall clock. Furthermore, there are no ISA IRQs and no PIC. So fill the platform callbacks accordingly. Signed-off-by: Jan Kiszka --- arch/x86/kernel/jailhouse.c | 10 ++ arch/x86/kernel/smpboot.c | 7 +-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/jailhouse.c b/arch/x86/kernel/jailhouse.c index 8e5b2f0c8a34..cfe8ae0c33a2 100644 --- a/arch/x86/kernel/jailhouse.c +++ b/arch/x86/kernel/jailhouse.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #define SETUP_JAILHOUSE0x53484c4a /* "JLHS" */ @@ -50,6 +51,11 @@ static uint32_t __init jailhouse_detect(void) return jailhouse_cpuid_base(); } +static void jailhouse_get_wallclock(struct timespec *now) +{ + memset(now, 0, sizeof(*now)); +} + #define MAX_RETRIES5 #define SMI_TRESHOLD 5 @@ -139,7 +145,11 @@ static void __init jailhouse_init_platform(void) unsigned int cpu; x86_init.timers.timer_init = jailhouse_timer_init; + x86_init.irqs.pre_vector_init = x86_init_noop; + legacy_pic = _legacy_pic; + x86_platform.legacy.rtc = 0; + x86_platform.get_wallclock = jailhouse_get_wallclock; x86_platform.calibrate_cpu = jailhouse_calibrate_cpu; x86_platform.calibrate_tsc = jailhouse_calibrate_tsc; diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 5f59e6bee123..81339dbafeba 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -78,6 +78,7 @@ #include #include #include +#include /* Number of siblings per CPU package */ int smp_num_siblings = 1; @@ -1006,7 +1007,8 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle, * the targeted processor. */ - if (get_uv_system_type() != UV_NON_UNIQUE_APIC) { + if (get_uv_system_type() != UV_NON_UNIQUE_APIC && + !jailhouse_paravirt()) { pr_debug("Setting warm reset code and vector.\n"); @@ -1078,7 +1080,8 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle, /* mark "stuck" area as not stuck */ *trampoline_status = 0; - if (get_uv_system_type() != UV_NON_UNIQUE_APIC) { + if (get_uv_system_type() != UV_NON_UNIQUE_APIC && + !jailhouse_paravirt()) { /* * Cleanup possible dangling ends... */ -- 2.12.3
Re: [PATCH] locking/Documentation: Revise Documentation/locking/crossrelease.txt
On 11/16/2017 4:22 PM, Ingo Molnar wrote: * Byungchul Parkwrote: On Sat, Nov 11, 2017 at 10:45:24PM +0900, Byungchul Park wrote: This is the big one including all of version 3. You can take only this. Hello Ingo, Could you consider this? Yeah, I'll have a look in a few days, but right now we are in the middle of the merge window. Thank you very much. Thanks, Ingo -- Thanks, Byungchul
Re: [PATCH] locking/Documentation: Revise Documentation/locking/crossrelease.txt
On 11/16/2017 4:22 PM, Ingo Molnar wrote: * Byungchul Park wrote: On Sat, Nov 11, 2017 at 10:45:24PM +0900, Byungchul Park wrote: This is the big one including all of version 3. You can take only this. Hello Ingo, Could you consider this? Yeah, I'll have a look in a few days, but right now we are in the middle of the merge window. Thank you very much. Thanks, Ingo -- Thanks, Byungchul
[PATCH 06/10] x86: jailhouse: Avoid access of unsupported platform resources
From: Jan Kiszka We don't have CMOS access, thus we can't set the warm-reset vectors in do_boot_cpu. There is no RTC, thus also no wall clock. Furthermore, there are no ISA IRQs and no PIC. So fill the platform callbacks accordingly. Signed-off-by: Jan Kiszka --- arch/x86/kernel/jailhouse.c | 10 ++ arch/x86/kernel/smpboot.c | 7 +-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/jailhouse.c b/arch/x86/kernel/jailhouse.c index 8e5b2f0c8a34..cfe8ae0c33a2 100644 --- a/arch/x86/kernel/jailhouse.c +++ b/arch/x86/kernel/jailhouse.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #define SETUP_JAILHOUSE0x53484c4a /* "JLHS" */ @@ -50,6 +51,11 @@ static uint32_t __init jailhouse_detect(void) return jailhouse_cpuid_base(); } +static void jailhouse_get_wallclock(struct timespec *now) +{ + memset(now, 0, sizeof(*now)); +} + #define MAX_RETRIES5 #define SMI_TRESHOLD 5 @@ -139,7 +145,11 @@ static void __init jailhouse_init_platform(void) unsigned int cpu; x86_init.timers.timer_init = jailhouse_timer_init; + x86_init.irqs.pre_vector_init = x86_init_noop; + legacy_pic = _legacy_pic; + x86_platform.legacy.rtc = 0; + x86_platform.get_wallclock = jailhouse_get_wallclock; x86_platform.calibrate_cpu = jailhouse_calibrate_cpu; x86_platform.calibrate_tsc = jailhouse_calibrate_tsc; diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 5f59e6bee123..81339dbafeba 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -78,6 +78,7 @@ #include #include #include +#include /* Number of siblings per CPU package */ int smp_num_siblings = 1; @@ -1006,7 +1007,8 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle, * the targeted processor. */ - if (get_uv_system_type() != UV_NON_UNIQUE_APIC) { + if (get_uv_system_type() != UV_NON_UNIQUE_APIC && + !jailhouse_paravirt()) { pr_debug("Setting warm reset code and vector.\n"); @@ -1078,7 +1080,8 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle, /* mark "stuck" area as not stuck */ *trampoline_status = 0; - if (get_uv_system_type() != UV_NON_UNIQUE_APIC) { + if (get_uv_system_type() != UV_NON_UNIQUE_APIC && + !jailhouse_paravirt()) { /* * Cleanup possible dangling ends... */ -- 2.12.3
[PATCH 00/10] x86: Add support for running as secondary Jailhouse guest
This series paves the way to run Linux in so-called non-root cells (guest partitions) of the Jailhouse hypervisor. Jailhouse [1] was started 4 years ago as an open-source (GPL) leight- weight hypervisor that statically partitions SMP systems. It's unique in that it uses one Linux instance, the root cell, as boot loader and management console. Jailhouse targets use cases for hard real-time and safety-critical systems that KVM cannot cater due to its inherent complexity. Jaihouse can run bare-metal, free and closed-source RTOSes as secondary guests and, with this series, also x86 Linux instances. While ARM and ARM64 non-root Linux guests are feasible without extra patches, thanks to the high configurability via device trees, x86 requires special platform support, mostly to step away from non-existing resources in a non-root Jailhouse cell. This series ensures that Linux can boot in a non-root cell, including SMP cells, has working timekeeping and can use the platform UARTs and PCI devices as assigned to it. In follow-up series, we will propose optimizations and enhancements for the PCI support, a simplistic debug console, and some improvement for Linux guests on ARM. What is not yet in upstream-ready state is a driver for inter-cell communication. The current implementation of virtual peer-to-peer network [2] uses an enhanced version of the QEMU ivshmem shared memory device. However we still need to finish the evaluation of virtio / vhost-pci options prior to settling over the final interface. This patch series is also available at git://git.kiszka.org/linux.git d0036688b2da Jan [1] http://jailhouse-project.org [2] http://git.kiszka.org/?p=linux.git;a=shortlog;h=refs/heads/queues/jailhouse Jan Kiszka (10): x86/apic: Install an empty physflat_init_apic_ldr x86: jailhouse: Add infrastructure for running in non-root cell x86: jailhouse: Enable APIC and SMP support x86: jailhouse: Enable PMTIMER x86: jailhouse: Set up timekeeping x86: jailhouse: Avoid access of unsupported platform resources x86: jailhouse: Silence ACPI warning x86: jailhouse: Halt instead of failing to restart x86: jailhouse: Wire up IOAPIC for legacy UART ports x86: jailhouse: Initialize PCI support arch/x86/Kconfig | 13 ++ arch/x86/include/asm/hypervisor.h | 1 + arch/x86/include/asm/jailhouse_para.h | 27 arch/x86/include/asm/tsc.h| 3 + arch/x86/kernel/Makefile | 2 + arch/x86/kernel/apic/apic_flat_64.c | 12 +- arch/x86/kernel/cpu/hypervisor.c | 4 + arch/x86/kernel/jailhouse.c | 252 ++ arch/x86/kernel/smpboot.c | 7 +- arch/x86/kernel/tsc.c | 14 +- drivers/acpi/Kconfig | 32 ++--- 11 files changed, 339 insertions(+), 28 deletions(-) create mode 100644 arch/x86/include/asm/jailhouse_para.h create mode 100644 arch/x86/kernel/jailhouse.c -- 2.12.3
[PATCH 00/10] x86: Add support for running as secondary Jailhouse guest
This series paves the way to run Linux in so-called non-root cells (guest partitions) of the Jailhouse hypervisor. Jailhouse [1] was started 4 years ago as an open-source (GPL) leight- weight hypervisor that statically partitions SMP systems. It's unique in that it uses one Linux instance, the root cell, as boot loader and management console. Jailhouse targets use cases for hard real-time and safety-critical systems that KVM cannot cater due to its inherent complexity. Jaihouse can run bare-metal, free and closed-source RTOSes as secondary guests and, with this series, also x86 Linux instances. While ARM and ARM64 non-root Linux guests are feasible without extra patches, thanks to the high configurability via device trees, x86 requires special platform support, mostly to step away from non-existing resources in a non-root Jailhouse cell. This series ensures that Linux can boot in a non-root cell, including SMP cells, has working timekeeping and can use the platform UARTs and PCI devices as assigned to it. In follow-up series, we will propose optimizations and enhancements for the PCI support, a simplistic debug console, and some improvement for Linux guests on ARM. What is not yet in upstream-ready state is a driver for inter-cell communication. The current implementation of virtual peer-to-peer network [2] uses an enhanced version of the QEMU ivshmem shared memory device. However we still need to finish the evaluation of virtio / vhost-pci options prior to settling over the final interface. This patch series is also available at git://git.kiszka.org/linux.git d0036688b2da Jan [1] http://jailhouse-project.org [2] http://git.kiszka.org/?p=linux.git;a=shortlog;h=refs/heads/queues/jailhouse Jan Kiszka (10): x86/apic: Install an empty physflat_init_apic_ldr x86: jailhouse: Add infrastructure for running in non-root cell x86: jailhouse: Enable APIC and SMP support x86: jailhouse: Enable PMTIMER x86: jailhouse: Set up timekeeping x86: jailhouse: Avoid access of unsupported platform resources x86: jailhouse: Silence ACPI warning x86: jailhouse: Halt instead of failing to restart x86: jailhouse: Wire up IOAPIC for legacy UART ports x86: jailhouse: Initialize PCI support arch/x86/Kconfig | 13 ++ arch/x86/include/asm/hypervisor.h | 1 + arch/x86/include/asm/jailhouse_para.h | 27 arch/x86/include/asm/tsc.h| 3 + arch/x86/kernel/Makefile | 2 + arch/x86/kernel/apic/apic_flat_64.c | 12 +- arch/x86/kernel/cpu/hypervisor.c | 4 + arch/x86/kernel/jailhouse.c | 252 ++ arch/x86/kernel/smpboot.c | 7 +- arch/x86/kernel/tsc.c | 14 +- drivers/acpi/Kconfig | 32 ++--- 11 files changed, 339 insertions(+), 28 deletions(-) create mode 100644 arch/x86/include/asm/jailhouse_para.h create mode 100644 arch/x86/kernel/jailhouse.c -- 2.12.3
[PATCH 08/10] x86: jailhouse: Halt instead of failing to restart
From: Jan KiszkaJailhouse provides no guest-initiated restart. So, do not even try to. Signed-off-by: Jan Kiszka --- arch/x86/kernel/jailhouse.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/arch/x86/kernel/jailhouse.c b/arch/x86/kernel/jailhouse.c index c1ed7fcd7bfa..0bcca175c35e 100644 --- a/arch/x86/kernel/jailhouse.c +++ b/arch/x86/kernel/jailhouse.c @@ -12,10 +12,12 @@ #include #include +#include #include #include #include #include +#include #include #define SETUP_JAILHOUSE0x53484c4a /* "JLHS" */ @@ -133,6 +135,12 @@ static unsigned long jailhouse_calibrate_tsc(void) return 0; } +static void jailhouse_no_restart(void) +{ + pr_notice("Jailhouse: Restart not supported, halting\n"); + machine_halt(); +} + static unsigned int x2apic_get_apic_id(unsigned long id) { return id; @@ -153,6 +161,8 @@ static void __init jailhouse_init_platform(void) x86_platform.calibrate_cpu = jailhouse_calibrate_cpu; x86_platform.calibrate_tsc = jailhouse_calibrate_tsc; + machine_ops.emergency_restart = jailhouse_no_restart; + data = early_memremap(pa_data, sizeof(*data)); if (data->header.type != SETUP_JAILHOUSE || -- 2.12.3
[PATCH 08/10] x86: jailhouse: Halt instead of failing to restart
From: Jan Kiszka Jailhouse provides no guest-initiated restart. So, do not even try to. Signed-off-by: Jan Kiszka --- arch/x86/kernel/jailhouse.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/arch/x86/kernel/jailhouse.c b/arch/x86/kernel/jailhouse.c index c1ed7fcd7bfa..0bcca175c35e 100644 --- a/arch/x86/kernel/jailhouse.c +++ b/arch/x86/kernel/jailhouse.c @@ -12,10 +12,12 @@ #include #include +#include #include #include #include #include +#include #include #define SETUP_JAILHOUSE0x53484c4a /* "JLHS" */ @@ -133,6 +135,12 @@ static unsigned long jailhouse_calibrate_tsc(void) return 0; } +static void jailhouse_no_restart(void) +{ + pr_notice("Jailhouse: Restart not supported, halting\n"); + machine_halt(); +} + static unsigned int x2apic_get_apic_id(unsigned long id) { return id; @@ -153,6 +161,8 @@ static void __init jailhouse_init_platform(void) x86_platform.calibrate_cpu = jailhouse_calibrate_cpu; x86_platform.calibrate_tsc = jailhouse_calibrate_tsc; + machine_ops.emergency_restart = jailhouse_no_restart; + data = early_memremap(pa_data, sizeof(*data)); if (data->header.type != SETUP_JAILHOUSE || -- 2.12.3
[current linus git] kernel warning : driver forgot to call drm_crtc_vblank_off()
Hi, I'm running current linus git kernel on VMWare Workstation 12 Pro (Host : windows 10, Guest : Fedora 27). commit e60e1ee60630cafef5e430c2ae364877e061d980 : Merge tag 'drm-for-v4.15' of git://people.freedesktop.org/~airlied/linux) When I login via Gnome GDM login screen, following kernel message occurs. I do not know whether this is an issue of vmwgfx driver or drm core. [ 147.619855] driver forgot to call drm_crtc_vblank_off() [ 147.619898] [ cut here ] [ 147.619910] WARNING: CPU: 1 PID: 131 at drivers/gpu/drm/drm_atomic_helper.c:892 drm_atomic_helper_commit_modeset_disables+0x3d3/0x3e0 [drm_kms_helper] [ 147.619911] Modules linked in: xt_CHECKSUM iptable_mangle ipt_MASQUERADE nf_nat_masquerade_ipv4 iptable_nat nf_nat_ipv4 nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 xt_conntrack nf_conntrack libcrc32c tun bridge stp llc ebtable_filter ebtables ip6table_filter ip6_tables vmw_vsock_vmci_transport vsock snd_seq_midi snd_seq_midi_event coretemp kvm_intel kvm snd_ens1371 gameport snd_ac97_codec irqbypass ac97_bus crct10dif_pclmul snd_seq snd_pcm crc32_pclmul snd_timer ghash_clmulni_intel snd_rawmidi intel_rapl_perf snd_seq_device snd soundcore joydev vmw_balloon shpchp nfit i2c_piix4 vmw_vmci vmwgfx drm_kms_helper mptspi scsi_transport_spi crc32c_intel ttm mptscsih serio_raw ata_generic pcnet32 mii drm mptbase pata_acpi [ 147.619957] CPU: 1 PID: 131 Comm: kworker/1:1 Not tainted 4.14.0+ #173 [ 147.619958] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 07/02/2015 [ 147.619974] Workqueue: events drm_mode_rmfb_work_fn [drm] [ 147.619975] task: 8f32f6962600 task.stack: b239c0ca [ 147.619980] RIP: 0010:drm_atomic_helper_commit_modeset_disables+0x3d3/0x3e0 [drm_kms_helper] [ 147.619981] RSP: 0018:b239c0ca3d48 EFLAGS: 00010286 [ 147.619982] RAX: 002b RBX: 8f336dda8380 RCX: [ 147.619982] RDX: RSI: 8f337fc4e138 RDI: 8f337fc4e138 [ 147.619983] RBP: 8f32f6c7a800 R08: 04b3 R09: 29286f5f6b6e [ 147.619984] R10: R11: 765f637472635f6d R12: c0275fa0 [ 147.619985] R13: R14: 8f3377f07000 R15: ffda [ 147.619986] FS: () GS:8f337fc4() knlGS: [ 147.619987] CS: 0010 DS: ES: CR0: 80050033 [ 147.619987] CR2: 7fec45daa688 CR3: 28009005 CR4: 001606e0 [ 147.620015] Call Trace: [ 147.620024] drm_atomic_helper_commit_tail+0x19/0x60 [drm_kms_helper] [ 147.620028] commit_tail+0x5c/0x70 [drm_kms_helper] [ 147.620032] drm_atomic_helper_commit+0xfc/0x110 [drm_kms_helper] [ 147.620048] drm_framebuffer_remove+0x2a2/0x3b0 [drm] [ 147.620059] drm_mode_rmfb_work_fn+0x4f/0x60 [drm] [ 147.620064] process_one_work+0x182/0x370 [ 147.620066] worker_thread+0x2e/0x380 [ 147.620068] ? process_one_work+0x370/0x370 [ 147.620085] kthread+0x111/0x130 [ 147.620090] ? kthread_create_worker_on_cpu+0x70/0x70 [ 147.620092] ret_from_fork+0x1f/0x30 [ 147.620094] Code: ff d0 e9 cf fd ff ff be 03 00 00 00 4c 89 f7 41 ff 14 24 e9 be fd ff ff 48 c7 c7 40 37 23 c0 c6 05 b2 6b 01 00 01 e8 08 1c ed d2 <0f> ff e9 59 ff ff ff 66 0f 1f 44 00 00 0f 1f 44 00 00 41 57 41 [ 147.620111] ---[ end trace fb8792a7d558d91c ]--- [ 149.045950] fuse init (API version 7.26) Thanks.
Re: [RESEND PATCH] ARM: dts: ls1021a: Add support for QSPI with ls1021a SoC
On Wed, Oct 25, 2017 at 04:00:36PM -0500, Li Yang wrote: > On Tue, Sep 12, 2017 at 1:49 AM, SZ Linwrote: > > Add QSPI node support, and this function is disabled by default > > This setting could be overwritten in board-level definitions > > Adding Shawn Guo. > > > > > Signed-off-by: SZ Lin > > Acked-by: Li Yang Applied, thanks.
[current linus git] kernel warning : driver forgot to call drm_crtc_vblank_off()
Hi, I'm running current linus git kernel on VMWare Workstation 12 Pro (Host : windows 10, Guest : Fedora 27). commit e60e1ee60630cafef5e430c2ae364877e061d980 : Merge tag 'drm-for-v4.15' of git://people.freedesktop.org/~airlied/linux) When I login via Gnome GDM login screen, following kernel message occurs. I do not know whether this is an issue of vmwgfx driver or drm core. [ 147.619855] driver forgot to call drm_crtc_vblank_off() [ 147.619898] [ cut here ] [ 147.619910] WARNING: CPU: 1 PID: 131 at drivers/gpu/drm/drm_atomic_helper.c:892 drm_atomic_helper_commit_modeset_disables+0x3d3/0x3e0 [drm_kms_helper] [ 147.619911] Modules linked in: xt_CHECKSUM iptable_mangle ipt_MASQUERADE nf_nat_masquerade_ipv4 iptable_nat nf_nat_ipv4 nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 xt_conntrack nf_conntrack libcrc32c tun bridge stp llc ebtable_filter ebtables ip6table_filter ip6_tables vmw_vsock_vmci_transport vsock snd_seq_midi snd_seq_midi_event coretemp kvm_intel kvm snd_ens1371 gameport snd_ac97_codec irqbypass ac97_bus crct10dif_pclmul snd_seq snd_pcm crc32_pclmul snd_timer ghash_clmulni_intel snd_rawmidi intel_rapl_perf snd_seq_device snd soundcore joydev vmw_balloon shpchp nfit i2c_piix4 vmw_vmci vmwgfx drm_kms_helper mptspi scsi_transport_spi crc32c_intel ttm mptscsih serio_raw ata_generic pcnet32 mii drm mptbase pata_acpi [ 147.619957] CPU: 1 PID: 131 Comm: kworker/1:1 Not tainted 4.14.0+ #173 [ 147.619958] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 07/02/2015 [ 147.619974] Workqueue: events drm_mode_rmfb_work_fn [drm] [ 147.619975] task: 8f32f6962600 task.stack: b239c0ca [ 147.619980] RIP: 0010:drm_atomic_helper_commit_modeset_disables+0x3d3/0x3e0 [drm_kms_helper] [ 147.619981] RSP: 0018:b239c0ca3d48 EFLAGS: 00010286 [ 147.619982] RAX: 002b RBX: 8f336dda8380 RCX: [ 147.619982] RDX: RSI: 8f337fc4e138 RDI: 8f337fc4e138 [ 147.619983] RBP: 8f32f6c7a800 R08: 04b3 R09: 29286f5f6b6e [ 147.619984] R10: R11: 765f637472635f6d R12: c0275fa0 [ 147.619985] R13: R14: 8f3377f07000 R15: ffda [ 147.619986] FS: () GS:8f337fc4() knlGS: [ 147.619987] CS: 0010 DS: ES: CR0: 80050033 [ 147.619987] CR2: 7fec45daa688 CR3: 28009005 CR4: 001606e0 [ 147.620015] Call Trace: [ 147.620024] drm_atomic_helper_commit_tail+0x19/0x60 [drm_kms_helper] [ 147.620028] commit_tail+0x5c/0x70 [drm_kms_helper] [ 147.620032] drm_atomic_helper_commit+0xfc/0x110 [drm_kms_helper] [ 147.620048] drm_framebuffer_remove+0x2a2/0x3b0 [drm] [ 147.620059] drm_mode_rmfb_work_fn+0x4f/0x60 [drm] [ 147.620064] process_one_work+0x182/0x370 [ 147.620066] worker_thread+0x2e/0x380 [ 147.620068] ? process_one_work+0x370/0x370 [ 147.620085] kthread+0x111/0x130 [ 147.620090] ? kthread_create_worker_on_cpu+0x70/0x70 [ 147.620092] ret_from_fork+0x1f/0x30 [ 147.620094] Code: ff d0 e9 cf fd ff ff be 03 00 00 00 4c 89 f7 41 ff 14 24 e9 be fd ff ff 48 c7 c7 40 37 23 c0 c6 05 b2 6b 01 00 01 e8 08 1c ed d2 <0f> ff e9 59 ff ff ff 66 0f 1f 44 00 00 0f 1f 44 00 00 41 57 41 [ 147.620111] ---[ end trace fb8792a7d558d91c ]--- [ 149.045950] fuse init (API version 7.26) Thanks.
Re: [RESEND PATCH] ARM: dts: ls1021a: Add support for QSPI with ls1021a SoC
On Wed, Oct 25, 2017 at 04:00:36PM -0500, Li Yang wrote: > On Tue, Sep 12, 2017 at 1:49 AM, SZ Lin wrote: > > Add QSPI node support, and this function is disabled by default > > This setting could be overwritten in board-level definitions > > Adding Shawn Guo. > > > > > Signed-off-by: SZ Lin > > Acked-by: Li Yang Applied, thanks.
Re: [PATCH] coccinelle: flags.cocci: reorganize patterns to improve efficiency
On Wed, 15 Nov 2017, Joe Perches wrote: > On Wed, 2017-11-15 at 22:55 +0100, Julia Lawall wrote: > > What version of Coccinelle do you have? > > > I tried 1.0.4 and 1.0.6, > > > but both failed. > > For me, it also fails for 1.0.6. It should be OK for 1.0.7. > > Then likely this patch should not be applied or > some form of local version checking should be done > in the script itself. > > Scripts that use various tools are subject to > language versioning requirements. > > For instance, there are many things that are > possible with later versions of perl, but are not > done for various scripts because many distributions > do not ship with the latest versions. It will say coccicheck failed if it is not compatible with the version of Coccinelle. But it shouldn't break anything. We should put that it requires 1.0.7, but I don't know if that is actually checked, or just provided as documentation for the reader. julia
Re: [PATCH] coccinelle: flags.cocci: reorganize patterns to improve efficiency
On Wed, 15 Nov 2017, Joe Perches wrote: > On Wed, 2017-11-15 at 22:55 +0100, Julia Lawall wrote: > > What version of Coccinelle do you have? > > > I tried 1.0.4 and 1.0.6, > > > but both failed. > > For me, it also fails for 1.0.6. It should be OK for 1.0.7. > > Then likely this patch should not be applied or > some form of local version checking should be done > in the script itself. > > Scripts that use various tools are subject to > language versioning requirements. > > For instance, there are many things that are > possible with later versions of perl, but are not > done for various scripts because many distributions > do not ship with the latest versions. It will say coccicheck failed if it is not compatible with the version of Coccinelle. But it shouldn't break anything. We should put that it requires 1.0.7, but I don't know if that is actually checked, or just provided as documentation for the reader. julia
RE: [PATCH] Input: ALPS - fix DualPoint flag for 74 03 28 devices
Hi, Pali, Aaron, Current code is correct device setting, previous code is wrong. If the trackstick does not work(DUALPOINT flag disable), Device Firmware setting is wrong. But recently I received the same report from Thinkpad L570 user, and I checked this device and found this device Firmware setting is wrong. Sorry for our mistake. Is your laptop L570 ? I will add code that supports the trackstick for this device. Best Regards, Masaki Ota -Original Message- From: Pali Rohár [mailto:pali.ro...@gmail.com] Sent: Wednesday, November 15, 2017 5:35 PM To: 太田 真喜 Masaki OtaCc: linux-in...@vger.kernel.org; linux-kernel@vger.kernel.org; dmitry.torok...@gmail.com; Aaron Ma Subject: Re: [PATCH] Input: ALPS - fix DualPoint flag for 74 03 28 devices On Wednesday 15 November 2017 14:34:04 Aaron Ma wrote: > There is a regression of commit 4a646580f793 ("Input: ALPS - fix > two-finger scroll breakage"), ALPS device fails with log: > > psmouse serio1: alps: Rejected trackstick packet from non DualPoint > device > > ALPS device with id "74 03 28" report OTP[0] data 0xCE after commit > 4a646580f793, after restore the OTP reading order, it becomes to 0x10 > as before and reports the right flag. > > Fixes: 4a646580f793 ("Input: ALPS - fix two-finger scroll breakage") > Cc: > Signed-off-by: Aaron Ma > --- > drivers/input/mouse/alps.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c > index 579b899add26..c59b8f7ca2fc 100644 > --- a/drivers/input/mouse/alps.c > +++ b/drivers/input/mouse/alps.c > @@ -2562,8 +2562,8 @@ static int alps_set_defaults_ss4_v2(struct > psmouse *psmouse, > > memset(otp, 0, sizeof(otp)); > > - if (alps_get_otp_values_ss4_v2(psmouse, 1, [1][0]) || > - alps_get_otp_values_ss4_v2(psmouse, 0, [0][0])) > + if (alps_get_otp_values_ss4_v2(psmouse, 0, [0][0]) || > + alps_get_otp_values_ss4_v2(psmouse, 1, [1][0])) > return -1; > > alps_update_device_area_ss4_v2(otp, priv); Masaki Ota, please look at this patch as it partially revert your commit 4a646580f793 ("Input: ALPS - fix two-finger scroll breakage"). Something smells here. -- Pali Rohár pali.ro...@gmail.com
RE: [PATCH] Input: ALPS - fix DualPoint flag for 74 03 28 devices
Hi, Pali, Aaron, Current code is correct device setting, previous code is wrong. If the trackstick does not work(DUALPOINT flag disable), Device Firmware setting is wrong. But recently I received the same report from Thinkpad L570 user, and I checked this device and found this device Firmware setting is wrong. Sorry for our mistake. Is your laptop L570 ? I will add code that supports the trackstick for this device. Best Regards, Masaki Ota -Original Message- From: Pali Rohár [mailto:pali.ro...@gmail.com] Sent: Wednesday, November 15, 2017 5:35 PM To: 太田 真喜 Masaki Ota Cc: linux-in...@vger.kernel.org; linux-kernel@vger.kernel.org; dmitry.torok...@gmail.com; Aaron Ma Subject: Re: [PATCH] Input: ALPS - fix DualPoint flag for 74 03 28 devices On Wednesday 15 November 2017 14:34:04 Aaron Ma wrote: > There is a regression of commit 4a646580f793 ("Input: ALPS - fix > two-finger scroll breakage"), ALPS device fails with log: > > psmouse serio1: alps: Rejected trackstick packet from non DualPoint > device > > ALPS device with id "74 03 28" report OTP[0] data 0xCE after commit > 4a646580f793, after restore the OTP reading order, it becomes to 0x10 > as before and reports the right flag. > > Fixes: 4a646580f793 ("Input: ALPS - fix two-finger scroll breakage") > Cc: > Signed-off-by: Aaron Ma > --- > drivers/input/mouse/alps.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c > index 579b899add26..c59b8f7ca2fc 100644 > --- a/drivers/input/mouse/alps.c > +++ b/drivers/input/mouse/alps.c > @@ -2562,8 +2562,8 @@ static int alps_set_defaults_ss4_v2(struct > psmouse *psmouse, > > memset(otp, 0, sizeof(otp)); > > - if (alps_get_otp_values_ss4_v2(psmouse, 1, [1][0]) || > - alps_get_otp_values_ss4_v2(psmouse, 0, [0][0])) > + if (alps_get_otp_values_ss4_v2(psmouse, 0, [0][0]) || > + alps_get_otp_values_ss4_v2(psmouse, 1, [1][0])) > return -1; > > alps_update_device_area_ss4_v2(otp, priv); Masaki Ota, please look at this patch as it partially revert your commit 4a646580f793 ("Input: ALPS - fix two-finger scroll breakage"). Something smells here. -- Pali Rohár pali.ro...@gmail.com
Re: [PATCH] arm: Remove unused __readwrite_bug function
On Wed, Nov 15, 2017 at 07:33:22PM +, Corentin Labbe wrote: > The function __readwrite_bug() is not used at all, so this patch remove > it. This function seems unused since 5621caac1d95 ("ARM: kill off __mem_pci"). Adding Rob as author to Cc. Best regards Uwe > Signed-off-by: Corentin Labbe> --- > arch/arm/include/asm/io.h | 5 - > arch/arm/kernel/traps.c | 7 --- > 2 files changed, 12 deletions(-) > > diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h > index 2cfbc531f63b..6a9d9d2d4c0a 100644 > --- a/arch/arm/include/asm/io.h > +++ b/arch/arm/include/asm/io.h > @@ -150,11 +150,6 @@ extern void __iomem * > (*arch_ioremap_caller)(phys_addr_t, size_t, > extern void (*arch_iounmap)(volatile void __iomem *); > > /* > - * Bad read/write accesses... > - */ > -extern void __readwrite_bug(const char *fn); > - > -/* > * A typesafe __io() helper > */ > static inline void __iomem *__typesafe_io(unsigned long addr) > diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c > index 5cf04888c581..cce8b18d673f 100644 > --- a/arch/arm/kernel/traps.c > +++ b/arch/arm/kernel/traps.c > @@ -757,13 +757,6 @@ baddataabort(int code, unsigned long instr, struct > pt_regs *regs) > arm_notify_die("unknown data abort code", regs, , instr, 0); > } > > -void __readwrite_bug(const char *fn) > -{ > - pr_err("%s called, but not implemented\n", fn); > - BUG(); > -} > -EXPORT_SYMBOL(__readwrite_bug); > - > void __pte_error(const char *file, int line, pte_t pte) > { > pr_err("%s:%d: bad pte %08llx.\n", file, line, (long long)pte_val(pte)); > -- > 2.13.6 > > > ___ > linux-arm-kernel mailing list > linux-arm-ker...@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel > -- Pengutronix e.K. | Uwe Kleine-König| Industrial Linux Solutions | http://www.pengutronix.de/ |
Re: [PATCH] arm: Remove unused __readwrite_bug function
On Wed, Nov 15, 2017 at 07:33:22PM +, Corentin Labbe wrote: > The function __readwrite_bug() is not used at all, so this patch remove > it. This function seems unused since 5621caac1d95 ("ARM: kill off __mem_pci"). Adding Rob as author to Cc. Best regards Uwe > Signed-off-by: Corentin Labbe > --- > arch/arm/include/asm/io.h | 5 - > arch/arm/kernel/traps.c | 7 --- > 2 files changed, 12 deletions(-) > > diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h > index 2cfbc531f63b..6a9d9d2d4c0a 100644 > --- a/arch/arm/include/asm/io.h > +++ b/arch/arm/include/asm/io.h > @@ -150,11 +150,6 @@ extern void __iomem * > (*arch_ioremap_caller)(phys_addr_t, size_t, > extern void (*arch_iounmap)(volatile void __iomem *); > > /* > - * Bad read/write accesses... > - */ > -extern void __readwrite_bug(const char *fn); > - > -/* > * A typesafe __io() helper > */ > static inline void __iomem *__typesafe_io(unsigned long addr) > diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c > index 5cf04888c581..cce8b18d673f 100644 > --- a/arch/arm/kernel/traps.c > +++ b/arch/arm/kernel/traps.c > @@ -757,13 +757,6 @@ baddataabort(int code, unsigned long instr, struct > pt_regs *regs) > arm_notify_die("unknown data abort code", regs, , instr, 0); > } > > -void __readwrite_bug(const char *fn) > -{ > - pr_err("%s called, but not implemented\n", fn); > - BUG(); > -} > -EXPORT_SYMBOL(__readwrite_bug); > - > void __pte_error(const char *file, int line, pte_t pte) > { > pr_err("%s:%d: bad pte %08llx.\n", file, line, (long long)pte_val(pte)); > -- > 2.13.6 > > > ___ > linux-arm-kernel mailing list > linux-arm-ker...@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel > -- Pengutronix e.K. | Uwe Kleine-König| Industrial Linux Solutions | http://www.pengutronix.de/ |
Re: [PATCH] locking/Documentation: Revise Documentation/locking/crossrelease.txt
* Byungchul Parkwrote: > On Sat, Nov 11, 2017 at 10:45:24PM +0900, Byungchul Park wrote: > > This is the big one including all of version 3. > > > > You can take only this. > > Hello Ingo, > > Could you consider this? Yeah, I'll have a look in a few days, but right now we are in the middle of the merge window. Thanks, Ingo
Re: [PATCH] locking/Documentation: Revise Documentation/locking/crossrelease.txt
* Byungchul Park wrote: > On Sat, Nov 11, 2017 at 10:45:24PM +0900, Byungchul Park wrote: > > This is the big one including all of version 3. > > > > You can take only this. > > Hello Ingo, > > Could you consider this? Yeah, I'll have a look in a few days, but right now we are in the middle of the merge window. Thanks, Ingo
Re: [PATCH V13 03/10] mmc: block: Add blk-mq support
On 15 November 2017 at 14:07, Adrian Hunterwrote: > On 15/11/17 12:55, Ulf Hansson wrote: >> Linus, Adrian, >> >> Apologize for sidetracking the discussion, just wanted to add some >> minor comments. >> >> [...] >> >>> > But what I think is nice in doing it around > each request is that since mmc_put_card() calls mmc_release_host() > contains this: > > if (--host->claim_cnt) { (...) > > So there is a counter inside the claim/release host functions > and now there is another counter keeping track if the in-flight > requests as well and it gives me the feeling we are maintaining > two counters when we only need one. The gets / puts also get runtime pm for the card. It is a lot a messing around for the sake of a quick check for the number of requests inflight - which is needed anyway for CQE. >> >> Actually the get / puts for runtime PM of the card is already done >> taking the host->claim_cnt into account. > > We do pm_runtime_get_sync(>dev) always i.e. > > void mmc_get_card(struct mmc_card *card, struct mmc_ctx *ctx) > { > pm_runtime_get_sync(>dev); > __mmc_claim_host(card->host, ctx, NULL); > } You are absolutely correct, so let's leave the inflight counter in. Apologize for the noise! I was thinking about the runtime PM of the host dev, which is managed by mmc_claim|release host(). [...] Well I saw 3% drop in sequential read performance, improving to 1% when an unbound workqueue was used. >> >> Can you please make this improvement as a standalone patch on top of >> the mq patch? > > Unfortunately it was just a hack to the blk-mq core - the block layer does > not have an unbound workqueue. I have not had time to consider a proper > fix. It will have to wait, but I agree 3% is not enough to delay going > forward. I see, thanks! [...] Kind regards Uffe
Re: [PATCH V13 03/10] mmc: block: Add blk-mq support
On 15 November 2017 at 14:07, Adrian Hunter wrote: > On 15/11/17 12:55, Ulf Hansson wrote: >> Linus, Adrian, >> >> Apologize for sidetracking the discussion, just wanted to add some >> minor comments. >> >> [...] >> >>> > But what I think is nice in doing it around > each request is that since mmc_put_card() calls mmc_release_host() > contains this: > > if (--host->claim_cnt) { (...) > > So there is a counter inside the claim/release host functions > and now there is another counter keeping track if the in-flight > requests as well and it gives me the feeling we are maintaining > two counters when we only need one. The gets / puts also get runtime pm for the card. It is a lot a messing around for the sake of a quick check for the number of requests inflight - which is needed anyway for CQE. >> >> Actually the get / puts for runtime PM of the card is already done >> taking the host->claim_cnt into account. > > We do pm_runtime_get_sync(>dev) always i.e. > > void mmc_get_card(struct mmc_card *card, struct mmc_ctx *ctx) > { > pm_runtime_get_sync(>dev); > __mmc_claim_host(card->host, ctx, NULL); > } You are absolutely correct, so let's leave the inflight counter in. Apologize for the noise! I was thinking about the runtime PM of the host dev, which is managed by mmc_claim|release host(). [...] Well I saw 3% drop in sequential read performance, improving to 1% when an unbound workqueue was used. >> >> Can you please make this improvement as a standalone patch on top of >> the mq patch? > > Unfortunately it was just a hack to the blk-mq core - the block layer does > not have an unbound workqueue. I have not had time to consider a proper > fix. It will have to wait, but I agree 3% is not enough to delay going > forward. I see, thanks! [...] Kind regards Uffe
[PATCH] soc: qcom: smp2p: Access APCS as mailbox client
Attempt to acquire the APCS IPC through the mailbox framework and fall back to the old syscon based approach, to allow us to move away from using the syscon. Signed-off-by: Bjorn Andersson--- drivers/soc/qcom/Kconfig | 1 + drivers/soc/qcom/smp2p.c | 38 -- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig index b00bccddcd3b..e67d9534fca0 100644 --- a/drivers/soc/qcom/Kconfig +++ b/drivers/soc/qcom/Kconfig @@ -64,6 +64,7 @@ config QCOM_SMEM_STATE config QCOM_SMP2P tristate "Qualcomm Shared Memory Point to Point support" + depends on MAILBOX depends on QCOM_SMEM select QCOM_SMEM_STATE help diff --git a/drivers/soc/qcom/smp2p.c b/drivers/soc/qcom/smp2p.c index f51fb2ea7200..7fdbb64142a0 100644 --- a/drivers/soc/qcom/smp2p.c +++ b/drivers/soc/qcom/smp2p.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -126,6 +127,8 @@ struct smp2p_entry { * @ipc_regmap:regmap for the outbound ipc * @ipc_offset:offset within the regmap * @ipc_bit: bit in regmap@offset to kick to signal remote processor + * @mbox_client: mailbox client handle + * @mbox_chan: apcs ipc mailbox channel handle * @inbound: list of inbound entries * @outbound: list of outbound entries */ @@ -146,6 +149,9 @@ struct qcom_smp2p { int ipc_offset; int ipc_bit; + struct mbox_client mbox_client; + struct mbox_chan *mbox_chan; + struct list_head inbound; struct list_head outbound; }; @@ -154,7 +160,13 @@ static void qcom_smp2p_kick(struct qcom_smp2p *smp2p) { /* Make sure any updated data is written before the kick */ wmb(); - regmap_write(smp2p->ipc_regmap, smp2p->ipc_offset, BIT(smp2p->ipc_bit)); + + if (smp2p->mbox_chan) { + mbox_send_message(smp2p->mbox_chan, NULL); + mbox_client_txdone(smp2p->mbox_chan, 0); + } else { + regmap_write(smp2p->ipc_regmap, smp2p->ipc_offset, BIT(smp2p->ipc_bit)); + } } /** @@ -453,10 +465,6 @@ static int qcom_smp2p_probe(struct platform_device *pdev) platform_set_drvdata(pdev, smp2p); - ret = smp2p_parse_ipc(smp2p); - if (ret) - return ret; - key = "qcom,smem"; ret = of_property_read_u32_array(pdev->dev.of_node, key, smp2p->smem_items, 2); @@ -483,9 +491,22 @@ static int qcom_smp2p_probe(struct platform_device *pdev) return irq; } + smp2p->mbox_client.dev = >dev; + smp2p->mbox_chan = mbox_request_channel(>mbox_client, 0); + if (IS_ERR(smp2p->mbox_chan)) { + if (PTR_ERR(smp2p->mbox_chan) != -ENODEV) + return PTR_ERR(smp2p->mbox_chan); + + smp2p->mbox_chan = NULL; + + ret = smp2p_parse_ipc(smp2p); + if (ret) + return ret; + } + ret = qcom_smp2p_alloc_outbound_item(smp2p); if (ret < 0) - return ret; + goto release_mbox; for_each_available_child_of_node(pdev->dev.of_node, node) { entry = devm_kzalloc(>dev, sizeof(*entry), GFP_KERNEL); @@ -540,6 +561,9 @@ static int qcom_smp2p_probe(struct platform_device *pdev) smp2p->out->valid_entries = 0; +release_mbox: + mbox_free_channel(smp2p->mbox_chan); + return ret; } @@ -554,6 +578,8 @@ static int qcom_smp2p_remove(struct platform_device *pdev) list_for_each_entry(entry, >outbound, node) qcom_smem_state_unregister(entry->state); + mbox_free_channel(smp2p->mbox_chan); + smp2p->out->valid_entries = 0; return 0; -- 2.15.0
[PATCH] soc: qcom: smp2p: Access APCS as mailbox client
Attempt to acquire the APCS IPC through the mailbox framework and fall back to the old syscon based approach, to allow us to move away from using the syscon. Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/Kconfig | 1 + drivers/soc/qcom/smp2p.c | 38 -- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig index b00bccddcd3b..e67d9534fca0 100644 --- a/drivers/soc/qcom/Kconfig +++ b/drivers/soc/qcom/Kconfig @@ -64,6 +64,7 @@ config QCOM_SMEM_STATE config QCOM_SMP2P tristate "Qualcomm Shared Memory Point to Point support" + depends on MAILBOX depends on QCOM_SMEM select QCOM_SMEM_STATE help diff --git a/drivers/soc/qcom/smp2p.c b/drivers/soc/qcom/smp2p.c index f51fb2ea7200..7fdbb64142a0 100644 --- a/drivers/soc/qcom/smp2p.c +++ b/drivers/soc/qcom/smp2p.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -126,6 +127,8 @@ struct smp2p_entry { * @ipc_regmap:regmap for the outbound ipc * @ipc_offset:offset within the regmap * @ipc_bit: bit in regmap@offset to kick to signal remote processor + * @mbox_client: mailbox client handle + * @mbox_chan: apcs ipc mailbox channel handle * @inbound: list of inbound entries * @outbound: list of outbound entries */ @@ -146,6 +149,9 @@ struct qcom_smp2p { int ipc_offset; int ipc_bit; + struct mbox_client mbox_client; + struct mbox_chan *mbox_chan; + struct list_head inbound; struct list_head outbound; }; @@ -154,7 +160,13 @@ static void qcom_smp2p_kick(struct qcom_smp2p *smp2p) { /* Make sure any updated data is written before the kick */ wmb(); - regmap_write(smp2p->ipc_regmap, smp2p->ipc_offset, BIT(smp2p->ipc_bit)); + + if (smp2p->mbox_chan) { + mbox_send_message(smp2p->mbox_chan, NULL); + mbox_client_txdone(smp2p->mbox_chan, 0); + } else { + regmap_write(smp2p->ipc_regmap, smp2p->ipc_offset, BIT(smp2p->ipc_bit)); + } } /** @@ -453,10 +465,6 @@ static int qcom_smp2p_probe(struct platform_device *pdev) platform_set_drvdata(pdev, smp2p); - ret = smp2p_parse_ipc(smp2p); - if (ret) - return ret; - key = "qcom,smem"; ret = of_property_read_u32_array(pdev->dev.of_node, key, smp2p->smem_items, 2); @@ -483,9 +491,22 @@ static int qcom_smp2p_probe(struct platform_device *pdev) return irq; } + smp2p->mbox_client.dev = >dev; + smp2p->mbox_chan = mbox_request_channel(>mbox_client, 0); + if (IS_ERR(smp2p->mbox_chan)) { + if (PTR_ERR(smp2p->mbox_chan) != -ENODEV) + return PTR_ERR(smp2p->mbox_chan); + + smp2p->mbox_chan = NULL; + + ret = smp2p_parse_ipc(smp2p); + if (ret) + return ret; + } + ret = qcom_smp2p_alloc_outbound_item(smp2p); if (ret < 0) - return ret; + goto release_mbox; for_each_available_child_of_node(pdev->dev.of_node, node) { entry = devm_kzalloc(>dev, sizeof(*entry), GFP_KERNEL); @@ -540,6 +561,9 @@ static int qcom_smp2p_probe(struct platform_device *pdev) smp2p->out->valid_entries = 0; +release_mbox: + mbox_free_channel(smp2p->mbox_chan); + return ret; } @@ -554,6 +578,8 @@ static int qcom_smp2p_remove(struct platform_device *pdev) list_for_each_entry(entry, >outbound, node) qcom_smem_state_unregister(entry->state); + mbox_free_channel(smp2p->mbox_chan); + smp2p->out->valid_entries = 0; return 0; -- 2.15.0
Re: [PATCH] mac80211: mwl8k: Expand non-DFS 5G channels
Weixiao Zhangwrites: > Signed-off-by: Weixiao Zhang No empty commit logs, please. And use v2, v3 to clearly mark what's the version of the patch: https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches#patch_version_missing > drivers/net/wireless/marvell/mwl8k.c | 7 ++- > 1 file changed, 6 insertions(+), 1 deletion(-) You should use "mac80211:" prefix only with patches touching net/mac80211. So for this one "mwl8k:" is enough. -- Kalle Valo
Re: [PATCH] mac80211: mwl8k: Expand non-DFS 5G channels
Weixiao Zhang writes: > Signed-off-by: Weixiao Zhang No empty commit logs, please. And use v2, v3 to clearly mark what's the version of the patch: https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches#patch_version_missing > drivers/net/wireless/marvell/mwl8k.c | 7 ++- > 1 file changed, 6 insertions(+), 1 deletion(-) You should use "mac80211:" prefix only with patches touching net/mac80211. So for this one "mwl8k:" is enough. -- Kalle Valo
Re: [GIT pull] printk updates for 4.15
On Wed, 15 Nov 2017, Linus Torvalds wrote: > On Wed, Nov 15, 2017 at 4:37 PM, Thomas Gleixnerwrote: > > > > This broke stuff because the historic behaviour was to not advance on > > resume and the change caused massive timer expiries right after resume > > which confused the hell out of things, because timers fired immediately > > which were not expected to fire as they were implicitely relying on suspend > > not affecting clock monotonic. > > Ahh, now that you mention it, I remember that. Things coming to a > complete halt because every single X event timer and network timer all > firing at resume. > > If the timer wheel thing doesn't happen any more, I'd still be willing > to try it out, but you're right, it might be much worse than I > thought. The timer wheel part is easy to cure, we actually tried that back then by advancing clock monotonic, but not jiffies. That made at least most of the kernel side issues go away, but the user space wreckage persisted and we saw now way to fix that w/o violating the no user space visible regression rule. It might be better now, so yes might can try and see what happens. The android folks surely an run a quick coverage test on their side, but we'd need to get some serious feedback from desktop and enterprise people as well. The first thing we need to look at before even going there is stuff like NTP which needs the coupling of MONOTONIC and MONOTONIC_RAW preserved. I need to make sure that this does not break in the first place. I hope that I can find a few spare cycles to whip up a POC patch which does not make stuff fall apart immediately. Thanks, tglx
Re: [GIT pull] printk updates for 4.15
On Wed, 15 Nov 2017, Linus Torvalds wrote: > On Wed, Nov 15, 2017 at 4:37 PM, Thomas Gleixner wrote: > > > > This broke stuff because the historic behaviour was to not advance on > > resume and the change caused massive timer expiries right after resume > > which confused the hell out of things, because timers fired immediately > > which were not expected to fire as they were implicitely relying on suspend > > not affecting clock monotonic. > > Ahh, now that you mention it, I remember that. Things coming to a > complete halt because every single X event timer and network timer all > firing at resume. > > If the timer wheel thing doesn't happen any more, I'd still be willing > to try it out, but you're right, it might be much worse than I > thought. The timer wheel part is easy to cure, we actually tried that back then by advancing clock monotonic, but not jiffies. That made at least most of the kernel side issues go away, but the user space wreckage persisted and we saw now way to fix that w/o violating the no user space visible regression rule. It might be better now, so yes might can try and see what happens. The android folks surely an run a quick coverage test on their side, but we'd need to get some serious feedback from desktop and enterprise people as well. The first thing we need to look at before even going there is stuff like NTP which needs the coupling of MONOTONIC and MONOTONIC_RAW preserved. I need to make sure that this does not break in the first place. I hope that I can find a few spare cycles to whip up a POC patch which does not make stuff fall apart immediately. Thanks, tglx
Re: [ANNOUNCE] Call for Papers - linux.conf.au Kernel Miniconf, Sydney, 22 January 2018
On 18/10/17 15:34, Andrew Donnellan wrote: Greetings, * TL;DR - LCA Kernel Miniconf, Sydney, Australia, 22 Jan 2018 - Submissions by 30 November 2017, 23:59 (AEDT/UTC+11) - Wanted: anything interesting to kernel hackers! Speakers from diverse backgrounds encouraged! - Form: https://rego.linux.conf.au/proposals/submit/kernel-miniconf/ * Submission deadline is 2 weeks away. I need more talks! :) Andrew linux.conf.au 2018 will be held at the University of Technology Sydney from 22-26 January 2018. The Kernel Miniconf is returning once again and the CFP is now open! What is the Kernel Miniconf? LCA's miniconfs are one-day special interest streams that allow in depth discussion of particular topics. The Kernel Miniconf will feature a variety of talks and discussions on kernel and systems programming topics, including technical talks on current kernel developments and kernel community/process. Past Kernel Miniconfs have included talks on various aspects of the kernel such as networking, filesystems, power management, and so on, as well as community issues such as licensing. The focus of the miniconf will primarily be on the Linux kernel, however interesting submissions about other Free Software kernels are welcome and encouraged. It's anticipated that most talks will be aimed at people with existing kernel and low-level programming experience, however anyone is welcome no matter what their level of experience. There will be a lightning talks/open discussion session at the end of the day. Who can attend? --- Anyone with an LCA ticket can attend. A limited number of miniconf-only day tickets may be available - contact me for further details. Who can speak? -- Anyone with something interesting and kernel-related to say! You will need to have an LCA ticket though - unfortunately miniconf speakers don't qualify for speakers' tickets. (Please contact me if that's a problem for you and we may be able to find some options.) We strongly encourage both first-time and seasoned speakers from all backgrounds, ages, genders, nationalities, ethnicities, religions and abilities. Like the main LCA conference itself, we respect and encourage diversity at our miniconf. If you would like any assistance with creating a proposal, don't hesitate to ask! Submission process -- To submit a proposal, go to https://rego.linux.conf.au/proposals/submit/kernel-miniconf/. Talks should be 25 minutes or 45 minutes. Please indicate your preferred timeslot length in your submission. Dates and deadlines --- * Right Now - CFP opens * 30 November 2017, 23:59 (AEDT/UTC+11) - CFP closes * by 7 December 2017 - Confirmation * 22 January 2018 - conference! Please indicate in your submission if you require earlier confirmation to assist in arranging travel/funding. Questions? -- If you've got any other questions about the Kernel Miniconf that I haven't covered here, ping me at andrew.donnel...@au1.ibm.com. For general LCA questions, ask t...@lca2018.org or @linuxconfau on Twitter. - Andrew -- Andrew Donnellan OzLabs, ADL Canberra andrew.donnel...@au1.ibm.com IBM Australia Limited
Re: [ANNOUNCE] Call for Papers - linux.conf.au Kernel Miniconf, Sydney, 22 January 2018
On 18/10/17 15:34, Andrew Donnellan wrote: Greetings, * TL;DR - LCA Kernel Miniconf, Sydney, Australia, 22 Jan 2018 - Submissions by 30 November 2017, 23:59 (AEDT/UTC+11) - Wanted: anything interesting to kernel hackers! Speakers from diverse backgrounds encouraged! - Form: https://rego.linux.conf.au/proposals/submit/kernel-miniconf/ * Submission deadline is 2 weeks away. I need more talks! :) Andrew linux.conf.au 2018 will be held at the University of Technology Sydney from 22-26 January 2018. The Kernel Miniconf is returning once again and the CFP is now open! What is the Kernel Miniconf? LCA's miniconfs are one-day special interest streams that allow in depth discussion of particular topics. The Kernel Miniconf will feature a variety of talks and discussions on kernel and systems programming topics, including technical talks on current kernel developments and kernel community/process. Past Kernel Miniconfs have included talks on various aspects of the kernel such as networking, filesystems, power management, and so on, as well as community issues such as licensing. The focus of the miniconf will primarily be on the Linux kernel, however interesting submissions about other Free Software kernels are welcome and encouraged. It's anticipated that most talks will be aimed at people with existing kernel and low-level programming experience, however anyone is welcome no matter what their level of experience. There will be a lightning talks/open discussion session at the end of the day. Who can attend? --- Anyone with an LCA ticket can attend. A limited number of miniconf-only day tickets may be available - contact me for further details. Who can speak? -- Anyone with something interesting and kernel-related to say! You will need to have an LCA ticket though - unfortunately miniconf speakers don't qualify for speakers' tickets. (Please contact me if that's a problem for you and we may be able to find some options.) We strongly encourage both first-time and seasoned speakers from all backgrounds, ages, genders, nationalities, ethnicities, religions and abilities. Like the main LCA conference itself, we respect and encourage diversity at our miniconf. If you would like any assistance with creating a proposal, don't hesitate to ask! Submission process -- To submit a proposal, go to https://rego.linux.conf.au/proposals/submit/kernel-miniconf/. Talks should be 25 minutes or 45 minutes. Please indicate your preferred timeslot length in your submission. Dates and deadlines --- * Right Now - CFP opens * 30 November 2017, 23:59 (AEDT/UTC+11) - CFP closes * by 7 December 2017 - Confirmation * 22 January 2018 - conference! Please indicate in your submission if you require earlier confirmation to assist in arranging travel/funding. Questions? -- If you've got any other questions about the Kernel Miniconf that I haven't covered here, ping me at andrew.donnel...@au1.ibm.com. For general LCA questions, ask t...@lca2018.org or @linuxconfau on Twitter. - Andrew -- Andrew Donnellan OzLabs, ADL Canberra andrew.donnel...@au1.ibm.com IBM Australia Limited
[PATCH] rpmsg: qcom_smd: Access APCS through mailbox framework
Attempt to acquire the APCS IPC through the mailbox framework and fall back to the old syscon based approach, to allow us to move away from using the syscon. Signed-off-by: Bjorn Andersson--- drivers/rpmsg/qcom_smd.c | 62 +--- 1 file changed, 43 insertions(+), 19 deletions(-) diff --git a/drivers/rpmsg/qcom_smd.c b/drivers/rpmsg/qcom_smd.c index b01774e9fac0..ef2a526ebc8f 100644 --- a/drivers/rpmsg/qcom_smd.c +++ b/drivers/rpmsg/qcom_smd.c @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -107,6 +108,8 @@ static const struct { * @ipc_regmap:regmap handle holding the outgoing ipc register * @ipc_offset:offset within @ipc_regmap of the register for ipc * @ipc_bit: bit in the register at @ipc_offset of @ipc_regmap + * @mbox_client: mailbox client handle + * @mbox_chan: apcs ipc mailbox channel handle * @channels: list of all channels detected on this edge * @channels_lock: guard for modifications of @channels * @allocated: array of bitmaps representing already allocated channels @@ -129,6 +132,9 @@ struct qcom_smd_edge { int ipc_offset; int ipc_bit; + struct mbox_client mbox_client; + struct mbox_chan *mbox_chan; + struct list_head channels; spinlock_t channels_lock; @@ -365,7 +371,12 @@ static void qcom_smd_signal_channel(struct qcom_smd_channel *channel) { struct qcom_smd_edge *edge = channel->edge; - regmap_write(edge->ipc_regmap, edge->ipc_offset, BIT(edge->ipc_bit)); + if (edge->mbox_chan) { + mbox_send_message(edge->mbox_chan, NULL); + mbox_client_txdone(edge->mbox_chan, 0); + } else { + regmap_write(edge->ipc_regmap, edge->ipc_offset, BIT(edge->ipc_bit)); + } } /* @@ -1268,27 +1279,37 @@ static int qcom_smd_parse_edge(struct device *dev, key = "qcom,remote-pid"; of_property_read_u32(node, key, >remote_pid); - syscon_np = of_parse_phandle(node, "qcom,ipc", 0); - if (!syscon_np) { - dev_err(dev, "no qcom,ipc node\n"); - return -ENODEV; - } + edge->mbox_client.dev = dev; + edge->mbox_client.knows_txdone = true; + edge->mbox_chan = mbox_request_channel(>mbox_client, 0); + if (IS_ERR(edge->mbox_chan)) { + if (PTR_ERR(edge->mbox_chan) != -ENODEV) + return PTR_ERR(edge->mbox_chan); - edge->ipc_regmap = syscon_node_to_regmap(syscon_np); - if (IS_ERR(edge->ipc_regmap)) - return PTR_ERR(edge->ipc_regmap); + edge->mbox_chan = NULL; - key = "qcom,ipc"; - ret = of_property_read_u32_index(node, key, 1, >ipc_offset); - if (ret < 0) { - dev_err(dev, "no offset in %s\n", key); - return -EINVAL; - } + syscon_np = of_parse_phandle(node, "qcom,ipc", 0); + if (!syscon_np) { + dev_err(dev, "no qcom,ipc node\n"); + return -ENODEV; + } - ret = of_property_read_u32_index(node, key, 2, >ipc_bit); - if (ret < 0) { - dev_err(dev, "no bit in %s\n", key); - return -EINVAL; + edge->ipc_regmap = syscon_node_to_regmap(syscon_np); + if (IS_ERR(edge->ipc_regmap)) + return PTR_ERR(edge->ipc_regmap); + + key = "qcom,ipc"; + ret = of_property_read_u32_index(node, key, 1, >ipc_offset); + if (ret < 0) { + dev_err(dev, "no offset in %s\n", key); + return -EINVAL; + } + + ret = of_property_read_u32_index(node, key, 2, >ipc_bit); + if (ret < 0) { + dev_err(dev, "no bit in %s\n", key); + return -EINVAL; + } } ret = of_property_read_string(node, "label", >name); @@ -1394,6 +1415,8 @@ struct qcom_smd_edge *qcom_smd_register_edge(struct device *parent, return edge; unregister_dev: + if (!IS_ERR_OR_NULL(edge->mbox_chan)) + mbox_free_channel(edge->mbox_chan); put_device(>dev); return ERR_PTR(ret); } @@ -1422,6 +1445,7 @@ int qcom_smd_unregister_edge(struct qcom_smd_edge *edge) if (ret) dev_warn(>dev, "can't remove smd device: %d\n", ret); + mbox_free_channel(edge->mbox_chan); device_unregister(>dev); return 0; -- 2.15.0
[PATCH] rpmsg: qcom_smd: Access APCS through mailbox framework
Attempt to acquire the APCS IPC through the mailbox framework and fall back to the old syscon based approach, to allow us to move away from using the syscon. Signed-off-by: Bjorn Andersson --- drivers/rpmsg/qcom_smd.c | 62 +--- 1 file changed, 43 insertions(+), 19 deletions(-) diff --git a/drivers/rpmsg/qcom_smd.c b/drivers/rpmsg/qcom_smd.c index b01774e9fac0..ef2a526ebc8f 100644 --- a/drivers/rpmsg/qcom_smd.c +++ b/drivers/rpmsg/qcom_smd.c @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -107,6 +108,8 @@ static const struct { * @ipc_regmap:regmap handle holding the outgoing ipc register * @ipc_offset:offset within @ipc_regmap of the register for ipc * @ipc_bit: bit in the register at @ipc_offset of @ipc_regmap + * @mbox_client: mailbox client handle + * @mbox_chan: apcs ipc mailbox channel handle * @channels: list of all channels detected on this edge * @channels_lock: guard for modifications of @channels * @allocated: array of bitmaps representing already allocated channels @@ -129,6 +132,9 @@ struct qcom_smd_edge { int ipc_offset; int ipc_bit; + struct mbox_client mbox_client; + struct mbox_chan *mbox_chan; + struct list_head channels; spinlock_t channels_lock; @@ -365,7 +371,12 @@ static void qcom_smd_signal_channel(struct qcom_smd_channel *channel) { struct qcom_smd_edge *edge = channel->edge; - regmap_write(edge->ipc_regmap, edge->ipc_offset, BIT(edge->ipc_bit)); + if (edge->mbox_chan) { + mbox_send_message(edge->mbox_chan, NULL); + mbox_client_txdone(edge->mbox_chan, 0); + } else { + regmap_write(edge->ipc_regmap, edge->ipc_offset, BIT(edge->ipc_bit)); + } } /* @@ -1268,27 +1279,37 @@ static int qcom_smd_parse_edge(struct device *dev, key = "qcom,remote-pid"; of_property_read_u32(node, key, >remote_pid); - syscon_np = of_parse_phandle(node, "qcom,ipc", 0); - if (!syscon_np) { - dev_err(dev, "no qcom,ipc node\n"); - return -ENODEV; - } + edge->mbox_client.dev = dev; + edge->mbox_client.knows_txdone = true; + edge->mbox_chan = mbox_request_channel(>mbox_client, 0); + if (IS_ERR(edge->mbox_chan)) { + if (PTR_ERR(edge->mbox_chan) != -ENODEV) + return PTR_ERR(edge->mbox_chan); - edge->ipc_regmap = syscon_node_to_regmap(syscon_np); - if (IS_ERR(edge->ipc_regmap)) - return PTR_ERR(edge->ipc_regmap); + edge->mbox_chan = NULL; - key = "qcom,ipc"; - ret = of_property_read_u32_index(node, key, 1, >ipc_offset); - if (ret < 0) { - dev_err(dev, "no offset in %s\n", key); - return -EINVAL; - } + syscon_np = of_parse_phandle(node, "qcom,ipc", 0); + if (!syscon_np) { + dev_err(dev, "no qcom,ipc node\n"); + return -ENODEV; + } - ret = of_property_read_u32_index(node, key, 2, >ipc_bit); - if (ret < 0) { - dev_err(dev, "no bit in %s\n", key); - return -EINVAL; + edge->ipc_regmap = syscon_node_to_regmap(syscon_np); + if (IS_ERR(edge->ipc_regmap)) + return PTR_ERR(edge->ipc_regmap); + + key = "qcom,ipc"; + ret = of_property_read_u32_index(node, key, 1, >ipc_offset); + if (ret < 0) { + dev_err(dev, "no offset in %s\n", key); + return -EINVAL; + } + + ret = of_property_read_u32_index(node, key, 2, >ipc_bit); + if (ret < 0) { + dev_err(dev, "no bit in %s\n", key); + return -EINVAL; + } } ret = of_property_read_string(node, "label", >name); @@ -1394,6 +1415,8 @@ struct qcom_smd_edge *qcom_smd_register_edge(struct device *parent, return edge; unregister_dev: + if (!IS_ERR_OR_NULL(edge->mbox_chan)) + mbox_free_channel(edge->mbox_chan); put_device(>dev); return ERR_PTR(ret); } @@ -1422,6 +1445,7 @@ int qcom_smd_unregister_edge(struct qcom_smd_edge *edge) if (ret) dev_warn(>dev, "can't remove smd device: %d\n", ret); + mbox_free_channel(edge->mbox_chan); device_unregister(>dev); return 0; -- 2.15.0
Re: [PATCH v5 1/2] x86/mm: add a function to check if a pfn is UC/UC-
On 11/15/17 11:44 +0100, David Hildenbrand wrote: > On 08.11.2017 08:56, Haozhong Zhang wrote: > > It will be used by KVM to check whether a pfn should be > > mapped to guest as UC. > > > > Signed-off-by: Haozhong Zhang> > --- > > arch/x86/include/asm/pat.h | 2 ++ > > arch/x86/mm/pat.c | 16 > > 2 files changed, 18 insertions(+) > > > > diff --git a/arch/x86/include/asm/pat.h b/arch/x86/include/asm/pat.h > > index fffb2794dd89..fabb0cf00e77 100644 > > --- a/arch/x86/include/asm/pat.h > > +++ b/arch/x86/include/asm/pat.h > > @@ -21,4 +21,6 @@ int io_reserve_memtype(resource_size_t start, > > resource_size_t end, > > > > void io_free_memtype(resource_size_t start, resource_size_t end); > > > > +bool pat_pfn_is_uc_or_uc_minus(unsigned long pfn); > > + > > #endif /* _ASM_X86_PAT_H */ > > diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c > > index fe7d57a8fb60..e1282dd4eeb8 100644 > > --- a/arch/x86/mm/pat.c > > +++ b/arch/x86/mm/pat.c > > @@ -677,6 +677,22 @@ static enum page_cache_mode lookup_memtype(u64 paddr) > > return rettype; > > } > > > > +/** > > + * Check with PAT whether the memory type of a pfn is UC or UC-. > > + * > > + * Only to be called when PAT is enabled. > > + * > > + * Returns true, if the memory type of @pfn is UC or UC-. > > + * Otherwise, returns false. > > + */ > > +bool pat_pfn_is_uc_or_uc_minus(unsigned long pfn) > > +{ > > + enum page_cache_mode cm = lookup_memtype(PFN_PHYS(pfn)); > > + > > + return cm == _PAGE_CACHE_MODE_UC || cm == _PAGE_CACHE_MODE_UC_MINUS; > > +} > > +EXPORT_SYMBOL_GPL(pat_pfn_is_uc_or_uc_minus); > > + > > /** > > * io_reserve_memtype - Request a memory type mapping for a region of > > memory > > * @start: start (physical address) of the region > > > > Wonder if we should check for pat internally. And if we should simply > return the memtype via lookup_memtype() instead of creating such a > strange named function (by providing e.g. a lookup_memtype() variant > that can be called with !pat_enabled()). > > The caller can easily check against _PAGE_CACHE_MODE_UC ... > Yes, the better solution should work for both PAT enabled and disabled cases, like what __vm_insert_mixed() does: use vma->vm_page_prot if PAT is disabled, and refer to track_pfn_insert() in addition if PAT is enabled. The early RFC patch [1] got the cache mode in a similar way via a new function kvm_vcpu_gfn_to_pgprot(). However, as explained in RFC, it does not work, because the existing MMIO check (where kvm_vcpu_gfn_to_pgprot() is called) in KVM is performed with a spinlock (vcpu->kvm->mmu_lock) being taken, but kvm_vcpu_gfn_to_pgprot() has to touch a semaphore (vcpu->kvm->mm->mmap_sem). Besides, KVM may prefetch and check MMIO of other pfns within vcpu->kvm->mmu_lock, and the prefectched pfns cannot be predicted in advance, which means we have to keep the MMIO check within vcpu->kvm->mmu_lock. Therefore, I only make a suboptimal fix in this patchset that only fixes PAT enabled cases, which I suppose is the usual usage scenario of NVDIMM. [1] https://patchwork.kernel.org/patch/10016261/ Haozhong
Re: [PATCH v5 1/2] x86/mm: add a function to check if a pfn is UC/UC-
On 11/15/17 11:44 +0100, David Hildenbrand wrote: > On 08.11.2017 08:56, Haozhong Zhang wrote: > > It will be used by KVM to check whether a pfn should be > > mapped to guest as UC. > > > > Signed-off-by: Haozhong Zhang > > --- > > arch/x86/include/asm/pat.h | 2 ++ > > arch/x86/mm/pat.c | 16 > > 2 files changed, 18 insertions(+) > > > > diff --git a/arch/x86/include/asm/pat.h b/arch/x86/include/asm/pat.h > > index fffb2794dd89..fabb0cf00e77 100644 > > --- a/arch/x86/include/asm/pat.h > > +++ b/arch/x86/include/asm/pat.h > > @@ -21,4 +21,6 @@ int io_reserve_memtype(resource_size_t start, > > resource_size_t end, > > > > void io_free_memtype(resource_size_t start, resource_size_t end); > > > > +bool pat_pfn_is_uc_or_uc_minus(unsigned long pfn); > > + > > #endif /* _ASM_X86_PAT_H */ > > diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c > > index fe7d57a8fb60..e1282dd4eeb8 100644 > > --- a/arch/x86/mm/pat.c > > +++ b/arch/x86/mm/pat.c > > @@ -677,6 +677,22 @@ static enum page_cache_mode lookup_memtype(u64 paddr) > > return rettype; > > } > > > > +/** > > + * Check with PAT whether the memory type of a pfn is UC or UC-. > > + * > > + * Only to be called when PAT is enabled. > > + * > > + * Returns true, if the memory type of @pfn is UC or UC-. > > + * Otherwise, returns false. > > + */ > > +bool pat_pfn_is_uc_or_uc_minus(unsigned long pfn) > > +{ > > + enum page_cache_mode cm = lookup_memtype(PFN_PHYS(pfn)); > > + > > + return cm == _PAGE_CACHE_MODE_UC || cm == _PAGE_CACHE_MODE_UC_MINUS; > > +} > > +EXPORT_SYMBOL_GPL(pat_pfn_is_uc_or_uc_minus); > > + > > /** > > * io_reserve_memtype - Request a memory type mapping for a region of > > memory > > * @start: start (physical address) of the region > > > > Wonder if we should check for pat internally. And if we should simply > return the memtype via lookup_memtype() instead of creating such a > strange named function (by providing e.g. a lookup_memtype() variant > that can be called with !pat_enabled()). > > The caller can easily check against _PAGE_CACHE_MODE_UC ... > Yes, the better solution should work for both PAT enabled and disabled cases, like what __vm_insert_mixed() does: use vma->vm_page_prot if PAT is disabled, and refer to track_pfn_insert() in addition if PAT is enabled. The early RFC patch [1] got the cache mode in a similar way via a new function kvm_vcpu_gfn_to_pgprot(). However, as explained in RFC, it does not work, because the existing MMIO check (where kvm_vcpu_gfn_to_pgprot() is called) in KVM is performed with a spinlock (vcpu->kvm->mmu_lock) being taken, but kvm_vcpu_gfn_to_pgprot() has to touch a semaphore (vcpu->kvm->mm->mmap_sem). Besides, KVM may prefetch and check MMIO of other pfns within vcpu->kvm->mmu_lock, and the prefectched pfns cannot be predicted in advance, which means we have to keep the MMIO check within vcpu->kvm->mmu_lock. Therefore, I only make a suboptimal fix in this patchset that only fixes PAT enabled cases, which I suppose is the usual usage scenario of NVDIMM. [1] https://patchwork.kernel.org/patch/10016261/ Haozhong
Re: [PATCH v2] arm64: dts: ls1088a: Add USB support
On Tue, Nov 14, 2017 at 08:00:00AM +, Yinbo Zhu wrote: > On Wed, Sep 13, 2017 at 05:10:09PM +0800, yinbo@nxp.com wrote: > > From: "yinbo.zhu"> > > > Fix the issue that usb is not detected on ls1088ardb > > >It's not really about fixing issue but adding support. > > The patch had been tested on upstream 4.14 code, it can fix the issue. > > > > Signed-off-by: yinbo.zhu > > Signed-off-by: Ran Wang > > --- > > >You should better have a version history here to tell what's changed between > >version. > > >I will add a version history on next v3 patch > Hi, > > I had modified the code as v4 version, > https://patchwork.kernel.org/patch/10027393/ > please check. You should copy me on that patch, if you expect me to pick it up. Shawn
Re: [PATCH v2] arm64: dts: ls1088a: Add USB support
On Tue, Nov 14, 2017 at 08:00:00AM +, Yinbo Zhu wrote: > On Wed, Sep 13, 2017 at 05:10:09PM +0800, yinbo@nxp.com wrote: > > From: "yinbo.zhu" > > > > Fix the issue that usb is not detected on ls1088ardb > > >It's not really about fixing issue but adding support. > > The patch had been tested on upstream 4.14 code, it can fix the issue. > > > > Signed-off-by: yinbo.zhu > > Signed-off-by: Ran Wang > > --- > > >You should better have a version history here to tell what's changed between > >version. > > >I will add a version history on next v3 patch > Hi, > > I had modified the code as v4 version, > https://patchwork.kernel.org/patch/10027393/ > please check. You should copy me on that patch, if you expect me to pick it up. Shawn
Re: [project-aspen-dev] Re: [PATCH 1/3] clk: hisilicon: add hisi phase clock support
On Thu, Nov 16, 2017 at 11:40:18AM +0800, Jiancheng Xue wrote: > >> +struct clk_hisi_phase { > >> + struct clk_hw hw; > >> + void __iomem*reg; > >> + u32 *phase_values; > >> + u32 *phase_regs; > >> + u8 phase_num; > > > > I do not think this value-reg table is necessary, as the register value > > maps to phase degree in a way that is easy for programming, i.e. degree > > increases 45 with register value increases one. > > > We expected that this interface could be more generic. That means it can > be also used in other maps instances. Okay, if you think there will be some case using different programming model, I'm fine with it. Shawn
Re: [project-aspen-dev] Re: [PATCH 1/3] clk: hisilicon: add hisi phase clock support
On Thu, Nov 16, 2017 at 11:40:18AM +0800, Jiancheng Xue wrote: > >> +struct clk_hisi_phase { > >> + struct clk_hw hw; > >> + void __iomem*reg; > >> + u32 *phase_values; > >> + u32 *phase_regs; > >> + u8 phase_num; > > > > I do not think this value-reg table is necessary, as the register value > > maps to phase degree in a way that is easy for programming, i.e. degree > > increases 45 with register value increases one. > > > We expected that this interface could be more generic. That means it can > be also used in other maps instances. Okay, if you think there will be some case using different programming model, I'm fine with it. Shawn
RE: [patches] Re: [PATCH v9 05/12] RISC-V: Atomic and Locking Code
> > In that case, maybe we should just start out having a fence on both > > sides for > > Actually, given your architecture is RCsc rather than RCpc, so I think maybe > you could follow the way that ARM uses(i.e. relaxed load + release store + a > full barrier). You can see the commit log of 8e86f0b409a4 > ("arm64: atomics: fix use of acquire + release for full barrier > semantics") for the reasoning: > > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/co > mmit/?id=8e86f0b409a44193f1587e87b69c5dcf8f65be67 OK I'm catching up now...and I have to say, that is clever! Thanks for the corrections. It would definitely be good to avoid the double fence. Let me think this over a bit more. One subtle point about RCpc vs. RCsc, though: see below. > > Sounds great! Any estimation when we can see that(maybe a draft)? The latest should be November 28-30, coinciding with the next RISC-V workshop. Possibly even sooner. We just recently resolved a big debate that's been holding us up for a while, and so now it's just a matter of me writing it all up so it's understandable. In the meantime, though, let me quickly and informally summarize some of the highlights, in case it helps unblock any further review here: - The model is now (other-)multi-copy atomic - .aq and .rl alone mean RCpc - .aqrl means RCsc - .aq applies only to the read part of an RMW - .rl applies only to the write part of an RMW - Syntactic dependencies are now respected I recognize this isn't enough detail to do it proper justice, but we'll get the full model out as soon as we can. > > Regards, > Boqun > > > Dan
RE: [patches] Re: [PATCH v9 05/12] RISC-V: Atomic and Locking Code
> > In that case, maybe we should just start out having a fence on both > > sides for > > Actually, given your architecture is RCsc rather than RCpc, so I think maybe > you could follow the way that ARM uses(i.e. relaxed load + release store + a > full barrier). You can see the commit log of 8e86f0b409a4 > ("arm64: atomics: fix use of acquire + release for full barrier > semantics") for the reasoning: > > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/co > mmit/?id=8e86f0b409a44193f1587e87b69c5dcf8f65be67 OK I'm catching up now...and I have to say, that is clever! Thanks for the corrections. It would definitely be good to avoid the double fence. Let me think this over a bit more. One subtle point about RCpc vs. RCsc, though: see below. > > Sounds great! Any estimation when we can see that(maybe a draft)? The latest should be November 28-30, coinciding with the next RISC-V workshop. Possibly even sooner. We just recently resolved a big debate that's been holding us up for a while, and so now it's just a matter of me writing it all up so it's understandable. In the meantime, though, let me quickly and informally summarize some of the highlights, in case it helps unblock any further review here: - The model is now (other-)multi-copy atomic - .aq and .rl alone mean RCpc - .aqrl means RCsc - .aq applies only to the read part of an RMW - .rl applies only to the write part of an RMW - Syntactic dependencies are now respected I recognize this isn't enough detail to do it proper justice, but we'll get the full model out as soon as we can. > > Regards, > Boqun > > > Dan
[PATCH] drivers/perf: arm_pmu: save/restore cpu cycle counter in cpu_pm_pmu_notify
Sometimes userspace need a high resolution cycle counter by reading pmccntr_el0. In commit da4e4f18afe0 ("drivers/perf: arm_pmu: implement CPU_PM notifier"), it resets all the counters even when the pmcr_el0.E and pmcntenset_el0.C are both 1 . That is incorrect. We need to save the registers and counter before CPU_PM_ENTER and restore them after CPU_PM_EXIT. Fixes: da4e4f18afe0 ("drivers/perf: arm_pmu: implement CPU_PM notifier") Signed-off-by: Jia He--- drivers/perf/arm_pmu.c | 72 +- 1 file changed, 66 insertions(+), 6 deletions(-) diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c index 7bc5eee..cf55c91 100644 --- a/drivers/perf/arm_pmu.c +++ b/drivers/perf/arm_pmu.c @@ -26,6 +26,12 @@ #include +#ifdef CONFIG_CPU_PM +DEFINE_PER_CPU(u32, saved_pmcr_el0); +DEFINE_PER_CPU(u32, saved_pmcntenset_el0); +DEFINE_PER_CPU(u64, saved_cycle_cnter); +#endif + static int armpmu_map_cache_event(const unsigned (*cache_map) [PERF_COUNT_HW_CACHE_MAX] @@ -719,6 +725,15 @@ static void cpu_pm_pmu_setup(struct arm_pmu *armpmu, unsigned long cmd) } } +static int pmc_cycle_counter_enabled(void) +{ + if ((read_sysreg(pmcr_el0) & ARMV8_PMU_PMCR_E) && + read_sysreg(pmcntenset_el0) & 1<<31) + return 1; + + return 0; +} + static int cpu_pm_pmu_notify(struct notifier_block *b, unsigned long cmd, void *v) { @@ -729,16 +744,53 @@ static int cpu_pm_pmu_notify(struct notifier_block *b, unsigned long cmd, if (!cpumask_test_cpu(smp_processor_id(), >supported_cpus)) return NOTIFY_DONE; - /* -* Always reset the PMU registers on power-up even if -* there are no events running. -*/ - if (cmd == CPU_PM_EXIT && armpmu->reset) - armpmu->reset(armpmu); + if (cmd == CPU_PM_EXIT) { + /* +* Always reset the PMU registers on power-up even if +* there are no events running. +*/ + if (armpmu->reset) + armpmu->reset(armpmu); + + /* +* Restore the saved pmcr_el0 and pmcntenset_el0 +* if pmc cycle counter is enabled, restore the counter +*/ + write_sysreg(get_cpu_var(saved_pmcr_el0), pmcr_el0); + write_sysreg(get_cpu_var(saved_pmcntenset_el0), + pmcntenset_el0); + + if (pmc_cycle_counter_enabled()) { + write_sysreg(get_cpu_var(saved_cycle_cnter), + pmccntr_el0); + put_cpu_var(saved_cycle_cnter); + } + put_cpu_var(saved_pmcntenset_el0); + put_cpu_var(saved_pmcr_el0); + } + + if (cmd == CPU_PM_ENTER) { + /* If currently pmc cycle counter is enabled, +* save the counter to percpu section +*/ + if (pmc_cycle_counter_enabled()) { + get_cpu_var(saved_cycle_cnter) = read_sysreg( + pmccntr_el0); + put_cpu_var(saved_cycle_cnter); + } + + get_cpu_var(saved_pmcr_el0) = read_sysreg(pmcr_el0); + + get_cpu_var(saved_pmcntenset_el0) = read_sysreg( + pmcntenset_el0); + put_cpu_var(saved_pmcntenset_el0); + put_cpu_var(saved_pmcr_el0); + } if (!enabled) return NOTIFY_OK; + /* if any hw_events is used */ switch (cmd) { case CPU_PM_ENTER: armpmu->stop(armpmu); @@ -758,7 +810,15 @@ static int cpu_pm_pmu_notify(struct notifier_block *b, unsigned long cmd, static int cpu_pm_pmu_register(struct arm_pmu *cpu_pmu) { + int i; cpu_pmu->cpu_pm_nb.notifier_call = cpu_pm_pmu_notify; + + for_each_possible_cpu(i) { + per_cpu(saved_pmcr_el0, i) = 0; + per_cpu(saved_pmcntenset_el0, i) = 0; + per_cpu(saved_cycle_cnter, i) = 0; + } + return cpu_pm_register_notifier(_pmu->cpu_pm_nb); } -- 2.7.4
[PATCH] drivers/perf: arm_pmu: save/restore cpu cycle counter in cpu_pm_pmu_notify
Sometimes userspace need a high resolution cycle counter by reading pmccntr_el0. In commit da4e4f18afe0 ("drivers/perf: arm_pmu: implement CPU_PM notifier"), it resets all the counters even when the pmcr_el0.E and pmcntenset_el0.C are both 1 . That is incorrect. We need to save the registers and counter before CPU_PM_ENTER and restore them after CPU_PM_EXIT. Fixes: da4e4f18afe0 ("drivers/perf: arm_pmu: implement CPU_PM notifier") Signed-off-by: Jia He --- drivers/perf/arm_pmu.c | 72 +- 1 file changed, 66 insertions(+), 6 deletions(-) diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c index 7bc5eee..cf55c91 100644 --- a/drivers/perf/arm_pmu.c +++ b/drivers/perf/arm_pmu.c @@ -26,6 +26,12 @@ #include +#ifdef CONFIG_CPU_PM +DEFINE_PER_CPU(u32, saved_pmcr_el0); +DEFINE_PER_CPU(u32, saved_pmcntenset_el0); +DEFINE_PER_CPU(u64, saved_cycle_cnter); +#endif + static int armpmu_map_cache_event(const unsigned (*cache_map) [PERF_COUNT_HW_CACHE_MAX] @@ -719,6 +725,15 @@ static void cpu_pm_pmu_setup(struct arm_pmu *armpmu, unsigned long cmd) } } +static int pmc_cycle_counter_enabled(void) +{ + if ((read_sysreg(pmcr_el0) & ARMV8_PMU_PMCR_E) && + read_sysreg(pmcntenset_el0) & 1<<31) + return 1; + + return 0; +} + static int cpu_pm_pmu_notify(struct notifier_block *b, unsigned long cmd, void *v) { @@ -729,16 +744,53 @@ static int cpu_pm_pmu_notify(struct notifier_block *b, unsigned long cmd, if (!cpumask_test_cpu(smp_processor_id(), >supported_cpus)) return NOTIFY_DONE; - /* -* Always reset the PMU registers on power-up even if -* there are no events running. -*/ - if (cmd == CPU_PM_EXIT && armpmu->reset) - armpmu->reset(armpmu); + if (cmd == CPU_PM_EXIT) { + /* +* Always reset the PMU registers on power-up even if +* there are no events running. +*/ + if (armpmu->reset) + armpmu->reset(armpmu); + + /* +* Restore the saved pmcr_el0 and pmcntenset_el0 +* if pmc cycle counter is enabled, restore the counter +*/ + write_sysreg(get_cpu_var(saved_pmcr_el0), pmcr_el0); + write_sysreg(get_cpu_var(saved_pmcntenset_el0), + pmcntenset_el0); + + if (pmc_cycle_counter_enabled()) { + write_sysreg(get_cpu_var(saved_cycle_cnter), + pmccntr_el0); + put_cpu_var(saved_cycle_cnter); + } + put_cpu_var(saved_pmcntenset_el0); + put_cpu_var(saved_pmcr_el0); + } + + if (cmd == CPU_PM_ENTER) { + /* If currently pmc cycle counter is enabled, +* save the counter to percpu section +*/ + if (pmc_cycle_counter_enabled()) { + get_cpu_var(saved_cycle_cnter) = read_sysreg( + pmccntr_el0); + put_cpu_var(saved_cycle_cnter); + } + + get_cpu_var(saved_pmcr_el0) = read_sysreg(pmcr_el0); + + get_cpu_var(saved_pmcntenset_el0) = read_sysreg( + pmcntenset_el0); + put_cpu_var(saved_pmcntenset_el0); + put_cpu_var(saved_pmcr_el0); + } if (!enabled) return NOTIFY_OK; + /* if any hw_events is used */ switch (cmd) { case CPU_PM_ENTER: armpmu->stop(armpmu); @@ -758,7 +810,15 @@ static int cpu_pm_pmu_notify(struct notifier_block *b, unsigned long cmd, static int cpu_pm_pmu_register(struct arm_pmu *cpu_pmu) { + int i; cpu_pmu->cpu_pm_nb.notifier_call = cpu_pm_pmu_notify; + + for_each_possible_cpu(i) { + per_cpu(saved_pmcr_el0, i) = 0; + per_cpu(saved_pmcntenset_el0, i) = 0; + per_cpu(saved_cycle_cnter, i) = 0; + } + return cpu_pm_register_notifier(_pmu->cpu_pm_nb); } -- 2.7.4
Re: PROBLEM: Asus C201 video mode problems on HDMI hotplug (regression)
Hi, Any ideas on this issue? Are there any additional tests I can perform to help debug this? On 2017-11-05 11:41 -0500, Nick Bowler wrote: > I completed bisecting this issue. See below. > > On 2017-11-02, Nick Bowlerwrote: > > ~50% of the time after a hotplug, there is a vertical pink bar on the > > left of the display area and audio is not working at all. According to > > the sink device the display size is 1282x720 which seems pretty wrong > > (normal and working situation is 1280x720). > > > > I posted photos of non-working versus working states here: > > > > https://imgur.com/a/qhAZG > > > > Unplugging and plugging the cable again will correct the issue (it seems > > to, for the most part, alternate between working and not-working states, > > although not always). It always works on power up with the cable initially > > connected. > > > > This is a regression from 4.11, where hotplug works perfectly every time. > > Bisection implicates the following commit: > > 181e0ef092a4952aa523c5b9cb21394cf43bcd46 is the first bad commit > commit 181e0ef092a4952aa523c5b9cb21394cf43bcd46 > Author: Laurent Pinchart > Date: Mon Mar 6 01:35:57 2017 +0200 > > drm: bridge: dw-hdmi: Fix the PHY power up sequence > > When powering the PHY up we need to wait for the PLL to lock. This is > done by polling the TX_PHY_LOCK bit in the HDMI_PHY_STAT0 register > (interrupt-based wait could be implemented as well but is likely > overkill). The bit is asserted when the PLL locks, but the current code > incorrectly waits for the bit to be deasserted. Fix it, and while at it, > replace the udelay() with a sleep as the code never runs in > non-sleepable context. > > To be consistent with the power down implementation move the poll loop > to the power off function. > > Signed-off-by: Laurent Pinchart > > Tested-by: Neil Armstrong > Reviewed-by: Jose Abreu > Signed-off-by: Archit Taneja > Link: > http://patchwork.freedesktop.org/patch/msgid/20170305233557.11945-1-laurent.pinchart+rene...@ideasonboard.com > > :04 04 0defad9d1a61c0355f49c679b18eebae2c4b9495 > 5d260e6db25d6abc1211d61ec3405be99e693a23 Mdrivers > > This commit does not revert cleanly, but on top of latest master (which has > the problem) I manually changed the relevant code back to its original state > and the problem is fixed, like this: > > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > index bf14214fa464..6618aac95a51 100644 > --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > @@ -1100,37 +1100,34 @@ static void dw_hdmi_phy_power_off(struct dw_hdmi > *hdmi) > > static int dw_hdmi_phy_power_on(struct dw_hdmi *hdmi) > { > - const struct dw_hdmi_phy_data *phy = hdmi->phy.data; > - unsigned int i; > - u8 val; > + u8 val, msec; > > - if (phy->gen == 1) { > - dw_hdmi_phy_enable_powerdown(hdmi, false); > + dw_hdmi_phy_enable_powerdown(hdmi, false); > > - /* Toggle TMDS enable. */ > - dw_hdmi_phy_enable_tmds(hdmi, 0); > - dw_hdmi_phy_enable_tmds(hdmi, 1); > - return 0; > - } > + /* toggle TMDS enable */ > + dw_hdmi_phy_enable_tmds(hdmi, 0); > + dw_hdmi_phy_enable_tmds(hdmi, 1); > > + /* gen2 tx power on */ > dw_hdmi_phy_gen2_txpwron(hdmi, 1); > dw_hdmi_phy_gen2_pddq(hdmi, 0); > > /* Wait for PHY PLL lock */ > - for (i = 0; i < 5; ++i) { > + msec = 5; > + do { > val = hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK; > - if (val) > + if (!val) > break; > > - usleep_range(1000, 2000); > - } > + if (msec == 0) { > + dev_err(hdmi->dev, "PHY PLL not locked\n"); > + return -ETIMEDOUT; > + } > > - if (!val) { > - dev_err(hdmi->dev, "PHY PLL failed to lock\n"); > - return -ETIMEDOUT; > - } > + udelay(1000); > + msec--; > + } while (1); > > - dev_dbg(hdmi->dev, "PHY PLL locked %u iterations\n", i); > return 0; > } > Thanks, Nick
Re: PROBLEM: Asus C201 video mode problems on HDMI hotplug (regression)
Hi, Any ideas on this issue? Are there any additional tests I can perform to help debug this? On 2017-11-05 11:41 -0500, Nick Bowler wrote: > I completed bisecting this issue. See below. > > On 2017-11-02, Nick Bowler wrote: > > ~50% of the time after a hotplug, there is a vertical pink bar on the > > left of the display area and audio is not working at all. According to > > the sink device the display size is 1282x720 which seems pretty wrong > > (normal and working situation is 1280x720). > > > > I posted photos of non-working versus working states here: > > > > https://imgur.com/a/qhAZG > > > > Unplugging and plugging the cable again will correct the issue (it seems > > to, for the most part, alternate between working and not-working states, > > although not always). It always works on power up with the cable initially > > connected. > > > > This is a regression from 4.11, where hotplug works perfectly every time. > > Bisection implicates the following commit: > > 181e0ef092a4952aa523c5b9cb21394cf43bcd46 is the first bad commit > commit 181e0ef092a4952aa523c5b9cb21394cf43bcd46 > Author: Laurent Pinchart > Date: Mon Mar 6 01:35:57 2017 +0200 > > drm: bridge: dw-hdmi: Fix the PHY power up sequence > > When powering the PHY up we need to wait for the PLL to lock. This is > done by polling the TX_PHY_LOCK bit in the HDMI_PHY_STAT0 register > (interrupt-based wait could be implemented as well but is likely > overkill). The bit is asserted when the PLL locks, but the current code > incorrectly waits for the bit to be deasserted. Fix it, and while at it, > replace the udelay() with a sleep as the code never runs in > non-sleepable context. > > To be consistent with the power down implementation move the poll loop > to the power off function. > > Signed-off-by: Laurent Pinchart > > Tested-by: Neil Armstrong > Reviewed-by: Jose Abreu > Signed-off-by: Archit Taneja > Link: > http://patchwork.freedesktop.org/patch/msgid/20170305233557.11945-1-laurent.pinchart+rene...@ideasonboard.com > > :04 04 0defad9d1a61c0355f49c679b18eebae2c4b9495 > 5d260e6db25d6abc1211d61ec3405be99e693a23 Mdrivers > > This commit does not revert cleanly, but on top of latest master (which has > the problem) I manually changed the relevant code back to its original state > and the problem is fixed, like this: > > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > index bf14214fa464..6618aac95a51 100644 > --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > @@ -1100,37 +1100,34 @@ static void dw_hdmi_phy_power_off(struct dw_hdmi > *hdmi) > > static int dw_hdmi_phy_power_on(struct dw_hdmi *hdmi) > { > - const struct dw_hdmi_phy_data *phy = hdmi->phy.data; > - unsigned int i; > - u8 val; > + u8 val, msec; > > - if (phy->gen == 1) { > - dw_hdmi_phy_enable_powerdown(hdmi, false); > + dw_hdmi_phy_enable_powerdown(hdmi, false); > > - /* Toggle TMDS enable. */ > - dw_hdmi_phy_enable_tmds(hdmi, 0); > - dw_hdmi_phy_enable_tmds(hdmi, 1); > - return 0; > - } > + /* toggle TMDS enable */ > + dw_hdmi_phy_enable_tmds(hdmi, 0); > + dw_hdmi_phy_enable_tmds(hdmi, 1); > > + /* gen2 tx power on */ > dw_hdmi_phy_gen2_txpwron(hdmi, 1); > dw_hdmi_phy_gen2_pddq(hdmi, 0); > > /* Wait for PHY PLL lock */ > - for (i = 0; i < 5; ++i) { > + msec = 5; > + do { > val = hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK; > - if (val) > + if (!val) > break; > > - usleep_range(1000, 2000); > - } > + if (msec == 0) { > + dev_err(hdmi->dev, "PHY PLL not locked\n"); > + return -ETIMEDOUT; > + } > > - if (!val) { > - dev_err(hdmi->dev, "PHY PLL failed to lock\n"); > - return -ETIMEDOUT; > - } > + udelay(1000); > + msec--; > + } while (1); > > - dev_dbg(hdmi->dev, "PHY PLL locked %u iterations\n", i); > return 0; > } > Thanks, Nick
[PATCH] arm64: defconfig: Select schedutil as default cpufreq governor
Currently performance governor is getting selected by default, which is surely not a very good choice as its pretty much power hungry. Select schedutil instead. Signed-off-by: Viresh Kumar--- arch/arm64/configs/defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 34480e9af2e7..9424a7aafdb2 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -93,6 +93,7 @@ CONFIG_HIBERNATION=y CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y CONFIG_ARM_CPUIDLE=y CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y CONFIG_CPUFREQ_DT=y CONFIG_ARM_BIG_LITTLE_CPUFREQ=y CONFIG_ARM_SCPI_CPUFREQ=y -- 2.15.0.194.g9af6a3dea062
[PATCH] arm64: defconfig: Select schedutil as default cpufreq governor
Currently performance governor is getting selected by default, which is surely not a very good choice as its pretty much power hungry. Select schedutil instead. Signed-off-by: Viresh Kumar --- arch/arm64/configs/defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 34480e9af2e7..9424a7aafdb2 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -93,6 +93,7 @@ CONFIG_HIBERNATION=y CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y CONFIG_ARM_CPUIDLE=y CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y CONFIG_CPUFREQ_DT=y CONFIG_ARM_BIG_LITTLE_CPUFREQ=y CONFIG_ARM_SCPI_CPUFREQ=y -- 2.15.0.194.g9af6a3dea062
Re: [PATCH] soc: qcom: smsm: fix child-node lookup
On Wed 15 Nov 03:07 PST 2017, Johan Hovold wrote: > Fix child-node lookup during probe, which ended up searching the whole > device tree depth-first starting at the parent rather than just matching > on its children. > > Note that the original premature free of the parent node has already > been fixed separately. > > Also note that this pattern of looking up the first child node with a > given property is rare enough that a generic helper is probably not > warranted. > I agree. > Fixes: c97c4090ff72 ("soc: qcom: smsm: Add driver for Qualcomm SMSM") > Fixes: 3e8b55411468 ("soc: qcom: smsm: fix of_node refcnting problem") > Cc: Bjorn Andersson> Cc: Rob Clark > Signed-off-by: Johan Hovold Reviewed-by: Bjorn Andersson Thanks, Bjorn > --- > drivers/soc/qcom/smsm.c | 6 -- > 1 file changed, 4 insertions(+), 2 deletions(-) > > diff --git a/drivers/soc/qcom/smsm.c b/drivers/soc/qcom/smsm.c > index 403bea9d546b..50214b620865 100644 > --- a/drivers/soc/qcom/smsm.c > +++ b/drivers/soc/qcom/smsm.c > @@ -496,8 +496,10 @@ static int qcom_smsm_probe(struct platform_device *pdev) > if (!smsm->hosts) > return -ENOMEM; > > - local_node = of_find_node_with_property(of_node_get(pdev->dev.of_node), > - "#qcom,smem-state-cells"); > + for_each_child_of_node(pdev->dev.of_node, local_node) { > + if (of_find_property(local_node, "#qcom,smem-state-cells", > NULL)) > + break; > + } > if (!local_node) { > dev_err(>dev, "no state entry\n"); > return -EINVAL; > -- > 2.15.0 >
Re: [PATCH] soc: qcom: smsm: fix child-node lookup
On Wed 15 Nov 03:07 PST 2017, Johan Hovold wrote: > Fix child-node lookup during probe, which ended up searching the whole > device tree depth-first starting at the parent rather than just matching > on its children. > > Note that the original premature free of the parent node has already > been fixed separately. > > Also note that this pattern of looking up the first child node with a > given property is rare enough that a generic helper is probably not > warranted. > I agree. > Fixes: c97c4090ff72 ("soc: qcom: smsm: Add driver for Qualcomm SMSM") > Fixes: 3e8b55411468 ("soc: qcom: smsm: fix of_node refcnting problem") > Cc: Bjorn Andersson > Cc: Rob Clark > Signed-off-by: Johan Hovold Reviewed-by: Bjorn Andersson Thanks, Bjorn > --- > drivers/soc/qcom/smsm.c | 6 -- > 1 file changed, 4 insertions(+), 2 deletions(-) > > diff --git a/drivers/soc/qcom/smsm.c b/drivers/soc/qcom/smsm.c > index 403bea9d546b..50214b620865 100644 > --- a/drivers/soc/qcom/smsm.c > +++ b/drivers/soc/qcom/smsm.c > @@ -496,8 +496,10 @@ static int qcom_smsm_probe(struct platform_device *pdev) > if (!smsm->hosts) > return -ENOMEM; > > - local_node = of_find_node_with_property(of_node_get(pdev->dev.of_node), > - "#qcom,smem-state-cells"); > + for_each_child_of_node(pdev->dev.of_node, local_node) { > + if (of_find_property(local_node, "#qcom,smem-state-cells", > NULL)) > + break; > + } > if (!local_node) { > dev_err(>dev, "no state entry\n"); > return -EINVAL; > -- > 2.15.0 >
[PATCHi v2] dt-bindings: add device tree binding for Arm TrustZone CryptoCell crypto engine
The Arm TrustZone CryptoCell is a hardware security engine. This patch adds DT bindings for its Rich Execution Environment crypto engine. A driver supporting this device is already present in the staging tree. Signed-off-by: Gilad Ben-YossefAcked-by: Rob Herring --- Changes from v1: - Change node name to reflect type of device in example as pointed out by Rob Herring. .../devicetree/bindings/crypto/arm-cryptocell.txt | 22 ++ 1 file changed, 22 insertions(+) create mode 100644 Documentation/devicetree/bindings/crypto/arm-cryptocell.txt diff --git a/Documentation/devicetree/bindings/crypto/arm-cryptocell.txt b/Documentation/devicetree/bindings/crypto/arm-cryptocell.txt new file mode 100644 index 000..cec8d5d --- /dev/null +++ b/Documentation/devicetree/bindings/crypto/arm-cryptocell.txt @@ -0,0 +1,22 @@ +Arm TrustZone CryptoCell cryptographic engine + +Required properties: +- compatible: Should be "arm,cryptocell-712-ree". +- reg: Base physical address of the engine and length of memory mapped region. +- interrupts: Interrupt number for the device. + +Optional properties: +- interrupt-parent: The phandle for the interrupt controller that services + interrupts for this device. +- clocks: Reference to the crypto engine clock. +- dma-coherent: Present if dma operations are coherent. + +Examples: + + arm_cc712: crypto@8000 { + compatible = "arm,cryptocell-712-ree"; + interrupt-parent = <>; + interrupts = < 0 30 4 >; + reg = < 0x8000 0x1 >; + + }; -- 2.7.4
[PATCHi v2] dt-bindings: add device tree binding for Arm TrustZone CryptoCell crypto engine
The Arm TrustZone CryptoCell is a hardware security engine. This patch adds DT bindings for its Rich Execution Environment crypto engine. A driver supporting this device is already present in the staging tree. Signed-off-by: Gilad Ben-Yossef Acked-by: Rob Herring --- Changes from v1: - Change node name to reflect type of device in example as pointed out by Rob Herring. .../devicetree/bindings/crypto/arm-cryptocell.txt | 22 ++ 1 file changed, 22 insertions(+) create mode 100644 Documentation/devicetree/bindings/crypto/arm-cryptocell.txt diff --git a/Documentation/devicetree/bindings/crypto/arm-cryptocell.txt b/Documentation/devicetree/bindings/crypto/arm-cryptocell.txt new file mode 100644 index 000..cec8d5d --- /dev/null +++ b/Documentation/devicetree/bindings/crypto/arm-cryptocell.txt @@ -0,0 +1,22 @@ +Arm TrustZone CryptoCell cryptographic engine + +Required properties: +- compatible: Should be "arm,cryptocell-712-ree". +- reg: Base physical address of the engine and length of memory mapped region. +- interrupts: Interrupt number for the device. + +Optional properties: +- interrupt-parent: The phandle for the interrupt controller that services + interrupts for this device. +- clocks: Reference to the crypto engine clock. +- dma-coherent: Present if dma operations are coherent. + +Examples: + + arm_cc712: crypto@8000 { + compatible = "arm,cryptocell-712-ree"; + interrupt-parent = <>; + interrupts = < 0 30 4 >; + reg = < 0x8000 0x1 >; + + }; -- 2.7.4
Re: [PATCH v5 1/2] x86/mm: add a function to check if a pfn is UC/UC-
On 11/15/17 07:17 -0800, Dan Williams wrote: > On Tue, Nov 7, 2017 at 11:56 PM, Haozhong Zhang >wrote: > > It will be used by KVM to check whether a pfn should be > > mapped to guest as UC. > > > > Signed-off-by: Haozhong Zhang > > --- > > arch/x86/include/asm/pat.h | 2 ++ > > arch/x86/mm/pat.c | 16 > > 2 files changed, 18 insertions(+) > > > > diff --git a/arch/x86/include/asm/pat.h b/arch/x86/include/asm/pat.h > > index fffb2794dd89..fabb0cf00e77 100644 > > --- a/arch/x86/include/asm/pat.h > > +++ b/arch/x86/include/asm/pat.h > > @@ -21,4 +21,6 @@ int io_reserve_memtype(resource_size_t start, > > resource_size_t end, > > > > void io_free_memtype(resource_size_t start, resource_size_t end); > > > > +bool pat_pfn_is_uc_or_uc_minus(unsigned long pfn); > > + > > #endif /* _ASM_X86_PAT_H */ > > diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c > > index fe7d57a8fb60..e1282dd4eeb8 100644 > > --- a/arch/x86/mm/pat.c > > +++ b/arch/x86/mm/pat.c > > @@ -677,6 +677,22 @@ static enum page_cache_mode lookup_memtype(u64 paddr) > > return rettype; > > } > > > > +/** > > + * Check with PAT whether the memory type of a pfn is UC or UC-. > > + * > > + * Only to be called when PAT is enabled. > > + * > > + * Returns true, if the memory type of @pfn is UC or UC-. > > + * Otherwise, returns false. > > + */ > > +bool pat_pfn_is_uc_or_uc_minus(unsigned long pfn) > > +{ > > + enum page_cache_mode cm = lookup_memtype(PFN_PHYS(pfn)); > > + > > + return cm == _PAGE_CACHE_MODE_UC || cm == _PAGE_CACHE_MODE_UC_MINUS; > > +} > > +EXPORT_SYMBOL_GPL(pat_pfn_is_uc_or_uc_minus); > > Why do we need this strangely named new accessor? It seems to be > open-coding a new / more limited version of track_pfn_insert(). In the first version patchset, KVM did extract and check the cache mode got from track_pfn_insert(), but Ingo thought it was better to keep all the low-level details out of KVM, so I encapsulated them in a function in mm in subsequent versions. Haozhong
Re: [PATCH v5 1/2] x86/mm: add a function to check if a pfn is UC/UC-
On 11/15/17 07:17 -0800, Dan Williams wrote: > On Tue, Nov 7, 2017 at 11:56 PM, Haozhong Zhang > wrote: > > It will be used by KVM to check whether a pfn should be > > mapped to guest as UC. > > > > Signed-off-by: Haozhong Zhang > > --- > > arch/x86/include/asm/pat.h | 2 ++ > > arch/x86/mm/pat.c | 16 > > 2 files changed, 18 insertions(+) > > > > diff --git a/arch/x86/include/asm/pat.h b/arch/x86/include/asm/pat.h > > index fffb2794dd89..fabb0cf00e77 100644 > > --- a/arch/x86/include/asm/pat.h > > +++ b/arch/x86/include/asm/pat.h > > @@ -21,4 +21,6 @@ int io_reserve_memtype(resource_size_t start, > > resource_size_t end, > > > > void io_free_memtype(resource_size_t start, resource_size_t end); > > > > +bool pat_pfn_is_uc_or_uc_minus(unsigned long pfn); > > + > > #endif /* _ASM_X86_PAT_H */ > > diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c > > index fe7d57a8fb60..e1282dd4eeb8 100644 > > --- a/arch/x86/mm/pat.c > > +++ b/arch/x86/mm/pat.c > > @@ -677,6 +677,22 @@ static enum page_cache_mode lookup_memtype(u64 paddr) > > return rettype; > > } > > > > +/** > > + * Check with PAT whether the memory type of a pfn is UC or UC-. > > + * > > + * Only to be called when PAT is enabled. > > + * > > + * Returns true, if the memory type of @pfn is UC or UC-. > > + * Otherwise, returns false. > > + */ > > +bool pat_pfn_is_uc_or_uc_minus(unsigned long pfn) > > +{ > > + enum page_cache_mode cm = lookup_memtype(PFN_PHYS(pfn)); > > + > > + return cm == _PAGE_CACHE_MODE_UC || cm == _PAGE_CACHE_MODE_UC_MINUS; > > +} > > +EXPORT_SYMBOL_GPL(pat_pfn_is_uc_or_uc_minus); > > Why do we need this strangely named new accessor? It seems to be > open-coding a new / more limited version of track_pfn_insert(). In the first version patchset, KVM did extract and check the cache mode got from track_pfn_insert(), but Ingo thought it was better to keep all the low-level details out of KVM, so I encapsulated them in a function in mm in subsequent versions. Haozhong
[PATCH] rpmsg: qcom: The mbox clients knows_txdone
As both the GLINK and SMD drivers are ticking the txdone of the mailbox (to implement the doorbell) they should set knows_txdone. Signed-off-by: Bjorn Andersson--- drivers/rpmsg/qcom_glink_native.c | 1 + drivers/rpmsg/qcom_smd.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c index 80d9af307b40..8ae81431bada 100644 --- a/drivers/rpmsg/qcom_glink_native.c +++ b/drivers/rpmsg/qcom_glink_native.c @@ -1576,6 +1576,7 @@ struct qcom_glink *qcom_glink_native_probe(struct device *dev, idr_init(>rcids); glink->mbox_client.dev = dev; + glink->mbox_client.knows_txdone = true; glink->mbox_chan = mbox_request_channel(>mbox_client, 0); if (IS_ERR(glink->mbox_chan)) { if (PTR_ERR(glink->mbox_chan) != -EPROBE_DEFER) diff --git a/drivers/rpmsg/qcom_smd.c b/drivers/rpmsg/qcom_smd.c index 2d7199e7cb3f..2770b3189e03 100644 --- a/drivers/rpmsg/qcom_smd.c +++ b/drivers/rpmsg/qcom_smd.c @@ -1280,6 +1280,7 @@ static int qcom_smd_parse_edge(struct device *dev, of_property_read_u32(node, key, >remote_pid); edge->mbox_client.dev = dev; + edge->mbox_client.knows_txdone = true; edge->mbox_chan = mbox_request_channel(>mbox_client, 0); if (IS_ERR(edge->mbox_chan)) { if (PTR_ERR(edge->mbox_chan) != -ENODEV) -- 2.15.0
[PATCH] rpmsg: qcom: The mbox clients knows_txdone
As both the GLINK and SMD drivers are ticking the txdone of the mailbox (to implement the doorbell) they should set knows_txdone. Signed-off-by: Bjorn Andersson --- drivers/rpmsg/qcom_glink_native.c | 1 + drivers/rpmsg/qcom_smd.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c index 80d9af307b40..8ae81431bada 100644 --- a/drivers/rpmsg/qcom_glink_native.c +++ b/drivers/rpmsg/qcom_glink_native.c @@ -1576,6 +1576,7 @@ struct qcom_glink *qcom_glink_native_probe(struct device *dev, idr_init(>rcids); glink->mbox_client.dev = dev; + glink->mbox_client.knows_txdone = true; glink->mbox_chan = mbox_request_channel(>mbox_client, 0); if (IS_ERR(glink->mbox_chan)) { if (PTR_ERR(glink->mbox_chan) != -EPROBE_DEFER) diff --git a/drivers/rpmsg/qcom_smd.c b/drivers/rpmsg/qcom_smd.c index 2d7199e7cb3f..2770b3189e03 100644 --- a/drivers/rpmsg/qcom_smd.c +++ b/drivers/rpmsg/qcom_smd.c @@ -1280,6 +1280,7 @@ static int qcom_smd_parse_edge(struct device *dev, of_property_read_u32(node, key, >remote_pid); edge->mbox_client.dev = dev; + edge->mbox_client.knows_txdone = true; edge->mbox_chan = mbox_request_channel(>mbox_client, 0); if (IS_ERR(edge->mbox_chan)) { if (PTR_ERR(edge->mbox_chan) != -ENODEV) -- 2.15.0
Re: [PATCH 2/2] drm/rockchip: vop: add rk3126 vop support
On 2017年11月14日 19:27, Sandy Huang wrote: RK3126 vop register layout is similar with rk3036, so some feature can reuse with rk3036. RK3126 support two overlay plane and one hwc plane, max output resolution is 1080p. it support IOMMU, and its IOMMU same as rk3288's Signed-off-by: Sandy HuangLooks good. Reviewed-by: Mark Yao --- drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 30 + drivers/gpu/drm/rockchip/rockchip_vop_reg.h | 6 ++ 2 files changed, 36 insertions(+) diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c index 4a39049..2e4eea3 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c @@ -149,6 +149,34 @@ static const struct vop_data rk3036_vop = { .win_size = ARRAY_SIZE(rk3036_vop_win_data), }; +static const struct vop_win_phy rk3126_win1_data = { + .data_formats = formats_win_lite, + .nformats = ARRAY_SIZE(formats_win_lite), + .enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 1), + .format = VOP_REG(RK3036_SYS_CTRL, 0x7, 6), + .rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 19), + .dsp_info = VOP_REG(RK3126_WIN1_DSP_INFO, 0x0fff0fff, 0), + .dsp_st = VOP_REG(RK3126_WIN1_DSP_ST, 0x1fff1fff, 0), + .yrgb_mst = VOP_REG(RK3126_WIN1_MST, 0x, 0), + .yrgb_vir = VOP_REG(RK3036_WIN1_VIR, 0x, 0), +}; + +static const struct vop_win_data rk3126_vop_win_data[] = { + { .base = 0x00, .phy = _win0_data, + .type = DRM_PLANE_TYPE_PRIMARY }, + { .base = 0x00, .phy = _win1_data, + .type = DRM_PLANE_TYPE_CURSOR }, +}; + +static const struct vop_data rk3126_vop = { + .intr = _intr, + .common = _common, + .modeset = _modeset, + .output = _output, + .win = rk3126_vop_win_data, + .win_size = ARRAY_SIZE(rk3126_vop_win_data), +}; + static const struct vop_scl_extension rk3288_win_full_scl_ext = { .cbcr_vsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 31), .cbcr_vsu_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 30), @@ -510,6 +538,8 @@ static const struct vop_data rk3328_vop = { static const struct of_device_id vop_driver_dt_match[] = { { .compatible = "rockchip,rk3036-vop", .data = _vop }, + { .compatible = "rockchip,rk3126-vop", + .data = _vop }, { .compatible = "rockchip,rk3288-vop", .data = _vop }, { .compatible = "rockchip,rk3368-vop", diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.h b/drivers/gpu/drm/rockchip/rockchip_vop_reg.h index 4a4799f..f81b510 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.h +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.h @@ -878,4 +878,10 @@ #define RK3036_HWC_LUT_ADDR 0x800 /* rk3036 register definition end */ +/* rk3126 register definition */ +#define RK3126_WIN1_MST0x4c +#define RK3126_WIN1_DSP_INFO 0x50 +#define RK3126_WIN1_DSP_ST 0x54 +/* rk3126 register definition end */ + #endif /* _ROCKCHIP_VOP_REG_H */
Re: [PATCH 2/2] drm/rockchip: vop: add rk3126 vop support
On 2017年11月14日 19:27, Sandy Huang wrote: RK3126 vop register layout is similar with rk3036, so some feature can reuse with rk3036. RK3126 support two overlay plane and one hwc plane, max output resolution is 1080p. it support IOMMU, and its IOMMU same as rk3288's Signed-off-by: Sandy Huang Looks good. Reviewed-by: Mark Yao --- drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 30 + drivers/gpu/drm/rockchip/rockchip_vop_reg.h | 6 ++ 2 files changed, 36 insertions(+) diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c index 4a39049..2e4eea3 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c @@ -149,6 +149,34 @@ static const struct vop_data rk3036_vop = { .win_size = ARRAY_SIZE(rk3036_vop_win_data), }; +static const struct vop_win_phy rk3126_win1_data = { + .data_formats = formats_win_lite, + .nformats = ARRAY_SIZE(formats_win_lite), + .enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 1), + .format = VOP_REG(RK3036_SYS_CTRL, 0x7, 6), + .rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 19), + .dsp_info = VOP_REG(RK3126_WIN1_DSP_INFO, 0x0fff0fff, 0), + .dsp_st = VOP_REG(RK3126_WIN1_DSP_ST, 0x1fff1fff, 0), + .yrgb_mst = VOP_REG(RK3126_WIN1_MST, 0x, 0), + .yrgb_vir = VOP_REG(RK3036_WIN1_VIR, 0x, 0), +}; + +static const struct vop_win_data rk3126_vop_win_data[] = { + { .base = 0x00, .phy = _win0_data, + .type = DRM_PLANE_TYPE_PRIMARY }, + { .base = 0x00, .phy = _win1_data, + .type = DRM_PLANE_TYPE_CURSOR }, +}; + +static const struct vop_data rk3126_vop = { + .intr = _intr, + .common = _common, + .modeset = _modeset, + .output = _output, + .win = rk3126_vop_win_data, + .win_size = ARRAY_SIZE(rk3126_vop_win_data), +}; + static const struct vop_scl_extension rk3288_win_full_scl_ext = { .cbcr_vsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 31), .cbcr_vsu_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 30), @@ -510,6 +538,8 @@ static const struct vop_data rk3328_vop = { static const struct of_device_id vop_driver_dt_match[] = { { .compatible = "rockchip,rk3036-vop", .data = _vop }, + { .compatible = "rockchip,rk3126-vop", + .data = _vop }, { .compatible = "rockchip,rk3288-vop", .data = _vop }, { .compatible = "rockchip,rk3368-vop", diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.h b/drivers/gpu/drm/rockchip/rockchip_vop_reg.h index 4a4799f..f81b510 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.h +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.h @@ -878,4 +878,10 @@ #define RK3036_HWC_LUT_ADDR 0x800 /* rk3036 register definition end */ +/* rk3126 register definition */ +#define RK3126_WIN1_MST0x4c +#define RK3126_WIN1_DSP_INFO 0x50 +#define RK3126_WIN1_DSP_ST 0x54 +/* rk3126 register definition end */ + #endif /* _ROCKCHIP_VOP_REG_H */
Re: [PATCH 2/2] drm/rockchip: vop: add rk3126 vop support
On 2017年11月14日 19:27, Sandy Huang wrote: RK3126 vop register layout is similar with rk3036, so some feature can reuse with rk3036. RK3126 support two overlay plane and one hwc plane, max output resolution is 1080p. it support IOMMU, and its IOMMU same as rk3288's Signed-off-by: Sandy HuangLooks good. Reviewed-by: Mark Yao --- drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 30 + drivers/gpu/drm/rockchip/rockchip_vop_reg.h | 6 ++ 2 files changed, 36 insertions(+) diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c index 4a39049..2e4eea3 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c @@ -149,6 +149,34 @@ static const struct vop_data rk3036_vop = { .win_size = ARRAY_SIZE(rk3036_vop_win_data), }; +static const struct vop_win_phy rk3126_win1_data = { + .data_formats = formats_win_lite, + .nformats = ARRAY_SIZE(formats_win_lite), + .enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 1), + .format = VOP_REG(RK3036_SYS_CTRL, 0x7, 6), + .rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 19), + .dsp_info = VOP_REG(RK3126_WIN1_DSP_INFO, 0x0fff0fff, 0), + .dsp_st = VOP_REG(RK3126_WIN1_DSP_ST, 0x1fff1fff, 0), + .yrgb_mst = VOP_REG(RK3126_WIN1_MST, 0x, 0), + .yrgb_vir = VOP_REG(RK3036_WIN1_VIR, 0x, 0), +}; + +static const struct vop_win_data rk3126_vop_win_data[] = { + { .base = 0x00, .phy = _win0_data, + .type = DRM_PLANE_TYPE_PRIMARY }, + { .base = 0x00, .phy = _win1_data, + .type = DRM_PLANE_TYPE_CURSOR }, +}; + +static const struct vop_data rk3126_vop = { + .intr = _intr, + .common = _common, + .modeset = _modeset, + .output = _output, + .win = rk3126_vop_win_data, + .win_size = ARRAY_SIZE(rk3126_vop_win_data), +}; + static const struct vop_scl_extension rk3288_win_full_scl_ext = { .cbcr_vsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 31), .cbcr_vsu_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 30), @@ -510,6 +538,8 @@ static const struct vop_data rk3328_vop = { static const struct of_device_id vop_driver_dt_match[] = { { .compatible = "rockchip,rk3036-vop", .data = _vop }, + { .compatible = "rockchip,rk3126-vop", + .data = _vop }, { .compatible = "rockchip,rk3288-vop", .data = _vop }, { .compatible = "rockchip,rk3368-vop", diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.h b/drivers/gpu/drm/rockchip/rockchip_vop_reg.h index 4a4799f..f81b510 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.h +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.h @@ -878,4 +878,10 @@ #define RK3036_HWC_LUT_ADDR 0x800 /* rk3036 register definition end */ +/* rk3126 register definition */ +#define RK3126_WIN1_MST0x4c +#define RK3126_WIN1_DSP_INFO 0x50 +#define RK3126_WIN1_DSP_ST 0x54 +/* rk3126 register definition end */ + #endif /* _ROCKCHIP_VOP_REG_H */
Re: [PATCH 2/2] drm/rockchip: vop: add rk3126 vop support
On 2017年11月14日 19:27, Sandy Huang wrote: RK3126 vop register layout is similar with rk3036, so some feature can reuse with rk3036. RK3126 support two overlay plane and one hwc plane, max output resolution is 1080p. it support IOMMU, and its IOMMU same as rk3288's Signed-off-by: Sandy Huang Looks good. Reviewed-by: Mark Yao --- drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 30 + drivers/gpu/drm/rockchip/rockchip_vop_reg.h | 6 ++ 2 files changed, 36 insertions(+) diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c index 4a39049..2e4eea3 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c @@ -149,6 +149,34 @@ static const struct vop_data rk3036_vop = { .win_size = ARRAY_SIZE(rk3036_vop_win_data), }; +static const struct vop_win_phy rk3126_win1_data = { + .data_formats = formats_win_lite, + .nformats = ARRAY_SIZE(formats_win_lite), + .enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 1), + .format = VOP_REG(RK3036_SYS_CTRL, 0x7, 6), + .rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 19), + .dsp_info = VOP_REG(RK3126_WIN1_DSP_INFO, 0x0fff0fff, 0), + .dsp_st = VOP_REG(RK3126_WIN1_DSP_ST, 0x1fff1fff, 0), + .yrgb_mst = VOP_REG(RK3126_WIN1_MST, 0x, 0), + .yrgb_vir = VOP_REG(RK3036_WIN1_VIR, 0x, 0), +}; + +static const struct vop_win_data rk3126_vop_win_data[] = { + { .base = 0x00, .phy = _win0_data, + .type = DRM_PLANE_TYPE_PRIMARY }, + { .base = 0x00, .phy = _win1_data, + .type = DRM_PLANE_TYPE_CURSOR }, +}; + +static const struct vop_data rk3126_vop = { + .intr = _intr, + .common = _common, + .modeset = _modeset, + .output = _output, + .win = rk3126_vop_win_data, + .win_size = ARRAY_SIZE(rk3126_vop_win_data), +}; + static const struct vop_scl_extension rk3288_win_full_scl_ext = { .cbcr_vsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 31), .cbcr_vsu_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 30), @@ -510,6 +538,8 @@ static const struct vop_data rk3328_vop = { static const struct of_device_id vop_driver_dt_match[] = { { .compatible = "rockchip,rk3036-vop", .data = _vop }, + { .compatible = "rockchip,rk3126-vop", + .data = _vop }, { .compatible = "rockchip,rk3288-vop", .data = _vop }, { .compatible = "rockchip,rk3368-vop", diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.h b/drivers/gpu/drm/rockchip/rockchip_vop_reg.h index 4a4799f..f81b510 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.h +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.h @@ -878,4 +878,10 @@ #define RK3036_HWC_LUT_ADDR 0x800 /* rk3036 register definition end */ +/* rk3126 register definition */ +#define RK3126_WIN1_MST0x4c +#define RK3126_WIN1_DSP_INFO 0x50 +#define RK3126_WIN1_DSP_ST 0x54 +/* rk3126 register definition end */ + #endif /* _ROCKCHIP_VOP_REG_H */
[PATCH v2] rtc: Add tracepoints for RTC system
It will be more helpful to add some tracepoints to track RTC actions when debugging RTC driver. Below sample is that we set/read the RTC time, then set 2 alarms, so we can see the trace logs: set/read RTC time: kworker/0:1-67 [000] 21.814245: rtc_set_time: 2017-11-10 08:13:00 UTC (1510301580) (0) kworker/0:1-67 [000] 21.814312: rtc_read_time: 2017-11-10 08:13:00 UTC (1510301580) (0) set the first alarm timer: kworker/0:1-67 [000] 21.829238: rtc_timer_enqueue: RTC timer:(ffc15eb49bc8) expires:15103017000 period:0 kworker/0:1-67 [000] 22.018279: rtc_set_alarm: 2017-11-10 08:15:00 UTC (1510301700) (0) set the second alarm timer: kworker/0:1-67 [000] 22.230284: rtc_timer_enqueue: RTC timer:(ff80088e6430) expires:15103018200 period:0 the first alarm timer was expired: kworker/0:1-67 [000] 145.155584: rtc_timer_dequeue: RTC timer:(ffc15eb49bc8) expires:15103017000 period:0 kworker/0:1-67 [000] 145.155593: rtc_timer_fired: RTC timer:(ffc15eb49bc8) expires:15103017000 period:0 kworker/0:1-67 [000] 145.172504: rtc_set_alarm: 2017-11-10 08:17:00 UTC (1510301820) (0) the second alarm timer was expired: kworker/0:1-67 [000] 269.102353: rtc_timer_dequeue: RTC timer:(ff80088e6430) expires:15103018200 period:0 kworker/0:1-67 [000] 269.102360: rtc_timer_fired: RTC timer:(ff80088e6430) expires:15103018200 period:0 disable alarm irq: kworker/0:1-67 [000] 269.102469: rtc_alarm_irq_enable: disable RTC alarm IRQ (0) Signed-off-by: Baolin Wang--- Changes since v1: - Use unconditional tracepoints with tracing the failures. - Simplify the rtc_timer_class. --- drivers/rtc/interface.c| 30 ++ include/trace/events/rtc.h | 220 2 files changed, 250 insertions(+) create mode 100644 include/trace/events/rtc.h diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 8cec9a0..879e40d 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -17,6 +17,9 @@ #include #include +#define CREATE_TRACE_POINTS +#include + static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer); static void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer); @@ -53,6 +56,8 @@ int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm) err = __rtc_read_time(rtc, tm); mutex_unlock(>ops_lock); + + trace_rtc_read_time(tm, err); return err; } EXPORT_SYMBOL_GPL(rtc_read_time); @@ -87,6 +92,8 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm) mutex_unlock(>ops_lock); /* A timer might have just expired */ schedule_work(>irqwork); + + trace_rtc_set_time(tm, err); return err; } EXPORT_SYMBOL_GPL(rtc_set_time); @@ -119,6 +126,8 @@ static int rtc_read_alarm_internal(struct rtc_device *rtc, struct rtc_wkalrm *al } mutex_unlock(>ops_lock); + + trace_rtc_read_alarm(>time, err); return err; } @@ -316,6 +325,7 @@ int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) } mutex_unlock(>ops_lock); + trace_rtc_read_alarm(>time, err); return err; } EXPORT_SYMBOL_GPL(rtc_read_alarm); @@ -352,6 +362,7 @@ static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) else err = rtc->ops->set_alarm(rtc->dev.parent, alarm); + trace_rtc_set_alarm(>time, err); return err; } @@ -406,6 +417,7 @@ int rtc_initialize_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) rtc->aie_timer.enabled = 1; timerqueue_add(>timerqueue, >aie_timer.node); + trace_rtc_timer_enqueue(>aie_timer); } mutex_unlock(>ops_lock); return err; @@ -435,6 +447,8 @@ int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled) err = rtc->ops->alarm_irq_enable(rtc->dev.parent, enabled); mutex_unlock(>ops_lock); + + trace_rtc_alarm_irq_enable(enabled, err); return err; } EXPORT_SYMBOL_GPL(rtc_alarm_irq_enable); @@ -709,6 +723,8 @@ int rtc_irq_set_state(struct rtc_device *rtc, struct rtc_task *task, int enabled rtc->pie_enabled = enabled; } spin_unlock_irqrestore(>irq_task_lock, flags); + + trace_rtc_irq_set_state(enabled, err); return err; } EXPORT_SYMBOL_GPL(rtc_irq_set_state); @@ -745,6 +761,8 @@ int rtc_irq_set_freq(struct rtc_device *rtc, struct rtc_task *task, int freq) } } spin_unlock_irqrestore(>irq_task_lock, flags); + + trace_rtc_irq_set_freq(freq, err); return err; } EXPORT_SYMBOL_GPL(rtc_irq_set_freq); @@ -779,6 +797,7 @@ static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer) } timerqueue_add(>timerqueue, >node); + trace_rtc_timer_enqueue(timer); if (!next) {
[PATCH v2] rtc: Add tracepoints for RTC system
It will be more helpful to add some tracepoints to track RTC actions when debugging RTC driver. Below sample is that we set/read the RTC time, then set 2 alarms, so we can see the trace logs: set/read RTC time: kworker/0:1-67 [000] 21.814245: rtc_set_time: 2017-11-10 08:13:00 UTC (1510301580) (0) kworker/0:1-67 [000] 21.814312: rtc_read_time: 2017-11-10 08:13:00 UTC (1510301580) (0) set the first alarm timer: kworker/0:1-67 [000] 21.829238: rtc_timer_enqueue: RTC timer:(ffc15eb49bc8) expires:15103017000 period:0 kworker/0:1-67 [000] 22.018279: rtc_set_alarm: 2017-11-10 08:15:00 UTC (1510301700) (0) set the second alarm timer: kworker/0:1-67 [000] 22.230284: rtc_timer_enqueue: RTC timer:(ff80088e6430) expires:15103018200 period:0 the first alarm timer was expired: kworker/0:1-67 [000] 145.155584: rtc_timer_dequeue: RTC timer:(ffc15eb49bc8) expires:15103017000 period:0 kworker/0:1-67 [000] 145.155593: rtc_timer_fired: RTC timer:(ffc15eb49bc8) expires:15103017000 period:0 kworker/0:1-67 [000] 145.172504: rtc_set_alarm: 2017-11-10 08:17:00 UTC (1510301820) (0) the second alarm timer was expired: kworker/0:1-67 [000] 269.102353: rtc_timer_dequeue: RTC timer:(ff80088e6430) expires:15103018200 period:0 kworker/0:1-67 [000] 269.102360: rtc_timer_fired: RTC timer:(ff80088e6430) expires:15103018200 period:0 disable alarm irq: kworker/0:1-67 [000] 269.102469: rtc_alarm_irq_enable: disable RTC alarm IRQ (0) Signed-off-by: Baolin Wang --- Changes since v1: - Use unconditional tracepoints with tracing the failures. - Simplify the rtc_timer_class. --- drivers/rtc/interface.c| 30 ++ include/trace/events/rtc.h | 220 2 files changed, 250 insertions(+) create mode 100644 include/trace/events/rtc.h diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 8cec9a0..879e40d 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -17,6 +17,9 @@ #include #include +#define CREATE_TRACE_POINTS +#include + static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer); static void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer); @@ -53,6 +56,8 @@ int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm) err = __rtc_read_time(rtc, tm); mutex_unlock(>ops_lock); + + trace_rtc_read_time(tm, err); return err; } EXPORT_SYMBOL_GPL(rtc_read_time); @@ -87,6 +92,8 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm) mutex_unlock(>ops_lock); /* A timer might have just expired */ schedule_work(>irqwork); + + trace_rtc_set_time(tm, err); return err; } EXPORT_SYMBOL_GPL(rtc_set_time); @@ -119,6 +126,8 @@ static int rtc_read_alarm_internal(struct rtc_device *rtc, struct rtc_wkalrm *al } mutex_unlock(>ops_lock); + + trace_rtc_read_alarm(>time, err); return err; } @@ -316,6 +325,7 @@ int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) } mutex_unlock(>ops_lock); + trace_rtc_read_alarm(>time, err); return err; } EXPORT_SYMBOL_GPL(rtc_read_alarm); @@ -352,6 +362,7 @@ static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) else err = rtc->ops->set_alarm(rtc->dev.parent, alarm); + trace_rtc_set_alarm(>time, err); return err; } @@ -406,6 +417,7 @@ int rtc_initialize_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) rtc->aie_timer.enabled = 1; timerqueue_add(>timerqueue, >aie_timer.node); + trace_rtc_timer_enqueue(>aie_timer); } mutex_unlock(>ops_lock); return err; @@ -435,6 +447,8 @@ int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled) err = rtc->ops->alarm_irq_enable(rtc->dev.parent, enabled); mutex_unlock(>ops_lock); + + trace_rtc_alarm_irq_enable(enabled, err); return err; } EXPORT_SYMBOL_GPL(rtc_alarm_irq_enable); @@ -709,6 +723,8 @@ int rtc_irq_set_state(struct rtc_device *rtc, struct rtc_task *task, int enabled rtc->pie_enabled = enabled; } spin_unlock_irqrestore(>irq_task_lock, flags); + + trace_rtc_irq_set_state(enabled, err); return err; } EXPORT_SYMBOL_GPL(rtc_irq_set_state); @@ -745,6 +761,8 @@ int rtc_irq_set_freq(struct rtc_device *rtc, struct rtc_task *task, int freq) } } spin_unlock_irqrestore(>irq_task_lock, flags); + + trace_rtc_irq_set_freq(freq, err); return err; } EXPORT_SYMBOL_GPL(rtc_irq_set_freq); @@ -779,6 +797,7 @@ static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer) } timerqueue_add(>timerqueue, >node); + trace_rtc_timer_enqueue(timer); if (!next) { struct
Re: [PATCH 1/2] x86,kvm: move qemu/guest FPU switching out to vcpu_run
2017-11-15 22:40 GMT+08:00 Rik van Riel: > On Wed, 2017-11-15 at 12:33 +0800, Wanpeng Li wrote: >> 2017-11-15 11:03 GMT+08:00 Rik van Riel : >> > On Wed, 2017-11-15 at 08:47 +0800, Wanpeng Li wrote: >> > > 2017-11-15 5:54 GMT+08:00 : >> > > > From: Rik van Riel >> > > > >> > > > Currently, every time a VCPU is scheduled out, the host kernel >> > > > will >> > > > first save the guest FPU/xstate context, then load the qemu >> > > > userspace >> > > > FPU context, only to then immediately save the qemu userspace >> > > > FPU >> > > > context back to memory. When scheduling in a VCPU, the same >> > > > extraneous >> > > > FPU loads and saves are done. >> > > > >> > > > This could be avoided by moving from a model where the guest >> > > > FPU is >> > > > loaded and stored with preemption disabled, to a model where >> > > > the >> > > > qemu userspace FPU is swapped out for the guest FPU context for >> > > > the duration of the KVM_RUN ioctl. >> > > >> > > What will happen if CONFIG_PREEMPT is enabled? >> > >> > The scheduler will save the guest FPU context when a >> > VCPU thread is preempted, and restore it when it is >> > scheduled back in. >> >> I mean all the involved processes will use fpu. Before patch if >> kernel >> preempt occur: >> >> context_switch >> -> prepare_task_switch >> -> fire_sched_out_preempt_notifiers >> -> kvm_sched_out >> -> kvm_arch_vcpu_put >> -> kvm_put_guest_fpu >>-> copy_fpregs_to_fpstate( >> >arch.guest_fpu) >> save xsave area to guest fpu >> buffer >>-> __kernel_fpu_end >> -> >> copy_kernel_to_fpregs(>thread.fpu.state) >> restore prev vCPU qemu >> userspace FPU to the xsave area >> -> switch_to >> -> __switch_to >> -> switch_fpu_prepare >> -> copy_fpregs_to_fpstate => save xsave area to >> prev >> vCPU qemu userspace FPU >> -> switch_fpu_finish >> -> copy_kernel_to_fpgregs => restore next task FPU >> to xsave area >> >> >> After the patch: >> >> context_switch >> -> prepare_task_switch >> -> fire_sched_out_preempt_notifiers >> -> kvm_sched_out >> >> -> switch_to >> -> __switch_to >> -> switch_fpu_prepare >> -> copy_fpregs_to_fpstate => Oops >> save xsave area to prev vCPU qemu userspace FPU, >> actually the guest FPU buffer is loaded in xsave area, you transmit >> guest FPU in xsave area into the prev vCPU qemu userspace FPU > > When entering kvm_arch_vcpu_ioctl_run we save the qemu userspace > FPU context in >arch.user_fpu, and we restore that before > leaving kvm_arch_vcpu_ioctl_run. > > Userspace should always see the userspace FPU context, no? You are right. Regards, Wanpeng Li
Re: [PATCH 1/2] x86,kvm: move qemu/guest FPU switching out to vcpu_run
2017-11-15 22:40 GMT+08:00 Rik van Riel : > On Wed, 2017-11-15 at 12:33 +0800, Wanpeng Li wrote: >> 2017-11-15 11:03 GMT+08:00 Rik van Riel : >> > On Wed, 2017-11-15 at 08:47 +0800, Wanpeng Li wrote: >> > > 2017-11-15 5:54 GMT+08:00 : >> > > > From: Rik van Riel >> > > > >> > > > Currently, every time a VCPU is scheduled out, the host kernel >> > > > will >> > > > first save the guest FPU/xstate context, then load the qemu >> > > > userspace >> > > > FPU context, only to then immediately save the qemu userspace >> > > > FPU >> > > > context back to memory. When scheduling in a VCPU, the same >> > > > extraneous >> > > > FPU loads and saves are done. >> > > > >> > > > This could be avoided by moving from a model where the guest >> > > > FPU is >> > > > loaded and stored with preemption disabled, to a model where >> > > > the >> > > > qemu userspace FPU is swapped out for the guest FPU context for >> > > > the duration of the KVM_RUN ioctl. >> > > >> > > What will happen if CONFIG_PREEMPT is enabled? >> > >> > The scheduler will save the guest FPU context when a >> > VCPU thread is preempted, and restore it when it is >> > scheduled back in. >> >> I mean all the involved processes will use fpu. Before patch if >> kernel >> preempt occur: >> >> context_switch >> -> prepare_task_switch >> -> fire_sched_out_preempt_notifiers >> -> kvm_sched_out >> -> kvm_arch_vcpu_put >> -> kvm_put_guest_fpu >>-> copy_fpregs_to_fpstate( >> >arch.guest_fpu) >> save xsave area to guest fpu >> buffer >>-> __kernel_fpu_end >> -> >> copy_kernel_to_fpregs(>thread.fpu.state) >> restore prev vCPU qemu >> userspace FPU to the xsave area >> -> switch_to >> -> __switch_to >> -> switch_fpu_prepare >> -> copy_fpregs_to_fpstate => save xsave area to >> prev >> vCPU qemu userspace FPU >> -> switch_fpu_finish >> -> copy_kernel_to_fpgregs => restore next task FPU >> to xsave area >> >> >> After the patch: >> >> context_switch >> -> prepare_task_switch >> -> fire_sched_out_preempt_notifiers >> -> kvm_sched_out >> >> -> switch_to >> -> __switch_to >> -> switch_fpu_prepare >> -> copy_fpregs_to_fpstate => Oops >> save xsave area to prev vCPU qemu userspace FPU, >> actually the guest FPU buffer is loaded in xsave area, you transmit >> guest FPU in xsave area into the prev vCPU qemu userspace FPU > > When entering kvm_arch_vcpu_ioctl_run we save the qemu userspace > FPU context in >arch.user_fpu, and we restore that before > leaving kvm_arch_vcpu_ioctl_run. > > Userspace should always see the userspace FPU context, no? You are right. Regards, Wanpeng Li
HELLO
-- Am Mr.Sare Ouedraogo. i work in one of the prime bank here in burkina faso, i want the bank to transfer the money left by our late customer is a foreigner from Korea. can you investment this money and also help the poor' the amount value at $13,300,000.00 (Thirteen Million Three Hundred Thousand United States American Dollars), left in his account still unclaimed. more details will be giving to you if you are interested best regards Mr.Sare Ouedraogo --
HELLO
-- Am Mr.Sare Ouedraogo. i work in one of the prime bank here in burkina faso, i want the bank to transfer the money left by our late customer is a foreigner from Korea. can you investment this money and also help the poor' the amount value at $13,300,000.00 (Thirteen Million Three Hundred Thousand United States American Dollars), left in his account still unclaimed. more details will be giving to you if you are interested best regards Mr.Sare Ouedraogo --
Re: [PATCH v3 1/5] soc: qcom: Introduce QMI encoder/decoder
On Wed 15 Nov 12:10 PST 2017, Bjorn Andersson wrote: > diff --git a/drivers/soc/qcom/qmi_encdec.c b/drivers/soc/qcom/qmi_encdec.c [..] > +void *qmi_encode_message(int type, unsigned int msg_id, size_t *len, > + unsigned int txn_id, struct qmi_elem_info *ei, > + const void *c_struct) > +{ > + struct qmi_header *hdr; > + ssize_t msglen = 0; > + void *msg; > + int ret; > + > + /* Check the possibility of a zero length QMI message */ > + if (!c_struct) { > + ret = qmi_calc_min_msg_len(ei, 1); > + if (ret) { > + pr_err("%s: Calc. len %d != 0, but NULL c_struct\n", > +__func__, ret); > + return ERR_PTR(-EINVAL); > + } > + } > + > + msg = kzalloc(sizeof(*hdr) + *len, GFP_KERNEL); > + if (!msg) > + return ERR_PTR(-ENOMEM); > + > + msglen = qmi_encode(ei, msg + sizeof(*hdr), c_struct, *len, 1); > + if (msglen < 0) { > + kfree(msg); > + return ERR_PTR(msglen); > + } Talked to Chris Lew about this earlier today; The check above implies that it's valid to call this function with a valid ei of minimum message length of 0 and c_struct being NULL. But the call to qmi_encdec() will dereference c_struct in order to know that the optional elements described in ei are unset. So the call to qmi_encode() needs to only be done conditionally on c_struct being non-NULL, logically interpreting c_struct being NULL as all optional fields are unset. Will post an update with this fixed. > + > + hdr = msg; > + hdr->type = type; > + hdr->txn_id = txn_id; > + hdr->msg_id = msg_id; > + hdr->msg_len = msglen; > + > + *len = sizeof(*hdr) + msglen; > + > + return msg; > +} > +EXPORT_SYMBOL(qmi_encode_message); Regards, Bjorn
Re: [PATCH v3 1/5] soc: qcom: Introduce QMI encoder/decoder
On Wed 15 Nov 12:10 PST 2017, Bjorn Andersson wrote: > diff --git a/drivers/soc/qcom/qmi_encdec.c b/drivers/soc/qcom/qmi_encdec.c [..] > +void *qmi_encode_message(int type, unsigned int msg_id, size_t *len, > + unsigned int txn_id, struct qmi_elem_info *ei, > + const void *c_struct) > +{ > + struct qmi_header *hdr; > + ssize_t msglen = 0; > + void *msg; > + int ret; > + > + /* Check the possibility of a zero length QMI message */ > + if (!c_struct) { > + ret = qmi_calc_min_msg_len(ei, 1); > + if (ret) { > + pr_err("%s: Calc. len %d != 0, but NULL c_struct\n", > +__func__, ret); > + return ERR_PTR(-EINVAL); > + } > + } > + > + msg = kzalloc(sizeof(*hdr) + *len, GFP_KERNEL); > + if (!msg) > + return ERR_PTR(-ENOMEM); > + > + msglen = qmi_encode(ei, msg + sizeof(*hdr), c_struct, *len, 1); > + if (msglen < 0) { > + kfree(msg); > + return ERR_PTR(msglen); > + } Talked to Chris Lew about this earlier today; The check above implies that it's valid to call this function with a valid ei of minimum message length of 0 and c_struct being NULL. But the call to qmi_encdec() will dereference c_struct in order to know that the optional elements described in ei are unset. So the call to qmi_encode() needs to only be done conditionally on c_struct being non-NULL, logically interpreting c_struct being NULL as all optional fields are unset. Will post an update with this fixed. > + > + hdr = msg; > + hdr->type = type; > + hdr->txn_id = txn_id; > + hdr->msg_id = msg_id; > + hdr->msg_len = msglen; > + > + *len = sizeof(*hdr) + msglen; > + > + return msg; > +} > +EXPORT_SYMBOL(qmi_encode_message); Regards, Bjorn
Re: [PATCH v5 2/4] KVM: X86: Add paravirt remote TLB flush
2017-11-13 18:01 GMT+08:00 Wanpeng Li: > From: Wanpeng Li > > Remote flushing api's does a busy wait which is fine in bare-metal > scenario. But with-in the guest, the vcpus might have been pre-empted > or blocked. In this scenario, the initator vcpu would end up > busy-waiting for a long amount of time. > > This patch set implements para-virt flush tlbs making sure that it does > not wait for vcpus that are sleeping. And all the sleeping vcpus flush > the tlb on guest enter. > > The best result is achieved when we're overcommiting the host by running > multiple vCPUs on each pCPU. In this case PV tlb flush avoids touching > vCPUs which are not scheduled and avoid the wait on the main CPU. > > Test on a Haswell i7 desktop 4 cores (2HT), so 8 pCPUs, running ebizzy > in one linux guest. > > ebizzy -M > vanillaoptimized boost > 8 vCPUs 10152 10083 -0.68% > 16 vCPUs12244866 297.5% > 24 vCPUs11093871 249% > 32 vCPUs10253375 229.3% > > Cc: Paolo Bonzini > Cc: Radim Krčmář > Cc: Peter Zijlstra > Signed-off-by: Wanpeng Li > --- > Documentation/virtual/kvm/cpuid.txt | 4 > arch/x86/include/uapi/asm/kvm_para.h | 2 ++ > arch/x86/kernel/kvm.c| 42 > +++- > 3 files changed, 47 insertions(+), 1 deletion(-) > > diff --git a/Documentation/virtual/kvm/cpuid.txt > b/Documentation/virtual/kvm/cpuid.txt > index 117066a..9693fcc 100644 > --- a/Documentation/virtual/kvm/cpuid.txt > +++ b/Documentation/virtual/kvm/cpuid.txt > @@ -60,6 +60,10 @@ KVM_FEATURE_PV_DEDICATED || 8 || guest > checks this feature bit > || || mizations such as usage of > || || qspinlocks. > > -- > +KVM_FEATURE_PV_TLB_FLUSH || 9 || guest checks this feature bit > + || || before enabling > paravirtualized > + || || tlb flush. > +-- > KVM_FEATURE_CLOCKSOURCE_STABLE_BIT ||24 || host will warn if no > guest-side > || || per-cpu warps are expected in > || || kvmclock. > diff --git a/arch/x86/include/uapi/asm/kvm_para.h > b/arch/x86/include/uapi/asm/kvm_para.h > index 6d66556..e267d83 100644 > --- a/arch/x86/include/uapi/asm/kvm_para.h > +++ b/arch/x86/include/uapi/asm/kvm_para.h > @@ -26,6 +26,7 @@ > #define KVM_FEATURE_PV_EOI 6 > #define KVM_FEATURE_PV_UNHALT 7 > #define KVM_FEATURE_PV_DEDICATED 8 > +#define KVM_FEATURE_PV_TLB_FLUSH 9 > > /* The last 8 bits are used to indicate how to interpret the flags field > * in pvclock structure. If no bits are set, all flags are ignored. > @@ -54,6 +55,7 @@ struct kvm_steal_time { > > #define KVM_VCPU_NOT_PREEMPTED (0 << 0) > #define KVM_VCPU_PREEMPTED (1 << 0) > +#define KVM_VCPU_SHOULD_FLUSH (1 << 1) > > #define KVM_CLOCK_PAIRING_WALLCLOCK 0 > struct kvm_clock_pairing { > diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c > index 66ed3bc..78794c1 100644 > --- a/arch/x86/kernel/kvm.c > +++ b/arch/x86/kernel/kvm.c > @@ -465,9 +465,40 @@ static void __init kvm_apf_trap_init(void) > update_intr_gate(X86_TRAP_PF, async_page_fault); > } > > +static DEFINE_PER_CPU(cpumask_var_t, __pv_tlb_mask); > + > +static void kvm_flush_tlb_others(const struct cpumask *cpumask, > + const struct flush_tlb_info *info) > +{ > + u8 state; > + int cpu; > + struct kvm_steal_time *src; > + struct cpumask *flushmask = this_cpu_cpumask_var_ptr(__pv_tlb_mask); > + > + if (unlikely(!flushmask)) > + return; > + > + cpumask_copy(flushmask, cpumask); > + /* > +* We have to call flush only on online vCPUs. And > +* queue flush_on_enter for pre-empted vCPUs > +*/ > + for_each_cpu(cpu, flushmask) { > + src = _cpu(steal_time, cpu); > + state = READ_ONCE(src->preempted); > + if ((state & KVM_VCPU_PREEMPTED)) { > + if (try_cmpxchg(>preempted, , > + state | KVM_VCPU_SHOULD_FLUSH)) > + __cpumask_clear_cpu(cpu, flushmask); > + } > + } > + > + native_flush_tlb_others(flushmask, info); > +} > + > void __init kvm_guest_init(void) > { > - int i; > + int i, cpu; > > if (!kvm_para_available()) > return; > @@ -484,6 +515,15 @@ void __init kvm_guest_init(void) >
[PATCH] mailbox: txdone_method shouldn't always be reset
A client that knows how to drive txdone would temporarily "upgrade" the method to TXDONE_BY_ACK. But with the introduction of commit 33cd7123ac0ba ("mailbox: reset txdone_method TXDONE_BY_POLL if client knows_txdone") there is no longer a distinction between a channel in "upgraded" state or a channel for a controller that only supports TXDONE_BY_ACK. So upon freeing the channel it will be "downgraded" to TXDONE_BY_POLL. But a channel that operates with the txdone method of TXDONE_BY_POLL requires that the controller implements the last_tx_done callback and that the associated hrtimer was initialized when the controller was registered. So the core now relies on the fact that subsequent calls to mbox_request_channel() "upgrades" the channel to TXDONE_BY_ACK or it will dereference the non-initialized hrtimer. The intention of commit 33cd7123ac0ba ("mailbox: reset txdone_method TXDONE_BY_POLL if client knows_txdone") is to not restart the hrtimer when the channel is in an "upgraded" state. So this patch reverts the commit, in order to never leave the channel is a invalid state, and instead only start the timer when we're in the "non-upgraded" POLL state. Fixes: 33cd7123ac0ba ("mailbox: reset txdone_method TXDONE_BY_POLL if client knows_txdone") Signed-off-by: Bjorn Andersson--- drivers/mailbox/mailbox.c | 6 +++--- drivers/mailbox/pcc.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c index 674b35f402f5..da8d666a8c56 100644 --- a/drivers/mailbox/mailbox.c +++ b/drivers/mailbox/mailbox.c @@ -85,7 +85,7 @@ static void msg_submit(struct mbox_chan *chan) exit: spin_unlock_irqrestore(>lock, flags); - if (!err && (chan->txdone_method & TXDONE_BY_POLL)) + if (!err && chan->txdone_method == TXDONE_BY_POLL) /* kick start the timer immediately to avoid delays */ hrtimer_start(>mbox->poll_hrt, 0, HRTIMER_MODE_REL); } @@ -351,7 +351,7 @@ struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index) init_completion(>tx_complete); if (chan->txdone_method == TXDONE_BY_POLL && cl->knows_txdone) - chan->txdone_method = TXDONE_BY_ACK; + chan->txdone_method |= TXDONE_BY_ACK; spin_unlock_irqrestore(>lock, flags); @@ -418,7 +418,7 @@ void mbox_free_channel(struct mbox_chan *chan) spin_lock_irqsave(>lock, flags); chan->cl = NULL; chan->active_req = NULL; - if (chan->txdone_method == TXDONE_BY_ACK) + if (chan->txdone_method == (TXDONE_BY_POLL | TXDONE_BY_ACK)) chan->txdone_method = TXDONE_BY_POLL; module_put(chan->mbox->dev->driver->owner); diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c index 3ef7f036ceea..e5a69679cfa2 100644 --- a/drivers/mailbox/pcc.c +++ b/drivers/mailbox/pcc.c @@ -265,7 +265,7 @@ struct mbox_chan *pcc_mbox_request_channel(struct mbox_client *cl, init_completion(>tx_complete); if (chan->txdone_method == TXDONE_BY_POLL && cl->knows_txdone) - chan->txdone_method = TXDONE_BY_ACK; + chan->txdone_method |= TXDONE_BY_ACK; spin_unlock_irqrestore(>lock, flags); @@ -311,7 +311,7 @@ void pcc_mbox_free_channel(struct mbox_chan *chan) spin_lock_irqsave(>lock, flags); chan->cl = NULL; chan->active_req = NULL; - if (chan->txdone_method == TXDONE_BY_ACK) + if (chan->txdone_method == (TXDONE_BY_POLL | TXDONE_BY_ACK)) chan->txdone_method = TXDONE_BY_POLL; spin_unlock_irqrestore(>lock, flags); -- 2.15.0