Commit ebb65c81 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'powerpc-4.3-4' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux

Pull powerpc fixes from Michael Ellerman:
 - Re-enable CONFIG_SCSI_DH in our defconfigs
 - Remove unused os_area_db_id_video_mode
 - cxl: fix leak of IRQ names in cxl_free_afu_irqs() from Andrew
 - cxl: fix leak of ctx->irq_bitmap when releasing context via kernel API from Andrew
 - cxl: fix leak of ctx->mapping when releasing kernel API contexts from Andrew
 - cxl: Workaround malformed pcie packets on some cards from Philippe
 - cxl: Fix number of allocated pages in SPA from Christophe Lombard
 - Fix checkstop in native_hpte_clear() with lockdep from Cyril
 - Panic on unhandled Machine Check on powernv from Daniel
 - selftests/powerpc: Fix build failure of load_unaligned_zeropad test

* tag 'powerpc-4.3-4' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux:
  selftests/powerpc: Fix build failure of load_unaligned_zeropad test
  powerpc/powernv: Panic on unhandled Machine Check
  powerpc: Fix checkstop in native_hpte_clear() with lockdep
  cxl: Fix number of allocated pages in SPA
  cxl: Workaround malformed pcie packets on some cards
  cxl: fix leak of ctx->mapping when releasing kernel API contexts
  cxl: fix leak of ctx->irq_bitmap when releasing context via kernel API
  cxl: fix leak of IRQ names in cxl_free_afu_irqs()
  powerpc/ps3: Remove unused os_area_db_id_video_mode
  powerpc/configs: Re-enable CONFIG_SCSI_DH
