Linux v4.0-rc4

- Drop arm64 RCU revert patch.  Should be fixed properly upstream now.
- Disable debugging options.
This commit is contained in:
Josh Boyer 2015-03-16 10:07:00 -04:00
parent cd37906b18
commit 9608f11d20
16 changed files with 189 additions and 737 deletions

View File

@ -43,7 +43,7 @@ Signed-off-by: Josh Stone <jistone@redhat.com>
2 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
index 1100ff3c77e3..b4f8a4909e4e 100644
index e734965b1604..c724e72b238d 100644
--- a/Makefile
+++ b/Makefile
@@ -706,7 +706,11 @@ KBUILD_CFLAGS += -fomit-frame-pointer

View File

@ -1,42 +0,0 @@
From: Josh Boyer <jwboyer@fedoraproject.org>
Date: Tue, 10 Mar 2015 20:21:24 -0400
Subject: [PATCH] Revert "cpupower Makefile change to help run the tool without
'make install'"
This reverts commit 5c1de006e8e66b0be05be422416629e344c71652.
While the original commit makes it easier to run cpupower from the local build
directory, it also leaves the binary with a rather poor rpath of './' in it
after it is installed on a system via 'make install'.
This is considered bad practice and can cause cpupower to fail in rpmbuild
with the following error:
ERROR 0004: file '/usr/bin/cpupower' contains an insecure rpath './' in [./]
error: Bad exit status from /var/tmp/rpm-tmp.A6u26r (%install)
Bad exit status from /var/tmp/rpm-tmp.A6u26r (%install)
Developers should be able to use LD_LIBRARY_PATH to achieve the same effect
and not introduce rpath into the binary.
Signed-off-by: Josh Boyer <jwboyer@feoraproject.org>
---
tools/power/cpupower/Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/power/cpupower/Makefile b/tools/power/cpupower/Makefile
index 3ed7c0476d48..2e2ba2efa0d9 100644
--- a/tools/power/cpupower/Makefile
+++ b/tools/power/cpupower/Makefile
@@ -209,7 +209,7 @@ $(OUTPUT)%.o: %.c
$(OUTPUT)cpupower: $(UTIL_OBJS) $(OUTPUT)libcpupower.so.$(LIB_MAJ)
$(ECHO) " CC " $@
- $(QUIET) $(CC) $(CFLAGS) $(LDFLAGS) $(UTIL_OBJS) -lcpupower -Wl,-rpath=./ -lrt -lpci -L$(OUTPUT) -o $@
+ $(QUIET) $(CC) $(CFLAGS) $(LDFLAGS) $(UTIL_OBJS) -lcpupower -lrt -lpci -L$(OUTPUT) -o $@
$(QUIET) $(STRIPCMD) $@
$(OUTPUT)po/$(PACKAGE).pot: $(UTIL_SRC)
--
2.1.0

View File

@ -9,10 +9,10 @@ Signed-off-by: Robert Nelson <robertcnelson@gmail.com>
1 file changed, 21 insertions(+)
diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi
index db880bf46135..c931ec7201c0 100644
index 9688dda39e7a..8e3e77f3121f 100644
--- a/arch/arm/boot/dts/am335x-bone-common.dtsi
+++ b/arch/arm/boot/dts/am335x-bone-common.dtsi
@@ -102,6 +102,27 @@
@@ -109,6 +109,27 @@
>;
};

View File

@ -8,7 +8,7 @@ Signed-off-by: Robert Nelson <robertcnelson@gmail.com>
1 file changed, 39 insertions(+)
diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi
index 2c6248d9a9ef..ec755eeb78ee 100644
index c3255e0c90aa..1fd496fe1a68 100644
--- a/arch/arm/boot/dts/am335x-bone-common.dtsi
+++ b/arch/arm/boot/dts/am335x-bone-common.dtsi
@@ -81,6 +81,13 @@

View File

@ -5,17 +5,24 @@ Subject: [PATCH] arm: dts: am335x-bone-common: setup default pinmux
Signed-off-by: Robert Nelson <robertcnelson@gmail.com>
---
arch/arm/boot/dts/am335x-bone-common.dtsi | 130 ++++++++++++++++++++++++++++++
1 file changed, 130 insertions(+)
arch/arm/boot/dts/am335x-bone-common.dtsi | 222 ++++++++++++++++++++++++++++++
1 file changed, 222 insertions(+)
diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi
index ec755eeb78ee..db880bf46135 100644
index 1fd496fe1a68..9688dda39e7a 100644
--- a/arch/arm/boot/dts/am335x-bone-common.dtsi
+++ b/arch/arm/boot/dts/am335x-bone-common.dtsi
@@ -95,6 +95,13 @@
@@ -95,6 +95,20 @@
>;
};
+ uart1_pins: pinmux_uart1_pins {
+ pinctrl-single,pins = <
+ 0x180 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart1_rxd.uart1_rxd */
+ 0x184 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart1_txd.uart1_txd */
+ >;
+ };
+
+ uart1_pins: pinmux_uart1_pins {
+ pinctrl-single,pins = <
+ 0x180 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart1_rxd.uart1_rxd */
@ -26,7 +33,7 @@ index ec755eeb78ee..db880bf46135 100644
clkout2_pin: pinmux_clkout2_pin {
pinctrl-single,pins = <
0x1b4 (PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr1.clkout2 */
@@ -175,6 +182,33 @@
@@ -175,6 +189,60 @@
0x1c (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad7.mmc1_dat7 */
>;
};
@ -56,14 +63,48 @@ index ec755eeb78ee..db880bf46135 100644
+ pinctrl-single,pins = <
+ 0x164 0x0 /* P9_42 (ZCZ ball C18) | MODE 0 */
+ >;
+ };
+
+ spi0_pins: pinmux_spi0_pins {
+ pinctrl-single,pins = <
+ 0x150 (PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_sclk.spi0_sclk */
+ 0x154 (PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_d0.spi0_d0 */
+ 0x158 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* spi0_d1.spi0_d1 */
+ 0x15c (PIN_OUTPUT_PULLUP | MUX_MODE0) /* spi0_cs0.spi0_cs0 */
+ >;
+ };
+
+ ehrpwm1_pin_p9_14: pinmux_ehrpwm1_pin_p9_14 {
+ pinctrl-single,pins = <
+ 0x048 0x6 /* P9_14 (ZCZ ball U14) | MODE 6 */
+ >;
+ };
+
+ ehrpwm1_pin_p9_16: pinmux_ehrpwm1_pin_p9_16 {
+ pinctrl-single,pins = <
+ 0x04c 0x6 /* P9_16 (ZCZ ball T14) | MODE 6 */
+ >;
+ };
+
+ ecap0_pin_p9_42: pinmux_ecap0_pin_p9_42 {
+ pinctrl-single,pins = <
+ 0x164 0x0 /* P9_42 (ZCZ ball C18) | MODE 0 */
+ >;
+ };
};
&uart0 {
@@ -184,6 +218,13 @@
@@ -184,6 +252,20 @@
status = "okay";
};
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
@ -74,10 +115,60 @@ index ec755eeb78ee..db880bf46135 100644
&usb {
status = "okay";
};
@@ -259,6 +300,56 @@
@@ -259,6 +341,106 @@
};
};
+&epwmss0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ecap0_pin_p9_42>;
+ status = "okay";
+
+ ecap@48300100 {
+ status = "okay";
+ };
+};
+
+&epwmss1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &ehrpwm1_pin_p9_14
+ &ehrpwm1_pin_p9_16
+ >;
+
+ status = "okay";
+
+ ehrpwm@48302200 {
+ status = "okay";
+ };
+};
+
+&spi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pins>;
+ status = "okay";
+
+ spidev0: spi@0 {
+ compatible = "spidev";
+ reg = <0>;
+ spi-max-frequency = <16000000>;
+ spi-cpha;
+ };
+
+ spidev1: spi@1 {
+ compatible = "spidev";
+ reg = <1>;
+ spi-max-frequency = <16000000>;
+ };
+};
+
+&tscadc {
+ status = "okay";
+ adc {
+ ti,adc-channels = <4 5 6>;
+ };
+};
+
+&epwmss0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ecap0_pin_p9_42>;
@ -131,10 +222,12 @@ index ec755eeb78ee..db880bf46135 100644
/include/ "tps65217.dtsi"
&tps {
@@ -340,3 +431,42 @@
cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
cd-inverted;
};
@@ -347,4 +529,44 @@
&sham {
status = "okay";
+
+};
+
+/ {
+ ocp {
@ -173,7 +266,7 @@ index ec755eeb78ee..db880bf46135 100644
+ status = "okay";
+ };
+ };
+};
};
--
2.1.0

View File

@ -1,436 +0,0 @@
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 1b8e973..31042fe 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -65,7 +65,6 @@ config ARM64
select HAVE_PERF_EVENTS
select HAVE_PERF_REGS
select HAVE_PERF_USER_STACK_DUMP
- select HAVE_RCU_TABLE_FREE
select HAVE_SYSCALL_TRACEPOINTS
select IRQ_DOMAIN
select MODULES_USE_ELF_RELA
@@ -119,9 +118,6 @@ config GENERIC_CALIBRATE_DELAY
config ZONE_DMA
def_bool y
-config HAVE_GENERIC_RCU_GUP
- def_bool y
-
config ARCH_DMA_ADDR_T_64BIT
def_bool y
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 800ec0e..e2e79ac 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -243,16 +243,6 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
#define __HAVE_ARCH_PTE_SPECIAL
-static inline pte_t pud_pte(pud_t pud)
-{
- return __pte(pud_val(pud));
-}
-
-static inline pmd_t pud_pmd(pud_t pud)
-{
- return __pmd(pud_val(pud));
-}
-
static inline pte_t pmd_pte(pmd_t pmd)
{
return __pte(pmd_val(pmd));
@@ -275,13 +265,7 @@ static inline pgprot_t mk_sect_prot(pgprot_t prot)
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
#define pmd_trans_huge(pmd) (pmd_val(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT))
#define pmd_trans_splitting(pmd) pte_special(pmd_pte(pmd))
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
-#define __HAVE_ARCH_PMDP_SPLITTING_FLUSH
-struct vm_area_struct;
-void pmdp_splitting_flush(struct vm_area_struct *vma, unsigned long address,
- pmd_t *pmdp);
-#endif /* CONFIG_HAVE_RCU_TABLE_FREE */
-#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
+#endif
#define pmd_dirty(pmd) pte_dirty(pmd_pte(pmd))
#define pmd_young(pmd) pte_young(pmd_pte(pmd))
@@ -302,7 +286,7 @@ void pmdp_splitting_flush(struct vm_area_struct *vma, unsigned long address,
#define pfn_pmd(pfn,prot) (__pmd(((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot)))
#define mk_pmd(page,prot) pfn_pmd(page_to_pfn(page),prot)
-#define pud_write(pud) pte_write(pud_pte(pud))
+#define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd) & PHYS_MASK))
#define pud_pfn(pud) (((pud_val(pud) & PUD_MASK) & PHYS_MASK) >> PAGE_SHIFT)
#define set_pmd_at(mm, addr, pmdp, pmd) set_pte_at(mm, addr, (pte_t *)pmdp, pmd_pte(pmd))
@@ -407,8 +391,6 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
return (pmd_t *)pud_page_vaddr(*pud) + pmd_index(addr);
}
-#define pud_page(pud) pfn_to_page(__phys_to_pfn(pud_val(pud) & PHYS_MASK))
-
#endif /* CONFIG_ARM64_PGTABLE_LEVELS > 2 */
#if CONFIG_ARM64_PGTABLE_LEVELS > 3
@@ -443,8 +425,6 @@ static inline pud_t *pud_offset(pgd_t *pgd, unsigned long addr)
return (pud_t *)pgd_page_vaddr(*pgd) + pud_index(addr);
}
-#define pgd_page(pgd) pfn_to_page(__phys_to_pfn(pgd_val(pgd) & PHYS_MASK))
-
#endif /* CONFIG_ARM64_PGTABLE_LEVELS > 3 */
#define pgd_ERROR(pgd) __pgd_error(__FILE__, __LINE__, pgd_val(pgd))
diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h
index c028fe3..62731ef 100644
--- a/arch/arm64/include/asm/tlb.h
+++ b/arch/arm64/include/asm/tlb.h
@@ -19,44 +19,84 @@
#ifndef __ASM_TLB_H
#define __ASM_TLB_H
-#include <linux/pagemap.h>
-#include <linux/swap.h>
-
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
-
-#define tlb_remove_entry(tlb, entry) tlb_remove_table(tlb, entry)
-static inline void __tlb_remove_table(void *_table)
-{
- free_page_and_swap_cache((struct page *)_table);
-}
-#else
-#define tlb_remove_entry(tlb, entry) tlb_remove_page(tlb, entry)
-#endif /* CONFIG_HAVE_RCU_TABLE_FREE */
+#define __tlb_remove_pmd_tlb_entry __tlb_remove_pmd_tlb_entry
#include <asm-generic/tlb.h>
+/*
+ * There's three ways the TLB shootdown code is used:
+ * 1. Unmapping a range of vmas. See zap_page_range(), unmap_region().
+ * tlb->fullmm = 0, and tlb_start_vma/tlb_end_vma will be called.
+ * 2. Unmapping all vmas. See exit_mmap().
+ * tlb->fullmm = 1, and tlb_start_vma/tlb_end_vma will be called.
+ * Page tables will be freed.
+ * 3. Unmapping argument pages. See shift_arg_pages().
+ * tlb->fullmm = 0, but tlb_start_vma/tlb_end_vma will not be called.
+ */
static inline void tlb_flush(struct mmu_gather *tlb)
{
if (tlb->fullmm) {
flush_tlb_mm(tlb->mm);
- } else {
+ } else if (tlb->end > 0) {
struct vm_area_struct vma = { .vm_mm = tlb->mm, };
flush_tlb_range(&vma, tlb->start, tlb->end);
+ tlb->start = TASK_SIZE;
+ tlb->end = 0;
+ }
+}
+
+static inline void tlb_add_flush(struct mmu_gather *tlb, unsigned long addr)
+{
+ if (!tlb->fullmm) {
+ tlb->start = min(tlb->start, addr);
+ tlb->end = max(tlb->end, addr + PAGE_SIZE);
}
}
+/*
+ * Memorize the range for the TLB flush.
+ */
+static inline void __tlb_remove_tlb_entry(struct mmu_gather *tlb, pte_t *ptep,
+ unsigned long addr)
+{
+ tlb_add_flush(tlb, addr);
+}
+
+/*
+ * In the case of tlb vma handling, we can optimise these away in the
+ * case where we're doing a full MM flush. When we're doing a munmap,
+ * the vmas are adjusted to only cover the region to be torn down.
+ */
+static inline void tlb_start_vma(struct mmu_gather *tlb,
+ struct vm_area_struct *vma)
+{
+ if (!tlb->fullmm) {
+ tlb->start = TASK_SIZE;
+ tlb->end = 0;
+ }
+}
+
+static inline void tlb_end_vma(struct mmu_gather *tlb,
+ struct vm_area_struct *vma)
+{
+ if (!tlb->fullmm)
+ tlb_flush(tlb);
+}
+
static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
unsigned long addr)
{
pgtable_page_dtor(pte);
- tlb_remove_entry(tlb, pte);
+ tlb_add_flush(tlb, addr);
+ tlb_remove_page(tlb, pte);
}
#if CONFIG_ARM64_PGTABLE_LEVELS > 2
static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp,
unsigned long addr)
{
- tlb_remove_entry(tlb, virt_to_page(pmdp));
+ tlb_add_flush(tlb, addr);
+ tlb_remove_page(tlb, virt_to_page(pmdp));
}
#endif
@@ -64,8 +104,15 @@ static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp,
static inline void __pud_free_tlb(struct mmu_gather *tlb, pud_t *pudp,
unsigned long addr)
{
- tlb_remove_entry(tlb, virt_to_page(pudp));
+ tlb_add_flush(tlb, addr);
+ tlb_remove_page(tlb, virt_to_page(pudp));
}
#endif
+static inline void __tlb_remove_pmd_tlb_entry(struct mmu_gather *tlb, pmd_t *pmdp,
+ unsigned long address)
+{
+ tlb_add_flush(tlb, address);
+}
+
#endif
diff --git a/arch/arm64/mm/flush.c b/arch/arm64/mm/flush.c
index b6f14e8..0d64089 100644
--- a/arch/arm64/mm/flush.c
+++ b/arch/arm64/mm/flush.c
@@ -104,19 +104,3 @@ EXPORT_SYMBOL(flush_dcache_page);
*/
EXPORT_SYMBOL(flush_cache_all);
EXPORT_SYMBOL(flush_icache_range);
-
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
-void pmdp_splitting_flush(struct vm_area_struct *vma, unsigned long address,
- pmd_t *pmdp)
-{
- pmd_t pmd = pmd_mksplitting(*pmdp);
-
- VM_BUG_ON(address & ~PMD_MASK);
- set_pmd_at(vma->vm_mm, address, pmdp, pmd);
-
- /* dummy IPI to serialise against fast_gup */
- kick_all_cpus_sync();
-}
-#endif /* CONFIG_HAVE_RCU_TABLE_FREE */
-#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h
index db284bf..5672d7e 100644
--- a/include/asm-generic/tlb.h
+++ b/include/asm-generic/tlb.h
@@ -96,9 +96,10 @@ struct mmu_gather {
#endif
unsigned long start;
unsigned long end;
+ unsigned int need_flush : 1, /* Did free PTEs */
/* we are in the middle of an operation to clear
* a full mm and can make some optimizations */
- unsigned int fullmm : 1,
+ fullmm : 1,
/* we have performed an operation which
* requires a complete flush of the tlb */
need_flush_all : 1;
@@ -127,58 +128,16 @@ static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page)
tlb_flush_mmu(tlb);
}
-static inline void __tlb_adjust_range(struct mmu_gather *tlb,
- unsigned long address)
-{
- tlb->start = min(tlb->start, address);
- tlb->end = max(tlb->end, address + PAGE_SIZE);
-}
-
-static inline void __tlb_reset_range(struct mmu_gather *tlb)
-{
- if (tlb->fullmm) {
- tlb->start = tlb->end = ~0;
- } else {
- tlb->start = TASK_SIZE;
- tlb->end = 0;
- }
-}
-
-/*
- * In the case of tlb vma handling, we can optimise these away in the
- * case where we're doing a full MM flush. When we're doing a munmap,
- * the vmas are adjusted to only cover the region to be torn down.
- */
-#ifndef tlb_start_vma
-#define tlb_start_vma(tlb, vma) do { } while (0)
-#endif
-
-#define __tlb_end_vma(tlb, vma) \
- do { \
- if (!tlb->fullmm && tlb->end) { \
- tlb_flush(tlb); \
- __tlb_reset_range(tlb); \
- } \
- } while (0)
-
-#ifndef tlb_end_vma
-#define tlb_end_vma __tlb_end_vma
-#endif
-
-#ifndef __tlb_remove_tlb_entry
-#define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0)
-#endif
-
/**
* tlb_remove_tlb_entry - remember a pte unmapping for later tlb invalidation.
*
- * Record the fact that pte's were really unmapped by updating the range,
- * so we can later optimise away the tlb invalidate. This helps when
- * userspace is unmapping already-unmapped pages, which happens quite a lot.
+ * Record the fact that pte's were really umapped in ->need_flush, so we can
+ * later optimise away the tlb invalidate. This helps when userspace is
+ * unmapping already-unmapped pages, which happens quite a lot.
*/
#define tlb_remove_tlb_entry(tlb, ptep, address) \
do { \
- __tlb_adjust_range(tlb, address); \
+ tlb->need_flush = 1; \
__tlb_remove_tlb_entry(tlb, ptep, address); \
} while (0)
@@ -192,27 +151,27 @@ static inline void __tlb_reset_range(struct mmu_gather *tlb)
#define tlb_remove_pmd_tlb_entry(tlb, pmdp, address) \
do { \
- __tlb_adjust_range(tlb, address); \
+ tlb->need_flush = 1; \
__tlb_remove_pmd_tlb_entry(tlb, pmdp, address); \
} while (0)
#define pte_free_tlb(tlb, ptep, address) \
do { \
- __tlb_adjust_range(tlb, address); \
+ tlb->need_flush = 1; \
__pte_free_tlb(tlb, ptep, address); \
} while (0)
#ifndef __ARCH_HAS_4LEVEL_HACK
#define pud_free_tlb(tlb, pudp, address) \
do { \
- __tlb_adjust_range(tlb, address); \
+ tlb->need_flush = 1; \
__pud_free_tlb(tlb, pudp, address); \
} while (0)
#endif
#define pmd_free_tlb(tlb, pmdp, address) \
do { \
- __tlb_adjust_range(tlb, address); \
+ tlb->need_flush = 1; \
__pmd_free_tlb(tlb, pmdp, address); \
} while (0)
diff --git a/mm/memory.c b/mm/memory.c
index 411144f..2772d7a 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -220,6 +220,9 @@ void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long
/* Is it from 0 to ~0? */
tlb->fullmm = !(start | (end+1));
tlb->need_flush_all = 0;
+ tlb->start = start;
+ tlb->end = end;
+ tlb->need_flush = 0;
tlb->local.next = NULL;
tlb->local.nr = 0;
tlb->local.max = ARRAY_SIZE(tlb->__pages);
@@ -229,28 +232,23 @@ void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long
#ifdef CONFIG_HAVE_RCU_TABLE_FREE
tlb->batch = NULL;
#endif
-
- __tlb_reset_range(tlb);
}
static void tlb_flush_mmu_tlbonly(struct mmu_gather *tlb)
{
- if (!tlb->end)
- return;
-
+ tlb->need_flush = 0;
tlb_flush(tlb);
mmu_notifier_invalidate_range(tlb->mm, tlb->start, tlb->end);
#ifdef CONFIG_HAVE_RCU_TABLE_FREE
tlb_table_flush(tlb);
#endif
- __tlb_reset_range(tlb);
}
static void tlb_flush_mmu_free(struct mmu_gather *tlb)
{
struct mmu_gather_batch *batch;
- for (batch = &tlb->local; batch && batch->nr; batch = batch->next) {
+ for (batch = &tlb->local; batch; batch = batch->next) {
free_pages_and_swap_cache(batch->pages, batch->nr);
batch->nr = 0;
}
@@ -259,6 +257,8 @@ static void tlb_flush_mmu_free(struct mmu_gather *tlb)
void tlb_flush_mmu(struct mmu_gather *tlb)
{
+ if (!tlb->need_flush)
+ return;
tlb_flush_mmu_tlbonly(tlb);
tlb_flush_mmu_free(tlb);
}
@@ -293,7 +293,7 @@ int __tlb_remove_page(struct mmu_gather *tlb, struct page *page)
{
struct mmu_gather_batch *batch;
- VM_BUG_ON(!tlb->end);
+ VM_BUG_ON(!tlb->need_flush);
batch = tlb->active;
batch->pages[batch->nr++] = page;
@@ -360,6 +360,8 @@ void tlb_remove_table(struct mmu_gather *tlb, void *table)
{
struct mmu_table_batch **batch = &tlb->batch;
+ tlb->need_flush = 1;
+
/*
* When there's less then two users of this mm there cannot be a
* concurrent page-table walk.
@@ -1161,8 +1163,20 @@ again:
arch_leave_lazy_mmu_mode();
/* Do the actual TLB flush before dropping ptl */
- if (force_flush)
+ if (force_flush) {
+ unsigned long old_end;
+
+ /*
+ * Flush the TLB just for the previous segment,
+ * then update the range to be the remaining
+ * TLB range.
+ */
+ old_end = tlb->end;
+ tlb->end = addr;
tlb_flush_mmu_tlbonly(tlb);
+ tlb->start = addr;
+ tlb->end = old_end;
+ }
pte_unmap_unlock(start_pte, ptl);
/*

View File

@ -1718,13 +1718,13 @@ CONFIG_B43_PCMCIA=y
CONFIG_B43_SDIO=y
CONFIG_B43_BCMA=y
CONFIG_B43_BCMA_PIO=y
CONFIG_B43_DEBUG=y
# CONFIG_B43_DEBUG is not set
CONFIG_B43_PHY_LP=y
CONFIG_B43_PHY_N=y
CONFIG_B43_PHY_HT=y
CONFIG_B43_PHY_G=y
CONFIG_B43LEGACY=m
CONFIG_B43LEGACY_DEBUG=y
# CONFIG_B43LEGACY_DEBUG is not set
CONFIG_B43LEGACY_DMA=y
CONFIG_B43LEGACY_PIO=y
CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y
@ -4785,7 +4785,7 @@ CONFIG_PM_DEBUG=y
# CONFIG_DPM_WATCHDOG is not set # revisit this in debug
CONFIG_PM_TRACE=y
CONFIG_PM_TRACE_RTC=y
CONFIG_PM_TEST_SUSPEND=y
# CONFIG_PM_TEST_SUSPEND is not set
CONFIG_PM_RUNTIME=y
# CONFIG_PM_OPP is not set
# CONFIG_PM_AUTOSLEEP is not set

View File

@ -2,100 +2,100 @@ CONFIG_SND_VERBOSE_PRINTK=y
CONFIG_SND_DEBUG=y
CONFIG_SND_PCM_XRUN_DEBUG=y
CONFIG_DEBUG_ATOMIC_SLEEP=y
# CONFIG_DEBUG_ATOMIC_SLEEP is not set
CONFIG_DEBUG_MUTEXES=y
CONFIG_DEBUG_RT_MUTEXES=y
CONFIG_DEBUG_LOCK_ALLOC=y
CONFIG_LOCK_TORTURE_TEST=m
CONFIG_PROVE_LOCKING=y
CONFIG_DEBUG_SPINLOCK=y
CONFIG_PROVE_RCU=y
# CONFIG_DEBUG_MUTEXES is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_DEBUG_LOCK_ALLOC is not set
# CONFIG_LOCK_TORTURE_TEST is not set
# CONFIG_PROVE_LOCKING is not set
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_PROVE_RCU is not set
# CONFIG_PROVE_RCU_REPEATEDLY is not set
CONFIG_DEBUG_PER_CPU_MAPS=y
# CONFIG_DEBUG_PER_CPU_MAPS is not set
CONFIG_CPUMASK_OFFSTACK=y
CONFIG_CPU_NOTIFIER_ERROR_INJECT=m
# CONFIG_CPU_NOTIFIER_ERROR_INJECT is not set
CONFIG_FAULT_INJECTION=y
CONFIG_FAILSLAB=y
CONFIG_FAIL_PAGE_ALLOC=y
CONFIG_FAIL_MAKE_REQUEST=y
CONFIG_FAULT_INJECTION_DEBUG_FS=y
CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y
CONFIG_FAIL_IO_TIMEOUT=y
CONFIG_FAIL_MMC_REQUEST=y
# CONFIG_FAULT_INJECTION is not set
# CONFIG_FAILSLAB is not set
# CONFIG_FAIL_PAGE_ALLOC is not set
# CONFIG_FAIL_MAKE_REQUEST is not set
# CONFIG_FAULT_INJECTION_DEBUG_FS is not set
# CONFIG_FAULT_INJECTION_STACKTRACE_FILTER is not set
# CONFIG_FAIL_IO_TIMEOUT is not set
# CONFIG_FAIL_MMC_REQUEST is not set
CONFIG_LOCK_STAT=y
# CONFIG_LOCK_STAT is not set
CONFIG_DEBUG_STACK_USAGE=y
# CONFIG_DEBUG_STACK_USAGE is not set
CONFIG_ACPI_DEBUG=y
# CONFIG_ACPI_DEBUG is not set
CONFIG_DEBUG_SG=y
CONFIG_DEBUG_PI_LIST=y
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_PI_LIST is not set
# CONFIG_PAGE_EXTENSION is not set
# CONFIG_PAGE_OWNER is not set
# CONFIG_DEBUG_PAGEALLOC is not set
CONFIG_DEBUG_OBJECTS=y
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_DEBUG_OBJECTS_SELFTEST is not set
CONFIG_DEBUG_OBJECTS_FREE=y
CONFIG_DEBUG_OBJECTS_TIMERS=y
CONFIG_DEBUG_OBJECTS_RCU_HEAD=y
# CONFIG_DEBUG_OBJECTS_FREE is not set
# CONFIG_DEBUG_OBJECTS_TIMERS is not set
# CONFIG_DEBUG_OBJECTS_RCU_HEAD is not set
CONFIG_DEBUG_OBJECTS_ENABLE_DEFAULT=1
CONFIG_X86_PTDUMP=y
CONFIG_ARM64_PTDUMP=y
CONFIG_EFI_PGT_DUMP=y
# CONFIG_ARM64_PTDUMP is not set
# CONFIG_EFI_PGT_DUMP is not set
CONFIG_CAN_DEBUG_DEVICES=y
# CONFIG_CAN_DEBUG_DEVICES is not set
CONFIG_MODULE_FORCE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
CONFIG_DEBUG_NOTIFIERS=y
# CONFIG_DEBUG_NOTIFIERS is not set
CONFIG_DMA_API_DEBUG=y
# CONFIG_DMA_API_DEBUG is not set
CONFIG_MMIOTRACE=y
# CONFIG_MMIOTRACE is not set
CONFIG_DEBUG_CREDENTIALS=y
# CONFIG_DEBUG_CREDENTIALS is not set
# off in both production debug and nodebug builds,
# on in rawhide nodebug builds
CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y
# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
CONFIG_EXT4_DEBUG=y
# CONFIG_EXT4_DEBUG is not set
# CONFIG_XFS_WARN is not set
CONFIG_DEBUG_PERF_USE_VMALLOC=y
# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
CONFIG_JBD2_DEBUG=y
# CONFIG_JBD2_DEBUG is not set
CONFIG_NFSD_FAULT_INJECTION=y
# CONFIG_NFSD_FAULT_INJECTION is not set
CONFIG_DEBUG_BLK_CGROUP=y
# CONFIG_DEBUG_BLK_CGROUP is not set
CONFIG_DRBD_FAULT_INJECTION=y
# CONFIG_DRBD_FAULT_INJECTION is not set
CONFIG_ATH_DEBUG=y
CONFIG_CARL9170_DEBUGFS=y
CONFIG_IWLWIFI_DEVICE_TRACING=y
# CONFIG_ATH_DEBUG is not set
# CONFIG_CARL9170_DEBUGFS is not set
# CONFIG_IWLWIFI_DEVICE_TRACING is not set
# CONFIG_RTLWIFI_DEBUG is not set
CONFIG_DEBUG_OBJECTS_WORK=y
# CONFIG_DEBUG_OBJECTS_WORK is not set
CONFIG_DMADEVICES_DEBUG=y
CONFIG_DMADEVICES_VDEBUG=y
# CONFIG_DMADEVICES_DEBUG is not set
# CONFIG_DMADEVICES_VDEBUG is not set
CONFIG_PM_ADVANCED_DEBUG=y
CONFIG_CEPH_LIB_PRETTYDEBUG=y
CONFIG_QUOTA_DEBUG=y
# CONFIG_CEPH_LIB_PRETTYDEBUG is not set
# CONFIG_QUOTA_DEBUG is not set
CONFIG_KGDB_KDB=y
@ -103,18 +103,18 @@ CONFIG_KDB_DEFAULT_ENABLE=0x0
CONFIG_KDB_KEYBOARD=y
CONFIG_KDB_CONTINUE_CATASTROPHIC=0
CONFIG_DEBUG_OBJECTS_PERCPU_COUNTER=y
# CONFIG_DEBUG_OBJECTS_PERCPU_COUNTER is not set
# CONFIG_PERCPU_TEST is not set
CONFIG_TEST_LIST_SORT=y
# CONFIG_TEST_LIST_SORT is not set
# CONFIG_TEST_STRING_HELPERS is not set
CONFIG_DETECT_HUNG_TASK=y
# CONFIG_DETECT_HUNG_TASK is not set
CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120
# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK=y
# CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK is not set
CONFIG_DEBUG_KMEMLEAK=y
# CONFIG_DEBUG_KMEMLEAK is not set
CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE=1024
# CONFIG_DEBUG_KMEMLEAK_TEST is not set
CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y
@ -125,7 +125,7 @@ CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y
# CONFIG_SPI_DEBUG is not set
CONFIG_X86_DEBUG_STATIC_CPU_HAS=y
# CONFIG_X86_DEBUG_STATIC_CPU_HAS is not set
# CONFIG_SCHEDSTATS is not set
# CONFIG_LATENCYTOP is not set

View File

@ -337,6 +337,7 @@ CONFIG_I2C_MPC=m
# CONFIG_CPU_IDLE is not set
# CONFIG_OF_UNITTEST is not set
# CONFIG_OF_SELFTEST is not set
# CONFIG_OF_OVERLAY is not set
# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set
# CONFIG_INPUT_GP2A is not set
# CONFIG_INPUT_GPIO_TILT_POLLED is not set

View File

@ -200,6 +200,7 @@ CONFIG_BACKLIGHT_PWM=m
# CONFIG_OF_UNITTEST is not set
# CONFIG_OF_SELFTEST is not set
# CONFIG_OF_OVERLAY is not set
# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set
# CONFIG_INPUT_GP2A is not set
# CONFIG_INPUT_GPIO_TILT_POLLED is not set

View File

@ -348,7 +348,7 @@ CONFIG_SP5100_TCO=m
# CONFIG_MEMTEST is not set
# CONFIG_DEBUG_TLBFLUSH is not set
CONFIG_MAXSMP=y
# CONFIG_MAXSMP is not set
CONFIG_HP_ILO=m

View File

@ -14,7 +14,7 @@ Upstream-status: http://lists.freedesktop.org/archives/intel-gfx/2013-November/0
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index e730789b53b7..74b3f14327cc 100644
index 9943c20a741d..bfac247e6d2c 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -10886,7 +10886,7 @@ check_crtc_state(struct drm_device *dev)

View File

@ -3595,14 +3595,15 @@ index cce9524..c50ca8f 100644
const struct cpu_operations **ops = supported_cpu_ops;
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
index b42c7b4..a92be8e 100644
index 2b8d70164428..f5808cee51a2 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c
@@ -354,3 +354,40 @@ void efi_virtmap_unload(void)
efi_set_pgd(current->active_mm);
preempt_enable();
@@ -363,3 +363,42 @@ bool efi_poweroff_required(void)
{
return efi_enabled(EFI_RUNTIME_SERVICES);
}
+
+
+/*
+ * If nothing else is handling pm_power_off, use EFI
+ *
@ -3639,6 +3640,7 @@ index b42c7b4..a92be8e 100644
+ return ret;
+}
+late_initcall(arm64_register_efi_restart);
+
diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c
index 6f93c24..c870fa4 100644
--- a/arch/arm64/kernel/pci.c

View File

@ -68,9 +68,9 @@ Summary: The Linux kernel
# define upstream_sublevel %(echo $((%{base_sublevel} + 1)))
%define upstream_sublevel 0
# The rc snapshot level
%define rcrev 3
%define rcrev 4
# The git snapshot level
%define gitrev 2
%define gitrev 0
# Set rpm version accordingly
%define rpmversion 4.%{upstream_sublevel}.0
%endif
@ -125,7 +125,7 @@ Summary: The Linux kernel
# Set debugbuildsenabled to 1 for production (build separate debug kernels)
# and 0 for rawhide (all kernels are debug kernels).
# See also 'make debug' and 'make release'.
%define debugbuildsenabled 0
%define debugbuildsenabled 1
# Want to build a vanilla kernel build without any non-upstream patches?
%define with_vanilla %{?_with_vanilla: 1} %{?!_with_vanilla: 0}
@ -412,7 +412,7 @@ BuildRequires: binutils-%{_build_arch}-linux-gnu, gcc-%{_build_arch}-linux-gnu
%endif
#Source0: ftp://ftp.kernel.org/pub/linux/kernel/v4.x/linux-%{kversion}.tar.xz
Source0: ftp://ftp.kernel.org/pub/linux/kernel/v4.x/linux-4.0-rc3.tar.xz
Source0: ftp://ftp.kernel.org/pub/linux/kernel/v4.x/linux-4.0-rc4.tar.xz
Source10: perf-man-%{kversion}.tar.gz
Source11: x509.genkey
@ -629,9 +629,6 @@ Patch26140: security-yama-Remove-unnecessary-selects-from-Kconfi.patch
Patch26141: mfd-rtsx_usb-prevent-DMA-from-stack.patch
#rhbz 1199312
Patch26142: Revert-cpupower-Makefile-change-to-help-run-the-tool.patch
#rhbz 1200777 1200778
Patch26150: Input-synaptics-split-synaptics_resolution-query-fir.patch
Patch26151: Input-synaptics-log-queried-and-quirked-dimension-va.patch
@ -649,9 +646,6 @@ Patch26162: Input-synaptics-remove-X1-Carbon-3rd-gen-from-the-to.patch
Patch26163: Input-synaptics-remove-X250-from-the-topbuttonpad-li.patch
Patch26164: Revert-Input-synaptics-use-dmax-in-input_mt_assign_s.patch
#CVE-2015-2150 rhbz 1196266 1200397
Patch26165: xen-pciback-limit-guest-control-of-command-register.patch
#CVE-2014-8159 rhbz 1181166 1200950
Patch26167: IB-core-Prevent-integer-overflow-in-ib_umem_get-addr.patch
@ -660,7 +654,6 @@ Patch26168: HID-multitouch-add-support-of-clickpads.patch
# git clone ssh://git.fedorahosted.org/git/kernel-arm64.git, git diff master...devel
Patch30000: kernel-arm64.patch
Patch30001: arm64-revert-tlb-rcu_table_free.patch
# END OF PATCH DEFINITIONS
@ -1392,9 +1385,6 @@ ApplyPatch security-yama-Remove-unnecessary-selects-from-Kconfi.patch
ApplyPatch mfd-rtsx_usb-prevent-DMA-from-stack.patch
#rhbz 1199312
ApplyPatch Revert-cpupower-Makefile-change-to-help-run-the-tool.patch
#rhbz 1200777 1200778
ApplyPatch Input-synaptics-split-synaptics_resolution-query-fir.patch
ApplyPatch Input-synaptics-log-queried-and-quirked-dimension-va.patch
@ -1412,9 +1402,6 @@ ApplyPatch Input-synaptics-remove-X1-Carbon-3rd-gen-from-the-to.patch
ApplyPatch Input-synaptics-remove-X250-from-the-topbuttonpad-li.patch
ApplyPatch Revert-Input-synaptics-use-dmax-in-input_mt_assign_s.patch
#CVE-2015-2150 rhbz 1196266 1200397
ApplyPatch xen-pciback-limit-guest-control-of-command-register.patch
#CVE-2014-8159 rhbz 1181166 1200950
ApplyPatch IB-core-Prevent-integer-overflow-in-ib_umem_get-addr.patch
@ -1423,10 +1410,8 @@ ApplyPatch HID-multitouch-add-support-of-clickpads.patch
%if 0%{?aarch64patches}
ApplyPatch kernel-arm64.patch
ApplyPatch arm64-revert-tlb-rcu_table_free.patch
%ifnarch aarch64 # this is stupid, but i want to notice before secondary koji does.
ApplyPatch kernel-arm64.patch -R
ApplyPatch arm64-revert-tlb-rcu_table_free.patch -R
%endif
%endif
@ -2280,6 +2265,11 @@ fi
#
#
%changelog
* Mon Mar 16 2015 Josh Boyer <jwboyer@fedoraproject.org> - 4.0.0-0.rc4.git0.1
- Linux v4.0-rc4
- Drop arm64 RCU revert patch. Should be fixed properly upstream now.
- Disable debugging options.
* Sun Mar 15 2015 Jarod Wilson <jwilson@fedoraproject.org>
- Fix kernel-tools sub-packages for variant builds

View File

@ -1,3 +1,2 @@
ea00d3ccc1249e1d068c96eb090a8cec linux-4.0-rc3.tar.xz
2d0e6d7e3c2ef9968f929ec031a36f93 perf-man-4.0-rc3.tar.gz
30f8cfa798597dc3afce1f5e0986f215 patch-4.0-rc3-git2.xz
0e37c076159538ff882f190d87fe9798 linux-4.0-rc4.tar.xz
53996d49f76b39851ab26efd8c70fe53 perf-man-4.0-rc4.tar.gz

View File

@ -1,156 +0,0 @@
From: Jan Beulich <JBeulich@suse.com>
Date: Wed, 11 Mar 2015 13:51:17 +0000
Subject: [PATCH] xen-pciback: limit guest control of command register
Otherwise the guest can abuse that control to cause e.g. PCIe
Unsupported Request responses (by disabling memory and/or I/O decoding
and subsequently causing [CPU side] accesses to the respective address
ranges), which (depending on system configuration) may be fatal to the
host.
Note that to alter any of the bits collected together as
PCI_COMMAND_GUEST permissive mode is now required to be enabled
globally or on the specific device.
This is CVE-2015-2150 / XSA-120.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
---
drivers/xen/xen-pciback/conf_space.c | 2 +-
drivers/xen/xen-pciback/conf_space.h | 2 +
drivers/xen/xen-pciback/conf_space_header.c | 61 +++++++++++++++++++++++------
3 files changed, 51 insertions(+), 14 deletions(-)
diff --git a/drivers/xen/xen-pciback/conf_space.c b/drivers/xen/xen-pciback/conf_space.c
index 46ae0f9f02ad..75fe3d466515 100644
--- a/drivers/xen/xen-pciback/conf_space.c
+++ b/drivers/xen/xen-pciback/conf_space.c
@@ -16,7 +16,7 @@
#include "conf_space.h"
#include "conf_space_quirks.h"
-static bool permissive;
+bool permissive;
module_param(permissive, bool, 0644);
/* This is where xen_pcibk_read_config_byte, xen_pcibk_read_config_word,
diff --git a/drivers/xen/xen-pciback/conf_space.h b/drivers/xen/xen-pciback/conf_space.h
index e56c934ad137..2e1d73d1d5d0 100644
--- a/drivers/xen/xen-pciback/conf_space.h
+++ b/drivers/xen/xen-pciback/conf_space.h
@@ -64,6 +64,8 @@ struct config_field_entry {
void *data;
};
+extern bool permissive;
+
#define OFFSET(cfg_entry) ((cfg_entry)->base_offset+(cfg_entry)->field->offset)
/* Add fields to a device - the add_fields macro expects to get a pointer to
diff --git a/drivers/xen/xen-pciback/conf_space_header.c b/drivers/xen/xen-pciback/conf_space_header.c
index c5ee82587e8c..2d7369391472 100644
--- a/drivers/xen/xen-pciback/conf_space_header.c
+++ b/drivers/xen/xen-pciback/conf_space_header.c
@@ -11,6 +11,10 @@
#include "pciback.h"
#include "conf_space.h"
+struct pci_cmd_info {
+ u16 val;
+};
+
struct pci_bar_info {
u32 val;
u32 len_val;
@@ -20,22 +24,36 @@ struct pci_bar_info {
#define is_enable_cmd(value) ((value)&(PCI_COMMAND_MEMORY|PCI_COMMAND_IO))
#define is_master_cmd(value) ((value)&PCI_COMMAND_MASTER)
-static int command_read(struct pci_dev *dev, int offset, u16 *value, void *data)
+/* Bits guests are allowed to control in permissive mode. */
+#define PCI_COMMAND_GUEST (PCI_COMMAND_MASTER|PCI_COMMAND_SPECIAL| \
+ PCI_COMMAND_INVALIDATE|PCI_COMMAND_VGA_PALETTE| \
+ PCI_COMMAND_WAIT|PCI_COMMAND_FAST_BACK)
+
+static void *command_init(struct pci_dev *dev, int offset)
{
- int i;
- int ret;
-
- ret = xen_pcibk_read_config_word(dev, offset, value, data);
- if (!pci_is_enabled(dev))
- return ret;
-
- for (i = 0; i < PCI_ROM_RESOURCE; i++) {
- if (dev->resource[i].flags & IORESOURCE_IO)
- *value |= PCI_COMMAND_IO;
- if (dev->resource[i].flags & IORESOURCE_MEM)
- *value |= PCI_COMMAND_MEMORY;
+ struct pci_cmd_info *cmd = kmalloc(sizeof(*cmd), GFP_KERNEL);
+ int err;
+
+ if (!cmd)
+ return ERR_PTR(-ENOMEM);
+
+ err = pci_read_config_word(dev, PCI_COMMAND, &cmd->val);
+ if (err) {
+ kfree(cmd);
+ return ERR_PTR(err);
}
+ return cmd;
+}
+
+static int command_read(struct pci_dev *dev, int offset, u16 *value, void *data)
+{
+ int ret = pci_read_config_word(dev, offset, value);
+ const struct pci_cmd_info *cmd = data;
+
+ *value &= PCI_COMMAND_GUEST;
+ *value |= cmd->val & ~PCI_COMMAND_GUEST;
+
return ret;
}
@@ -43,6 +61,8 @@ static int command_write(struct pci_dev *dev, int offset, u16 value, void *data)
{
struct xen_pcibk_dev_data *dev_data;
int err;
+ u16 val;
+ struct pci_cmd_info *cmd = data;
dev_data = pci_get_drvdata(dev);
if (!pci_is_enabled(dev) && is_enable_cmd(value)) {
@@ -83,6 +103,19 @@ static int command_write(struct pci_dev *dev, int offset, u16 value, void *data)
}
}
+ cmd->val = value;
+
+ if (!permissive && (!dev_data || !dev_data->permissive))
+ return 0;
+
+ /* Only allow the guest to control certain bits. */
+ err = pci_read_config_word(dev, offset, &val);
+ if (err || val == value)
+ return err;
+
+ value &= PCI_COMMAND_GUEST;
+ value |= val & ~PCI_COMMAND_GUEST;
+
return pci_write_config_word(dev, offset, value);
}
@@ -282,6 +315,8 @@ static const struct config_field header_common[] = {
{
.offset = PCI_COMMAND,
.size = 2,
+ .init = command_init,
+ .release = bar_release,
.u.w.read = command_read,
.u.w.write = command_write,
},
--
2.1.0