parents 3d875182 abb39bc7
...@@ -111,7 +111,7 @@ CONFIG_SCSI_QLA_FC=m ...@@ -111,7 +111,7 @@ CONFIG_SCSI_QLA_FC=m
CONFIG_SCSI_QLA_ISCSI=m CONFIG_SCSI_QLA_ISCSI=m
CONFIG_SCSI_LPFC=m CONFIG_SCSI_LPFC=m
CONFIG_SCSI_VIRTIO=m CONFIG_SCSI_VIRTIO=m
CONFIG_SCSI_DH=m CONFIG_SCSI_DH=y
CONFIG_SCSI_DH_RDAC=m CONFIG_SCSI_DH_RDAC=m
CONFIG_SCSI_DH_ALUA=m CONFIG_SCSI_DH_ALUA=m
CONFIG_ATA=y CONFIG_ATA=y
......
...@@ -114,7 +114,7 @@ CONFIG_SCSI_QLA_FC=m ...@@ -114,7 +114,7 @@ CONFIG_SCSI_QLA_FC=m
CONFIG_SCSI_QLA_ISCSI=m CONFIG_SCSI_QLA_ISCSI=m
CONFIG_SCSI_LPFC=m CONFIG_SCSI_LPFC=m
CONFIG_SCSI_VIRTIO=m CONFIG_SCSI_VIRTIO=m
CONFIG_SCSI_DH=m CONFIG_SCSI_DH=y
CONFIG_SCSI_DH_RDAC=m CONFIG_SCSI_DH_RDAC=m
CONFIG_SCSI_DH_ALUA=m CONFIG_SCSI_DH_ALUA=m
CONFIG_ATA=y CONFIG_ATA=y
......
...@@ -61,8 +61,13 @@ struct machdep_calls { ...@@ -61,8 +61,13 @@ struct machdep_calls {
unsigned long addr, unsigned long addr,
unsigned char *hpte_slot_array, unsigned char *hpte_slot_array,
int psize, int ssize, int local); int psize, int ssize, int local);
/* special for kexec, to be called in real mode, linear mapping is /*
* destroyed as well */ * Special for kexec.
* To be called in real mode with interrupts disabled. No locks are
* taken as such, concurrent access on pre POWER5 hardware could result
* in a deadlock.
* The linear mapping is destroyed as well.
*/
void (*hpte_clear_all)(void); void (*hpte_clear_all)(void);
void __iomem * (*ioremap)(phys_addr_t addr, unsigned long size, void __iomem * (*ioremap)(phys_addr_t addr, unsigned long size,
......
...@@ -582,13 +582,21 @@ static void hpte_decode(struct hash_pte *hpte, unsigned long slot, ...@@ -582,13 +582,21 @@ static void hpte_decode(struct hash_pte *hpte, unsigned long slot,
* be when they isi), and we are the only one left. We rely on our kernel * be when they isi), and we are the only one left. We rely on our kernel
* mapping being 0xC0's and the hardware ignoring those two real bits. * mapping being 0xC0's and the hardware ignoring those two real bits.
* *
* This must be called with interrupts disabled.
*
* Taking the native_tlbie_lock is unsafe here due to the possibility of
* lockdep being on. On pre POWER5 hardware, not taking the lock could
* cause deadlock. POWER5 and newer not taking the lock is fine. This only
* gets called during boot before secondary CPUs have come up and during
* crashdump and all bets are off anyway.
*
* TODO: add batching support when enabled. remember, no dynamic memory here, * TODO: add batching support when enabled. remember, no dynamic memory here,
* athough there is the control page available... * athough there is the control page available...
*/ */
static void native_hpte_clear(void) static void native_hpte_clear(void)
{ {
unsigned long vpn = 0; unsigned long vpn = 0;
unsigned long slot, slots, flags; unsigned long slot, slots;
struct hash_pte *hptep = htab_address; struct hash_pte *hptep = htab_address;
unsigned long hpte_v; unsigned long hpte_v;
unsigned long pteg_count; unsigned long pteg_count;
...@@ -596,13 +604,6 @@ static void native_hpte_clear(void) ...@@ -596,13 +604,6 @@ static void native_hpte_clear(void)
pteg_count = htab_hash_mask + 1; pteg_count = htab_hash_mask + 1;
local_irq_save(flags);
/* we take the tlbie lock and hold it. Some hardware will
* deadlock if we try to tlbie from two processors at once.
*/
raw_spin_lock(&native_tlbie_lock);
slots = pteg_count * HPTES_PER_GROUP; slots = pteg_count * HPTES_PER_GROUP;
for (slot = 0; slot < slots; slot++, hptep++) { for (slot = 0; slot < slots; slot++, hptep++) {
...@@ -614,8 +615,8 @@ static void native_hpte_clear(void) ...@@ -614,8 +615,8 @@ static void native_hpte_clear(void)
hpte_v = be64_to_cpu(hptep->v); hpte_v = be64_to_cpu(hptep->v);
/* /*
* Call __tlbie() here rather than tlbie() since we * Call __tlbie() here rather than tlbie() since we can't take the
* already hold the native_tlbie_lock. * native_tlbie_lock.
*/ */
if (hpte_v & HPTE_V_VALID) { if (hpte_v & HPTE_V_VALID) {
hpte_decode(hptep, slot, &psize, &apsize, &ssize, &vpn); hpte_decode(hptep, slot, &psize, &apsize, &ssize, &vpn);
...@@ -625,8 +626,6 @@ static void native_hpte_clear(void) ...@@ -625,8 +626,6 @@ static void native_hpte_clear(void)
} }
asm volatile("eieio; tlbsync; ptesync":::"memory"); asm volatile("eieio; tlbsync; ptesync":::"memory");
raw_spin_unlock(&native_tlbie_lock);
local_irq_restore(flags);
} }
/* /*
......
...@@ -487,9 +487,12 @@ int opal_machine_check(struct pt_regs *regs) ...@@ -487,9 +487,12 @@ int opal_machine_check(struct pt_regs *regs)
* PRD component would have already got notified about this * PRD component would have already got notified about this
* error through other channels. * error through other channels.
* *
* In any case, let us just fall through. We anyway heading * If hardware marked this as an unrecoverable MCE, we are
* down to panic path. * going to panic anyway. Even if it didn't, it's not safe to
* continue at this point, so we should explicitly panic.
*/ */
panic("PowerNV Unrecovered Machine Check");
return 0; return 0;
} }
......
...@@ -194,11 +194,6 @@ static const struct os_area_db_id os_area_db_id_rtc_diff = { ...@@ -194,11 +194,6 @@ static const struct os_area_db_id os_area_db_id_rtc_diff = {
.key = OS_AREA_DB_KEY_RTC_DIFF .key = OS_AREA_DB_KEY_RTC_DIFF
}; };
static const struct os_area_db_id os_area_db_id_video_mode = {
.owner = OS_AREA_DB_OWNER_LINUX,
.key = OS_AREA_DB_KEY_VIDEO_MODE
};
#define SECONDS_FROM_1970_TO_2000 946684800LL #define SECONDS_FROM_1970_TO_2000 946684800LL
/** /**
......
...@@ -105,6 +105,7 @@ EXPORT_SYMBOL_GPL(cxl_allocate_afu_irqs); ...@@ -105,6 +105,7 @@ EXPORT_SYMBOL_GPL(cxl_allocate_afu_irqs);
void cxl_free_afu_irqs(struct cxl_context *ctx) void cxl_free_afu_irqs(struct cxl_context *ctx)
{ {
afu_irq_name_free(ctx);
cxl_release_irq_ranges(&ctx->irqs, ctx->afu->adapter); cxl_release_irq_ranges(&ctx->irqs, ctx->afu->adapter);
} }
EXPORT_SYMBOL_GPL(cxl_free_afu_irqs); EXPORT_SYMBOL_GPL(cxl_free_afu_irqs);
......
...@@ -275,6 +275,9 @@ static void reclaim_ctx(struct rcu_head *rcu) ...@@ -275,6 +275,9 @@ static void reclaim_ctx(struct rcu_head *rcu)
if (ctx->kernelapi) if (ctx->kernelapi)
kfree(ctx->mapping); kfree(ctx->mapping);
if (ctx->irq_bitmap)
kfree(ctx->irq_bitmap);
kfree(ctx); kfree(ctx);
} }
......
...@@ -677,6 +677,7 @@ int cxl_register_serr_irq(struct cxl_afu *afu); ...@@ -677,6 +677,7 @@ int cxl_register_serr_irq(struct cxl_afu *afu);
void cxl_release_serr_irq(struct cxl_afu *afu); void cxl_release_serr_irq(struct cxl_afu *afu);
int afu_register_irqs(struct cxl_context *ctx, u32 count); int afu_register_irqs(struct cxl_context *ctx, u32 count);
void afu_release_irqs(struct cxl_context *ctx, void *cookie); void afu_release_irqs(struct cxl_context *ctx, void *cookie);
void afu_irq_name_free(struct cxl_context *ctx);
irqreturn_t cxl_slice_irq_err(int irq, void *data); irqreturn_t cxl_slice_irq_err(int irq, void *data);
int cxl_debugfs_init(void); int cxl_debugfs_init(void);
......
...@@ -120,9 +120,16 @@ int afu_release(struct inode *inode, struct file *file) ...@@ -120,9 +120,16 @@ int afu_release(struct inode *inode, struct file *file)
__func__, ctx->pe); __func__, ctx->pe);
cxl_context_detach(ctx); cxl_context_detach(ctx);
/*
* Delete the context's mapping pointer, unless it's created by the
* kernel API, in which case leave it so it can be freed by reclaim_ctx()
*/
if (!ctx->kernelapi) {
mutex_lock(&ctx->mapping_lock); mutex_lock(&ctx->mapping_lock);
ctx->mapping = NULL; ctx->mapping = NULL;
mutex_unlock(&ctx->mapping_lock); mutex_unlock(&ctx->mapping_lock);
}
put_device(&ctx->afu->dev); put_device(&ctx->afu->dev);
......
...@@ -414,7 +414,7 @@ void cxl_release_psl_irq(struct cxl_afu *afu) ...@@ -414,7 +414,7 @@ void cxl_release_psl_irq(struct cxl_afu *afu)
kfree(afu->psl_irq_name); kfree(afu->psl_irq_name);
} }
static void afu_irq_name_free(struct cxl_context *ctx) void afu_irq_name_free(struct cxl_context *ctx)
{ {
struct cxl_irq_name *irq_name, *tmp; struct cxl_irq_name *irq_name, *tmp;
...@@ -524,7 +524,5 @@ void afu_release_irqs(struct cxl_context *ctx, void *cookie) ...@@ -524,7 +524,5 @@ void afu_release_irqs(struct cxl_context *ctx, void *cookie)
afu_irq_name_free(ctx); afu_irq_name_free(ctx);
cxl_release_irq_ranges(&ctx->irqs, ctx->afu->adapter); cxl_release_irq_ranges(&ctx->irqs, ctx->afu->adapter);
kfree(ctx->irq_bitmap);
ctx->irq_bitmap = NULL;
ctx->irq_count = 0; ctx->irq_count = 0;
} }
...@@ -457,6 +457,7 @@ static int activate_afu_directed(struct cxl_afu *afu) ...@@ -457,6 +457,7 @@ static int activate_afu_directed(struct cxl_afu *afu)
dev_info(&afu->dev, "Activating AFU directed mode\n"); dev_info(&afu->dev, "Activating AFU directed mode\n");
afu->num_procs = afu->max_procs_virtualised;
if (afu->spa == NULL) { if (afu->spa == NULL) {
if (cxl_alloc_spa(afu)) if (cxl_alloc_spa(afu))
return -ENOMEM; return -ENOMEM;
...@@ -468,7 +469,6 @@ static int activate_afu_directed(struct cxl_afu *afu) ...@@ -468,7 +469,6 @@ static int activate_afu_directed(struct cxl_afu *afu)
cxl_p1n_write(afu, CXL_PSL_ID_An, CXL_PSL_ID_An_F | CXL_PSL_ID_An_L); cxl_p1n_write(afu, CXL_PSL_ID_An, CXL_PSL_ID_An_F | CXL_PSL_ID_An_L);
afu->current_mode = CXL_MODE_DIRECTED; afu->current_mode = CXL_MODE_DIRECTED;
afu->num_procs = afu->max_procs_virtualised;
if ((rc = cxl_chardev_m_afu_add(afu))) if ((rc = cxl_chardev_m_afu_add(afu)))
return rc; return rc;
......
...@@ -1035,6 +1035,32 @@ static int cxl_read_vsec(struct cxl *adapter, struct pci_dev *dev) ...@@ -1035,6 +1035,32 @@ static int cxl_read_vsec(struct cxl *adapter, struct pci_dev *dev)
return 0; return 0;
} }
/*
* Workaround a PCIe Host Bridge defect on some cards, that can cause
* malformed Transaction Layer Packet (TLP) errors to be erroneously
* reported. Mask this error in the Uncorrectable Error Mask Register.
*
* The upper nibble of the PSL revision is used to distinguish between
* different cards. The affected ones have it set to 0.
*/
static void cxl_fixup_malformed_tlp(struct cxl *adapter, struct pci_dev *dev)
{
int aer;
u32 data;
if (adapter->psl_rev & 0xf000)
return;
if (!(aer = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR)))
return;
pci_read_config_dword(dev, aer + PCI_ERR_UNCOR_MASK, &data);
if (data & PCI_ERR_UNC_MALF_TLP)
if (data & PCI_ERR_UNC_INTN)
return;
data |= PCI_ERR_UNC_MALF_TLP;
data |= PCI_ERR_UNC_INTN;
pci_write_config_dword(dev, aer + PCI_ERR_UNCOR_MASK, data);
}
static int cxl_vsec_looks_ok(struct cxl *adapter, struct pci_dev *dev) static int cxl_vsec_looks_ok(struct cxl *adapter, struct pci_dev *dev)
{ {
if (adapter->vsec_status & CXL_STATUS_SECOND_PORT) if (adapter->vsec_status & CXL_STATUS_SECOND_PORT)
...@@ -1134,6 +1160,8 @@ static int cxl_configure_adapter(struct cxl *adapter, struct pci_dev *dev) ...@@ -1134,6 +1160,8 @@ static int cxl_configure_adapter(struct cxl *adapter, struct pci_dev *dev)
if ((rc = cxl_vsec_looks_ok(adapter, dev))) if ((rc = cxl_vsec_looks_ok(adapter, dev)))
return rc; return rc;
cxl_fixup_malformed_tlp(adapter, dev);
if ((rc = setup_cxl_bars(dev))) if ((rc = setup_cxl_bars(dev)))
return rc; return rc;
......
...@@ -25,10 +25,19 @@ ...@@ -25,10 +25,19 @@
#define FIXUP_SECTION ".ex_fixup" #define FIXUP_SECTION ".ex_fixup"
static inline unsigned long __fls(unsigned long x);
#include "word-at-a-time.h" #include "word-at-a-time.h"
#include "utils.h" #include "utils.h"
static inline unsigned long __fls(unsigned long x)
{
int lz;
asm (PPC_CNTLZL "%0,%1" : "=r" (lz) : "r" (x));
return sizeof(unsigned long) - 1 - lz;
}
static int page_size; static int page_size;
static char *mem_region; static char *mem_region;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment